@warlock.js/cascade 5.19.0 → 5.20.0
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 +6 -0
- package/cjs/index.cjs +78 -7
- package/cjs/index.cjs.map +1 -1
- package/esm/context/database-transaction-context.d.mts +10 -0
- package/esm/context/database-transaction-context.d.mts.map +1 -1
- package/esm/context/database-transaction-context.mjs +17 -0
- package/esm/context/database-transaction-context.mjs.map +1 -1
- package/esm/drivers/mongodb/mongodb-driver.d.mts.map +1 -1
- package/esm/drivers/mongodb/mongodb-driver.mjs +13 -5
- package/esm/drivers/mongodb/mongodb-driver.mjs.map +1 -1
- package/esm/drivers/postgres/postgres-driver.d.mts.map +1 -1
- package/esm/drivers/postgres/postgres-driver.mjs +8 -3
- package/esm/drivers/postgres/postgres-driver.mjs.map +1 -1
- package/esm/index.d.mts +2 -1
- package/esm/index.mjs +2 -1
- package/esm/migration/migration-runner.mjs +1 -1
- package/esm/transactions/after-commit.d.mts +24 -0
- package/esm/transactions/after-commit.d.mts.map +1 -0
- package/esm/transactions/after-commit.mjs +47 -0
- package/esm/transactions/after-commit.mjs.map +1 -0
- package/llms-full.txt +2783 -2766
- package/llms.txt +15 -15
- package/package.json +6 -6
- package/skills/aggregate-data/SKILL.md +165 -165
- package/skills/alter-migration/SKILL.md +531 -531
- package/skills/configure-delete-strategy/SKILL.md +130 -130
- package/skills/define-model/SKILL.md +205 -205
- package/skills/define-relations/SKILL.md +171 -171
- package/skills/index.md +23 -0
- package/skills/manage-data-sources/SKILL.md +140 -140
- package/skills/manage-transactions/SKILL.md +208 -191
- package/skills/paginate-results/SKILL.md +122 -122
- package/skills/perform-atomic-ops/SKILL.md +156 -156
- package/skills/query-data/SKILL.md +213 -213
- package/skills/run-cascade-cli/SKILL.md +125 -125
- package/skills/search-by-vector/SKILL.md +127 -127
- package/skills/subscribe-to-model-events/SKILL.md +148 -148
- package/skills/track-changes/SKILL.md +127 -127
- package/skills/write-migration/SKILL.md +206 -206
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,12 @@ All notable changes to `@warlock.js/cascade` are documented in this file.
|
|
|
4
4
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). `@warlock.js/*` packages are released in lockstep — every package shares the same version number, so a version below may list only the changes that affected this package.
|
|
6
6
|
|
|
7
|
+
## 5.20.0 - 2026-09-24
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- `afterCommit(fn)` — run a side effect only once the transaction has committed. Inside a transaction, `fn` is queued and runs after the outermost COMMIT (in order, awaited one by one); it is discarded on rollback or a failed COMMIT. Outside a transaction, it runs on the next microtask. Errors are logged and never change the transaction result. Use it in model event listeners (`saved`, `created`, ...) for cache clears, sitemap regeneration and emails.
|
|
12
|
+
|
|
7
13
|
## 5.19.0 - 2026-09-23
|
|
8
14
|
|
|
9
15
|
### Changed
|
package/cjs/index.cjs
CHANGED
|
@@ -27,6 +27,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
27
27
|
|
|
28
28
|
//#endregion
|
|
29
29
|
let _warlock_js_context = require("@warlock.js/context");
|
|
30
|
+
let _warlock_js_logger = require("@warlock.js/logger");
|
|
30
31
|
let node_events = require("node:events");
|
|
31
32
|
let _mongez_reinforcements = require("@mongez/reinforcements");
|
|
32
33
|
let _mongez_supportive_is = require("@mongez/supportive-is");
|
|
@@ -34,7 +35,6 @@ let _mongez_events = require("@mongez/events");
|
|
|
34
35
|
_mongez_events = __toESM(_mongez_events, 1);
|
|
35
36
|
let _warlock_js_seal = require("@warlock.js/seal");
|
|
36
37
|
let _mongez_copper = require("@mongez/copper");
|
|
37
|
-
let _warlock_js_logger = require("@warlock.js/logger");
|
|
38
38
|
let fs = require("fs");
|
|
39
39
|
fs = __toESM(fs, 1);
|
|
40
40
|
let path = require("path");
|
|
@@ -98,6 +98,23 @@ var DatabaseTransactionContext = class extends _warlock_js_context.Context {
|
|
|
98
98
|
this.set("session", session);
|
|
99
99
|
}
|
|
100
100
|
/**
|
|
101
|
+
* Queue a callback to run once the active transaction commits
|
|
102
|
+
*/
|
|
103
|
+
addAfterCommit(fn) {
|
|
104
|
+
const queue = this.get("afterCommit") ?? [];
|
|
105
|
+
queue.push(fn);
|
|
106
|
+
this.set("afterCommit", queue);
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Take (and empty) the queued after-commit callbacks.
|
|
110
|
+
* Must be called before `exit()`, which clears the store.
|
|
111
|
+
*/
|
|
112
|
+
takeAfterCommit() {
|
|
113
|
+
const queue = this.get("afterCommit") ?? [];
|
|
114
|
+
this.set("afterCommit", []);
|
|
115
|
+
return queue;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
101
118
|
* Exit the transaction context
|
|
102
119
|
*/
|
|
103
120
|
exit() {
|
|
@@ -113,6 +130,48 @@ var DatabaseTransactionContext = class extends _warlock_js_context.Context {
|
|
|
113
130
|
const databaseTransactionContext = new DatabaseTransactionContext();
|
|
114
131
|
_warlock_js_context.contextManager.register("db.transaction", databaseTransactionContext);
|
|
115
132
|
|
|
133
|
+
//#endregion
|
|
134
|
+
//#region ../cascade/src/transactions/after-commit.ts
|
|
135
|
+
function reportFailure(error) {
|
|
136
|
+
_warlock_js_logger.log.error("database", "afterCommit", `[cascade] afterCommit callback failed: ${error}`);
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Run a callback only once the current transaction has COMMITTED.
|
|
140
|
+
*
|
|
141
|
+
* Model events (`saved`, `created`, `updated`, `deleted`) fire INSIDE the
|
|
142
|
+
* transaction, before COMMIT. Anything that must observe committed data
|
|
143
|
+
* (cache invalidation, sitemap regeneration, webhooks) belongs here.
|
|
144
|
+
*
|
|
145
|
+
* - Inside a transaction: queued, run after the outermost COMMIT, in order,
|
|
146
|
+
* awaited one by one. Discarded on rollback or a failed COMMIT.
|
|
147
|
+
* - Outside a transaction: run on the next microtask (not awaited by the caller).
|
|
148
|
+
* - A callback that throws is logged; it never affects the transaction result
|
|
149
|
+
* or the remaining callbacks.
|
|
150
|
+
* - Callbacks run after the transaction context has exited, so any DB work
|
|
151
|
+
* they do is outside the finished transaction.
|
|
152
|
+
*
|
|
153
|
+
* @example
|
|
154
|
+
* Product.events().onSaved(() => afterCommit(() => regenerateSitemap()));
|
|
155
|
+
*/
|
|
156
|
+
function afterCommit(fn) {
|
|
157
|
+
if (databaseTransactionContext.hasActiveTransaction()) {
|
|
158
|
+
databaseTransactionContext.addAfterCommit(fn);
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
Promise.resolve().then(fn).catch(reportFailure);
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Run committed callbacks sequentially. Never throws.
|
|
165
|
+
* Drivers call this after a successful COMMIT and after the context exited.
|
|
166
|
+
*/
|
|
167
|
+
async function flushAfterCommit(callbacks) {
|
|
168
|
+
for (const callback of callbacks) try {
|
|
169
|
+
await callback();
|
|
170
|
+
} catch (error) {
|
|
171
|
+
reportFailure(error);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
116
175
|
//#endregion
|
|
117
176
|
//#region ../cascade/src/data-source/data-source.ts
|
|
118
177
|
/**
|
|
@@ -13979,15 +14038,18 @@ var MongoDbDriver = class {
|
|
|
13979
14038
|
await session.startTransaction(this.transactionOptions);
|
|
13980
14039
|
databaseTransactionContext.enter({ session });
|
|
13981
14040
|
let finished = false;
|
|
13982
|
-
const finalize = async (operation) => {
|
|
14041
|
+
const finalize = async (operation, committing = false) => {
|
|
13983
14042
|
if (finished) return;
|
|
14043
|
+
let committedCallbacks = [];
|
|
13984
14044
|
try {
|
|
13985
14045
|
await operation();
|
|
14046
|
+
if (committing) committedCallbacks = databaseTransactionContext.takeAfterCommit();
|
|
13986
14047
|
} finally {
|
|
13987
14048
|
finished = true;
|
|
13988
14049
|
databaseTransactionContext.exit();
|
|
13989
14050
|
await session.endSession().catch(() => void 0);
|
|
13990
14051
|
}
|
|
14052
|
+
await flushAfterCommit(committedCallbacks);
|
|
13991
14053
|
};
|
|
13992
14054
|
return {
|
|
13993
14055
|
context: session,
|
|
@@ -13999,7 +14061,7 @@ var MongoDbDriver = class {
|
|
|
13999
14061
|
await session.abortTransaction().catch(() => void 0);
|
|
14000
14062
|
throw error;
|
|
14001
14063
|
}
|
|
14002
|
-
});
|
|
14064
|
+
}, true);
|
|
14003
14065
|
},
|
|
14004
14066
|
rollback: async () => {
|
|
14005
14067
|
await finalize(async () => {
|
|
@@ -14030,6 +14092,8 @@ var MongoDbDriver = class {
|
|
|
14030
14092
|
if (databaseTransactionContext.hasActiveTransaction()) return fn(ctx);
|
|
14031
14093
|
await this.ensureReplicaSetAvailable();
|
|
14032
14094
|
const session = this.getClientInstance().startSession();
|
|
14095
|
+
let committedCallbacks = [];
|
|
14096
|
+
let result;
|
|
14033
14097
|
try {
|
|
14034
14098
|
await session.startTransaction({
|
|
14035
14099
|
...this.transactionOptions,
|
|
@@ -14037,9 +14101,9 @@ var MongoDbDriver = class {
|
|
|
14037
14101
|
});
|
|
14038
14102
|
databaseTransactionContext.enter({ session });
|
|
14039
14103
|
try {
|
|
14040
|
-
|
|
14104
|
+
result = await fn(ctx);
|
|
14041
14105
|
await session.commitTransaction();
|
|
14042
|
-
|
|
14106
|
+
committedCallbacks = databaseTransactionContext.takeAfterCommit();
|
|
14043
14107
|
} catch (error) {
|
|
14044
14108
|
await session.abortTransaction().catch(() => void 0);
|
|
14045
14109
|
throw error;
|
|
@@ -14049,6 +14113,8 @@ var MongoDbDriver = class {
|
|
|
14049
14113
|
} finally {
|
|
14050
14114
|
await session.endSession().catch(() => void 0);
|
|
14051
14115
|
}
|
|
14116
|
+
await flushAfterCommit(committedCallbacks);
|
|
14117
|
+
return result;
|
|
14052
14118
|
}
|
|
14053
14119
|
/**
|
|
14054
14120
|
* Execute atomic operations (typically $inc/$set style updates) against documents.
|
|
@@ -18723,11 +18789,13 @@ var PostgresDriver = class {
|
|
|
18723
18789
|
const tx = await this.beginTransaction(options);
|
|
18724
18790
|
databaseTransactionContext.enter({ session: tx.context });
|
|
18725
18791
|
let commitStarted = false;
|
|
18792
|
+
let committedCallbacks = [];
|
|
18793
|
+
let result;
|
|
18726
18794
|
try {
|
|
18727
|
-
|
|
18795
|
+
result = await fn(ctx);
|
|
18728
18796
|
commitStarted = true;
|
|
18729
18797
|
await tx.commit();
|
|
18730
|
-
|
|
18798
|
+
committedCallbacks = databaseTransactionContext.takeAfterCommit();
|
|
18731
18799
|
} catch (error) {
|
|
18732
18800
|
if (commitStarted) _warlock_js_logger.log.error(`database.postgress`, "transaction", "Transaction COMMIT failed; client discarded, no rollback issued");
|
|
18733
18801
|
else try {
|
|
@@ -18740,6 +18808,8 @@ var PostgresDriver = class {
|
|
|
18740
18808
|
} finally {
|
|
18741
18809
|
databaseTransactionContext.exit();
|
|
18742
18810
|
}
|
|
18811
|
+
await flushAfterCommit(committedCallbacks);
|
|
18812
|
+
return result;
|
|
18743
18813
|
}
|
|
18744
18814
|
/**
|
|
18745
18815
|
* Perform an atomic update operation.
|
|
@@ -23758,6 +23828,7 @@ exports.UnsafeRawExpressionError = UnsafeRawExpressionError;
|
|
|
23758
23828
|
exports.UnsupportedLeanOperationError = UnsupportedLeanOperationError;
|
|
23759
23829
|
exports.UnsupportedQueryOperationError = UnsupportedQueryOperationError;
|
|
23760
23830
|
exports.UnsupportedUpdateOperationError = UnsupportedUpdateOperationError;
|
|
23831
|
+
exports.afterCommit = afterCommit;
|
|
23761
23832
|
exports.arrayBigInt = arrayBigInt;
|
|
23762
23833
|
exports.arrayBoolean = arrayBoolean;
|
|
23763
23834
|
exports.arrayDate = arrayDate;
|