@warlock.js/cascade 5.30.0 → 5.32.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.
Files changed (277) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/README.md +1 -5
  3. package/cjs/index.cjs +104 -86
  4. package/cjs/index.cjs.map +1 -1
  5. package/esm/context/database-data-source-context.d.mts +2 -3
  6. package/esm/context/database-data-source-context.d.mts.map +1 -1
  7. package/esm/context/database-transaction-context.d.mts +2 -3
  8. package/esm/context/database-transaction-context.d.mts.map +1 -1
  9. package/esm/contracts/database-driver.contract.d.mts +56 -36
  10. package/esm/contracts/database-driver.contract.d.mts.map +1 -1
  11. package/esm/contracts/database-id-generator.contract.d.mts +7 -5
  12. package/esm/contracts/database-id-generator.contract.d.mts.map +1 -1
  13. package/esm/contracts/database-remover.contract.d.mts +3 -5
  14. package/esm/contracts/database-remover.contract.d.mts.map +1 -1
  15. package/esm/contracts/database-restorer.contract.d.mts +6 -6
  16. package/esm/contracts/database-restorer.contract.d.mts.map +1 -1
  17. package/esm/contracts/database-writer.contract.d.mts +4 -6
  18. package/esm/contracts/database-writer.contract.d.mts.map +1 -1
  19. package/esm/contracts/driver-blueprint.contract.d.mts +2 -3
  20. package/esm/contracts/driver-blueprint.contract.d.mts.map +1 -1
  21. package/esm/contracts/index.d.mts +2 -1
  22. package/esm/contracts/migration-driver.contract.d.mts +101 -53
  23. package/esm/contracts/migration-driver.contract.d.mts.map +1 -1
  24. package/esm/contracts/query-builder.contract.d.mts +51 -33
  25. package/esm/contracts/query-builder.contract.d.mts.map +1 -1
  26. package/esm/contracts/sync-adapter.contract.d.mts +25 -14
  27. package/esm/contracts/sync-adapter.contract.d.mts.map +1 -1
  28. package/esm/data-source/data-source-registry.d.mts +4 -5
  29. package/esm/data-source/data-source-registry.d.mts.map +1 -1
  30. package/esm/data-source/data-source-registry.mjs.map +1 -1
  31. package/esm/data-source/data-source.d.mts +8 -5
  32. package/esm/data-source/data-source.d.mts.map +1 -1
  33. package/esm/database-dirty-tracker.d.mts +2 -2
  34. package/esm/database-dirty-tracker.d.mts.map +1 -1
  35. package/esm/database-dirty-tracker.mjs +3 -2
  36. package/esm/database-dirty-tracker.mjs.map +1 -1
  37. package/esm/drivers/mongodb/mongodb-driver.d.mts +3 -4
  38. package/esm/drivers/mongodb/mongodb-driver.d.mts.map +1 -1
  39. package/esm/drivers/mongodb/mongodb-driver.mjs.map +1 -1
  40. package/esm/drivers/mongodb/mongodb-id-generator.d.mts +2 -3
  41. package/esm/drivers/mongodb/mongodb-id-generator.d.mts.map +1 -1
  42. package/esm/drivers/mongodb/mongodb-id-generator.mjs.map +1 -1
  43. package/esm/drivers/mongodb/mongodb-migration-driver.d.mts +1 -3
  44. package/esm/drivers/mongodb/mongodb-migration-driver.d.mts.map +1 -1
  45. package/esm/drivers/mongodb/mongodb-query-builder.d.mts +2 -3
  46. package/esm/drivers/mongodb/mongodb-query-builder.d.mts.map +1 -1
  47. package/esm/drivers/mongodb/mongodb-query-builder.mjs +8 -5
  48. package/esm/drivers/mongodb/mongodb-query-builder.mjs.map +1 -1
  49. package/esm/drivers/mongodb/mongodb-query-operations.d.mts +1 -3
  50. package/esm/drivers/mongodb/mongodb-query-operations.d.mts.map +1 -1
  51. package/esm/drivers/mongodb/mongodb-query-operations.mjs.map +1 -1
  52. package/esm/drivers/mongodb/mongodb-query-parser.d.mts +7 -6
  53. package/esm/drivers/mongodb/mongodb-query-parser.d.mts.map +1 -1
  54. package/esm/drivers/mongodb/mongodb-query-parser.mjs +2 -6
  55. package/esm/drivers/mongodb/mongodb-query-parser.mjs.map +1 -1
  56. package/esm/drivers/mongodb/mongodb-sync-adapter.d.mts +1 -3
  57. package/esm/drivers/mongodb/mongodb-sync-adapter.d.mts.map +1 -1
  58. package/esm/drivers/mongodb/types.d.mts +11 -9
  59. package/esm/drivers/mongodb/types.d.mts.map +1 -1
  60. package/esm/drivers/postgres/index.d.mts +2 -1
  61. package/esm/drivers/postgres/index.mjs +1 -1
  62. package/esm/drivers/postgres/naming.mjs +1 -1
  63. package/esm/drivers/postgres/naming.mjs.map +1 -1
  64. package/esm/drivers/postgres/postgres-blueprint.d.mts +1 -3
  65. package/esm/drivers/postgres/postgres-blueprint.d.mts.map +1 -1
  66. package/esm/drivers/postgres/postgres-dialect.d.mts +4 -6
  67. package/esm/drivers/postgres/postgres-dialect.d.mts.map +1 -1
  68. package/esm/drivers/postgres/postgres-dialect.mjs.map +1 -1
  69. package/esm/drivers/postgres/postgres-driver.d.mts +4 -5
  70. package/esm/drivers/postgres/postgres-driver.d.mts.map +1 -1
  71. package/esm/drivers/postgres/postgres-driver.mjs.map +1 -1
  72. package/esm/drivers/postgres/postgres-migration-driver.d.mts +1 -3
  73. package/esm/drivers/postgres/postgres-migration-driver.d.mts.map +1 -1
  74. package/esm/drivers/postgres/postgres-migration-driver.mjs +13 -10
  75. package/esm/drivers/postgres/postgres-migration-driver.mjs.map +1 -1
  76. package/esm/drivers/postgres/postgres-query-builder.d.mts +4 -4
  77. package/esm/drivers/postgres/postgres-query-builder.d.mts.map +1 -1
  78. package/esm/drivers/postgres/postgres-query-builder.mjs +14 -10
  79. package/esm/drivers/postgres/postgres-query-builder.mjs.map +1 -1
  80. package/esm/drivers/postgres/postgres-query-parser.d.mts +16 -11
  81. package/esm/drivers/postgres/postgres-query-parser.d.mts.map +1 -1
  82. package/esm/drivers/postgres/postgres-query-parser.mjs +1 -2
  83. package/esm/drivers/postgres/postgres-query-parser.mjs.map +1 -1
  84. package/esm/drivers/postgres/postgres-sql-serializer.mjs +13 -10
  85. package/esm/drivers/postgres/postgres-sql-serializer.mjs.map +1 -1
  86. package/esm/drivers/postgres/postgres-ttl-purge.mjs +1 -1
  87. package/esm/drivers/postgres/postgres-ttl-purge.mjs.map +1 -1
  88. package/esm/drivers/postgres/postgres-type-converters.mjs +2 -2
  89. package/esm/drivers/postgres/postgres-type-converters.mjs.map +1 -1
  90. package/esm/drivers/postgres/postgres-update-validator.mjs +1 -1
  91. package/esm/drivers/postgres/postgres-update-validator.mjs.map +1 -1
  92. package/esm/drivers/postgres/types.d.mts +87 -45
  93. package/esm/drivers/postgres/types.d.mts.map +1 -1
  94. package/esm/drivers/sql/sql-dialect.contract.d.mts +1 -3
  95. package/esm/drivers/sql/sql-dialect.contract.d.mts.map +1 -1
  96. package/esm/drivers/sql/sql-types.d.mts +113 -59
  97. package/esm/drivers/sql/sql-types.d.mts.map +1 -1
  98. package/esm/errors/missing-data-source.error.d.mts +1 -2
  99. package/esm/errors/missing-data-source.error.d.mts.map +1 -1
  100. package/esm/errors/transaction-rollback.error.d.mts +1 -2
  101. package/esm/errors/transaction-rollback.error.d.mts.map +1 -1
  102. package/esm/errors/undefined-where-value.error.d.mts +1 -2
  103. package/esm/errors/undefined-where-value.error.d.mts.map +1 -1
  104. package/esm/errors/unsafe-filter.error.d.mts +1 -2
  105. package/esm/errors/unsafe-filter.error.d.mts.map +1 -1
  106. package/esm/errors/unsafe-raw-expression.error.d.mts +1 -2
  107. package/esm/errors/unsafe-raw-expression.error.d.mts.map +1 -1
  108. package/esm/errors/unsupported-lean-operation.error.d.mts +1 -2
  109. package/esm/errors/unsupported-lean-operation.error.d.mts.map +1 -1
  110. package/esm/errors/unsupported-lock-for-update.error.d.mts +1 -2
  111. package/esm/errors/unsupported-lock-for-update.error.d.mts.map +1 -1
  112. package/esm/errors/unsupported-query-operation.error.d.mts +1 -2
  113. package/esm/errors/unsupported-query-operation.error.d.mts.map +1 -1
  114. package/esm/errors/unsupported-query-operation.error.mjs.map +1 -1
  115. package/esm/errors/unsupported-update-operation.error.d.mts +1 -2
  116. package/esm/errors/unsupported-update-operation.error.d.mts.map +1 -1
  117. package/esm/events/model-events.d.mts +8 -6
  118. package/esm/events/model-events.d.mts.map +1 -1
  119. package/esm/expressions/aggregate-expressions.d.mts +7 -7
  120. package/esm/expressions/aggregate-expressions.d.mts.map +1 -1
  121. package/esm/expressions/column-expressions.d.mts +11 -11
  122. package/esm/expressions/column-expressions.d.mts.map +1 -1
  123. package/esm/expressions/column-expressions.mjs.map +1 -1
  124. package/esm/index.d.mts +7 -2
  125. package/esm/index.mjs +1 -1
  126. package/esm/migration/column-builder.d.mts +2 -3
  127. package/esm/migration/column-builder.d.mts.map +1 -1
  128. package/esm/migration/column-helpers.d.mts +49 -50
  129. package/esm/migration/column-helpers.d.mts.map +1 -1
  130. package/esm/migration/column-helpers.mjs +1 -1
  131. package/esm/migration/foreign-key-builder.d.mts +2 -3
  132. package/esm/migration/foreign-key-builder.d.mts.map +1 -1
  133. package/esm/migration/foreign-key-builder.mjs.map +1 -1
  134. package/esm/migration/index.d.mts +3 -2
  135. package/esm/migration/index.mjs +2 -2
  136. package/esm/migration/migration-runner.d.mts +7 -6
  137. package/esm/migration/migration-runner.d.mts.map +1 -1
  138. package/esm/migration/migration-runner.mjs +15 -11
  139. package/esm/migration/migration-runner.mjs.map +1 -1
  140. package/esm/migration/migration.d.mts +50 -32
  141. package/esm/migration/migration.d.mts.map +1 -1
  142. package/esm/migration/migration.mjs +1 -3
  143. package/esm/migration/migration.mjs.map +1 -1
  144. package/esm/migration/parse-created-at.mjs.map +1 -1
  145. package/esm/migration/sql-grammar.mjs.map +1 -1
  146. package/esm/migration/sql-serializer.d.mts +1 -3
  147. package/esm/migration/sql-serializer.d.mts.map +1 -1
  148. package/esm/migration/types.d.mts +7 -7
  149. package/esm/migration/types.d.mts.map +1 -1
  150. package/esm/model/generate-model-id.mjs.map +1 -1
  151. package/esm/model/methods/accessor-methods.mjs +1 -1
  152. package/esm/model/methods/accessor-methods.mjs.map +1 -1
  153. package/esm/model/methods/dirty-methods.mjs.map +1 -1
  154. package/esm/model/methods/hydration-methods.mjs.map +1 -1
  155. package/esm/model/methods/meta-methods.mjs +4 -2
  156. package/esm/model/methods/meta-methods.mjs.map +1 -1
  157. package/esm/model/methods/query-methods.mjs +1 -1
  158. package/esm/model/methods/query-methods.mjs.map +1 -1
  159. package/esm/model/methods/scope-methods.mjs.map +1 -1
  160. package/esm/model/methods/static-event-methods.mjs.map +1 -1
  161. package/esm/model/methods/write-methods.d.mts +3 -2
  162. package/esm/model/methods/write-methods.d.mts.map +1 -1
  163. package/esm/model/methods/write-methods.mjs +5 -2
  164. package/esm/model/methods/write-methods.mjs.map +1 -1
  165. package/esm/model/model.d.mts +9 -9
  166. package/esm/model/model.d.mts.map +1 -1
  167. package/esm/model/model.mjs.map +1 -1
  168. package/esm/model/model.types.d.mts +7 -7
  169. package/esm/model/model.types.d.mts.map +1 -1
  170. package/esm/model/register-model.d.mts +13 -15
  171. package/esm/model/register-model.d.mts.map +1 -1
  172. package/esm/model/register-model.mjs.map +1 -1
  173. package/esm/model/relation-decorators.d.mts +6 -8
  174. package/esm/model/relation-decorators.d.mts.map +1 -1
  175. package/esm/operations/database.d.mts +13 -8
  176. package/esm/operations/database.d.mts.map +1 -1
  177. package/esm/operations/index.d.mts +2 -1
  178. package/esm/operations/index.mjs +1 -1
  179. package/esm/operations/migrations.d.mts +18 -14
  180. package/esm/operations/migrations.d.mts.map +1 -1
  181. package/esm/operations/migrations.mjs.map +1 -1
  182. package/esm/query-builder/query-builder.d.mts +2 -4
  183. package/esm/query-builder/query-builder.d.mts.map +1 -1
  184. package/esm/query-builder/query-builder.mjs +12 -11
  185. package/esm/query-builder/query-builder.mjs.map +1 -1
  186. package/esm/relations/index.d.mts +2 -1
  187. package/esm/relations/index.mjs +1 -1
  188. package/esm/relations/key-conventions.mjs +2 -1
  189. package/esm/relations/key-conventions.mjs.map +1 -1
  190. package/esm/relations/pivot-operations.d.mts +3 -5
  191. package/esm/relations/pivot-operations.d.mts.map +1 -1
  192. package/esm/relations/pivot-operations.mjs.map +1 -1
  193. package/esm/relations/relation-hydrator.d.mts +3 -5
  194. package/esm/relations/relation-hydrator.d.mts.map +1 -1
  195. package/esm/relations/relation-loader.d.mts +2 -4
  196. package/esm/relations/relation-loader.d.mts.map +1 -1
  197. package/esm/relations/relation-loader.mjs +4 -5
  198. package/esm/relations/relation-loader.mjs.map +1 -1
  199. package/esm/relations/types.d.mts +14 -15
  200. package/esm/relations/types.d.mts.map +1 -1
  201. package/esm/remover/database-remover.d.mts +1 -3
  202. package/esm/remover/database-remover.d.mts.map +1 -1
  203. package/esm/remover/database-remover.mjs.map +1 -1
  204. package/esm/restorer/database-restorer.d.mts +1 -3
  205. package/esm/restorer/database-restorer.d.mts.map +1 -1
  206. package/esm/restorer/database-restorer.mjs +2 -1
  207. package/esm/restorer/database-restorer.mjs.map +1 -1
  208. package/esm/sql-database-dirty-tracker.d.mts +1 -3
  209. package/esm/sql-database-dirty-tracker.d.mts.map +1 -1
  210. package/esm/sync/model-events.mjs +1 -1
  211. package/esm/sync/model-sync-operation.d.mts +2 -4
  212. package/esm/sync/model-sync-operation.d.mts.map +1 -1
  213. package/esm/sync/model-sync.d.mts +3 -4
  214. package/esm/sync/model-sync.d.mts.map +1 -1
  215. package/esm/sync/sync-context.d.mts +2 -4
  216. package/esm/sync/sync-context.d.mts.map +1 -1
  217. package/esm/sync/sync-context.mjs.map +1 -1
  218. package/esm/sync/sync-fanout.mjs +1 -1
  219. package/esm/sync/sync-fanout.mjs.map +1 -1
  220. package/esm/sync/sync-manager.d.mts +2 -4
  221. package/esm/sync/sync-manager.d.mts.map +1 -1
  222. package/esm/sync/sync-manager.mjs.map +1 -1
  223. package/esm/sync/types.d.mts +121 -64
  224. package/esm/sync/types.d.mts.map +1 -1
  225. package/esm/transactions/after-commit.d.mts +2 -2
  226. package/esm/transactions/after-commit.d.mts.map +1 -1
  227. package/esm/types.d.mts +7 -8
  228. package/esm/types.d.mts.map +1 -1
  229. package/esm/utils/connect-to-database.d.mts +7 -8
  230. package/esm/utils/connect-to-database.d.mts.map +1 -1
  231. package/esm/utils/database-writer.utils.d.mts +3 -4
  232. package/esm/utils/database-writer.utils.d.mts.map +1 -1
  233. package/esm/utils/database-writer.utils.mjs.map +1 -1
  234. package/esm/utils/define-model.d.mts +3 -5
  235. package/esm/utils/define-model.d.mts.map +1 -1
  236. package/esm/utils/escape-regex.d.mts +3 -4
  237. package/esm/utils/escape-regex.d.mts.map +1 -1
  238. package/esm/utils/is-valid-date-value.mjs.map +1 -1
  239. package/esm/utils/once-connected.d.mts +2 -4
  240. package/esm/utils/once-connected.d.mts.map +1 -1
  241. package/esm/utils/sanitize-filter.d.mts +3 -4
  242. package/esm/utils/sanitize-filter.d.mts.map +1 -1
  243. package/esm/validation/database-seal-plugins.d.mts +2 -1
  244. package/esm/validation/database-writer-validation-error.d.mts +1 -3
  245. package/esm/validation/database-writer-validation-error.d.mts.map +1 -1
  246. package/esm/validation/index.d.mts +3 -1
  247. package/esm/validation/index.mjs +1 -1
  248. package/esm/validation/plugins/database-rules-plugin.d.mts +2 -3
  249. package/esm/validation/plugins/database-rules-plugin.d.mts.map +1 -1
  250. package/esm/validation/plugins/embed-validator-plugin.d.mts +4 -3
  251. package/esm/validation/plugins/embed-validator-plugin.d.mts.map +1 -1
  252. package/esm/validation/types.d.mts +14 -10
  253. package/esm/validation/types.d.mts.map +1 -1
  254. package/esm/validation/validators/embed-validator.d.mts +2 -3
  255. package/esm/validation/validators/embed-validator.d.mts.map +1 -1
  256. package/esm/writer/database-writer.d.mts +1 -3
  257. package/esm/writer/database-writer.d.mts.map +1 -1
  258. package/esm/writer/database-writer.mjs +1 -1
  259. package/esm/writer/database-writer.mjs.map +1 -1
  260. package/llms-full.txt +541 -434
  261. package/package.json +5 -5
  262. package/skills/aggregate-data/SKILL.md +28 -17
  263. package/skills/alter-migration/SKILL.md +325 -233
  264. package/skills/cascade-basics/SKILL.md +19 -19
  265. package/skills/configure-delete-strategy/SKILL.md +11 -11
  266. package/skills/define-model/SKILL.md +19 -17
  267. package/skills/define-relations/SKILL.md +13 -18
  268. package/skills/index.md +3 -0
  269. package/skills/manage-transactions/SKILL.md +18 -12
  270. package/skills/paginate-results/SKILL.md +6 -8
  271. package/skills/perform-atomic-ops/SKILL.md +26 -21
  272. package/skills/query-data/SKILL.md +27 -33
  273. package/skills/run-cascade-cli/SKILL.md +11 -10
  274. package/skills/search-by-vector/SKILL.md +8 -5
  275. package/skills/subscribe-to-model-events/SKILL.md +17 -17
  276. package/skills/track-changes/SKILL.md +9 -9
  277. package/skills/write-migration/SKILL.md +4 -4
@@ -96,7 +96,10 @@ async function answer(question: string) {
96
96
  // optional: drop low-similarity hits in code
97
97
  const relevant = context.filter((document) => document.score >= 0.75);
98
98
 
99
- const prompt = buildPrompt(question, relevant.map((document) => document.body));
99
+ const prompt = buildPrompt(
100
+ question,
101
+ relevant.map((document) => document.body),
102
+ );
100
103
  return ai.complete(prompt);
101
104
  }
102
105
  ```
@@ -105,11 +108,11 @@ A score threshold isn't a query option — filter on the `score` column in code
105
108
 
106
109
  ## Driver support
107
110
 
108
- | Driver | Vector |
109
- | --- | --- |
110
- | Postgres (with `CREATE EXTENSION vector`) | ✅ pgvector + IVFFlat index |
111
+ | Driver | Vector |
112
+ | ---------------------------------------------- | ------------------------------------ |
113
+ | Postgres (with `CREATE EXTENSION vector`) | ✅ pgvector + IVFFlat index |
111
114
  | MongoDB Atlas (paid tier + Atlas Search index) | ✅ `$vectorSearch` aggregation stage |
112
- | MongoDB community / self-hosted / local | ❌ Atlas-only |
115
+ | MongoDB community / self-hosted / local | ❌ Atlas-only |
113
116
 
114
117
  For local dev with MongoDB, develop the vector path against Postgres + pgvector.
115
118
 
@@ -25,18 +25,18 @@ Listeners are async-aware — the model's persistence awaits the listener before
25
25
 
26
26
  The events fire in this order. The **gerund** form (`saving`, `creating`) is the "before" hook — there is no `beforeSave` alias.
27
27
 
28
- | Event | Fires |
29
- | --- | --- |
30
- | `saving` | Before validation, on every `save()` (both insert and update paths) |
31
- | `validating` / `validated` | Around schema validation |
32
- | `creating` | Before a new record is inserted (first save) |
33
- | `updating` | Before an existing record's update is written |
34
- | `saved` | After a successful write (any branch — insert or update) |
35
- | `created` | After a new record is inserted |
36
- | `updated` | After an existing record's update is written |
37
- | `deleting` / `deleted` | Before / after the delete strategy runs |
38
- | `restoring` / `restored` | Before / after a soft-deleted or trashed record is restored |
39
- | `fetching` / `fetched` / `hydrating` | Around reads / instance hydration |
28
+ | Event | Fires |
29
+ | ------------------------------------ | ------------------------------------------------------------------- |
30
+ | `saving` | Before validation, on every `save()` (both insert and update paths) |
31
+ | `validating` / `validated` | Around schema validation |
32
+ | `creating` | Before a new record is inserted (first save) |
33
+ | `updating` | Before an existing record's update is written |
34
+ | `saved` | After a successful write (any branch — insert or update) |
35
+ | `created` | After a new record is inserted |
36
+ | `updated` | After an existing record's update is written |
37
+ | `deleting` / `deleted` | Before / after the delete strategy runs |
38
+ | `restoring` / `restored` | Before / after a soft-deleted or trashed record is restored |
39
+ | `fetching` / `fetched` / `hydrating` | Around reads / instance hydration |
40
40
 
41
41
  `saving` fires for both inserts and updates; `creating` / `updating` narrow to the branch. So `saved` always fires; exactly one of `created` / `updated` follows.
42
42
 
@@ -67,17 +67,17 @@ Pair with `isDirty()` from the `track-changes` topic so the listener only runs i
67
67
 
68
68
  ## Global listeners — across all models
69
69
 
70
- For framework-level concerns (audit log, observability, cache invalidation), subscribe on the base `Model` — the listener runs for every model:
70
+ For framework-level concerns (audit log, observability, cache invalidation), subscribe through `Model.globalEvents()` — the listener runs for every model:
71
71
 
72
72
  ```ts
73
73
  import { Model } from "@warlock.js/cascade";
74
74
 
75
- Model.on("saved", async (instance) => {
76
- await audit.log("save", instance.constructor.name, instance.id, instance.getDirtyColumns());
75
+ Model.globalEvents().on("saved", (instance) => {
76
+ console.info("save", instance.constructor.name, instance.id, instance.getDirtyColumns());
77
77
  });
78
78
  ```
79
79
 
80
- Filter by `instance.constructor.name === "User"` when you only care about specific models, or register per-model handlers when the scope is narrow. (`Model.globalEvents()` returns the underlying global emitter if you need direct access.)
80
+ Filter by `instance.constructor.name === "User"` when you only care about specific models, or register per-model handlers when the scope is narrow. The base `Model` is abstract; its per-model `on()` shortcut expects a concrete subclass.
81
81
 
82
82
  ## `off()` to unsubscribe
83
83
 
@@ -115,7 +115,7 @@ Model.on("updated", async (instance) => {
115
115
  });
116
116
  ```
117
117
 
118
- Use `updated` (not `saved`) when you only want change diffs — `getDirtyColumnsWithValues()` is still populated in the post-write events because the tracker resets *after* they fire.
118
+ Use `updated` (not `saved`) when you only want change diffs — `getDirtyColumnsWithValues()` is still populated in the post-write events because the tracker resets _after_ they fire.
119
119
 
120
120
  ### Cache invalidation
121
121
 
@@ -10,11 +10,11 @@ Every Cascade model carries a dirty tracker that records which fields you've cha
10
10
  ## The main reads
11
11
 
12
12
  ```ts
13
- user.hasChanges(); // boolean — any field changed (or removed)?
14
- user.isDirty("email"); // boolean — specifically this column?
13
+ user.hasChanges(); // boolean — any field changed (or removed)?
14
+ user.isDirty("email"); // boolean — specifically this column?
15
15
 
16
- user.getDirtyColumns(); // string[] — names of changed columns
17
- user.getRemovedColumns(); // string[] — columns explicitly unset since load
16
+ user.getDirtyColumns(); // string[] — names of changed columns
17
+ user.getRemovedColumns(); // string[] — columns explicitly unset since load
18
18
 
19
19
  user.getDirtyColumnsWithValues();
20
20
  // Record<string, { oldValue, newValue }> — the full diff, old + new per column
@@ -59,9 +59,9 @@ await AuditLog.create({
59
59
 
60
60
  ```ts
61
61
  user.set("name", "Augusta");
62
- user.isDirty("name"); // true
62
+ user.isDirty("name"); // true
63
63
  await user.save();
64
- user.isDirty("name"); // false — tracker reset to the just-saved state
64
+ user.isDirty("name"); // false — tracker reset to the just-saved state
65
65
  ```
66
66
 
67
67
  `save()` resets the tracker's baseline to the persisted state. Subsequent `isDirty()` checks measure changes since the last `save()`, not since the original load.
@@ -103,12 +103,12 @@ for (const [field, { oldValue, newValue }] of Object.entries(dirty)) {
103
103
 
104
104
  ```ts
105
105
  // plain object → merged key-by-key, siblings survive
106
- user.merge({ profile: { age: 26 } }); // profile.city untouched
107
- user.getDirtyColumns(); // ["profile.age"]
106
+ user.merge({ profile: { age: 26 } }); // profile.city untouched
107
+ user.getDirtyColumns(); // ["profile.age"]
108
108
 
109
109
  // Date → replaced, not merged
110
110
  conversation.merge({ lastOutboundAt: new Date() });
111
- conversation.getDirtyColumns(); // ["lastOutboundAt"]
111
+ conversation.getDirtyColumns(); // ["lastOutboundAt"]
112
112
  ```
113
113
 
114
114
  :::note[Fixed in 4.9.1]
@@ -129,10 +129,10 @@ Class-form builders include `createTable()` / `createTableIfNotExists()`, `dropT
129
129
  `this.foreignId(name)` (5.8+) derives the column's type from `migrationDefaults.primaryKey` so a foreign-key column always matches the type of the `id` it points at, instead of hardcoding one:
130
130
 
131
131
  | `migrationDefaults.primaryKey` | `foreignId` produces |
132
- | --- | --- |
133
- | `uuid` | `uuid` column |
134
- | `bigInt` | `bigInteger` column |
135
- | anything else (default) | `integer` column |
132
+ | ------------------------------ | -------------------- |
133
+ | `uuid` | `uuid` column |
134
+ | `bigInt` | `bigInteger` column |
135
+ | anything else (default) | `integer` column |
136
136
 
137
137
  ```ts
138
138
  import { Migration } from "@warlock.js/cascade";