@proseql/core 0.1.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 (342) hide show
  1. package/LICENSE +21 -0
  2. package/dist/errors/crud-errors.d.ts +98 -0
  3. package/dist/errors/crud-errors.d.ts.map +1 -0
  4. package/dist/errors/crud-errors.js +23 -0
  5. package/dist/errors/crud-errors.js.map +1 -0
  6. package/dist/errors/index.d.ts +16 -0
  7. package/dist/errors/index.d.ts.map +1 -0
  8. package/dist/errors/index.js +12 -0
  9. package/dist/errors/index.js.map +1 -0
  10. package/dist/errors/migration-errors.d.ts +22 -0
  11. package/dist/errors/migration-errors.d.ts.map +1 -0
  12. package/dist/errors/migration-errors.js +14 -0
  13. package/dist/errors/migration-errors.js.map +1 -0
  14. package/dist/errors/plugin-errors.d.ts +15 -0
  15. package/dist/errors/plugin-errors.d.ts.map +1 -0
  16. package/dist/errors/plugin-errors.js +11 -0
  17. package/dist/errors/plugin-errors.js.map +1 -0
  18. package/dist/errors/query-errors.d.ts +31 -0
  19. package/dist/errors/query-errors.d.ts.map +1 -0
  20. package/dist/errors/query-errors.js +11 -0
  21. package/dist/errors/query-errors.js.map +1 -0
  22. package/dist/errors/storage-errors.d.ts +30 -0
  23. package/dist/errors/storage-errors.d.ts.map +1 -0
  24. package/dist/errors/storage-errors.js +11 -0
  25. package/dist/errors/storage-errors.js.map +1 -0
  26. package/dist/factories/crud-factory-with-relationships.d.ts +28 -0
  27. package/dist/factories/crud-factory-with-relationships.d.ts.map +1 -0
  28. package/dist/factories/crud-factory-with-relationships.js +8 -0
  29. package/dist/factories/crud-factory-with-relationships.js.map +1 -0
  30. package/dist/factories/crud-factory.d.ts +25 -0
  31. package/dist/factories/crud-factory.d.ts.map +1 -0
  32. package/dist/factories/crud-factory.js +8 -0
  33. package/dist/factories/crud-factory.js.map +1 -0
  34. package/dist/factories/database-effect.d.ts +241 -0
  35. package/dist/factories/database-effect.d.ts.map +1 -0
  36. package/dist/factories/database-effect.js +859 -0
  37. package/dist/factories/database-effect.js.map +1 -0
  38. package/dist/hooks/hook-runner.d.ts +60 -0
  39. package/dist/hooks/hook-runner.d.ts.map +1 -0
  40. package/dist/hooks/hook-runner.js +107 -0
  41. package/dist/hooks/hook-runner.js.map +1 -0
  42. package/dist/index.d.ts +84 -0
  43. package/dist/index.d.ts.map +1 -0
  44. package/dist/index.js +110 -0
  45. package/dist/index.js.map +1 -0
  46. package/dist/indexes/index-lookup.d.ts +33 -0
  47. package/dist/indexes/index-lookup.d.ts.map +1 -0
  48. package/dist/indexes/index-lookup.js +180 -0
  49. package/dist/indexes/index-lookup.js.map +1 -0
  50. package/dist/indexes/index-manager.d.ts +118 -0
  51. package/dist/indexes/index-manager.d.ts.map +1 -0
  52. package/dist/indexes/index-manager.js +345 -0
  53. package/dist/indexes/index-manager.js.map +1 -0
  54. package/dist/indexes/search-index.d.ts +179 -0
  55. package/dist/indexes/search-index.d.ts.map +1 -0
  56. package/dist/indexes/search-index.js +405 -0
  57. package/dist/indexes/search-index.js.map +1 -0
  58. package/dist/migrations/migration-runner.d.ts +70 -0
  59. package/dist/migrations/migration-runner.d.ts.map +1 -0
  60. package/dist/migrations/migration-runner.js +271 -0
  61. package/dist/migrations/migration-runner.js.map +1 -0
  62. package/dist/migrations/migration-types.d.ts +63 -0
  63. package/dist/migrations/migration-types.d.ts.map +1 -0
  64. package/dist/migrations/migration-types.js +5 -0
  65. package/dist/migrations/migration-types.js.map +1 -0
  66. package/dist/operations/crud/create-with-relationships.d.ts +44 -0
  67. package/dist/operations/crud/create-with-relationships.d.ts.map +1 -0
  68. package/dist/operations/crud/create-with-relationships.js +483 -0
  69. package/dist/operations/crud/create-with-relationships.js.map +1 -0
  70. package/dist/operations/crud/create.d.ts +48 -0
  71. package/dist/operations/crud/create.d.ts.map +1 -0
  72. package/dist/operations/crud/create.js +333 -0
  73. package/dist/operations/crud/create.js.map +1 -0
  74. package/dist/operations/crud/delete-with-relationships.d.ts +63 -0
  75. package/dist/operations/crud/delete-with-relationships.d.ts.map +1 -0
  76. package/dist/operations/crud/delete-with-relationships.js +395 -0
  77. package/dist/operations/crud/delete-with-relationships.js.map +1 -0
  78. package/dist/operations/crud/delete.d.ts +58 -0
  79. package/dist/operations/crud/delete.d.ts.map +1 -0
  80. package/dist/operations/crud/delete.js +267 -0
  81. package/dist/operations/crud/delete.js.map +1 -0
  82. package/dist/operations/crud/unique-check.d.ts +114 -0
  83. package/dist/operations/crud/unique-check.d.ts.map +1 -0
  84. package/dist/operations/crud/unique-check.js +383 -0
  85. package/dist/operations/crud/unique-check.js.map +1 -0
  86. package/dist/operations/crud/update-with-relationships.d.ts +45 -0
  87. package/dist/operations/crud/update-with-relationships.d.ts.map +1 -0
  88. package/dist/operations/crud/update-with-relationships.js +516 -0
  89. package/dist/operations/crud/update-with-relationships.js.map +1 -0
  90. package/dist/operations/crud/update.d.ts +91 -0
  91. package/dist/operations/crud/update.d.ts.map +1 -0
  92. package/dist/operations/crud/update.js +505 -0
  93. package/dist/operations/crud/update.js.map +1 -0
  94. package/dist/operations/crud/upsert.d.ts +52 -0
  95. package/dist/operations/crud/upsert.d.ts.map +1 -0
  96. package/dist/operations/crud/upsert.js +386 -0
  97. package/dist/operations/crud/upsert.js.map +1 -0
  98. package/dist/operations/query/aggregate.d.ts +30 -0
  99. package/dist/operations/query/aggregate.d.ts.map +1 -0
  100. package/dist/operations/query/aggregate.js +227 -0
  101. package/dist/operations/query/aggregate.js.map +1 -0
  102. package/dist/operations/query/cursor-stream.d.ts +18 -0
  103. package/dist/operations/query/cursor-stream.d.ts.map +1 -0
  104. package/dist/operations/query/cursor-stream.js +199 -0
  105. package/dist/operations/query/cursor-stream.js.map +1 -0
  106. package/dist/operations/query/filter-stream.d.ts +12 -0
  107. package/dist/operations/query/filter-stream.d.ts.map +1 -0
  108. package/dist/operations/query/filter-stream.js +167 -0
  109. package/dist/operations/query/filter-stream.js.map +1 -0
  110. package/dist/operations/query/filter.d.ts +13 -0
  111. package/dist/operations/query/filter.d.ts.map +1 -0
  112. package/dist/operations/query/filter.js +267 -0
  113. package/dist/operations/query/filter.js.map +1 -0
  114. package/dist/operations/query/paginate-stream.d.ts +11 -0
  115. package/dist/operations/query/paginate-stream.d.ts.map +1 -0
  116. package/dist/operations/query/paginate-stream.js +22 -0
  117. package/dist/operations/query/paginate-stream.js.map +1 -0
  118. package/dist/operations/query/query-helpers.d.ts +14 -0
  119. package/dist/operations/query/query-helpers.d.ts.map +1 -0
  120. package/dist/operations/query/query-helpers.js +22 -0
  121. package/dist/operations/query/query-helpers.js.map +1 -0
  122. package/dist/operations/query/resolve-computed.d.ts +142 -0
  123. package/dist/operations/query/resolve-computed.d.ts.map +1 -0
  124. package/dist/operations/query/resolve-computed.js +197 -0
  125. package/dist/operations/query/resolve-computed.js.map +1 -0
  126. package/dist/operations/query/search.d.ts +110 -0
  127. package/dist/operations/query/search.d.ts.map +1 -0
  128. package/dist/operations/query/search.js +188 -0
  129. package/dist/operations/query/search.js.map +1 -0
  130. package/dist/operations/query/select-stream.d.ts +27 -0
  131. package/dist/operations/query/select-stream.d.ts.map +1 -0
  132. package/dist/operations/query/select-stream.js +88 -0
  133. package/dist/operations/query/select-stream.js.map +1 -0
  134. package/dist/operations/query/select.d.ts +54 -0
  135. package/dist/operations/query/select.d.ts.map +1 -0
  136. package/dist/operations/query/select.js +159 -0
  137. package/dist/operations/query/select.js.map +1 -0
  138. package/dist/operations/query/sort-stream.d.ts +46 -0
  139. package/dist/operations/query/sort-stream.d.ts.map +1 -0
  140. package/dist/operations/query/sort-stream.js +158 -0
  141. package/dist/operations/query/sort-stream.js.map +1 -0
  142. package/dist/operations/query/sort.d.ts +9 -0
  143. package/dist/operations/query/sort.d.ts.map +1 -0
  144. package/dist/operations/query/sort.js +58 -0
  145. package/dist/operations/query/sort.js.map +1 -0
  146. package/dist/operations/relationships/populate-stream.d.ts +29 -0
  147. package/dist/operations/relationships/populate-stream.d.ts.map +1 -0
  148. package/dist/operations/relationships/populate-stream.js +159 -0
  149. package/dist/operations/relationships/populate-stream.js.map +1 -0
  150. package/dist/operations/relationships/populate.d.ts +15 -0
  151. package/dist/operations/relationships/populate.d.ts.map +1 -0
  152. package/dist/operations/relationships/populate.js +228 -0
  153. package/dist/operations/relationships/populate.js.map +1 -0
  154. package/dist/plugins/plugin-hooks.d.ts +25 -0
  155. package/dist/plugins/plugin-hooks.d.ts.map +1 -0
  156. package/dist/plugins/plugin-hooks.js +64 -0
  157. package/dist/plugins/plugin-hooks.js.map +1 -0
  158. package/dist/plugins/plugin-registry.d.ts +26 -0
  159. package/dist/plugins/plugin-registry.d.ts.map +1 -0
  160. package/dist/plugins/plugin-registry.js +150 -0
  161. package/dist/plugins/plugin-registry.js.map +1 -0
  162. package/dist/plugins/plugin-types.d.ts +95 -0
  163. package/dist/plugins/plugin-types.d.ts.map +1 -0
  164. package/dist/plugins/plugin-types.js +6 -0
  165. package/dist/plugins/plugin-types.js.map +1 -0
  166. package/dist/plugins/plugin-validation.d.ts +49 -0
  167. package/dist/plugins/plugin-validation.d.ts.map +1 -0
  168. package/dist/plugins/plugin-validation.js +295 -0
  169. package/dist/plugins/plugin-validation.js.map +1 -0
  170. package/dist/reactive/change-event.d.ts +44 -0
  171. package/dist/reactive/change-event.d.ts.map +1 -0
  172. package/dist/reactive/change-event.js +49 -0
  173. package/dist/reactive/change-event.js.map +1 -0
  174. package/dist/reactive/change-pubsub.d.ts +32 -0
  175. package/dist/reactive/change-pubsub.d.ts.map +1 -0
  176. package/dist/reactive/change-pubsub.js +31 -0
  177. package/dist/reactive/change-pubsub.js.map +1 -0
  178. package/dist/reactive/evaluate-query.d.ts +62 -0
  179. package/dist/reactive/evaluate-query.d.ts.map +1 -0
  180. package/dist/reactive/evaluate-query.js +57 -0
  181. package/dist/reactive/evaluate-query.js.map +1 -0
  182. package/dist/reactive/watch-by-id.d.ts +53 -0
  183. package/dist/reactive/watch-by-id.d.ts.map +1 -0
  184. package/dist/reactive/watch-by-id.js +55 -0
  185. package/dist/reactive/watch-by-id.js.map +1 -0
  186. package/dist/reactive/watch.d.ts +78 -0
  187. package/dist/reactive/watch.d.ts.map +1 -0
  188. package/dist/reactive/watch.js +133 -0
  189. package/dist/reactive/watch.js.map +1 -0
  190. package/dist/serializers/codecs/hjson.d.ts +33 -0
  191. package/dist/serializers/codecs/hjson.d.ts.map +1 -0
  192. package/dist/serializers/codecs/hjson.js +40 -0
  193. package/dist/serializers/codecs/hjson.js.map +1 -0
  194. package/dist/serializers/codecs/json.d.ts +22 -0
  195. package/dist/serializers/codecs/json.d.ts.map +1 -0
  196. package/dist/serializers/codecs/json.js +28 -0
  197. package/dist/serializers/codecs/json.js.map +1 -0
  198. package/dist/serializers/codecs/json5.d.ts +26 -0
  199. package/dist/serializers/codecs/json5.d.ts.map +1 -0
  200. package/dist/serializers/codecs/json5.js +33 -0
  201. package/dist/serializers/codecs/json5.js.map +1 -0
  202. package/dist/serializers/codecs/jsonc.d.ts +29 -0
  203. package/dist/serializers/codecs/jsonc.d.ts.map +1 -0
  204. package/dist/serializers/codecs/jsonc.js +38 -0
  205. package/dist/serializers/codecs/jsonc.js.map +1 -0
  206. package/dist/serializers/codecs/jsonl.d.ts +17 -0
  207. package/dist/serializers/codecs/jsonl.d.ts.map +1 -0
  208. package/dist/serializers/codecs/jsonl.js +31 -0
  209. package/dist/serializers/codecs/jsonl.js.map +1 -0
  210. package/dist/serializers/codecs/prose.d.ts +419 -0
  211. package/dist/serializers/codecs/prose.d.ts.map +1 -0
  212. package/dist/serializers/codecs/prose.js +1060 -0
  213. package/dist/serializers/codecs/prose.js.map +1 -0
  214. package/dist/serializers/codecs/toml.d.ts +23 -0
  215. package/dist/serializers/codecs/toml.d.ts.map +1 -0
  216. package/dist/serializers/codecs/toml.js +66 -0
  217. package/dist/serializers/codecs/toml.js.map +1 -0
  218. package/dist/serializers/codecs/toon.d.ts +20 -0
  219. package/dist/serializers/codecs/toon.d.ts.map +1 -0
  220. package/dist/serializers/codecs/toon.js +33 -0
  221. package/dist/serializers/codecs/toon.js.map +1 -0
  222. package/dist/serializers/codecs/yaml.d.ts +24 -0
  223. package/dist/serializers/codecs/yaml.d.ts.map +1 -0
  224. package/dist/serializers/codecs/yaml.js +31 -0
  225. package/dist/serializers/codecs/yaml.js.map +1 -0
  226. package/dist/serializers/format-codec.d.ts +53 -0
  227. package/dist/serializers/format-codec.d.ts.map +1 -0
  228. package/dist/serializers/format-codec.js +148 -0
  229. package/dist/serializers/format-codec.js.map +1 -0
  230. package/dist/serializers/presets.d.ts +48 -0
  231. package/dist/serializers/presets.d.ts.map +1 -0
  232. package/dist/serializers/presets.js +72 -0
  233. package/dist/serializers/presets.js.map +1 -0
  234. package/dist/serializers/serializer-service.d.ts +11 -0
  235. package/dist/serializers/serializer-service.d.ts.map +1 -0
  236. package/dist/serializers/serializer-service.js +4 -0
  237. package/dist/serializers/serializer-service.js.map +1 -0
  238. package/dist/state/collection-state.d.ts +19 -0
  239. package/dist/state/collection-state.d.ts.map +1 -0
  240. package/dist/state/collection-state.js +15 -0
  241. package/dist/state/collection-state.js.map +1 -0
  242. package/dist/state/state-operations.d.ts +38 -0
  243. package/dist/state/state-operations.d.ts.map +1 -0
  244. package/dist/state/state-operations.js +65 -0
  245. package/dist/state/state-operations.js.map +1 -0
  246. package/dist/storage/in-memory-adapter-layer.d.ts +16 -0
  247. package/dist/storage/in-memory-adapter-layer.d.ts.map +1 -0
  248. package/dist/storage/in-memory-adapter-layer.js +81 -0
  249. package/dist/storage/in-memory-adapter-layer.js.map +1 -0
  250. package/dist/storage/persistence-effect.d.ts +244 -0
  251. package/dist/storage/persistence-effect.d.ts.map +1 -0
  252. package/dist/storage/persistence-effect.js +551 -0
  253. package/dist/storage/persistence-effect.js.map +1 -0
  254. package/dist/storage/storage-service.d.ts +22 -0
  255. package/dist/storage/storage-service.d.ts.map +1 -0
  256. package/dist/storage/storage-service.js +4 -0
  257. package/dist/storage/storage-service.js.map +1 -0
  258. package/dist/storage/transforms.d.ts +183 -0
  259. package/dist/storage/transforms.d.ts.map +1 -0
  260. package/dist/storage/transforms.js +263 -0
  261. package/dist/storage/transforms.js.map +1 -0
  262. package/dist/transactions/transaction.d.ts +87 -0
  263. package/dist/transactions/transaction.d.ts.map +1 -0
  264. package/dist/transactions/transaction.js +240 -0
  265. package/dist/transactions/transaction.js.map +1 -0
  266. package/dist/types/aggregate-types.d.ts +73 -0
  267. package/dist/types/aggregate-types.d.ts.map +1 -0
  268. package/dist/types/aggregate-types.js +14 -0
  269. package/dist/types/aggregate-types.js.map +1 -0
  270. package/dist/types/computed-types.d.ts +71 -0
  271. package/dist/types/computed-types.d.ts.map +1 -0
  272. package/dist/types/computed-types.js +8 -0
  273. package/dist/types/computed-types.js.map +1 -0
  274. package/dist/types/crud-relationship-types.d.ts +180 -0
  275. package/dist/types/crud-relationship-types.d.ts.map +1 -0
  276. package/dist/types/crud-relationship-types.js +17 -0
  277. package/dist/types/crud-relationship-types.js.map +1 -0
  278. package/dist/types/crud-types.d.ts +343 -0
  279. package/dist/types/crud-types.d.ts.map +1 -0
  280. package/dist/types/crud-types.js +43 -0
  281. package/dist/types/crud-types.js.map +1 -0
  282. package/dist/types/cursor-types.d.ts +52 -0
  283. package/dist/types/cursor-types.d.ts.map +1 -0
  284. package/dist/types/cursor-types.js +2 -0
  285. package/dist/types/cursor-types.js.map +1 -0
  286. package/dist/types/database-config-types.d.ts +196 -0
  287. package/dist/types/database-config-types.d.ts.map +1 -0
  288. package/dist/types/database-config-types.js +11 -0
  289. package/dist/types/database-config-types.js.map +1 -0
  290. package/dist/types/hook-types.d.ts +158 -0
  291. package/dist/types/hook-types.d.ts.map +1 -0
  292. package/dist/types/hook-types.js +6 -0
  293. package/dist/types/hook-types.js.map +1 -0
  294. package/dist/types/index-types.d.ts +42 -0
  295. package/dist/types/index-types.d.ts.map +1 -0
  296. package/dist/types/index-types.js +8 -0
  297. package/dist/types/index-types.js.map +1 -0
  298. package/dist/types/operators.d.ts +5 -0
  299. package/dist/types/operators.d.ts.map +1 -0
  300. package/dist/types/operators.js +297 -0
  301. package/dist/types/operators.js.map +1 -0
  302. package/dist/types/query-overloads.d.ts +54 -0
  303. package/dist/types/query-overloads.d.ts.map +1 -0
  304. package/dist/types/query-overloads.js +3 -0
  305. package/dist/types/query-overloads.js.map +1 -0
  306. package/dist/types/reactive-types.d.ts +75 -0
  307. package/dist/types/reactive-types.d.ts.map +1 -0
  308. package/dist/types/reactive-types.js +7 -0
  309. package/dist/types/reactive-types.js.map +1 -0
  310. package/dist/types/schema-types.d.ts +56 -0
  311. package/dist/types/schema-types.d.ts.map +1 -0
  312. package/dist/types/schema-types.js +8 -0
  313. package/dist/types/schema-types.js.map +1 -0
  314. package/dist/types/search-types.d.ts +82 -0
  315. package/dist/types/search-types.d.ts.map +1 -0
  316. package/dist/types/search-types.js +110 -0
  317. package/dist/types/search-types.js.map +1 -0
  318. package/dist/types/types.d.ts +286 -0
  319. package/dist/types/types.d.ts.map +1 -0
  320. package/dist/types/types.js +2 -0
  321. package/dist/types/types.js.map +1 -0
  322. package/dist/utils/id-generator.d.ts +97 -0
  323. package/dist/utils/id-generator.d.ts.map +1 -0
  324. package/dist/utils/id-generator.js +247 -0
  325. package/dist/utils/id-generator.js.map +1 -0
  326. package/dist/utils/nested-path.d.ts +56 -0
  327. package/dist/utils/nested-path.d.ts.map +1 -0
  328. package/dist/utils/nested-path.js +119 -0
  329. package/dist/utils/nested-path.js.map +1 -0
  330. package/dist/utils/path.d.ts +16 -0
  331. package/dist/utils/path.d.ts.map +1 -0
  332. package/dist/utils/path.js +24 -0
  333. package/dist/utils/path.js.map +1 -0
  334. package/dist/validators/foreign-key.d.ts +49 -0
  335. package/dist/validators/foreign-key.d.ts.map +1 -0
  336. package/dist/validators/foreign-key.js +153 -0
  337. package/dist/validators/foreign-key.js.map +1 -0
  338. package/dist/validators/schema-validator.d.ts +19 -0
  339. package/dist/validators/schema-validator.d.ts.map +1 -0
  340. package/dist/validators/schema-validator.js +34 -0
  341. package/dist/validators/schema-validator.js.map +1 -0
  342. package/package.json +57 -0
@@ -0,0 +1,505 @@
1
+ /**
2
+ * Effect-based update operations for entities.
3
+ *
4
+ * Uses Ref<ReadonlyMap> for atomic state mutation, Effect Schema for validation,
5
+ * and typed errors (ValidationError, NotFoundError, ForeignKeyError).
6
+ *
7
+ * Preserves all update operators: $increment, $decrement, $multiply,
8
+ * $append, $prepend, $remove, $toggle, $set.
9
+ */
10
+ import { Effect, PubSub, Ref } from "effect";
11
+ import { NotFoundError, ValidationError, } from "../../errors/crud-errors.js";
12
+ import { runAfterUpdateHooks, runBeforeUpdateHooks, runOnChangeHooks, } from "../../hooks/hook-runner.js";
13
+ import { updateInIndex } from "../../indexes/index-manager.js";
14
+ import { updateInSearchIndex } from "../../indexes/search-index.js";
15
+ import { validateForeignKeysEffect } from "../../validators/foreign-key.js";
16
+ import { validateEntity } from "../../validators/schema-validator.js";
17
+ import { checkUniqueConstraints, } from "./unique-check.js";
18
+ // ============================================================================
19
+ // Update Operators Implementation
20
+ // ============================================================================
21
+ /**
22
+ * Check if an object is a plain object (not null, not an array).
23
+ */
24
+ function isPlainObject(value) {
25
+ return value !== null && typeof value === "object" && !Array.isArray(value);
26
+ }
27
+ /**
28
+ * Check if an object contains any $-prefixed keys (operator object).
29
+ */
30
+ function hasOperatorKeys(obj) {
31
+ return Object.keys(obj).some((k) => k.startsWith("$"));
32
+ }
33
+ /**
34
+ * Apply update operators to a value.
35
+ * Supports: $increment, $decrement, $multiply (number),
36
+ * $append, $prepend (string/array), $remove (array),
37
+ * $toggle (boolean), $set (all types).
38
+ */
39
+ function applyOperator(currentValue, operator) {
40
+ // Number operators
41
+ if (typeof currentValue === "number") {
42
+ if ("$increment" in operator && typeof operator.$increment === "number") {
43
+ return (currentValue + operator.$increment);
44
+ }
45
+ if ("$decrement" in operator && typeof operator.$decrement === "number") {
46
+ return (currentValue - operator.$decrement);
47
+ }
48
+ if ("$multiply" in operator && typeof operator.$multiply === "number") {
49
+ return (currentValue * operator.$multiply);
50
+ }
51
+ if ("$set" in operator) {
52
+ return operator.$set;
53
+ }
54
+ }
55
+ // String operators
56
+ if (typeof currentValue === "string") {
57
+ if ("$append" in operator && typeof operator.$append === "string") {
58
+ return (currentValue + operator.$append);
59
+ }
60
+ if ("$prepend" in operator && typeof operator.$prepend === "string") {
61
+ return (operator.$prepend + currentValue);
62
+ }
63
+ if ("$set" in operator) {
64
+ return operator.$set;
65
+ }
66
+ }
67
+ // Array operators
68
+ if (Array.isArray(currentValue)) {
69
+ if ("$append" in operator) {
70
+ const toAppend = Array.isArray(operator.$append)
71
+ ? operator.$append
72
+ : [operator.$append];
73
+ return [...currentValue, ...toAppend];
74
+ }
75
+ if ("$prepend" in operator) {
76
+ const toPrepend = Array.isArray(operator.$prepend)
77
+ ? operator.$prepend
78
+ : [operator.$prepend];
79
+ return [...toPrepend, ...currentValue];
80
+ }
81
+ if ("$remove" in operator) {
82
+ if (typeof operator.$remove === "function") {
83
+ return currentValue.filter((item) => !operator.$remove(item));
84
+ }
85
+ return currentValue.filter((item) => item !== operator.$remove);
86
+ }
87
+ if ("$set" in operator) {
88
+ return operator.$set;
89
+ }
90
+ }
91
+ // Boolean operators
92
+ if (typeof currentValue === "boolean") {
93
+ if ("$toggle" in operator && operator.$toggle === true) {
94
+ return !currentValue;
95
+ }
96
+ if ("$set" in operator) {
97
+ return operator.$set;
98
+ }
99
+ }
100
+ // Default: just set the value
101
+ if ("$set" in operator) {
102
+ return operator.$set;
103
+ }
104
+ // If no operator matched, return current value
105
+ return currentValue;
106
+ }
107
+ /**
108
+ * Deep merge an update object into a current object, handling operators at any level.
109
+ *
110
+ * Rules:
111
+ * 1. If update value has $-prefixed keys → it's an operator, apply to current value
112
+ * 2. If update value is a plain object with no $-keys AND current value is also a plain object → recurse
113
+ * 3. Otherwise → direct assignment (replace current value with update value)
114
+ *
115
+ * This allows nested updates like:
116
+ * - `{ metadata: { views: 500 } }` → merges into metadata, preserving other fields
117
+ * - `{ metadata: { views: { $increment: 1 } } }` → applies operator to metadata.views
118
+ * - `{ metadata: { $set: { views: 0 } } }` → replaces entire metadata
119
+ *
120
+ * @param current - The current object to merge into
121
+ * @param updates - The update object containing values and/or operators
122
+ * @returns A new object with updates applied
123
+ */
124
+ export function deepMergeUpdates(current, updates) {
125
+ const result = { ...current };
126
+ for (const [key, updateValue] of Object.entries(updates)) {
127
+ if (updateValue === undefined) {
128
+ // Skip undefined values
129
+ continue;
130
+ }
131
+ const currentValue = current[key];
132
+ if (isPlainObject(updateValue)) {
133
+ if (hasOperatorKeys(updateValue)) {
134
+ // Update value is an operator object → apply operator to current value
135
+ result[key] = applyOperator(currentValue, updateValue);
136
+ }
137
+ else if (isPlainObject(currentValue)) {
138
+ // Both update and current are plain objects with no $ keys → recurse
139
+ result[key] = deepMergeUpdates(currentValue, updateValue);
140
+ }
141
+ else {
142
+ // Current value is not a plain object → direct assignment
143
+ result[key] = updateValue;
144
+ }
145
+ }
146
+ else {
147
+ // Update value is a primitive or array → direct assignment
148
+ result[key] = updateValue;
149
+ }
150
+ }
151
+ return result;
152
+ }
153
+ /**
154
+ * Apply update operations to an entity.
155
+ * Handles both direct value assignments and operator objects at any nesting level.
156
+ * Uses deepMergeUpdates for nested object merging with operator support.
157
+ * Automatically sets updatedAt timestamp.
158
+ */
159
+ export function applyUpdates(entity, updates) {
160
+ const now = new Date().toISOString();
161
+ // Use deepMergeUpdates to handle nested objects and operators at any level
162
+ const merged = deepMergeUpdates(entity, updates);
163
+ // Ensure updatedAt is set
164
+ if (!("updatedAt" in updates)) {
165
+ merged.updatedAt = now;
166
+ }
167
+ return merged;
168
+ }
169
+ /**
170
+ * Validate that an update doesn't violate immutable fields (id, createdAt).
171
+ */
172
+ export function validateImmutableFields(updates) {
173
+ const immutableFields = ["id", "createdAt"];
174
+ for (const field of immutableFields) {
175
+ if (field in updates) {
176
+ return { valid: false, field };
177
+ }
178
+ }
179
+ return { valid: true };
180
+ }
181
+ // ============================================================================
182
+ // Computed Field Stripping
183
+ // ============================================================================
184
+ /**
185
+ * Strip computed field keys from an update input object.
186
+ * Used to remove computed field names from update input before schema validation.
187
+ *
188
+ * @param updates - The update payload (possibly with computed field keys)
189
+ * @param computed - The computed fields configuration that defines which keys to strip
190
+ * @returns A new object with computed field keys removed
191
+ */
192
+ const stripComputedFromUpdates = (updates, computed) => {
193
+ if (computed === undefined || Object.keys(computed).length === 0) {
194
+ return updates;
195
+ }
196
+ const computedKeys = new Set(Object.keys(computed));
197
+ const result = {};
198
+ for (const key of Object.keys(updates)) {
199
+ if (!computedKeys.has(key)) {
200
+ result[key] = updates[key];
201
+ }
202
+ }
203
+ return result;
204
+ };
205
+ // ============================================================================
206
+ // Unique Constraint Helpers
207
+ // ============================================================================
208
+ /**
209
+ * Check if an update operation touches any unique fields.
210
+ *
211
+ * Extracts the update keys (handling $set operators) and checks if any
212
+ * intersect with the fields in the unique constraints.
213
+ *
214
+ * @param updates - The update payload (may contain direct values or operators)
215
+ * @param constraints - Normalized unique constraints
216
+ * @returns True if the update modifies any field that's part of a unique constraint
217
+ */
218
+ function updateTouchesUniqueFields(updates, constraints) {
219
+ if (constraints.length === 0) {
220
+ return false;
221
+ }
222
+ // Extract the fields being updated
223
+ const updateKeys = new Set();
224
+ for (const [key, value] of Object.entries(updates)) {
225
+ // Check if it's a $set operator
226
+ if (typeof value === "object" &&
227
+ value !== null &&
228
+ !Array.isArray(value) &&
229
+ "$set" in value) {
230
+ updateKeys.add(key);
231
+ }
232
+ else if (value !== undefined) {
233
+ // Direct value assignment or other operators
234
+ updateKeys.add(key);
235
+ }
236
+ }
237
+ // Check if any update key is in any constraint
238
+ for (const constraintFields of constraints) {
239
+ for (const field of constraintFields) {
240
+ if (updateKeys.has(field)) {
241
+ return true;
242
+ }
243
+ }
244
+ }
245
+ return false;
246
+ }
247
+ // ============================================================================
248
+ // Update Single Entity
249
+ // ============================================================================
250
+ /**
251
+ * Update a single entity by ID with validation, hooks, and foreign key checks.
252
+ *
253
+ * Steps:
254
+ * 1. Validate immutable fields are not being modified
255
+ * 2. Look up entity by ID in Ref state (O(1)) - capture as previous
256
+ * 3. Run beforeUpdate hooks (can transform update payload)
257
+ * 4. Apply update operators to produce new entity
258
+ * 5. Validate through Effect Schema
259
+ * 6. Validate foreign key constraints if relationship fields changed
260
+ * 7. Atomically update in Ref state
261
+ * 8. Update indexes if provided
262
+ */
263
+ export const update = (collectionName, schema, relationships, ref, stateRefs, indexes, hooks, uniqueFields = [], computed, searchIndexRef, searchIndexFields, changePubSub) => (id, updates) => Effect.gen(function* () {
264
+ // Strip computed field keys from updates (they are derived, not stored)
265
+ const sanitizedUpdates = stripComputedFromUpdates(updates, computed);
266
+ // Validate immutable fields
267
+ const immutableCheck = validateImmutableFields(sanitizedUpdates);
268
+ if (!immutableCheck.valid) {
269
+ const fieldName = immutableCheck.field ?? "unknown";
270
+ return yield* Effect.fail(new ValidationError({
271
+ message: `Cannot update immutable field: ${fieldName}`,
272
+ issues: [
273
+ {
274
+ field: fieldName,
275
+ message: `Cannot update immutable field: ${fieldName}`,
276
+ },
277
+ ],
278
+ }));
279
+ }
280
+ // Look up entity by ID (O(1)) - capture as previous for hooks
281
+ const currentMap = yield* Ref.get(ref);
282
+ const previous = currentMap.get(id);
283
+ if (previous === undefined) {
284
+ return yield* Effect.fail(new NotFoundError({
285
+ collection: collectionName,
286
+ id,
287
+ message: `Entity '${id}' not found in collection '${collectionName}'`,
288
+ }));
289
+ }
290
+ // Run beforeUpdate hooks (can transform the update payload)
291
+ const transformedUpdates = yield* runBeforeUpdateHooks(hooks?.beforeUpdate, {
292
+ operation: "update",
293
+ collection: collectionName,
294
+ id,
295
+ existing: previous,
296
+ update: sanitizedUpdates,
297
+ });
298
+ // Apply update operators with (possibly transformed) updates
299
+ const updated = applyUpdates(previous, transformedUpdates);
300
+ // Validate through Effect Schema
301
+ const validated = yield* validateEntity(schema, updated);
302
+ // Validate foreign keys if any relationship fields were updated
303
+ const relationshipFields = Object.keys(relationships).map((field) => relationships[field].foreignKey || `${field}Id`);
304
+ const hasRelationshipUpdate = Object.keys(transformedUpdates).some((key) => relationshipFields.includes(key));
305
+ if (hasRelationshipUpdate) {
306
+ yield* validateForeignKeysEffect(validated, collectionName, relationships, stateRefs);
307
+ }
308
+ // Check unique constraints if the update touches any unique fields
309
+ if (updateTouchesUniqueFields(transformedUpdates, uniqueFields)) {
310
+ yield* checkUniqueConstraints(validated, currentMap, uniqueFields, collectionName);
311
+ }
312
+ // Atomically update in state
313
+ yield* Ref.update(ref, (map) => {
314
+ const next = new Map(map);
315
+ next.set(id, validated);
316
+ return next;
317
+ });
318
+ // Update indexes if provided
319
+ if (indexes && indexes.size > 0) {
320
+ yield* updateInIndex(indexes, previous, validated);
321
+ }
322
+ // Update search index if configured
323
+ if (searchIndexRef && searchIndexFields && searchIndexFields.length > 0) {
324
+ yield* updateInSearchIndex(searchIndexRef, previous, validated, searchIndexFields);
325
+ }
326
+ // Run afterUpdate hooks (fire-and-forget, errors swallowed)
327
+ yield* runAfterUpdateHooks(hooks?.afterUpdate, {
328
+ operation: "update",
329
+ collection: collectionName,
330
+ id,
331
+ previous,
332
+ current: validated,
333
+ update: transformedUpdates,
334
+ });
335
+ // Run onChange hooks with type: "update" (fire-and-forget, errors swallowed)
336
+ yield* runOnChangeHooks(hooks?.onChange, {
337
+ type: "update",
338
+ collection: collectionName,
339
+ id,
340
+ previous,
341
+ current: validated,
342
+ });
343
+ // Publish change event to reactive subscribers
344
+ if (changePubSub) {
345
+ yield* PubSub.publish(changePubSub, {
346
+ collection: collectionName,
347
+ operation: "update",
348
+ });
349
+ }
350
+ return validated;
351
+ });
352
+ // ============================================================================
353
+ // Update Multiple Entities
354
+ // ============================================================================
355
+ /**
356
+ * Update multiple entities matching a filter predicate.
357
+ *
358
+ * Uses a predicate function to select which entities to update.
359
+ * The caller (database factory) can use the Stream-based filter pipeline
360
+ * to build the predicate from a WhereClause.
361
+ *
362
+ * Runs hooks per entity: beforeUpdate can transform the update payload,
363
+ * afterUpdate and onChange run after state mutation.
364
+ *
365
+ * All matching entities are updated atomically in a single Ref.update call.
366
+ */
367
+ export const updateMany = (collectionName, schema, relationships, ref, stateRefs, indexes, hooks, uniqueFields = [], computed, searchIndexRef, searchIndexFields, changePubSub) => (predicate, updates) => Effect.gen(function* () {
368
+ // Strip computed field keys from updates (they are derived, not stored)
369
+ const sanitizedUpdates = stripComputedFromUpdates(updates, computed);
370
+ // Validate immutable fields
371
+ const immutableCheck = validateImmutableFields(sanitizedUpdates);
372
+ if (!immutableCheck.valid) {
373
+ const fieldName = immutableCheck.field ?? "unknown";
374
+ return yield* Effect.fail(new ValidationError({
375
+ message: `Cannot update immutable field: ${fieldName}`,
376
+ issues: [
377
+ {
378
+ field: fieldName,
379
+ message: `Cannot update immutable field: ${fieldName}`,
380
+ },
381
+ ],
382
+ }));
383
+ }
384
+ // Get current state and find matching entities
385
+ const currentMap = yield* Ref.get(ref);
386
+ const matchingEntities = [];
387
+ for (const entity of currentMap.values()) {
388
+ if (predicate(entity)) {
389
+ matchingEntities.push(entity);
390
+ }
391
+ }
392
+ if (matchingEntities.length === 0) {
393
+ return { count: 0, updated: [] };
394
+ }
395
+ // Apply updates, run beforeUpdate hooks, and validate each entity
396
+ // We need to track both previous and validated for hooks later
397
+ const entityPairs = [];
398
+ for (const entity of matchingEntities) {
399
+ // Run beforeUpdate hooks (can transform the update payload)
400
+ const transformedUpdates = yield* runBeforeUpdateHooks(hooks?.beforeUpdate, {
401
+ operation: "update",
402
+ collection: collectionName,
403
+ id: entity.id,
404
+ existing: entity,
405
+ update: sanitizedUpdates,
406
+ });
407
+ const updated = applyUpdates(entity, transformedUpdates);
408
+ const validated = yield* validateEntity(schema, updated);
409
+ entityPairs.push({
410
+ previous: entity,
411
+ validated,
412
+ transformedUpdates: transformedUpdates,
413
+ });
414
+ }
415
+ // Validate foreign keys if relationship fields were updated
416
+ const relationshipFields = Object.keys(relationships).map((field) => relationships[field].foreignKey || `${field}Id`);
417
+ const hasRelationshipUpdate = Object.keys(sanitizedUpdates).some((key) => relationshipFields.includes(key));
418
+ if (hasRelationshipUpdate) {
419
+ for (const { validated } of entityPairs) {
420
+ yield* validateForeignKeysEffect(validated, collectionName, relationships, stateRefs);
421
+ }
422
+ }
423
+ // Check unique constraints if the update touches any unique fields
424
+ if (updateTouchesUniqueFields(sanitizedUpdates, uniqueFields)) {
425
+ // For updateMany, we need to check each entity against:
426
+ // 1. Existing entities (excluding entities being updated)
427
+ // 2. Other entities in the batch (they might conflict with each other)
428
+ // Create a temporary map that includes our updates for checking
429
+ const checkMap = new Map(currentMap);
430
+ for (const { validated } of entityPairs) {
431
+ checkMap.set(validated.id, validated);
432
+ }
433
+ for (const { validated } of entityPairs) {
434
+ // Check against all other entities (excluding self)
435
+ yield* checkUniqueConstraints(validated, checkMap, uniqueFields, collectionName);
436
+ }
437
+ }
438
+ // Atomically update all matching entities in state
439
+ yield* Ref.update(ref, (map) => {
440
+ const next = new Map(map);
441
+ for (const { validated } of entityPairs) {
442
+ next.set(validated.id, validated);
443
+ }
444
+ return next;
445
+ });
446
+ // Update indexes if provided
447
+ if (indexes && indexes.size > 0) {
448
+ for (const { previous, validated } of entityPairs) {
449
+ yield* updateInIndex(indexes, previous, validated);
450
+ }
451
+ }
452
+ // Update search index if configured
453
+ if (searchIndexRef && searchIndexFields && searchIndexFields.length > 0) {
454
+ for (const { previous, validated } of entityPairs) {
455
+ yield* updateInSearchIndex(searchIndexRef, previous, validated, searchIndexFields);
456
+ }
457
+ }
458
+ // Run afterUpdate and onChange hooks for each updated entity
459
+ for (const { previous, validated, transformedUpdates } of entityPairs) {
460
+ // Run afterUpdate hooks (fire-and-forget, errors swallowed)
461
+ yield* runAfterUpdateHooks(hooks?.afterUpdate, {
462
+ operation: "update",
463
+ collection: collectionName,
464
+ id: validated.id,
465
+ previous,
466
+ current: validated,
467
+ update: transformedUpdates,
468
+ });
469
+ // Run onChange hooks with type: "update" (fire-and-forget, errors swallowed)
470
+ yield* runOnChangeHooks(hooks?.onChange, {
471
+ type: "update",
472
+ collection: collectionName,
473
+ id: validated.id,
474
+ previous,
475
+ current: validated,
476
+ });
477
+ }
478
+ // Publish a single change event after all updates are complete
479
+ if (changePubSub && entityPairs.length > 0) {
480
+ yield* PubSub.publish(changePubSub, {
481
+ collection: collectionName,
482
+ operation: "update",
483
+ });
484
+ }
485
+ return {
486
+ count: entityPairs.length,
487
+ updated: entityPairs.map((p) => p.validated),
488
+ };
489
+ });
490
+ // ============================================================================
491
+ // Helper Functions
492
+ // ============================================================================
493
+ /**
494
+ * Extract fields that were actually changed between two entity versions.
495
+ */
496
+ export function getChangedFields(original, updated) {
497
+ const changed = [];
498
+ for (const key of Object.keys(updated)) {
499
+ if (original[key] !== updated[key]) {
500
+ changed.push(String(key));
501
+ }
502
+ }
503
+ return changed;
504
+ }
505
+ //# sourceMappingURL=update.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update.js","sourceRoot":"","sources":["../../../src/operations/crud/update.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Effect-based upsert operations for entities.
3
+ *
4
+ * Uses Ref<ReadonlyMap> for atomic state mutation, Effect Schema for validation,
5
+ * and typed errors (ValidationError, ForeignKeyError).
6
+ *
7
+ * Upsert = find by `where` clause → update if exists, create if not.
8
+ */
9
+ import { Effect, PubSub, Ref, type Schema } from "effect";
10
+ import type { ForeignKeyError, HookError, UniqueConstraintError, ValidationError } from "../../errors/crud-errors.js";
11
+ import type { UpsertInternalInput, UpsertManyResult, UpsertResult } from "../../types/crud-types.js";
12
+ import type { HooksConfig } from "../../types/hook-types.js";
13
+ import type { CollectionIndexes } from "../../types/index-types.js";
14
+ import type { ChangeEvent } from "../../types/reactive-types.js";
15
+ import type { SearchIndexMap } from "../../types/search-types.js";
16
+ import { type NormalizedConstraints } from "./unique-check.js";
17
+ type HasId = {
18
+ readonly id: string;
19
+ };
20
+ type RelationshipConfig = {
21
+ readonly type: "ref" | "inverse";
22
+ readonly target: string;
23
+ readonly foreignKey?: string;
24
+ };
25
+ /**
26
+ * Upsert a single entity: find by `where`, update if exists, create if not.
27
+ *
28
+ * Steps:
29
+ * 1. Look up entity by where clause in Ref state
30
+ * 2a. If found: run beforeUpdate hooks, apply update operators, validate, update in state, run afterUpdate/onChange
31
+ * 2b. If not found: merge where + create data, generate ID/timestamps, validate, run beforeCreate hooks, add to state, run afterCreate/onChange
32
+ * 3. Validate foreign key constraints
33
+ * 4. Return entity with __action metadata
34
+ */
35
+ export declare const upsert: <T extends HasId, I = T>(collectionName: string, schema: Schema.Schema<T, I>, relationships: Record<string, RelationshipConfig>, ref: Ref.Ref<ReadonlyMap<string, T>>, stateRefs: Record<string, Ref.Ref<ReadonlyMap<string, HasId>>>, indexes?: CollectionIndexes, hooks?: HooksConfig<T>, uniqueFields?: NormalizedConstraints, searchIndexRef?: Ref.Ref<SearchIndexMap>, searchIndexFields?: ReadonlyArray<string>, changePubSub?: PubSub.PubSub<ChangeEvent>) => (input: UpsertInternalInput<T>) => Effect.Effect<UpsertResult<T>, ValidationError | ForeignKeyError | HookError | UniqueConstraintError>;
36
+ /**
37
+ * Upsert multiple entities efficiently.
38
+ *
39
+ * For each input:
40
+ * - If entity matches where clause: apply updates (or skip if unchanged)
41
+ * - If no match: create new entity
42
+ *
43
+ * All changes validated and applied atomically.
44
+ * Returns categorized results: created, updated, unchanged.
45
+ *
46
+ * Runs hooks per entity:
47
+ * - Create path: beforeCreate → mutation → afterCreate → onChange("create")
48
+ * - Update path: beforeUpdate → mutation → afterUpdate → onChange("update")
49
+ */
50
+ export declare const upsertMany: <T extends HasId, I = T>(collectionName: string, schema: Schema.Schema<T, I>, relationships: Record<string, RelationshipConfig>, ref: Ref.Ref<ReadonlyMap<string, T>>, stateRefs: Record<string, Ref.Ref<ReadonlyMap<string, HasId>>>, indexes?: CollectionIndexes, hooks?: HooksConfig<T>, uniqueFields?: NormalizedConstraints, searchIndexRef?: Ref.Ref<SearchIndexMap>, searchIndexFields?: ReadonlyArray<string>, changePubSub?: PubSub.PubSub<ChangeEvent>) => (inputs: ReadonlyArray<UpsertInternalInput<T>>) => Effect.Effect<UpsertManyResult<T>, ValidationError | ForeignKeyError | HookError | UniqueConstraintError>;
51
+ export {};
52
+ //# sourceMappingURL=upsert.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"upsert.d.ts","sourceRoot":"","sources":["../../../src/operations/crud/upsert.ts"],"names":[],"mappings":"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"}