@effect-app/infra 4.0.0-beta.19 → 4.0.0-beta.191

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 (305) hide show
  1. package/CHANGELOG.md +1285 -0
  2. package/_check.sh +1 -1
  3. package/dist/CUPS.d.ts +15 -7
  4. package/dist/CUPS.d.ts.map +1 -1
  5. package/dist/CUPS.js +10 -12
  6. package/dist/Emailer/Sendgrid.d.ts +14 -14
  7. package/dist/Emailer/Sendgrid.d.ts.map +1 -1
  8. package/dist/Emailer/Sendgrid.js +16 -15
  9. package/dist/Emailer/fake.d.ts +1 -1
  10. package/dist/Emailer/service.d.ts +10 -4
  11. package/dist/Emailer/service.d.ts.map +1 -1
  12. package/dist/Emailer/service.js +3 -3
  13. package/dist/Emailer.d.ts +1 -1
  14. package/dist/MainFiberSet.d.ts +9 -9
  15. package/dist/MainFiberSet.d.ts.map +1 -1
  16. package/dist/MainFiberSet.js +3 -3
  17. package/dist/Model/Repository/Registry.d.ts +20 -0
  18. package/dist/Model/Repository/Registry.d.ts.map +1 -0
  19. package/dist/Model/Repository/Registry.js +17 -0
  20. package/dist/Model/Repository/ext.d.ts +33 -15
  21. package/dist/Model/Repository/ext.d.ts.map +1 -1
  22. package/dist/Model/Repository/ext.js +54 -2
  23. package/dist/Model/Repository/internal/internal.d.ts +6 -6
  24. package/dist/Model/Repository/internal/internal.d.ts.map +1 -1
  25. package/dist/Model/Repository/internal/internal.js +43 -32
  26. package/dist/Model/Repository/legacy.d.ts +1 -1
  27. package/dist/Model/Repository/makeRepo.d.ts +7 -6
  28. package/dist/Model/Repository/makeRepo.d.ts.map +1 -1
  29. package/dist/Model/Repository/makeRepo.js +5 -1
  30. package/dist/Model/Repository/service.d.ts +28 -23
  31. package/dist/Model/Repository/service.d.ts.map +1 -1
  32. package/dist/Model/Repository/validation.d.ts +142 -17
  33. package/dist/Model/Repository/validation.d.ts.map +1 -1
  34. package/dist/Model/Repository/validation.js +5 -5
  35. package/dist/Model/Repository.d.ts +2 -1
  36. package/dist/Model/Repository.d.ts.map +1 -1
  37. package/dist/Model/Repository.js +2 -1
  38. package/dist/Model/dsl.d.ts +4 -4
  39. package/dist/Model/dsl.d.ts.map +1 -1
  40. package/dist/Model/filter/filterApi.d.ts +5 -5
  41. package/dist/Model/filter/filterApi.d.ts.map +1 -1
  42. package/dist/Model/filter/types/errors.d.ts +1 -1
  43. package/dist/Model/filter/types/fields.d.ts +1 -1
  44. package/dist/Model/filter/types/path/common.d.ts +1 -1
  45. package/dist/Model/filter/types/path/eager.d.ts +1 -1
  46. package/dist/Model/filter/types/path/eager.d.ts.map +1 -1
  47. package/dist/Model/filter/types/path/eager.js +1 -1
  48. package/dist/Model/filter/types/path/index.d.ts +1 -1
  49. package/dist/Model/filter/types/utils.d.ts +1 -1
  50. package/dist/Model/filter/types/validator.d.ts +1 -1
  51. package/dist/Model/filter/types.d.ts +1 -1
  52. package/dist/Model/query/dsl.d.ts +16 -16
  53. package/dist/Model/query/dsl.d.ts.map +1 -1
  54. package/dist/Model/query/new-kid-interpreter.d.ts +6 -6
  55. package/dist/Model/query/new-kid-interpreter.d.ts.map +1 -1
  56. package/dist/Model/query/new-kid-interpreter.js +3 -3
  57. package/dist/Model/query.d.ts +1 -1
  58. package/dist/Model.d.ts +2 -1
  59. package/dist/Model.d.ts.map +1 -1
  60. package/dist/Model.js +2 -1
  61. package/dist/QueueMaker/SQLQueue.d.ts +5 -7
  62. package/dist/QueueMaker/SQLQueue.d.ts.map +1 -1
  63. package/dist/QueueMaker/SQLQueue.js +105 -114
  64. package/dist/QueueMaker/errors.d.ts +2 -2
  65. package/dist/QueueMaker/errors.d.ts.map +1 -1
  66. package/dist/QueueMaker/memQueue.d.ts +7 -4
  67. package/dist/QueueMaker/memQueue.d.ts.map +1 -1
  68. package/dist/QueueMaker/memQueue.js +51 -62
  69. package/dist/QueueMaker/sbqueue.d.ts +6 -3
  70. package/dist/QueueMaker/sbqueue.d.ts.map +1 -1
  71. package/dist/QueueMaker/sbqueue.js +37 -53
  72. package/dist/QueueMaker/service.d.ts +1 -1
  73. package/dist/RequestContext.d.ts +114 -26
  74. package/dist/RequestContext.d.ts.map +1 -1
  75. package/dist/RequestContext.js +7 -8
  76. package/dist/RequestFiberSet.d.ts +7 -7
  77. package/dist/RequestFiberSet.d.ts.map +1 -1
  78. package/dist/RequestFiberSet.js +5 -5
  79. package/dist/Store/ContextMapContainer.d.ts +19 -3
  80. package/dist/Store/ContextMapContainer.d.ts.map +1 -1
  81. package/dist/Store/ContextMapContainer.js +13 -3
  82. package/dist/Store/Cosmos/query.d.ts +1 -1
  83. package/dist/Store/Cosmos/query.d.ts.map +1 -1
  84. package/dist/Store/Cosmos/query.js +10 -12
  85. package/dist/Store/Cosmos.d.ts +1 -1
  86. package/dist/Store/Cosmos.d.ts.map +1 -1
  87. package/dist/Store/Cosmos.js +308 -242
  88. package/dist/Store/Disk.d.ts +2 -2
  89. package/dist/Store/Disk.d.ts.map +1 -1
  90. package/dist/Store/Disk.js +25 -22
  91. package/dist/Store/Memory.d.ts +4 -4
  92. package/dist/Store/Memory.d.ts.map +1 -1
  93. package/dist/Store/Memory.js +27 -22
  94. package/dist/Store/SQL/Pg.d.ts +4 -0
  95. package/dist/Store/SQL/Pg.d.ts.map +1 -0
  96. package/dist/Store/SQL/Pg.js +189 -0
  97. package/dist/Store/SQL/query.d.ts +38 -0
  98. package/dist/Store/SQL/query.d.ts.map +1 -0
  99. package/dist/Store/SQL/query.js +367 -0
  100. package/dist/Store/SQL.d.ts +20 -0
  101. package/dist/Store/SQL.d.ts.map +1 -0
  102. package/dist/Store/SQL.js +381 -0
  103. package/dist/Store/codeFilter.d.ts +1 -1
  104. package/dist/Store/codeFilter.d.ts.map +1 -1
  105. package/dist/Store/codeFilter.js +2 -1
  106. package/dist/Store/index.d.ts +5 -2
  107. package/dist/Store/index.d.ts.map +1 -1
  108. package/dist/Store/index.js +15 -3
  109. package/dist/Store/service.d.ts +18 -7
  110. package/dist/Store/service.d.ts.map +1 -1
  111. package/dist/Store/service.js +24 -6
  112. package/dist/Store/utils.d.ts +1 -1
  113. package/dist/Store/utils.d.ts.map +1 -1
  114. package/dist/Store/utils.js +3 -4
  115. package/dist/Store.d.ts +1 -1
  116. package/dist/adapters/SQL/Model.d.ts +28 -42
  117. package/dist/adapters/SQL/Model.d.ts.map +1 -1
  118. package/dist/adapters/SQL/Model.js +2 -2
  119. package/dist/adapters/SQL.d.ts +1 -1
  120. package/dist/adapters/ServiceBus.d.ts +11 -11
  121. package/dist/adapters/ServiceBus.d.ts.map +1 -1
  122. package/dist/adapters/ServiceBus.js +13 -15
  123. package/dist/adapters/cosmos-client.d.ts +3 -3
  124. package/dist/adapters/cosmos-client.d.ts.map +1 -1
  125. package/dist/adapters/cosmos-client.js +3 -3
  126. package/dist/adapters/index.d.ts +8 -2
  127. package/dist/adapters/index.d.ts.map +1 -1
  128. package/dist/adapters/index.js +8 -2
  129. package/dist/adapters/logger.d.ts +2 -2
  130. package/dist/adapters/logger.d.ts.map +1 -1
  131. package/dist/adapters/memQueue.d.ts +3 -3
  132. package/dist/adapters/memQueue.d.ts.map +1 -1
  133. package/dist/adapters/memQueue.js +3 -3
  134. package/dist/adapters/mongo-client.d.ts +3 -3
  135. package/dist/adapters/mongo-client.d.ts.map +1 -1
  136. package/dist/adapters/mongo-client.js +3 -3
  137. package/dist/adapters/redis-client.d.ts +3 -3
  138. package/dist/adapters/redis-client.d.ts.map +1 -1
  139. package/dist/adapters/redis-client.js +3 -3
  140. package/dist/api/ContextProvider.d.ts +8 -8
  141. package/dist/api/ContextProvider.d.ts.map +1 -1
  142. package/dist/api/ContextProvider.js +6 -6
  143. package/dist/api/codec.d.ts +1 -1
  144. package/dist/api/internal/RequestContextMiddleware.d.ts +2 -2
  145. package/dist/api/internal/RequestContextMiddleware.d.ts.map +1 -1
  146. package/dist/api/internal/RequestContextMiddleware.js +2 -2
  147. package/dist/api/internal/auth.d.ts +44 -6
  148. package/dist/api/internal/auth.d.ts.map +1 -1
  149. package/dist/api/internal/auth.js +160 -29
  150. package/dist/api/internal/events.d.ts +3 -3
  151. package/dist/api/internal/events.d.ts.map +1 -1
  152. package/dist/api/internal/events.js +9 -7
  153. package/dist/api/internal/health.d.ts +1 -1
  154. package/dist/api/layerUtils.d.ts +6 -6
  155. package/dist/api/layerUtils.d.ts.map +1 -1
  156. package/dist/api/layerUtils.js +5 -5
  157. package/dist/api/middlewares.d.ts +1 -1
  158. package/dist/api/reportError.d.ts +1 -1
  159. package/dist/api/routing/middleware/RouterMiddleware.d.ts +4 -4
  160. package/dist/api/routing/middleware/RouterMiddleware.d.ts.map +1 -1
  161. package/dist/api/routing/middleware/middleware.d.ts +50 -4
  162. package/dist/api/routing/middleware/middleware.d.ts.map +1 -1
  163. package/dist/api/routing/middleware/middleware.js +75 -17
  164. package/dist/api/routing/middleware.d.ts +1 -2
  165. package/dist/api/routing/middleware.d.ts.map +1 -1
  166. package/dist/api/routing/middleware.js +1 -2
  167. package/dist/api/routing/schema/jwt.d.ts +1 -1
  168. package/dist/api/routing/schema/jwt.d.ts.map +1 -1
  169. package/dist/api/routing/tsort.d.ts +1 -1
  170. package/dist/api/routing/tsort.d.ts.map +1 -1
  171. package/dist/api/routing/utils.d.ts +3 -3
  172. package/dist/api/routing/utils.d.ts.map +1 -1
  173. package/dist/api/routing.d.ts +31 -23
  174. package/dist/api/routing.d.ts.map +1 -1
  175. package/dist/api/routing.js +70 -11
  176. package/dist/api/setupRequest.d.ts +8 -5
  177. package/dist/api/setupRequest.d.ts.map +1 -1
  178. package/dist/api/setupRequest.js +12 -7
  179. package/dist/api/util.d.ts +1 -1
  180. package/dist/arbs.d.ts +1 -1
  181. package/dist/arbs.d.ts.map +1 -1
  182. package/dist/arbs.js +5 -3
  183. package/dist/errorReporter.d.ts +4 -4
  184. package/dist/errorReporter.d.ts.map +1 -1
  185. package/dist/errorReporter.js +20 -25
  186. package/dist/errors.d.ts +1 -1
  187. package/dist/fileUtil.d.ts +1 -1
  188. package/dist/fileUtil.d.ts.map +1 -1
  189. package/dist/index.d.ts +1 -1
  190. package/dist/logger/jsonLogger.d.ts +1 -1
  191. package/dist/logger/logFmtLogger.d.ts +1 -1
  192. package/dist/logger/shared.d.ts +1 -1
  193. package/dist/logger/shared.js +2 -2
  194. package/dist/logger.d.ts +1 -1
  195. package/dist/logger.d.ts.map +1 -1
  196. package/dist/rateLimit.d.ts +9 -3
  197. package/dist/rateLimit.d.ts.map +1 -1
  198. package/dist/rateLimit.js +5 -11
  199. package/dist/test.d.ts +2 -2
  200. package/dist/test.d.ts.map +1 -1
  201. package/dist/test.js +1 -1
  202. package/dist/vitest.d.ts +1 -1
  203. package/examples/query.ts +39 -35
  204. package/package.json +41 -37
  205. package/src/CUPS.ts +9 -11
  206. package/src/Emailer/Sendgrid.ts +17 -14
  207. package/src/Emailer/service.ts +9 -3
  208. package/src/MainFiberSet.ts +5 -6
  209. package/src/Model/Repository/Registry.ts +33 -0
  210. package/src/Model/Repository/ext.ts +96 -10
  211. package/src/Model/Repository/internal/internal.ts +97 -88
  212. package/src/Model/Repository/makeRepo.ts +12 -10
  213. package/src/Model/Repository/service.ts +31 -22
  214. package/src/Model/Repository/validation.ts +4 -4
  215. package/src/Model/Repository.ts +1 -0
  216. package/src/Model/dsl.ts +3 -3
  217. package/src/Model/filter/types/path/eager.ts +1 -2
  218. package/src/Model/query/dsl.ts +18 -18
  219. package/src/Model/query/new-kid-interpreter.ts +2 -2
  220. package/src/Model.ts +1 -0
  221. package/src/QueueMaker/SQLQueue.ts +121 -151
  222. package/src/QueueMaker/memQueue.ts +82 -103
  223. package/src/QueueMaker/sbqueue.ts +56 -86
  224. package/src/RequestContext.ts +7 -9
  225. package/src/RequestFiberSet.ts +4 -4
  226. package/src/Store/ContextMapContainer.ts +41 -2
  227. package/src/Store/Cosmos/query.ts +16 -20
  228. package/src/Store/Cosmos.ts +437 -343
  229. package/src/Store/Disk.ts +52 -49
  230. package/src/Store/Memory.ts +54 -48
  231. package/src/Store/SQL/Pg.ts +318 -0
  232. package/src/Store/SQL/query.ts +409 -0
  233. package/src/Store/SQL.ts +668 -0
  234. package/src/Store/codeFilter.ts +1 -0
  235. package/src/Store/index.ts +17 -2
  236. package/src/Store/service.ts +32 -8
  237. package/src/Store/utils.ts +23 -22
  238. package/src/adapters/SQL/Model.ts +10 -4
  239. package/src/adapters/ServiceBus.ts +112 -116
  240. package/src/adapters/cosmos-client.ts +2 -2
  241. package/src/adapters/index.ts +7 -0
  242. package/src/adapters/memQueue.ts +2 -2
  243. package/src/adapters/mongo-client.ts +2 -2
  244. package/src/adapters/redis-client.ts +2 -2
  245. package/src/api/ContextProvider.ts +12 -13
  246. package/src/api/internal/RequestContextMiddleware.ts +1 -1
  247. package/src/api/internal/auth.ts +246 -44
  248. package/src/api/internal/events.ts +12 -8
  249. package/src/api/layerUtils.ts +8 -8
  250. package/src/api/routing/middleware/RouterMiddleware.ts +4 -4
  251. package/src/api/routing/middleware/middleware.ts +109 -15
  252. package/src/api/routing/middleware.ts +0 -2
  253. package/src/api/routing.ts +164 -29
  254. package/src/api/setupRequest.ts +28 -8
  255. package/src/arbs.ts +4 -2
  256. package/src/errorReporter.ts +62 -74
  257. package/src/logger/shared.ts +1 -1
  258. package/src/rateLimit.ts +30 -22
  259. package/src/test.ts +1 -1
  260. package/test/auth.test.ts +101 -0
  261. package/test/contextProvider.test.ts +11 -11
  262. package/test/controller.test.ts +18 -14
  263. package/test/dist/auth.test.d.ts.map +1 -0
  264. package/test/dist/contextProvider.test.d.ts.map +1 -1
  265. package/test/dist/controller.test.d.ts.map +1 -1
  266. package/test/dist/date-query.test.d.ts.map +1 -0
  267. package/test/dist/fixtures.d.ts +26 -12
  268. package/test/dist/fixtures.d.ts.map +1 -1
  269. package/test/dist/fixtures.js +12 -10
  270. package/test/dist/query.test.d.ts.map +1 -1
  271. package/test/dist/rawQuery.test.d.ts.map +1 -1
  272. package/test/dist/repository-ext.test.d.ts.map +1 -0
  273. package/test/dist/requires.test.d.ts.map +1 -1
  274. package/test/dist/router-generator.test.d.ts.map +1 -0
  275. package/test/dist/routing-interruptibility.test.d.ts.map +1 -0
  276. package/test/dist/rpc-e2e-invalidation.test.d.ts.map +1 -0
  277. package/test/dist/rpc-multi-middleware.test.d.ts.map +1 -1
  278. package/test/dist/rpc-stream-fullstack.test.d.ts.map +1 -0
  279. package/test/dist/sql-store.test.d.ts.map +1 -0
  280. package/test/fixtures.ts +11 -9
  281. package/test/query.test.ts +216 -34
  282. package/test/rawQuery.test.ts +23 -19
  283. package/test/repository-ext.test.ts +60 -0
  284. package/test/requires.test.ts +6 -6
  285. package/test/router-generator.test.ts +180 -0
  286. package/test/routing-interruptibility.test.ts +63 -0
  287. package/test/rpc-e2e-invalidation.test.ts +507 -0
  288. package/test/rpc-multi-middleware.test.ts +78 -9
  289. package/test/rpc-stream-fullstack.test.ts +181 -0
  290. package/test/sql-store.test.ts +1064 -0
  291. package/test/validateSample.test.ts +15 -12
  292. package/tsconfig.examples.json +1 -1
  293. package/tsconfig.json +0 -1
  294. package/tsconfig.json.bak +2 -2
  295. package/tsconfig.src.json +35 -35
  296. package/tsconfig.test.json +2 -2
  297. package/dist/Operations.d.ts +0 -55
  298. package/dist/Operations.d.ts.map +0 -1
  299. package/dist/Operations.js +0 -102
  300. package/dist/OperationsRepo.d.ts +0 -41
  301. package/dist/OperationsRepo.d.ts.map +0 -1
  302. package/dist/OperationsRepo.js +0 -14
  303. package/eslint.config.mjs +0 -24
  304. package/src/Operations.ts +0 -235
  305. package/src/OperationsRepo.ts +0 -16
@@ -9,6 +9,7 @@ import { InfraLogger } from "../logger.js"
9
9
  import type { FieldValues } from "../Model/filter/types.js"
10
10
  import { type RawQuery } from "../Model/query.js"
11
11
  import { buildWhereCosmosQuery3, logQuery } from "./Cosmos/query.js"
12
+ import { storeId } from "./Memory.js"
12
13
  import { type FilterArgs, type PersistenceModelType, type StorageConfig, type Store, type StoreConfig, StoreMaker } from "./service.js"
13
14
 
14
15
  const makeMapId =
@@ -25,148 +26,219 @@ class CosmosDbOperationError {
25
26
  constructor(readonly message: string, readonly raw?: unknown) {}
26
27
  } // TODO: Retry operation when running into RU limit.
27
28
 
28
- function makeCosmosStore({ prefix }: StorageConfig) {
29
- return Effect.gen(function*() {
30
- const { db } = yield* CosmosClient
31
- return {
32
- make: <IdKey extends keyof Encoded, Encoded extends FieldValues, R = never, E = never>(
33
- name: string,
34
- idKey: IdKey,
35
- seed?: Effect.Effect<Iterable<Encoded>, E, R>,
36
- config?: StoreConfig<Encoded>
37
- ) =>
38
- Effect.gen(function*() {
39
- const mapId = makeMapId<IdKey, Encoded>(idKey)
40
- const mapReverseId = makeReverseMapId<IdKey, Encoded>(idKey)
41
- type PM = PersistenceModelType<Encoded>
42
- type PMCosmos = PersistenceModelType<Omit<Encoded, IdKey> & { id: string }>
43
- const containerId = `${prefix}${name}`
44
- yield* Effect.promise(() =>
45
- db.containers.createIfNotExists(dropUndefinedT({
46
- id: containerId,
47
- uniqueKeyPolicy: config?.uniqueKeys
48
- ? { uniqueKeys: config.uniqueKeys }
49
- : undefined
50
- }))
51
- )
29
+ const makeCosmosStore = Effect.fnUntraced(function*({ prefix }: StorageConfig) {
30
+ const { db } = yield* CosmosClient
31
+ return {
32
+ make: Effect.fnUntraced(function*<IdKey extends keyof Encoded, Encoded extends FieldValues, R = never, E = never>(
33
+ name: string,
34
+ idKey: IdKey,
35
+ seed?: Effect.Effect<Iterable<Encoded>, E, R>,
36
+ config?: StoreConfig<Encoded>
37
+ ) {
38
+ const mapId = makeMapId<IdKey, Encoded>(idKey)
39
+ const mapReverseId = makeReverseMapId<IdKey, Encoded>(idKey)
40
+ type PM = PersistenceModelType<Encoded>
41
+ type PMCosmos = PersistenceModelType<Omit<Encoded, IdKey> & { id: string }>
42
+ const containerId = `${prefix}${name}`
43
+ yield* Effect.promise(() =>
44
+ db.containers.createIfNotExists(dropUndefinedT({
45
+ id: containerId,
46
+ uniqueKeyPolicy: config?.uniqueKeys
47
+ ? { uniqueKeys: config.uniqueKeys }
48
+ : undefined,
49
+ partitionKey: {
50
+ paths: ["/_partitionKey"],
51
+ version: 2 // support large partitionkeys so that the hash is not based on just the first 100 bytes!
52
+ }
53
+ }))
54
+ )
52
55
 
53
- const mainPartitionKey = config?.partitionValue() ?? "primary"
56
+ const basePartitionKey = config?.partitionValue() ?? "primary"
57
+ const nsPrefix = (ns: string) => ns === "primary" ? "" : `${ns}::`
58
+ const nsPartitionValue = (ns: string, e?: Encoded) => {
59
+ const base = config?.partitionValue(e) ?? "primary"
60
+ return `${nsPrefix(ns)}${base}`
61
+ }
62
+ const nsBasePartitionKey = (ns: string) => `${nsPrefix(ns)}${basePartitionKey}`
63
+ const resolveNamespace = !config?.allowNamespace
64
+ ? Effect.succeed("primary")
65
+ : storeId.asEffect().pipe(Effect.map((namespace) => {
66
+ if (namespace !== "primary" && !config.allowNamespace!(namespace)) {
67
+ throw new Error(`Namespace ${namespace} not allowed!`)
68
+ }
69
+ return namespace
70
+ }))
54
71
 
55
- const defaultValues = config?.defaultValues ?? {}
56
- const container = db.container(containerId)
57
- const bulk = container.items.bulk.bind(container.items)
58
- const execBatch = container.items.batch.bind(container.items)
59
- // TODO: move the marker to a separate container and get rid of the checks on every query
60
- // then need to clean up the actual data.. perhaps first do with a config toggle to prescribe to it.
61
- const importedMarkerId = containerId
72
+ const defaultValues = config?.defaultValues ?? {}
73
+ const container = db.container(containerId)
74
+ const bulk = container.items.bulk.bind(container.items)
75
+ const execBatch = container.items.batch.bind(container.items)
76
+ // TODO: move the marker to a separate container and get rid of the checks on every query
77
+ // then need to clean up the actual data.. perhaps first do with a config toggle to prescribe to it.
78
+ const importedMarkerId = containerId
62
79
 
63
- const bulkSet = (items: NonEmptyReadonlyArray<PM>) =>
64
- Effect
65
- .gen(function*() {
66
- // TODO: disable batching if need atomicity
67
- // we delay and batch to keep low amount of RUs
68
- const b = [...items]
69
- .map(
70
- (x) =>
71
- [
72
- x,
73
- Option.match(Option.fromNullishOr(x._etag), {
74
- onNone: () =>
75
- dropUndefinedT({
76
- operationType: "Create" as const,
77
- resourceBody: {
78
- ...Struct.omit(x, ["_etag", idKey]),
79
- id: x[idKey],
80
- _partitionKey: config?.partitionValue(x)
81
- }
82
- // don't use this or we get an error that the request and some item partition key dont match - makese no sense
83
- // partitionKey: config?.partitionValue(x)
84
- }),
85
- onSome: (eTag) =>
86
- dropUndefinedT({
87
- operationType: "Replace" as const,
88
- id: x[idKey],
89
- resourceBody: {
90
- ...Struct.omit(x, ["_etag", idKey]),
91
- id: x[idKey],
92
- _partitionKey: config?.partitionValue(x)
93
- },
94
- ifMatch: eTag
95
- // don't use this or we get an error that the request and some item partition key dont match - makese no sense
96
- // partitionKey: config?.partitionValue(x)
97
- })
98
- })
99
- ] as const
80
+ const ctx = yield* Effect.context<R>()
81
+ const seedCache = new Map<string, Effect.Effect<void>>()
82
+ const makeSeedEffect = (ns: string) => {
83
+ const markerId = ns === "primary" ? importedMarkerId : `${importedMarkerId}::${ns}`
84
+ return Effect
85
+ .promise(() =>
86
+ container
87
+ .item(markerId, markerId)
88
+ .read<{ id: string }>()
89
+ .then(({ resource }) => Option.fromNullishOr(resource))
90
+ )
91
+ .pipe(
92
+ Effect.flatMap((marker) => {
93
+ if (Option.isSome(marker)) return Effect.void
94
+ return InfraLogger.logInfo(`Creating mock data for ${name} (namespace: ${ns})`).pipe(
95
+ Effect.andThen(seed!),
96
+ Effect.flatMap((m) =>
97
+ Effect.flatMapOption(
98
+ Effect.succeed(toNonEmptyArray([...m])),
99
+ (a) => bulkSetInternal(a, ns).pipe(Effect.orDie)
100
100
  )
101
- const batches = Array.chunksOf(b, config?.maxBulkSize ?? 10)
101
+ ),
102
+ Effect.andThen(
103
+ Effect.promise(() =>
104
+ container.items.create({
105
+ _partitionKey: markerId,
106
+ id: markerId,
107
+ ttl: -1
108
+ })
109
+ )
110
+ ),
111
+ Effect.provide(ctx),
112
+ Effect.orDie
113
+ )
114
+ }),
115
+ Effect.withLogSpan(`Cosmos.seedCheck ${name} in ${ns} [effect-app/infra/Store]`),
116
+ Effect.withSpan("Cosmos.seed [effect-app/infra/Store]", { attributes: { name, namespace: ns } })
117
+ )
118
+ }
119
+ const seedNamespace = Effect.fn("seedNamespace")(function*(ns: string) {
120
+ if (!seed) return
121
+ let cached = seedCache.get(ns)
122
+ if (!cached) {
123
+ cached = yield* Effect.cached(Effect.uninterruptible(makeSeedEffect(ns)))
124
+ seedCache.set(ns, cached)
125
+ }
126
+ yield* cached
127
+ })
128
+ const bulkSetInternal = (items: NonEmptyReadonlyArray<PM>, ns: string) =>
129
+ Effect
130
+ .gen(function*() {
131
+ // TODO: disable batching if need atomicity
132
+ // we delay and batch to keep low amount of RUs
133
+ const b = [...items]
134
+ .map(
135
+ (x) =>
136
+ [
137
+ x,
138
+ Option.match(Option.fromNullishOr(x._etag), {
139
+ onNone: () =>
140
+ dropUndefinedT({
141
+ operationType: "Create" as const,
142
+ resourceBody: {
143
+ ...Struct.omit(x, ["_etag", idKey]),
144
+ id: x[idKey],
145
+ _partitionKey: nsPartitionValue(ns, x)
146
+ }
147
+ // don't use this or we get an error that the request and some item partition key dont match - makese no sense
148
+ // partitionKey: config?.partitionValue(x)
149
+ }),
150
+ onSome: (eTag) =>
151
+ dropUndefinedT({
152
+ operationType: "Replace" as const,
153
+ id: x[idKey],
154
+ resourceBody: {
155
+ ...Struct.omit(x, ["_etag", idKey]),
156
+ id: x[idKey],
157
+ _partitionKey: nsPartitionValue(ns, x)
158
+ },
159
+ ifMatch: eTag
160
+ // don't use this or we get an error that the request and some item partition key dont match - makese no sense
161
+ // partitionKey: config?.partitionValue(x)
162
+ })
163
+ })
164
+ ] as const
165
+ )
166
+ const batches = Array.chunksOf(b, config?.maxBulkSize ?? 10)
102
167
 
103
- const batchResult = yield* Effect.forEach(
104
- batches
105
- .map((x, i) => [i, x] as const),
106
- ([i, batch]) =>
168
+ const batchResult = yield* Effect.forEach(
169
+ batches
170
+ .map((x, i) => [i, x] as const),
171
+ ([i, batch]) =>
172
+ Effect
173
+ .promise(() => bulk(batch.map(([, op]) => op)))
174
+ .pipe(
107
175
  Effect
108
- .promise(() => bulk(batch.map(([, op]) => op)))
109
- .pipe(
110
- Effect
111
- .delay(Duration.millis(i === 0 ? 0 : 1100)),
112
- Effect
113
- .flatMap((responses) =>
114
- Effect.gen(function*() {
115
- const r = responses.find((x) =>
116
- x.statusCode === 412 || x.statusCode === 404 || x.statusCode === 409
117
- )
118
- if (r) {
119
- return yield* Effect.fail(
120
- new OptimisticConcurrencyException(
121
- {
122
- type: name,
123
- id: JSON.stringify(r.resourceBody?.["id"]),
124
- code: r.statusCode,
125
- raw: responses
126
- }
127
- )
128
- )
129
- }
130
- const r2 = responses.find(
131
- (x) => x.statusCode !== 424 && (x.statusCode > 299 || x.statusCode < 200)
176
+ .delay(Duration.millis(i === 0 ? 0 : 150)),
177
+ Effect
178
+ .flatMap((responses) =>
179
+ Effect.gen(function*() {
180
+ const r = responses.find((x) =>
181
+ x.statusCode === 412 || x.statusCode === 404 || x.statusCode === 409
182
+ )
183
+ if (r) {
184
+ return yield* Effect.fail(
185
+ new OptimisticConcurrencyException(
186
+ {
187
+ type: name,
188
+ id: JSON.stringify(r.resourceBody?.["id"]),
189
+ code: r.statusCode,
190
+ raw: responses
191
+ }
132
192
  )
133
- if (r2) {
134
- return yield* Effect.die(
135
- new CosmosDbOperationError(
136
- "not able to update records: " + r2.statusCode,
137
- responses
138
- )
139
- )
140
- }
141
- const r3 = responses.find(
142
- (x) => x.statusCode > 299 || x.statusCode < 200
193
+ )
194
+ }
195
+ const r2 = responses.find(
196
+ (x) => x.statusCode !== 424 && (x.statusCode > 299 || x.statusCode < 200)
197
+ )
198
+ if (r2) {
199
+ return yield* Effect.die(
200
+ new CosmosDbOperationError(
201
+ "not able to update records: " + r2.statusCode,
202
+ responses
143
203
  )
144
- if (r3) {
145
- return yield* Effect.die(
146
- new CosmosDbOperationError(
147
- "not able to update records: " + r3.statusCode,
148
- responses
149
- )
150
- )
151
- }
152
- return batch.map(([e], i) => ({
153
- ...e,
154
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
155
- _etag: responses[i]!.eTag
156
- }))
157
- })
204
+ )
205
+ }
206
+ const r3 = responses.find(
207
+ (x) => x.statusCode > 299 || x.statusCode < 200
158
208
  )
209
+ if (r3) {
210
+ return yield* Effect.die(
211
+ new CosmosDbOperationError(
212
+ "not able to update records: " + r3.statusCode,
213
+ responses
214
+ )
215
+ )
216
+ }
217
+ return batch.map(([e], i) => ({
218
+ ...e,
219
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
220
+ _etag: responses[i]!.eTag
221
+ }))
222
+ })
159
223
  )
160
- )
224
+ )
225
+ )
161
226
 
162
- return batchResult.flat() as unknown as NonEmptyReadonlyArray<Encoded>
163
- })
164
- .pipe(Effect.withSpan("Cosmos.bulkSet [effect-app/infra/Store]", {
165
- attributes: { "repository.container_id": containerId, "repository.model_name": name }
166
- }, { captureStackTrace: false }))
227
+ return batchResult.flat() as unknown as NonEmptyReadonlyArray<Encoded>
228
+ })
229
+ .pipe(
230
+ Effect.withSpan("Cosmos.bulkSet [effect-app/infra/Store]", {
231
+ attributes: { "repository.container_id": containerId, "repository.model_name": name, namespace: ns }
232
+ }, { captureStackTrace: false })
233
+ )
167
234
 
168
- const batchSet = (items: NonEmptyReadonlyArray<PM>) => {
169
- return Effect
235
+ const bulkSet = (items: NonEmptyReadonlyArray<PM>) =>
236
+ resolveNamespace.pipe(Effect.flatMap((ns) => bulkSetInternal(items, ns)))
237
+
238
+ const batchSet = (items: NonEmptyReadonlyArray<PM>) => {
239
+ return resolveNamespace
240
+ .pipe(Effect.flatMap((ns) =>
241
+ Effect
170
242
  .suspend(() => {
171
243
  const batch = [...items].map(
172
244
  (x) =>
@@ -178,7 +250,7 @@ function makeCosmosStore({ prefix }: StorageConfig) {
178
250
  resourceBody: {
179
251
  ...Struct.omit(x, ["_etag", idKey]),
180
252
  id: x[idKey],
181
- _partitionKey: config?.partitionValue(x)
253
+ _partitionKey: nsPartitionValue(ns, x)
182
254
  }
183
255
  // don't use this or we get an error that the request and some item partition key dont match - makese no sense
184
256
  // partitionKey: config?.partitionValue(x)
@@ -189,7 +261,7 @@ function makeCosmosStore({ prefix }: StorageConfig) {
189
261
  resourceBody: {
190
262
  ...Struct.omit(x, ["_etag", idKey]),
191
263
  id: x[idKey],
192
- _partitionKey: config?.partitionValue(x)
264
+ _partitionKey: nsPartitionValue(ns, x)
193
265
  },
194
266
  // don't use this or we get an error that the request and some item partition key dont match - makese no sense
195
267
  // partitionKey: config?.partitionValue(x)
@@ -227,36 +299,51 @@ function makeCosmosStore({ prefix }: StorageConfig) {
227
299
  })
228
300
  .pipe(Effect
229
301
  .withSpan("Cosmos.batchSet [effect-app/infra/Store]", {
230
- attributes: { "repository.container_id": containerId, "repository.model_name": name }
302
+ attributes: {
303
+ "repository.container_id": containerId,
304
+ "repository.model_name": name,
305
+ namespace: ns
306
+ }
231
307
  }, { captureStackTrace: false }))
232
- }
308
+ ))
309
+ }
233
310
 
234
- const s: Store<IdKey, Encoded> = {
235
- queryRaw: <Out>(query: RawQuery<Encoded, Out>) =>
236
- Effect
237
- .sync(() => query.cosmos({ name }))
238
- .pipe(
239
- Effect.tap((q) => logQuery(q)),
240
- Effect.flatMap((q) =>
241
- Effect.promise(() =>
242
- container
243
- .items
244
- .query<Out>(q, { partitionKey: mainPartitionKey })
245
- .fetchAll()
246
- .then(({ resources }) =>
247
- resources.map(
248
- (_) => ({ ...defaultValues, ...mapReverseId(_ as any) }) as Out
249
- )
311
+ const s: Store<IdKey, Encoded> = {
312
+ seedNamespace: (ns) => seedNamespace(ns),
313
+
314
+ queryRaw: <Out>(query: RawQuery<Encoded, Out>) =>
315
+ Effect
316
+ .all({ q: Effect.sync(() => query.cosmos({ name })), ns: resolveNamespace })
317
+ .pipe(
318
+ Effect.tap(({ q }) => logQuery(q)),
319
+ Effect.flatMap(({ ns, q }) =>
320
+ Effect
321
+ .promise(() =>
322
+ container
323
+ .items
324
+ .query<Out>(q, { partitionKey: nsBasePartitionKey(ns) })
325
+ .fetchAll()
326
+ .then(({ resources }) =>
327
+ resources.map(
328
+ (_) => ({ ...defaultValues, ...mapReverseId(_ as any) }) as Out
250
329
  )
251
- )
252
- ),
253
- Effect
254
- .withSpan("Cosmos.queryRaw [effect-app/infra/Store]", {
255
- attributes: { "repository.container_id": containerId, "repository.model_name": name }
330
+ )
331
+ )
332
+ .pipe(
333
+ Effect.withSpan("Cosmos.queryRaw [effect-app/infra/Store]", {
334
+ attributes: {
335
+ "repository.container_id": containerId,
336
+ "repository.model_name": name,
337
+ namespace: ns
338
+ }
256
339
  }, { captureStackTrace: false })
257
- ),
258
- batchRemove: (ids, partitionKey?: string) =>
259
- Effect.promise(() =>
340
+ )
341
+ )
342
+ ),
343
+ batchRemove: (ids, partitionKey?: string) =>
344
+ resolveNamespace.pipe(Effect.flatMap((ns) =>
345
+ Effect
346
+ .promise(() =>
260
347
  execBatch(
261
348
  mutable(ids.map((id) =>
262
349
  dropUndefinedT({
@@ -266,208 +353,215 @@ function makeCosmosStore({ prefix }: StorageConfig) {
266
353
  // partitionKey: config?.partitionValue({ [idKey]: id } as Encoded)
267
354
  })
268
355
  )),
269
- partitionKey ?? mainPartitionKey
356
+ partitionKey ?? nsBasePartitionKey(ns)
270
357
  )
271
- ),
272
- all: Effect
273
- .sync(() => ({
274
- query: `SELECT * FROM ${name}`,
275
- parameters: []
276
- }))
358
+ )
277
359
  .pipe(
278
- Effect.tap((q) => logQuery(q)),
279
- Effect.flatMap((q) =>
280
- Effect.promise(() =>
281
- container
282
- .items
283
- .query<PMCosmos>(q, { partitionKey: mainPartitionKey })
284
- .fetchAll()
285
- .then(({ resources }) =>
286
- resources.map(
287
- (_) => ({ ...defaultValues, ...mapReverseId(_) })
288
- )
289
- )
290
- )
291
- ),
292
- Effect
293
- .withSpan("Cosmos.all [effect-app/infra/Store]", {
294
- attributes: { "repository.container_id": containerId, "repository.model_name": name }
295
- }, { captureStackTrace: false })
296
- ),
297
- /**
298
- * May return duplicate results for "join_find", when matching more than once.
299
- */
300
- filter: <U extends keyof Encoded = never>(
301
- f: FilterArgs<Encoded, U>
302
- ) => {
303
- const skip = f?.skip
304
- const limit = f?.limit
305
- const filter = f.filter
306
- type M = U extends undefined ? Encoded : Pick<Encoded, U>
307
- return Effect
308
- .sync(() =>
309
- buildWhereCosmosQuery3(
310
- idKey,
311
- filter ? [{ t: "where-scope", result: filter, relation: "some" }] : [],
312
- name,
313
- defaultValues,
314
- f.select as NonEmptyReadonlyArray<string | { key: string; subKeys: readonly string[] }> | undefined,
315
- f.order as NonEmptyReadonlyArray<{ key: string; direction: "ASC" | "DESC" }> | undefined,
316
- skip,
317
- limit
318
- )
319
- )
320
- .pipe(
321
- Effect.tap((q) => logQuery(q)),
322
- Effect
323
- .flatMap((q) =>
324
- Effect.promise(() =>
325
- f.select
326
- ? container
327
- .items
328
- .query<M>(q, { partitionKey: mainPartitionKey })
329
- .fetchAll()
330
- .then(({ resources }) =>
331
- resources.map((_) => ({
332
- ...pipe(
333
- defaultValues,
334
- Struct.pick(f.select!.filter((_) => typeof _ === "string") as never[])
335
- ),
336
- ...mapReverseId(_ as any)
337
- }))
338
- )
339
- : container
340
- .items
341
- .query<{ f: M }>(q, { partitionKey: mainPartitionKey })
342
- .fetchAll()
343
- .then(({ resources }) =>
344
- resources.map(({ f }) => ({ ...defaultValues, ...mapReverseId(f as any) }) as any)
345
- )
346
- )
347
- )
348
- )
349
- .pipe(
350
- Effect.withSpan("Cosmos.filter [effect-app/infra/Store]", {
351
- attributes: { "repository.container_id": containerId, "repository.model_name": name }
352
- }, { captureStackTrace: false })
353
- )
354
- },
355
- find: (id) =>
360
+ Effect.withSpan("Cosmos.batchRemove [effect-app/infra/Store]", {
361
+ attributes: {
362
+ "repository.container_id": containerId,
363
+ "repository.model_name": name,
364
+ namespace: ns
365
+ }
366
+ }, { captureStackTrace: false })
367
+ )
368
+ )),
369
+ all: Effect
370
+ .all({
371
+ q: Effect.sync(() => ({
372
+ query: `SELECT * FROM ${name}`,
373
+ parameters: []
374
+ })),
375
+ ns: resolveNamespace
376
+ })
377
+ .pipe(
378
+ Effect.tap(({ q }) => logQuery(q)),
379
+ Effect.flatMap(({ ns, q }) =>
356
380
  Effect
357
381
  .promise(() =>
358
382
  container
359
- .item(id, config?.partitionValue({ [idKey]: id } as Encoded))
360
- .read<Encoded>()
361
- .then(({ resource }) =>
362
- Option.fromNullishOr(resource).pipe(Option.map((_) => ({ ...defaultValues, ...mapReverseId(_) })))
383
+ .items
384
+ .query<PMCosmos>(q, { partitionKey: nsBasePartitionKey(ns) })
385
+ .fetchAll()
386
+ .then(({ resources }) =>
387
+ resources.map(
388
+ (_) => ({ ...defaultValues, ...mapReverseId(_) })
389
+ )
363
390
  )
364
391
  )
365
- .pipe(Effect
366
- .withSpan("Cosmos.find [effect-app/infra/Store]", {
392
+ .pipe(
393
+ Effect.withSpan("Cosmos.all [effect-app/infra/Store]", {
367
394
  attributes: {
368
395
  "repository.container_id": containerId,
369
396
  "repository.model_name": name,
370
- partitionValue: config?.partitionValue({ [idKey]: id } as Encoded),
371
- id
397
+ namespace: ns
372
398
  }
373
- }, { captureStackTrace: false })),
374
- set: (e) =>
375
- Option
376
- .match(
377
- Option
378
- .fromNullishOr(e._etag),
379
- {
380
- onNone: () =>
381
- Effect.promise(() =>
382
- container.items.create({
383
- ...mapId(e),
384
- _partitionKey: config?.partitionValue(e)
385
- })
386
- ),
387
- onSome: (eTag) =>
388
- Effect.promise(() =>
389
- container.item(e[idKey], config?.partitionValue(e)).replace(
390
- { ...mapId(e), _partitionKey: config?.partitionValue(e) },
391
- {
392
- accessCondition: {
393
- type: "IfMatch",
394
- condition: eTag
395
- }
396
- }
397
- )
398
- )
399
- }
399
+ }, { captureStackTrace: false })
400
400
  )
401
- .pipe(
401
+ )
402
+ ),
403
+ /**
404
+ * May return duplicate results for "join_find", when matching more than once.
405
+ */
406
+ filter: <U extends keyof Encoded = never>(
407
+ f: FilterArgs<Encoded, U>
408
+ ) => {
409
+ const skip = f?.skip
410
+ const limit = f?.limit
411
+ const filter = f.filter
412
+ type M = U extends undefined ? Encoded : Pick<Encoded, U>
413
+ return Effect
414
+ .all({
415
+ q: Effect.sync(() =>
416
+ buildWhereCosmosQuery3(
417
+ idKey,
418
+ filter ? [{ t: "where-scope", result: filter, relation: "some" }] : [],
419
+ name,
420
+ defaultValues,
421
+ f.select as
422
+ | NonEmptyReadonlyArray<string | { key: string; subKeys: readonly string[] }>
423
+ | undefined,
424
+ f.order as NonEmptyReadonlyArray<{ key: string; direction: "ASC" | "DESC" }> | undefined,
425
+ skip,
426
+ limit
427
+ )
428
+ ),
429
+ ns: resolveNamespace
430
+ })
431
+ .pipe(
432
+ Effect.tap(({ q }) => logQuery(q)),
433
+ Effect
434
+ .flatMap(({ ns, q }) =>
402
435
  Effect
403
- .flatMap((x) => {
404
- if (x.statusCode === 412 || x.statusCode === 404 || x.statusCode === 409) {
405
- return Effect.fail(
406
- new OptimisticConcurrencyException({ type: name, id: e[idKey], code: x.statusCode })
407
- )
408
- }
409
- if (x.statusCode > 299 || x.statusCode < 200) {
410
- return Effect.die(
411
- new CosmosDbOperationError(
412
- "not able to update record: " + x.statusCode
436
+ .promise(() =>
437
+ f.select
438
+ ? container
439
+ .items
440
+ .query<M>(q, { partitionKey: nsBasePartitionKey(ns) })
441
+ .fetchAll()
442
+ .then(({ resources }) =>
443
+ resources.map((_) => ({
444
+ ...pipe(
445
+ defaultValues,
446
+ Struct.pick(f.select!.filter((_) => typeof _ === "string") as never[])
447
+ ),
448
+ ...mapReverseId(_ as any)
449
+ }))
450
+ )
451
+ : container
452
+ .items
453
+ .query<{ f: M }>(q, { partitionKey: nsBasePartitionKey(ns) })
454
+ .fetchAll()
455
+ .then(({ resources }) =>
456
+ resources.map(({ f }) => ({ ...defaultValues, ...mapReverseId(f as any) }) as any)
413
457
  )
458
+ )
459
+ .pipe(
460
+ Effect.withSpan("Cosmos.filter [effect-app/infra/Store]", {
461
+ attributes: {
462
+ "repository.container_id": containerId,
463
+ "repository.model_name": name,
464
+ namespace: ns
465
+ }
466
+ }, { captureStackTrace: false })
467
+ )
468
+ )
469
+ )
470
+ },
471
+ find: (id) =>
472
+ resolveNamespace.pipe(Effect.flatMap((ns) =>
473
+ Effect
474
+ .promise(() =>
475
+ container
476
+ .item(id, nsPartitionValue(ns, { [idKey]: id } as Encoded))
477
+ .read<Encoded>()
478
+ .then(({ resource }) =>
479
+ Option.fromNullishOr(resource).pipe(
480
+ Option.map((_) => ({ ...defaultValues, ...mapReverseId(_) }))
481
+ )
482
+ )
483
+ )
484
+ .pipe(Effect
485
+ .withSpan("Cosmos.find [effect-app/infra/Store]", {
486
+ attributes: {
487
+ "repository.container_id": containerId,
488
+ "repository.model_name": name,
489
+ partitionValue: nsPartitionValue(ns, { [idKey]: id } as Encoded),
490
+ namespace: ns,
491
+ id
492
+ }
493
+ }, { captureStackTrace: false }))
494
+ )),
495
+ set: (e) =>
496
+ resolveNamespace.pipe(Effect.flatMap((ns) =>
497
+ Option
498
+ .match(
499
+ Option
500
+ .fromNullishOr(e._etag),
501
+ {
502
+ onNone: () =>
503
+ Effect.promise(() =>
504
+ container.items.create({
505
+ ...mapId(e),
506
+ _partitionKey: nsPartitionValue(ns, e)
507
+ })
508
+ ),
509
+ onSome: (eTag) =>
510
+ Effect.promise(() =>
511
+ container.item(e[idKey], nsPartitionValue(ns, e)).replace(
512
+ { ...mapId(e), _partitionKey: nsPartitionValue(ns, e) },
513
+ {
514
+ accessCondition: {
515
+ type: "IfMatch",
516
+ condition: eTag
517
+ }
518
+ }
519
+ )
520
+ )
521
+ }
522
+ )
523
+ .pipe(
524
+ Effect
525
+ .flatMap((x) => {
526
+ if (x.statusCode === 412 || x.statusCode === 404 || x.statusCode === 409) {
527
+ return Effect.fail(
528
+ new OptimisticConcurrencyException({ type: name, id: e[idKey], code: x.statusCode })
529
+ )
530
+ }
531
+ if (x.statusCode > 299 || x.statusCode < 200) {
532
+ return Effect.die(
533
+ new CosmosDbOperationError(
534
+ "not able to update record: " + x.statusCode
414
535
  )
415
- }
416
- return Effect.sync(() => ({
417
- ...e,
418
- _etag: x.etag
419
- }))
420
- }),
421
- Effect
422
- .withSpan("Cosmos.set [effect-app/infra/Store]", {
423
- attributes: {
424
- "repository.container_id": containerId,
425
- "repository.model_name": name,
426
- id: e[idKey]
427
- }
428
- }, { captureStackTrace: false })
429
- ),
430
- batchSet,
431
- bulkSet
432
- }
536
+ )
537
+ }
538
+ return Effect.sync(() => ({
539
+ ...e,
540
+ _etag: x.etag
541
+ }))
542
+ }),
543
+ Effect
544
+ .withSpan("Cosmos.set [effect-app/infra/Store]", {
545
+ attributes: {
546
+ "repository.container_id": containerId,
547
+ "repository.model_name": name,
548
+ namespace: ns,
549
+ id: e[idKey]
550
+ }
551
+ }, { captureStackTrace: false })
552
+ )
553
+ )),
554
+ batchSet,
555
+ bulkSet
556
+ }
433
557
 
434
- // handle mock data
435
- const marker = yield* Effect.promise(() =>
436
- container
437
- .item(importedMarkerId, importedMarkerId)
438
- .read<{ id: string }>()
439
- .then(({ resource }) => Option.fromNullishOr(resource))
440
- )
558
+ // Eagerly seed primary namespace on initialization
559
+ yield* seedNamespace("primary")
441
560
 
442
- if (!Option.isSome(marker)) {
443
- yield* InfraLogger.logInfo("Creating mock data for " + name)
444
- if (seed) {
445
- const m = yield* seed
446
- yield* Effect.flatMapOption(
447
- Effect.succeed(toNonEmptyArray([...m])),
448
- (a) =>
449
- s.bulkSet(a).pipe(
450
- Effect.orDie,
451
- Effect
452
- // we delay extra here, so that initial creation between Companies/POs also have an interval between them.
453
- .delay(Duration.millis(1100))
454
- )
455
- )
456
- }
457
- // Mark as imported
458
- yield* Effect.promise(() =>
459
- container.items.create({
460
- _partitionKey: importedMarkerId,
461
- id: importedMarkerId,
462
- ttl: -1
463
- })
464
- )
465
- }
466
- return s
467
- })
468
- }
469
- })
470
- }
561
+ return s
562
+ })
563
+ }
564
+ })
471
565
 
472
566
  export function CosmosStoreLayer(cfg: StorageConfig) {
473
567
  return StoreMaker