@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,333 @@
1
+ /**
2
+ * Effect-based create operations for entities.
3
+ *
4
+ * Uses Ref<ReadonlyMap> for atomic state mutation, Effect Schema for validation,
5
+ * and typed errors (ValidationError, DuplicateKeyError, ForeignKeyError).
6
+ */
7
+ import { Effect, PubSub, Ref } from "effect";
8
+ import { DuplicateKeyError, } from "../../errors/crud-errors.js";
9
+ import { runAfterCreateHooks, runBeforeCreateHooks, runOnChangeHooks, } from "../../hooks/hook-runner.js";
10
+ import { addManyToIndex, addToIndex } from "../../indexes/index-manager.js";
11
+ import { addToSearchIndex } from "../../indexes/search-index.js";
12
+ import { generateId } from "../../utils/id-generator.js";
13
+ import { validateForeignKeysEffect } from "../../validators/foreign-key.js";
14
+ import { validateEntity } from "../../validators/schema-validator.js";
15
+ import { addEntityToBatchIndex, checkEntityUniqueConstraints, checkUniqueConstraints, } from "./unique-check.js";
16
+ // ============================================================================
17
+ // Create Single Entity
18
+ // ============================================================================
19
+ /**
20
+ * Strip computed field keys from an input object.
21
+ * Used to remove computed field names from create/update input before schema validation.
22
+ *
23
+ * @param input - The input object (possibly with computed field keys)
24
+ * @param computed - The computed fields configuration that defines which keys to strip
25
+ * @returns A new object with computed field keys removed
26
+ */
27
+ const stripComputedFromInput = (input, computed) => {
28
+ if (computed === undefined || Object.keys(computed).length === 0) {
29
+ return input;
30
+ }
31
+ const computedKeys = new Set(Object.keys(computed));
32
+ const result = {};
33
+ for (const key of Object.keys(input)) {
34
+ if (!computedKeys.has(key)) {
35
+ result[key] = input[key];
36
+ }
37
+ }
38
+ return result;
39
+ };
40
+ /**
41
+ * Create a single entity with validation, hooks, and foreign key checks.
42
+ *
43
+ * Steps:
44
+ * 1. Strip computed field keys from input (they are derived, not stored)
45
+ * 2. Generate ID if not provided, add timestamps
46
+ * 3. Validate through Effect Schema
47
+ * 4. Run beforeCreate hooks (can transform entity)
48
+ * 5. Check for duplicate ID in Ref state
49
+ * 6. Validate foreign key constraints
50
+ * 7. Atomically add to Ref state
51
+ * 8. Update indexes if provided
52
+ */
53
+ export const create = (collectionName, schema, relationships, ref, stateRefs, indexes, hooks, uniqueFields = [], computed, searchIndexRef, searchIndexFields, idGeneratorName, idGeneratorMap, changePubSub) => (input) => Effect.gen(function* () {
54
+ // Strip computed field keys from input (they are derived, not stored)
55
+ const sanitizedInput = stripComputedFromInput(input, computed);
56
+ // Determine which ID generator to use:
57
+ // 1. If input has an id, use it
58
+ // 2. If collection specifies idGenerator and it exists in the map, use the plugin generator
59
+ // 3. Otherwise, use the default generateId
60
+ const inputId = sanitizedInput.id;
61
+ let id;
62
+ if (inputId) {
63
+ id = inputId;
64
+ }
65
+ else if (idGeneratorName && idGeneratorMap?.has(idGeneratorName)) {
66
+ const generator = idGeneratorMap.get(idGeneratorName);
67
+ id = generator ? generator.generate() : generateId();
68
+ }
69
+ else {
70
+ id = generateId();
71
+ }
72
+ const now = new Date().toISOString();
73
+ // Build raw entity object for schema validation
74
+ const raw = {
75
+ ...sanitizedInput,
76
+ id,
77
+ createdAt: now,
78
+ updatedAt: now,
79
+ };
80
+ // Validate through Effect Schema
81
+ const validated = yield* validateEntity(schema, raw);
82
+ // Run beforeCreate hooks (can transform the entity)
83
+ const entity = yield* runBeforeCreateHooks(hooks?.beforeCreate, {
84
+ operation: "create",
85
+ collection: collectionName,
86
+ data: validated,
87
+ });
88
+ // Check for duplicate ID atomically
89
+ const currentMap = yield* Ref.get(ref);
90
+ if (currentMap.has(id)) {
91
+ return yield* Effect.fail(new DuplicateKeyError({
92
+ collection: collectionName,
93
+ field: "id",
94
+ value: id,
95
+ existingId: id,
96
+ message: `Duplicate value for field 'id': "${id}"`,
97
+ }));
98
+ }
99
+ // Check unique constraints
100
+ yield* checkUniqueConstraints(entity, currentMap, uniqueFields, collectionName);
101
+ // Validate foreign keys
102
+ yield* validateForeignKeysEffect(entity, collectionName, relationships, stateRefs);
103
+ // Atomically add to state
104
+ yield* Ref.update(ref, (map) => {
105
+ const next = new Map(map);
106
+ next.set(id, entity);
107
+ return next;
108
+ });
109
+ // Update indexes if provided
110
+ if (indexes && indexes.size > 0) {
111
+ yield* addToIndex(indexes, entity);
112
+ }
113
+ // Update search index if configured
114
+ if (searchIndexRef && searchIndexFields && searchIndexFields.length > 0) {
115
+ yield* addToSearchIndex(searchIndexRef, entity, searchIndexFields);
116
+ }
117
+ // Run afterCreate hooks (fire-and-forget, errors swallowed)
118
+ yield* runAfterCreateHooks(hooks?.afterCreate, {
119
+ operation: "create",
120
+ collection: collectionName,
121
+ entity,
122
+ });
123
+ // Run onChange hooks with type: "create" (fire-and-forget, errors swallowed)
124
+ yield* runOnChangeHooks(hooks?.onChange, {
125
+ type: "create",
126
+ collection: collectionName,
127
+ entity,
128
+ });
129
+ // Publish change event to reactive subscribers
130
+ if (changePubSub) {
131
+ yield* PubSub.publish(changePubSub, {
132
+ collection: collectionName,
133
+ operation: "create",
134
+ });
135
+ }
136
+ return entity;
137
+ });
138
+ // ============================================================================
139
+ // Create Multiple Entities
140
+ // ============================================================================
141
+ /**
142
+ * Create multiple entities with batch validation, hooks, and optional duplicate skipping.
143
+ *
144
+ * When `skipDuplicates` is true, entities that fail validation, have duplicate IDs,
145
+ * or have a HookError are skipped and reported in the result. Otherwise, the first error
146
+ * stops the operation.
147
+ */
148
+ export const createMany = (collectionName, schema, relationships, ref, stateRefs, indexes, hooks, uniqueFields = [], computed, searchIndexRef, searchIndexFields, idGeneratorName, idGeneratorMap, changePubSub) => (inputs, options) => Effect.gen(function* () {
149
+ const created = [];
150
+ const skipped = [];
151
+ const now = new Date().toISOString();
152
+ const skipOnError = options?.skipDuplicates === true;
153
+ // Get current state once for duplicate checking
154
+ const currentMap = yield* Ref.get(ref);
155
+ const existingIds = new Set(currentMap.keys());
156
+ // Track IDs we're adding in this batch
157
+ const batchIds = new Set();
158
+ // Phase 1: Validate all entities and run beforeCreate hooks
159
+ const validEntities = [];
160
+ for (const input of inputs) {
161
+ // Strip computed field keys from input (they are derived, not stored)
162
+ const sanitizedInput = stripComputedFromInput(input, computed);
163
+ // Determine which ID generator to use for this entity:
164
+ // 1. If input has an id, use it
165
+ // 2. If collection specifies idGenerator and it exists in the map, use the plugin generator
166
+ // 3. Otherwise, use the default generateId
167
+ const inputId = sanitizedInput.id;
168
+ let id;
169
+ if (inputId) {
170
+ id = inputId;
171
+ }
172
+ else if (idGeneratorName && idGeneratorMap?.has(idGeneratorName)) {
173
+ const generator = idGeneratorMap.get(idGeneratorName);
174
+ id = generator ? generator.generate() : generateId();
175
+ }
176
+ else {
177
+ id = generateId();
178
+ }
179
+ // Check for duplicate ID
180
+ if (existingIds.has(id) || batchIds.has(id)) {
181
+ if (skipOnError) {
182
+ skipped.push({
183
+ data: { ...sanitizedInput, id },
184
+ reason: `Duplicate ID: ${id}`,
185
+ });
186
+ continue;
187
+ }
188
+ return yield* Effect.fail(new DuplicateKeyError({
189
+ collection: collectionName,
190
+ field: "id",
191
+ value: id,
192
+ existingId: id,
193
+ message: `Duplicate value for field 'id': "${id}"`,
194
+ }));
195
+ }
196
+ const raw = { ...sanitizedInput, id, createdAt: now, updatedAt: now };
197
+ // Validate through schema
198
+ const validationResult = yield* validateEntity(schema, raw).pipe(Effect.map((validated) => ({ _tag: "ok", validated })), Effect.catchTag("ValidationError", (err) => skipOnError
199
+ ? Effect.succeed({ _tag: "skipped", error: err })
200
+ : Effect.fail(err)));
201
+ if (validationResult._tag === "skipped") {
202
+ skipped.push({
203
+ data: { ...sanitizedInput, id },
204
+ reason: `Validation failed: ${validationResult.error.issues[0]?.message ?? "unknown"}`,
205
+ });
206
+ continue;
207
+ }
208
+ const validated = validationResult.validated;
209
+ // Run beforeCreate hooks (can transform or reject the entity)
210
+ const hookResult = yield* runBeforeCreateHooks(hooks?.beforeCreate, {
211
+ operation: "create",
212
+ collection: collectionName,
213
+ data: validated,
214
+ }).pipe(Effect.map((entity) => ({ _tag: "ok", entity })), Effect.catchTag("HookError", (err) => skipOnError
215
+ ? Effect.succeed({ _tag: "skipped", error: err })
216
+ : Effect.fail(err)));
217
+ if (hookResult._tag === "skipped") {
218
+ skipped.push({
219
+ data: { ...sanitizedInput, id },
220
+ reason: `Hook rejected: ${hookResult.error.message}`,
221
+ });
222
+ continue;
223
+ }
224
+ batchIds.add(id);
225
+ validEntities.push(hookResult.entity);
226
+ }
227
+ // Phase 2: Check unique constraints (with per-entity skipDuplicates handling)
228
+ // We check incrementally to support skipDuplicates for unique violations
229
+ const uniquePassedEntities = [];
230
+ // Track constraint values we've seen in this batch for inter-batch conflict detection
231
+ // Key: constraintName + ":" + serialized values, Value: entity id
232
+ const batchConstraintIndex = new Map();
233
+ for (const entity of validEntities) {
234
+ const entityRecord = entity;
235
+ // Check this entity against existing map and batch index
236
+ const uniqueResult = yield* checkEntityUniqueConstraints(entity, entityRecord, currentMap, uniqueFields, collectionName, batchConstraintIndex).pipe(Effect.map(() => ({ _tag: "ok" })), Effect.catchTag("UniqueConstraintError", (err) => skipOnError
237
+ ? Effect.succeed({ _tag: "skipped", error: err })
238
+ : Effect.fail(err)));
239
+ if (uniqueResult._tag === "skipped") {
240
+ skipped.push({
241
+ data: entity,
242
+ reason: `Unique constraint violation: ${uniqueResult.error.message}`,
243
+ });
244
+ continue;
245
+ }
246
+ // Add this entity to the batch constraint index for subsequent checks
247
+ addEntityToBatchIndex(entity, entityRecord, uniqueFields, batchConstraintIndex);
248
+ uniquePassedEntities.push(entity);
249
+ }
250
+ // Phase 3: Validate foreign keys if requested
251
+ if (options?.validateRelationships !== false) {
252
+ const finalEntities = [];
253
+ for (let i = 0; i < uniquePassedEntities.length; i++) {
254
+ const entity = uniquePassedEntities[i];
255
+ if (!entity)
256
+ continue;
257
+ const fkResult = yield* validateForeignKeysEffect(entity, collectionName, relationships, stateRefs).pipe(Effect.map(() => ({ _tag: "ok" })), Effect.catchTag("ForeignKeyError", (err) => skipOnError
258
+ ? Effect.succeed({ _tag: "skipped", error: err })
259
+ : Effect.fail(err)));
260
+ if (fkResult._tag === "skipped") {
261
+ skipped.push({
262
+ data: entity,
263
+ reason: `Foreign key violation: ${fkResult.error.message}`,
264
+ });
265
+ }
266
+ else {
267
+ finalEntities.push(entity);
268
+ created.push(entity);
269
+ }
270
+ }
271
+ // Atomically add all valid entities to state
272
+ if (finalEntities.length > 0) {
273
+ yield* Ref.update(ref, (map) => {
274
+ const next = new Map(map);
275
+ for (const entity of finalEntities) {
276
+ next.set(entity.id, entity);
277
+ }
278
+ return next;
279
+ });
280
+ }
281
+ }
282
+ else {
283
+ // No FK validation, add all unique-passed entities
284
+ created.push(...uniquePassedEntities);
285
+ if (uniquePassedEntities.length > 0) {
286
+ yield* Ref.update(ref, (map) => {
287
+ const next = new Map(map);
288
+ for (const entity of uniquePassedEntities) {
289
+ next.set(entity.id, entity);
290
+ }
291
+ return next;
292
+ });
293
+ }
294
+ }
295
+ // Update indexes for all created entities using batch operation
296
+ if (indexes && indexes.size > 0 && created.length > 0) {
297
+ yield* addManyToIndex(indexes, created);
298
+ }
299
+ // Update search index for all created entities
300
+ if (searchIndexRef &&
301
+ searchIndexFields &&
302
+ searchIndexFields.length > 0 &&
303
+ created.length > 0) {
304
+ for (const entity of created) {
305
+ yield* addToSearchIndex(searchIndexRef, entity, searchIndexFields);
306
+ }
307
+ }
308
+ // Phase 3: Run afterCreate and onChange hooks for each created entity
309
+ for (const entity of created) {
310
+ yield* runAfterCreateHooks(hooks?.afterCreate, {
311
+ operation: "create",
312
+ collection: collectionName,
313
+ entity,
314
+ });
315
+ yield* runOnChangeHooks(hooks?.onChange, {
316
+ type: "create",
317
+ collection: collectionName,
318
+ entity,
319
+ });
320
+ }
321
+ // Publish a single change event after all entities are inserted
322
+ if (changePubSub && created.length > 0) {
323
+ yield* PubSub.publish(changePubSub, {
324
+ collection: collectionName,
325
+ operation: "create",
326
+ });
327
+ }
328
+ return {
329
+ created,
330
+ ...(skipped.length > 0 ? { skipped } : {}),
331
+ };
332
+ });
333
+ //# sourceMappingURL=create.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create.js","sourceRoot":"","sources":["../../../src/operations/crud/create.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,63 @@
1
+ /**
2
+ * Effect-based delete operations with relationship cascade support.
3
+ *
4
+ * Uses Ref<ReadonlyMap> for atomic state mutation and typed errors.
5
+ * Supports cascade, restrict, set_null, cascade_soft, and preserve
6
+ * cascade options for relationship handling during deletion.
7
+ */
8
+ import { Effect, PubSub, Ref } from "effect";
9
+ import { NotFoundError, type OperationError, ValidationError } from "../../errors/crud-errors.js";
10
+ import type { DeleteWithRelationshipsOptions, DeleteWithRelationshipsResult } from "../../types/crud-relationship-types.js";
11
+ import type { ChangeEvent } from "../../types/reactive-types.js";
12
+ import type { RelationshipDef } from "../../types/types.js";
13
+ type HasId = {
14
+ readonly id: string;
15
+ };
16
+ type RelationshipConfig = {
17
+ readonly type: "ref" | "inverse";
18
+ readonly target?: string;
19
+ readonly __targetCollection?: string;
20
+ readonly foreignKey?: string;
21
+ };
22
+ type CollectionConfig = {
23
+ readonly schema: unknown;
24
+ readonly relationships: Record<string, RelationshipConfig>;
25
+ };
26
+ type DatabaseConfig = Record<string, CollectionConfig>;
27
+ type CascadeResult = {
28
+ readonly [collection: string]: {
29
+ readonly count: number;
30
+ readonly ids: ReadonlyArray<string>;
31
+ };
32
+ };
33
+ /**
34
+ * Delete a single entity with relationship cascade support.
35
+ *
36
+ * Steps:
37
+ * 1. Look up entity by ID in Ref state (O(1))
38
+ * 2. Process relationship cascades (restrict, cascade, set_null, etc.)
39
+ * 3. Fail if any restrict violations exist
40
+ * 4. Perform the delete (soft or hard)
41
+ * 5. Return deleted entity with cascade information
42
+ */
43
+ export declare const deleteWithRelationships: <T extends HasId>(collectionName: string, relationships: Record<string, RelationshipConfig>, ref: Ref.Ref<ReadonlyMap<string, T>>, stateRefs: Record<string, Ref.Ref<ReadonlyMap<string, HasId>>>, dbConfig: DatabaseConfig, changePubSub?: PubSub.PubSub<ChangeEvent>) => (id: string, options?: DeleteWithRelationshipsOptions<T, Record<string, RelationshipDef>>) => Effect.Effect<DeleteWithRelationshipsResult<T>, NotFoundError | ValidationError | OperationError>;
44
+ /**
45
+ * Delete multiple entities matching a predicate with relationship cascade support.
46
+ *
47
+ * Steps:
48
+ * 1. Find all matching entities using predicate
49
+ * 2. Apply limit if specified
50
+ * 3. Check all restrict violations first (fail-fast)
51
+ * 4. Process cascade operations for all entities
52
+ * 5. Perform the deletes (soft or hard)
53
+ * 6. Return count, deleted entities, and cascade information
54
+ */
55
+ export declare const deleteManyWithRelationships: <T extends HasId>(collectionName: string, relationships: Record<string, RelationshipConfig>, ref: Ref.Ref<ReadonlyMap<string, T>>, stateRefs: Record<string, Ref.Ref<ReadonlyMap<string, HasId>>>, dbConfig: DatabaseConfig, changePubSub?: PubSub.PubSub<ChangeEvent>) => (predicate: (entity: T) => boolean, options?: DeleteWithRelationshipsOptions<T, Record<string, RelationshipDef>> & {
56
+ readonly limit?: number;
57
+ }) => Effect.Effect<{
58
+ readonly count: number;
59
+ readonly deleted: ReadonlyArray<T>;
60
+ readonly cascaded?: CascadeResult;
61
+ }, ValidationError | OperationError>;
62
+ export {};
63
+ //# sourceMappingURL=delete-with-relationships.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"delete-with-relationships.d.ts","sourceRoot":"","sources":["../../../src/operations/crud/delete-with-relationships.ts"],"names":[],"mappings":"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"}