@effect-app/infra 4.0.0-beta.250 → 4.0.0-beta.252

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 (59) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/dist/QueueMaker/SQLQueue.d.ts +1 -1
  3. package/dist/QueueMaker/SQLQueue.d.ts.map +1 -1
  4. package/dist/QueueMaker/SQLQueue.js +2 -2
  5. package/dist/QueueMaker/memQueue.d.ts +1 -1
  6. package/dist/QueueMaker/memQueue.d.ts.map +1 -1
  7. package/dist/QueueMaker/memQueue.js +2 -2
  8. package/dist/QueueMaker/sbqueue.d.ts +1 -1
  9. package/dist/QueueMaker/sbqueue.d.ts.map +1 -1
  10. package/dist/QueueMaker/sbqueue.js +2 -2
  11. package/dist/Store/Cosmos.d.ts +1 -1
  12. package/dist/Store/Cosmos.d.ts.map +1 -1
  13. package/dist/Store/Cosmos.js +2 -3
  14. package/dist/Store/Disk.d.ts +1 -1
  15. package/dist/Store/Disk.d.ts.map +1 -1
  16. package/dist/Store/Disk.js +3 -3
  17. package/dist/Store/Memory.d.ts +1 -7
  18. package/dist/Store/Memory.d.ts.map +1 -1
  19. package/dist/Store/Memory.js +2 -7
  20. package/dist/Store/SQL/Pg.d.ts +1 -1
  21. package/dist/Store/SQL/Pg.d.ts.map +1 -1
  22. package/dist/Store/SQL/Pg.js +2 -3
  23. package/dist/Store/SQL.d.ts +1 -1
  24. package/dist/Store/SQL.d.ts.map +1 -1
  25. package/dist/Store/SQL.js +2 -3
  26. package/dist/errorReporter.d.ts +1 -1
  27. package/dist/errorReporter.d.ts.map +1 -1
  28. package/dist/errorReporter.js +2 -2
  29. package/dist/internal/RequestContextMiddleware.d.ts +1 -1
  30. package/dist/internal/RequestContextMiddleware.d.ts.map +1 -1
  31. package/dist/internal/RequestContextMiddleware.js +3 -4
  32. package/dist/internal/events.d.ts +1 -1
  33. package/dist/internal/events.d.ts.map +1 -1
  34. package/dist/internal/events.js +3 -3
  35. package/dist/logger/shared.d.ts +1 -1
  36. package/dist/logger/shared.d.ts.map +1 -1
  37. package/dist/logger/shared.js +2 -2
  38. package/package.json +2 -6
  39. package/src/QueueMaker/SQLQueue.ts +1 -1
  40. package/src/QueueMaker/memQueue.ts +1 -1
  41. package/src/QueueMaker/sbqueue.ts +1 -1
  42. package/src/Store/Cosmos.ts +1 -2
  43. package/src/Store/Disk.ts +2 -2
  44. package/src/Store/Memory.ts +1 -6
  45. package/src/Store/SQL/Pg.ts +1 -2
  46. package/src/Store/SQL.ts +1 -2
  47. package/src/errorReporter.ts +1 -1
  48. package/src/internal/RequestContextMiddleware.ts +2 -3
  49. package/src/internal/events.ts +2 -2
  50. package/src/logger/shared.ts +1 -1
  51. package/test/dist/rawQuery.test.d.ts.map +1 -1
  52. package/test/query.test.ts +1 -1
  53. package/test/rawQuery.test.ts +1 -1
  54. package/test/repository-ext.test.ts +1 -1
  55. package/test/validateSample.test.ts +1 -1
  56. package/dist/setupRequest.d.ts +0 -19
  57. package/dist/setupRequest.d.ts.map +0 -1
  58. package/dist/setupRequest.js +0 -70
  59. package/src/setupRequest.ts +0 -135
@@ -1,4 +1,4 @@
1
1
  import { RequestContext } from "effect-app/RequestContext";
2
2
  import type * as Fiber from "effect/Fiber";
3
3
  export declare function getRequestContextFromFiber(fiber: Fiber.Fiber<unknown, unknown>): RequestContext;
4
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2hhcmVkLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvbG9nZ2VyL3NoYXJlZC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFDQSxPQUFPLEVBQWEsY0FBYyxFQUFFLE1BQU0sMkJBQTJCLENBQUE7QUFFckUsT0FBTyxLQUFLLEtBQUssS0FBSyxNQUFNLGNBQWMsQ0FBQTtBQUcxQyx3QkFBZ0IsMEJBQTBCLENBQUMsS0FBSyxFQUFFLEtBQUssQ0FBQyxLQUFLLENBQUMsT0FBTyxFQUFFLE9BQU8sQ0FBQyxrQkFZOUUifQ==
4
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2hhcmVkLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvbG9nZ2VyL3NoYXJlZC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFDQSxPQUFPLEVBQWEsY0FBYyxFQUFFLE1BQU0sMkJBQTJCLENBQUE7QUFHckUsT0FBTyxLQUFLLEtBQUssS0FBSyxNQUFNLGNBQWMsQ0FBQTtBQUUxQyx3QkFBZ0IsMEJBQTBCLENBQUMsS0FBSyxFQUFFLEtBQUssQ0FBQyxLQUFLLENBQUMsT0FBTyxFQUFFLE9BQU8sQ0FBQyxrQkFZOUUifQ==
@@ -1 +1 @@
1
- {"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../src/logger/shared.ts"],"names":[],"mappings":"AACA,OAAO,EAAa,cAAc,EAAE,MAAM,2BAA2B,CAAA;AAErE,OAAO,KAAK,KAAK,KAAK,MAAM,cAAc,CAAA;AAG1C,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,kBAY9E"}
1
+ {"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../src/logger/shared.ts"],"names":[],"mappings":"AACA,OAAO,EAAa,cAAc,EAAE,MAAM,2BAA2B,CAAA;AAGrE,OAAO,KAAK,KAAK,KAAK,MAAM,cAAc,CAAA;AAE1C,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,kBAY9E"}
@@ -1,7 +1,7 @@
1
1
  import * as Option from "effect-app/Option";
2
2
  import { LocaleRef, RequestContext } from "effect-app/RequestContext";
3
3
  import { NonEmptyString255 } from "effect-app/Schema";
4
- import { storeId } from "../Store/Memory.js";
4
+ import { storeId } from "effect-app/Store";
5
5
  export function getRequestContextFromFiber(fiber) {
6
6
  const span = Option.fromNullishOr(fiber.currentSpan);
7
7
  const locale = fiber.getRef(LocaleRef);
@@ -13,4 +13,4 @@ export function getRequestContextFromFiber(fiber) {
13
13
  namespace
14
14
  });
15
15
  }
16
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2hhcmVkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2xvZ2dlci9zaGFyZWQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLE1BQU0sTUFBTSxtQkFBbUIsQ0FBQTtBQUMzQyxPQUFPLEVBQUUsU0FBUyxFQUFFLGNBQWMsRUFBRSxNQUFNLDJCQUEyQixDQUFBO0FBQ3JFLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLG1CQUFtQixDQUFBO0FBRXJELE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQTtBQUU1QyxNQUFNLFVBQVUsMEJBQTBCLENBQUMsS0FBb0M7SUFDN0UsTUFBTSxJQUFJLEdBQUcsTUFBTSxDQUFDLGFBQWEsQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFDLENBQUE7SUFDcEQsTUFBTSxNQUFNLEdBQUcsS0FBSyxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsQ0FBQTtJQUN0QyxNQUFNLFNBQVMsR0FBRyxLQUFLLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFBO0lBQ3ZDLE9BQU8sY0FBYyxDQUFDLElBQUksQ0FBQztRQUN6QixJQUFJLEVBQUUsTUFBTSxDQUFDLEdBQUcsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsRUFBRSxNQUFNLEVBQUUsQ0FBQyxDQUFDLE1BQU0sRUFBRSxPQUFPLEVBQUUsQ0FBQyxDQUFDLE9BQU8sRUFBRSxPQUFPLEVBQUUsQ0FBQyxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQ2hHLE1BQU0sQ0FBQyxTQUFTLENBQUMsR0FBRyxFQUFFLENBQUMsQ0FBQyxFQUFFLE1BQU0sRUFBRSxPQUFPLEVBQUUsT0FBTyxFQUFFLElBQUksRUFBRSxPQUFPLEVBQUUsT0FBTyxFQUFFLENBQUMsQ0FBQyxDQUMvRTtRQUNELElBQUksRUFBRSxpQkFBaUIsQ0FBQyxHQUFHLENBQUM7UUFDNUIsTUFBTTtRQUNOLFNBQVM7S0FDVixDQUFDLENBQUE7QUFDSixDQUFDIn0=
16
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2hhcmVkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2xvZ2dlci9zaGFyZWQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLE1BQU0sTUFBTSxtQkFBbUIsQ0FBQTtBQUMzQyxPQUFPLEVBQUUsU0FBUyxFQUFFLGNBQWMsRUFBRSxNQUFNLDJCQUEyQixDQUFBO0FBQ3JFLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLG1CQUFtQixDQUFBO0FBQ3JELE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQTtBQUcxQyxNQUFNLFVBQVUsMEJBQTBCLENBQUMsS0FBb0M7SUFDN0UsTUFBTSxJQUFJLEdBQUcsTUFBTSxDQUFDLGFBQWEsQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFDLENBQUE7SUFDcEQsTUFBTSxNQUFNLEdBQUcsS0FBSyxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsQ0FBQTtJQUN0QyxNQUFNLFNBQVMsR0FBRyxLQUFLLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFBO0lBQ3ZDLE9BQU8sY0FBYyxDQUFDLElBQUksQ0FBQztRQUN6QixJQUFJLEVBQUUsTUFBTSxDQUFDLEdBQUcsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsRUFBRSxNQUFNLEVBQUUsQ0FBQyxDQUFDLE1BQU0sRUFBRSxPQUFPLEVBQUUsQ0FBQyxDQUFDLE9BQU8sRUFBRSxPQUFPLEVBQUUsQ0FBQyxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQ2hHLE1BQU0sQ0FBQyxTQUFTLENBQUMsR0FBRyxFQUFFLENBQUMsQ0FBQyxFQUFFLE1BQU0sRUFBRSxPQUFPLEVBQUUsT0FBTyxFQUFFLElBQUksRUFBRSxPQUFPLEVBQUUsT0FBTyxFQUFFLENBQUMsQ0FBQyxDQUMvRTtRQUNELElBQUksRUFBRSxpQkFBaUIsQ0FBQyxHQUFHLENBQUM7UUFDNUIsTUFBTTtRQUNOLFNBQVM7S0FDVixDQUFDLENBQUE7QUFDSixDQUFDIn0=
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@effect-app/infra",
3
- "version": "4.0.0-beta.250",
3
+ "version": "4.0.0-beta.252",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "dependencies": {
@@ -13,7 +13,7 @@
13
13
  "proper-lockfile": "^4.1.2",
14
14
  "pure-rand": "8.4.0",
15
15
  "query-string": "^9.3.1",
16
- "effect-app": "4.0.0-beta.250"
16
+ "effect-app": "4.0.0-beta.252"
17
17
  },
18
18
  "devDependencies": {
19
19
  "@azure/cosmos": "^4.9.3",
@@ -252,10 +252,6 @@
252
252
  "types": "./dist/routing/utils.d.ts",
253
253
  "default": "./dist/routing/utils.js"
254
254
  },
255
- "./setupRequest": {
256
- "types": "./dist/setupRequest.d.ts",
257
- "default": "./dist/setupRequest.js"
258
- },
259
255
  "./test": {
260
256
  "types": "./dist/test.d.ts",
261
257
  "default": "./dist/test.js"
@@ -1,5 +1,4 @@
1
1
  import { reportNonInterruptedFailure } from "@effect-app/infra/QueueMaker/errors"
2
- import { getRequestContext, setupRequestContextWithCustomSpan } from "@effect-app/infra/setupRequest"
3
2
  import { subMinutes } from "date-fns"
4
3
  import type { NonEmptyReadonlyArray } from "effect-app/Array"
5
4
  import * as Effect from "effect-app/Effect"
@@ -7,6 +6,7 @@ import * as Option from "effect-app/Option"
7
6
  import { type QueueBase, QueueMeta } from "effect-app/QueueMaker"
8
7
  import * as S from "effect-app/Schema"
9
8
  import { type NonEmptyString255 } from "effect-app/Schema"
9
+ import { getRequestContext, setupRequestContextWithCustomSpan } from "effect-app/setupRequest"
10
10
  import { pretty } from "effect-app/utils"
11
11
  import * as Fiber from "effect/Fiber"
12
12
  import * as Tracer from "effect/Tracer"
@@ -2,6 +2,7 @@ import type { NonEmptyReadonlyArray } from "effect-app/Array"
2
2
  import * as Effect from "effect-app/Effect"
3
3
  import { QueueMeta } from "effect-app/QueueMaker"
4
4
  import * as S from "effect-app/Schema"
5
+ import { getRequestContext, setupRequestContextWithCustomSpan } from "effect-app/setupRequest"
5
6
  import { pretty } from "effect-app/utils"
6
7
  import * as Cause from "effect/Cause"
7
8
  import * as Fiber from "effect/Fiber"
@@ -11,7 +12,6 @@ import * as Tracer from "effect/Tracer"
11
12
  import { InfraLogger } from "../logger.js"
12
13
  import { MemQueue } from "../memQueue.js"
13
14
  import { messagingSpanArgs } from "../otel.js"
14
- import { getRequestContext, setupRequestContextWithCustomSpan } from "../setupRequest.js"
15
15
  import { reportNonInterruptedFailure, reportNonInterruptedFailureCause } from "./errors.js"
16
16
 
17
17
  export const makeMemQueue = Effect.fnUntraced(function*<
@@ -3,6 +3,7 @@ import * as Effect from "effect-app/Effect"
3
3
  import { QueueMeta } from "effect-app/QueueMaker"
4
4
  import * as S from "effect-app/Schema"
5
5
  import type { StringId } from "effect-app/Schema"
6
+ import { getRequestContext, setupRequestContextWithCustomSpan } from "effect-app/setupRequest"
6
7
  import { pretty } from "effect-app/utils"
7
8
  import * as Cause from "effect/Cause"
8
9
  import { flow } from "effect/Function"
@@ -10,7 +11,6 @@ import * as Tracer from "effect/Tracer"
10
11
  import { InfraLogger } from "../logger.js"
11
12
  import { messagingSpanArgs } from "../otel.js"
12
13
  import { Receiver, Sender } from "../ServiceBus.js"
13
- import { getRequestContext, setupRequestContextWithCustomSpan } from "../setupRequest.js"
14
14
  import { reportNonInterruptedFailure, reportNonInterruptedFailureCause, reportQueueError } from "./errors.js"
15
15
 
16
16
  export function makeServiceBusQueue<
@@ -8,7 +8,7 @@ import * as Layer from "effect-app/Layer"
8
8
  import type { FieldValues } from "effect-app/Model/filter/types"
9
9
  import { type ComputedProjectionIrExpression, type RawQuery } from "effect-app/Model/query"
10
10
  import * as Option from "effect-app/Option"
11
- import { type FilterArgs, type PersistenceModelType, type StorageConfig, type Store, type StoreConfig, StoreMaker } from "effect-app/Store"
11
+ import { type FilterArgs, type PersistenceModelType, type StorageConfig, type Store, type StoreConfig, storeId, StoreMaker } from "effect-app/Store"
12
12
  import { dropUndefinedT, mutable } from "effect-app/utils"
13
13
  import * as Duration from "effect/Duration"
14
14
  import { pipe } from "effect/Function"
@@ -19,7 +19,6 @@ import { OptimisticConcurrencyException } from "../errors.js"
19
19
  import { InfraLogger } from "../logger.js"
20
20
  import { annotateCosmosResponse, annotateDb } from "../otel.js"
21
21
  import { buildWhereCosmosQuery3, logQuery } from "./Cosmos/query.js"
22
- import { storeId } from "./Memory.js"
23
22
 
24
23
  const makeMapId =
25
24
  <IdKey extends keyof Encoded, Encoded extends FieldValues>(idKey: IdKey) => ({ [idKey]: id, ...e }: Encoded) => ({
package/src/Store/Disk.ts CHANGED
@@ -5,12 +5,12 @@ import fs from "fs"
5
5
 
6
6
  import * as Effect from "effect-app/Effect"
7
7
  import type { FieldValues } from "effect-app/Model/filter/types"
8
- import { type PersistenceModelType, type StorageConfig, type Store, type StoreConfig, StoreMaker } from "effect-app/Store"
8
+ import { type PersistenceModelType, type StorageConfig, type Store, type StoreConfig, storeId, StoreMaker } from "effect-app/Store"
9
9
  import * as Console from "effect/Console"
10
10
  import { flow } from "effect/Function"
11
11
  import * as Semaphore from "effect/Semaphore"
12
12
  import { annotateDb } from "../otel.js"
13
- import { makeMemoryStoreInt, storeId } from "./Memory.js"
13
+ import { makeMemoryStoreInt } from "./Memory.js"
14
14
 
15
15
  function makeDiskStoreInt<IdKey extends keyof Encoded, Encoded extends FieldValues, R, E>(
16
16
  prefix: string,
@@ -2,14 +2,12 @@
2
2
 
3
3
  import * as Array from "effect-app/Array"
4
4
  import type { NonEmptyReadonlyArray } from "effect-app/Array"
5
- import * as Context from "effect-app/Context"
6
5
  import * as Effect from "effect-app/Effect"
7
6
  import type { FilterResult } from "effect-app/Model/filter/filterApi"
8
7
  import type { FieldValues } from "effect-app/Model/filter/types"
9
8
  import type { AggregateIrExpression, ComputedProjectionIrExpression, ComputedProjectionMathIrExpression } from "effect-app/Model/query"
10
9
  import * as Option from "effect-app/Option"
11
- import { NonEmptyString255 } from "effect-app/Schema"
12
- import { type FilterArgs, type PersistenceModelType, type Store, type StoreConfig, StoreMaker } from "effect-app/Store"
10
+ import { type FilterArgs, type PersistenceModelType, type Store, type StoreConfig, storeId, StoreMaker } from "effect-app/Store"
13
11
  import { assertUnreachable } from "effect-app/utils"
14
12
  import { flow, pipe } from "effect/Function"
15
13
  import * as Order from "effect/Order"
@@ -315,9 +313,6 @@ export function memFilter<T extends FieldValues, U extends keyof T = never>(f: F
315
313
  })
316
314
  }
317
315
 
318
- const defaultNs: NonEmptyString255 = NonEmptyString255("primary")
319
- export class storeId extends Context.Reference("StoreId", { defaultValue: (): NonEmptyString255 => defaultNs }) {}
320
-
321
316
  function logQuery(f: FilterArgs<any, any>, defaultValues?: any) {
322
317
  return InfraLogger
323
318
  .logDebug("mem query")
@@ -6,13 +6,12 @@ import * as Effect from "effect-app/Effect"
6
6
  import type { FieldValues } from "effect-app/Model/filter/types"
7
7
  import type { ComputedProjectionIrExpression } from "effect-app/Model/query"
8
8
  import * as Option from "effect-app/Option"
9
- import { type FilterArgs, type PersistenceModelType, type StorageConfig, type Store, type StoreConfig, StoreMaker } from "effect-app/Store"
9
+ import { type FilterArgs, type PersistenceModelType, type StorageConfig, type Store, type StoreConfig, storeId, StoreMaker } from "effect-app/Store"
10
10
  import * as Struct from "effect/Struct"
11
11
  import { SqlClient } from "effect/unstable/sql"
12
12
  import { OptimisticConcurrencyException } from "../../errors.js"
13
13
  import { InfraLogger } from "../../logger.js"
14
14
  import { annotateDb } from "../../otel.js"
15
- import { storeId } from "../Memory.js"
16
15
  import { makeETag } from "../utils.js"
17
16
  import { buildWhereSQLQuery, logQuery, pgDialect } from "./query.js"
18
17
 
package/src/Store/SQL.ts CHANGED
@@ -6,7 +6,7 @@ import * as Effect from "effect-app/Effect"
6
6
  import type { FieldValues } from "effect-app/Model/filter/types"
7
7
  import type { ComputedProjectionIrExpression } from "effect-app/Model/query"
8
8
  import * as Option from "effect-app/Option"
9
- import { type FilterArgs, type PersistenceModelType, type StorageConfig, type Store, type StoreConfig, StoreMaker } from "effect-app/Store"
9
+ import { type FilterArgs, type PersistenceModelType, type StorageConfig, type Store, type StoreConfig, storeId, StoreMaker } from "effect-app/Store"
10
10
  import * as Context from "effect/Context"
11
11
  import * as Layer from "effect/Layer"
12
12
  import * as LayerMap from "effect/LayerMap"
@@ -15,7 +15,6 @@ import { SqlClient } from "effect/unstable/sql"
15
15
  import { OptimisticConcurrencyException } from "../errors.js"
16
16
  import { InfraLogger } from "../logger.js"
17
17
  import { annotateDb, type DbSystem } from "../otel.js"
18
- import { storeId } from "./Memory.js"
19
18
  import { buildWhereSQLQuery, logQuery, type SQLDialect, sqliteDialect } from "./SQL/query.js"
20
19
  import { makeETag } from "./utils.js"
21
20
 
@@ -1,11 +1,11 @@
1
1
  import * as Sentry from "@sentry/node"
2
2
  import * as Effect from "effect-app/Effect"
3
+ import { getRC } from "effect-app/setupRequest"
3
4
  import { dropUndefined, LogLevelToSentry } from "effect-app/utils"
4
5
  import * as Cause from "effect/Cause"
5
6
  import type * as LogLevel from "effect/LogLevel"
6
7
  import { CauseException, tryToJson, tryToReport } from "./errors.js"
7
8
  import { InfraLogger } from "./logger.js"
8
- import { getRC } from "./setupRequest.js"
9
9
 
10
10
  const tryCauseException = <E>(cause: Cause.Cause<E>, name: string): CauseException<E> => {
11
11
  try {
@@ -3,9 +3,8 @@ import { HttpMiddleware, HttpServerRequest, HttpServerResponse } from "effect-ap
3
3
  import * as Layer from "effect-app/Layer"
4
4
  import { Locale, LocaleRef, RequestContext, spanAttributes } from "effect-app/RequestContext"
5
5
  import { NonEmptyString255 } from "effect-app/Schema"
6
- import { ContextMapContainer } from "effect-app/Store"
7
- import { provideOnRequestScope } from "../setupRequest.js"
8
- import { storeId } from "../Store/Memory.js"
6
+ import { provideOnRequestScope } from "effect-app/setupRequest"
7
+ import { ContextMapContainer, storeId } from "effect-app/Store"
9
8
 
10
9
  export const RequestContextMiddleware = (defaultLocale: Locale = "en") =>
11
10
  HttpMiddleware.make((app) =>
@@ -1,13 +1,13 @@
1
1
  import * as Effect from "effect-app/Effect"
2
2
  import { HttpHeaders, HttpServerResponse } from "effect-app/http"
3
3
  import * as S from "effect-app/Schema"
4
+ import { setupStreamingRequestContextFromCurrent } from "effect-app/setupRequest"
5
+ import { storeId } from "effect-app/Store"
4
6
  import * as Duration from "effect/Duration"
5
7
  import { pipe } from "effect/Function"
6
8
  import * as Schedule from "effect/Schedule"
7
9
  import * as Stream from "effect/Stream"
8
10
  import { reportError } from "../errorReporter.js"
9
- import { setupStreamingRequestContextFromCurrent } from "../setupRequest.js"
10
- import { storeId } from "../Store/Memory.js"
11
11
 
12
12
  // Tell the client to retry every 10 seconds if connectivity is lost
13
13
  const setRetry = Stream.succeed("retry: 10000")
@@ -1,8 +1,8 @@
1
1
  import * as Option from "effect-app/Option"
2
2
  import { LocaleRef, RequestContext } from "effect-app/RequestContext"
3
3
  import { NonEmptyString255 } from "effect-app/Schema"
4
+ import { storeId } from "effect-app/Store"
4
5
  import type * as Fiber from "effect/Fiber"
5
- import { storeId } from "../Store/Memory.js"
6
6
 
7
7
  export function getRequestContextFromFiber(fiber: Fiber.Fiber<unknown, unknown>) {
8
8
  const span = Option.fromNullishOr(fiber.currentSpan)
@@ -1 +1 @@
1
- {"version":3,"file":"rawQuery.test.d.ts","sourceRoot":"","sources":["../rawQuery.test.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,cAAc,MAAM,uBAAuB,CAAA;AAUvD,eAAO,MAAM,EAAE,6CAWb,CAAA"}
1
+ {"version":3,"file":"rawQuery.test.d.ts","sourceRoot":"","sources":["../rawQuery.test.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,cAAc,MAAM,uBAAuB,CAAA;AASvD,eAAO,MAAM,EAAE,6CAWb,CAAA"}
@@ -9,12 +9,12 @@ import { makeRepo } from "effect-app/Model/Repository"
9
9
  import { RepositoryRegistryLive } from "effect-app/Model/Repository/Registry"
10
10
  import * as Option from "effect-app/Option"
11
11
  import * as S from "effect-app/Schema"
12
+ import { setupRequestContextFromCurrent } from "effect-app/setupRequest"
12
13
  import { flow, pipe } from "effect/Function"
13
14
  import * as SchemaTransformation from "effect/SchemaTransformation"
14
15
  import * as Struct from "effect/Struct"
15
16
  import { inspect } from "util"
16
17
  import { expect, expectTypeOf, it } from "vitest"
17
- import { setupRequestContextFromCurrent } from "../src/setupRequest.js"
18
18
  import { memFilter, MemoryStoreLive } from "../src/Store/Memory.js"
19
19
  import { SomeService } from "./fixtures.js"
20
20
 
@@ -9,6 +9,7 @@ import { and, computed, or, project, projectComputed, relation, where, whereEver
9
9
  import { makeRepo } from "effect-app/Model/Repository/makeRepo"
10
10
  import { RepositoryRegistryLive } from "effect-app/Model/Repository/Registry"
11
11
  import * as S from "effect-app/Schema"
12
+ import { setupRequestContextFromCurrent } from "effect-app/setupRequest"
12
13
  import { LogLevels } from "effect-app/utils"
13
14
  import { flow } from "effect/Function"
14
15
  import * as ManagedRuntime from "effect/ManagedRuntime"
@@ -16,7 +17,6 @@ import * as Redacted from "effect/Redacted"
16
17
  import * as References from "effect/References"
17
18
  import * as Result from "effect/Result"
18
19
  import * as Struct from "effect/Struct"
19
- import { setupRequestContextFromCurrent } from "../src/setupRequest.js"
20
20
  import { CosmosStoreLayer } from "../src/Store/Cosmos.js"
21
21
  import { MemoryStoreLive } from "../src/Store/Memory.js"
22
22
  import { SQLiteStoreLayer } from "../src/Store/SQL.js"
@@ -4,7 +4,7 @@ import * as Layer from "effect-app/Layer"
4
4
  import { makeRepo } from "effect-app/Model/Repository"
5
5
  import { RepositoryRegistryLive } from "effect-app/Model/Repository/Registry"
6
6
  import * as S from "effect-app/Schema"
7
- import { setupRequestContextFromCurrent } from "../src/setupRequest.js"
7
+ import { setupRequestContextFromCurrent } from "effect-app/setupRequest"
8
8
  import { MemoryStoreLive } from "../src/Store/Memory.js"
9
9
 
10
10
  class BatchItem extends S.Class<BatchItem>("BatchItem")({
@@ -3,8 +3,8 @@ import * as Layer from "effect-app/Layer"
3
3
  import { makeRepo, ValidationError, ValidationResult } from "effect-app/Model/Repository"
4
4
  import { RepositoryRegistryLive } from "effect-app/Model/Repository/Registry"
5
5
  import * as S from "effect-app/Schema"
6
+ import { setupRequestContextFromCurrent } from "effect-app/setupRequest"
6
7
  import { describe, expect, it } from "vitest"
7
- import { setupRequestContextFromCurrent } from "../src/setupRequest.js"
8
8
  import { MemoryStoreLive } from "../src/Store/Memory.js"
9
9
 
10
10
  const TestStoreLive = Layer.merge(MemoryStoreLive, RepositoryRegistryLive)
@@ -1,19 +0,0 @@
1
- import * as Effect from "effect-app/Effect";
2
- import * as Layer from "effect-app/Layer";
3
- import { RequestContext } from "effect-app/RequestContext";
4
- import { NonEmptyString255 } from "effect-app/Schema";
5
- import * as Tracer from "effect/Tracer";
6
- export declare const getRequestContext: Effect.Effect<RequestContext, never, never>;
7
- export declare const getRC: Effect.Effect<{
8
- locale: "de" | "en";
9
- namespace: NonEmptyString255;
10
- }, never, never>;
11
- export interface SetupRequestOptions {
12
- readonly withTransaction?: boolean;
13
- }
14
- export declare const provideOnRequestScope: <ROut, E2, RIn>(layer: Layer.Layer<ROut, E2, RIn>) => <A, E, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<A, E | E2, RIn | import("effect/Scope").Scope | Exclude<R, ROut>>;
15
- export declare const setupRequestContextFromCurrent: (name?: string, options?: Tracer.SpanOptions & SetupRequestOptions) => <R, E, A>(self: Effect.Effect<A, E, R>) => Effect.Effect<A, E, Exclude<Exclude<R, Tracer.ParentSpan>, never>>;
16
- export declare const setupStreamingRequestContextFromCurrent: (name?: string, options?: Tracer.SpanOptions & SetupRequestOptions) => <R, E, A>(self: Effect.Effect<A, E, R>) => Effect.Effect<A, E, import("effect/Scope").Scope | Exclude<Exclude<R, Tracer.ParentSpan>, never>>;
17
- export declare function setupRequestContext<R, E, A>(self: Effect.Effect<A, E, R>, requestContext: RequestContext, options?: SetupRequestOptions): Effect.Effect<A, E, Exclude<Exclude<R, Tracer.ParentSpan>, never>>;
18
- export declare function setupRequestContextWithCustomSpan<R, E, A>(self: Effect.Effect<A, E, R>, requestContext: RequestContext, name: string, options?: Tracer.SpanOptions & SetupRequestOptions): Effect.Effect<A, E, Exclude<Exclude<R, Tracer.ParentSpan>, never>>;
19
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2V0dXBSZXF1ZXN0LmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvc2V0dXBSZXF1ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxNQUFNLE1BQU0sbUJBQW1CLENBQUE7QUFDM0MsT0FBTyxLQUFLLEtBQUssTUFBTSxrQkFBa0IsQ0FBQTtBQUV6QyxPQUFPLEVBQWEsY0FBYyxFQUFrQixNQUFNLDJCQUEyQixDQUFBO0FBQ3JGLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLG1CQUFtQixDQUFBO0FBRXJELE9BQU8sS0FBSyxNQUFNLE1BQU0sZUFBZSxDQUFBO0FBWXZDLGVBQU8sTUFBTSxpQkFBaUIsNkNBZTNCLENBQUE7QUFFSCxlQUFPLE1BQU0sS0FBSzs7O2dCQUdoQixDQUFBO0FBbUJGLE1BQU0sV0FBVyxtQkFBbUI7SUFDbEMsUUFBUSxDQUFDLGVBQWUsQ0FBQyxFQUFFLE9BQU8sQ0FBQTtDQUNuQztBQU1ELGVBQU8sTUFBTSxxQkFBcUIsR0FDL0IsSUFBSSxFQUFFLEVBQUUsRUFBRSxHQUFHLFNBQVMsS0FBSyxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsRUFBRSxFQUFFLEdBQUcsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxRQUFRLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsb0ZBU3hGLENBQUE7QUFFTixlQUFPLE1BQU0sOEJBQThCLDRCQUNaLE1BQU0sQ0FBQyxXQUFXLEdBQUcsbUJBQW1CLE1BQU0sQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLFFBQVEsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyx1RUFNM0csQ0FBQTtBQU1QLGVBQU8sTUFBTSx1Q0FBdUMsNEJBQ3JCLE1BQU0sQ0FBQyxXQUFXLEdBQUcsbUJBQW1CLE1BQU0sQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLFFBQVEsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxzR0FLN0csQ0FBQTtBQUdMLHdCQUFnQixtQkFBbUIsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFDekMsSUFBSSxFQUFFLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFDNUIsY0FBYyxFQUFFLGNBQWMsRUFDOUIsT0FBTyxDQUFDLEVBQUUsbUJBQW1CLHNFQWE5QjtBQUVELHdCQUFnQixpQ0FBaUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFDdkQsSUFBSSxFQUFFLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFDNUIsY0FBYyxFQUFFLGNBQWMsRUFDOUIsSUFBSSxFQUFFLE1BQU0sRUFDWixPQUFPLENBQUMsRUFBRSxNQUFNLENBQUMsV0FBVyxHQUFHLG1CQUFtQixzRUFhbkQifQ==
@@ -1 +0,0 @@
1
- {"version":3,"file":"setupRequest.d.ts","sourceRoot":"","sources":["../src/setupRequest.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,mBAAmB,CAAA;AAC3C,OAAO,KAAK,KAAK,MAAM,kBAAkB,CAAA;AAEzC,OAAO,EAAa,cAAc,EAAkB,MAAM,2BAA2B,CAAA;AACrF,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAA;AAErD,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AAYvC,eAAO,MAAM,iBAAiB,6CAe3B,CAAA;AAEH,eAAO,MAAM,KAAK;;;gBAGhB,CAAA;AAmBF,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,eAAe,CAAC,EAAE,OAAO,CAAA;CACnC;AAMD,eAAO,MAAM,qBAAqB,GAC/B,IAAI,EAAE,EAAE,EAAE,GAAG,SAAS,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,QAAQ,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,oFASxF,CAAA;AAEN,eAAO,MAAM,8BAA8B,4BACZ,MAAM,CAAC,WAAW,GAAG,mBAAmB,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,QAAQ,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,uEAM3G,CAAA;AAMP,eAAO,MAAM,uCAAuC,4BACrB,MAAM,CAAC,WAAW,GAAG,mBAAmB,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,QAAQ,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,sGAK7G,CAAA;AAGL,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EACzC,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAC5B,cAAc,EAAE,cAAc,EAC9B,OAAO,CAAC,EAAE,mBAAmB,sEAa9B;AAED,wBAAgB,iCAAiC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EACvD,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAC5B,cAAc,EAAE,cAAc,EAC9B,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE,MAAM,CAAC,WAAW,GAAG,mBAAmB,sEAanD"}
@@ -1,70 +0,0 @@
1
- import * as Effect from "effect-app/Effect";
2
- import * as Layer from "effect-app/Layer";
3
- import * as Option from "effect-app/Option";
4
- import { LocaleRef, RequestContext, spanAttributes } from "effect-app/RequestContext";
5
- import { NonEmptyString255 } from "effect-app/Schema";
6
- import { ContextMapContainer } from "effect-app/Store";
7
- import * as Tracer from "effect/Tracer";
8
- import { SqlClient } from "effect/unstable/sql";
9
- import { storeId } from "./Store/Memory.js";
10
- const withSqlTransaction = (self) => Effect.serviceOption(SqlClient.SqlClient).pipe(Effect.flatMap(Option.match({
11
- onNone: () => self,
12
- onSome: (sql) => sql.withTransaction(self).pipe(Effect.orDie)
13
- })));
14
- export const getRequestContext = Effect
15
- .all({
16
- span: Effect.currentSpan.pipe(Effect.orDie),
17
- locale: LocaleRef,
18
- namespace: storeId
19
- })
20
- .pipe(Effect.map(({ locale, namespace, span }) => RequestContext.make({
21
- span: Tracer.externalSpan(span),
22
- locale,
23
- namespace,
24
- name: NonEmptyString255(span.name)
25
- })));
26
- export const getRC = Effect.all({
27
- locale: LocaleRef,
28
- namespace: storeId
29
- });
30
- const withRequestSpan = (name = "request", options) => (f) => Effect.andThen(getRC, (ctx) => f.pipe(Effect.withSpan(name, {
31
- ...options,
32
- attributes: { ...spanAttributes({ ...ctx, name: NonEmptyString255(name) }), ...options?.attributes }
33
- }, {
34
- captureStackTrace: options?.captureStackTrace ?? false
35
- }),
36
- // TODO: false
37
- // request context info is picked up directly in the logger for annotations.
38
- Effect.withLogSpan(name)));
39
- // Build `layer` against the ambient (request) scope rather than a sub-scope of the
40
- // returned Effect. Required when the returned value is a streaming HttpServerResponse:
41
- // the response body keeps producing chunks (and using layer-provided state) after the
42
- // Effect returns, so a sub-scope would close too early and run finalizers mid-stream.
43
- export const provideOnRequestScope = (layer) => (self) => Effect.gen(function* () {
44
- const requestScope = yield* Effect.scope;
45
- // Fresh MemoMap per request: `Layer.buildWithScope` would otherwise reuse
46
- // the ambient MemoMap living on the HTTP server fiber, sharing the built
47
- // value (e.g. ContextMap) across every request handled by that server.
48
- const memoMap = yield* Layer.makeMemoMap;
49
- const ctx = yield* Layer.buildWithMemoMap(layer, memoMap, requestScope);
50
- return yield* Effect.provide(self, ctx);
51
- });
52
- export const setupRequestContextFromCurrent = (name = "request", options) => (self) => self
53
- .pipe(options?.withTransaction === true ? withSqlTransaction : (_) => _, withRequestSpan(name, options), Effect.provide(ContextMapContainer.layer, { local: true }));
54
- // Streaming variant: binds ContextMapContainer to the ambient (request) scope so its
55
- // finalizer (clear()) runs only after the response body is fully drained, not when the
56
- // outer Effect returns its HttpServerResponse value. Use for handlers that return a
57
- // streaming HttpServerResponse (e.g. SSE) — see RequestContextMiddleware for context.
58
- export const setupStreamingRequestContextFromCurrent = (name = "request", options) => (self) => self.pipe(options?.withTransaction === true ? withSqlTransaction : (_) => _, withRequestSpan(name, options), provideOnRequestScope(ContextMapContainer.layer));
59
- // TODO: consider integrating Effect.withParentSpan
60
- export function setupRequestContext(self, requestContext, options) {
61
- const layer = Layer.mergeAll(ContextMapContainer.layer, Layer.succeed(LocaleRef, requestContext.locale), Layer.succeed(storeId, requestContext.namespace));
62
- return self
63
- .pipe(options?.withTransaction === true ? withSqlTransaction : (_) => _, withRequestSpan(requestContext.name), Effect.provide(layer, { local: true }));
64
- }
65
- export function setupRequestContextWithCustomSpan(self, requestContext, name, options) {
66
- const layer = Layer.mergeAll(ContextMapContainer.layer, Layer.succeed(LocaleRef, requestContext.locale), Layer.succeed(storeId, requestContext.namespace));
67
- return self
68
- .pipe(options?.withTransaction === true ? withSqlTransaction : (_) => _, withRequestSpan(name, options), Effect.provide(layer, { local: true }));
69
- }
70
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2V0dXBSZXF1ZXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL3NldHVwUmVxdWVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssTUFBTSxNQUFNLG1CQUFtQixDQUFBO0FBQzNDLE9BQU8sS0FBSyxLQUFLLE1BQU0sa0JBQWtCLENBQUE7QUFDekMsT0FBTyxLQUFLLE1BQU0sTUFBTSxtQkFBbUIsQ0FBQTtBQUMzQyxPQUFPLEVBQUUsU0FBUyxFQUFFLGNBQWMsRUFBRSxjQUFjLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQTtBQUNyRixPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQTtBQUNyRCxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQTtBQUN0RCxPQUFPLEtBQUssTUFBTSxNQUFNLGVBQWUsQ0FBQTtBQUN2QyxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0scUJBQXFCLENBQUE7QUFDL0MsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLG1CQUFtQixDQUFBO0FBRTNDLE1BQU0sa0JBQWtCLEdBQUcsQ0FBVSxJQUE0QixFQUEwQixFQUFFLENBQzNGLE1BQU0sQ0FBQyxhQUFhLENBQUMsU0FBUyxDQUFDLFNBQVMsQ0FBQyxDQUFDLElBQUksQ0FDNUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDO0lBQzFCLE1BQU0sRUFBRSxHQUFHLEVBQUUsQ0FBQyxJQUFJO0lBQ2xCLE1BQU0sRUFBRSxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsR0FBRyxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQztDQUM5RCxDQUFDLENBQUMsQ0FDSixDQUFBO0FBRUgsTUFBTSxDQUFDLE1BQU0saUJBQWlCLEdBQUcsTUFBTTtLQUNwQyxHQUFHLENBQUM7SUFDSCxJQUFJLEVBQUUsTUFBTSxDQUFDLFdBQVcs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
@@ -1,135 +0,0 @@
1
- import * as Effect from "effect-app/Effect"
2
- import * as Layer from "effect-app/Layer"
3
- import * as Option from "effect-app/Option"
4
- import { LocaleRef, RequestContext, spanAttributes } from "effect-app/RequestContext"
5
- import { NonEmptyString255 } from "effect-app/Schema"
6
- import { ContextMapContainer } from "effect-app/Store"
7
- import * as Tracer from "effect/Tracer"
8
- import { SqlClient } from "effect/unstable/sql"
9
- import { storeId } from "./Store/Memory.js"
10
-
11
- const withSqlTransaction = <R, E, A>(self: Effect.Effect<A, E, R>): Effect.Effect<A, E, R> =>
12
- Effect.serviceOption(SqlClient.SqlClient).pipe(
13
- Effect.flatMap(Option.match({
14
- onNone: () => self,
15
- onSome: (sql) => sql.withTransaction(self).pipe(Effect.orDie)
16
- }))
17
- )
18
-
19
- export const getRequestContext = Effect
20
- .all({
21
- span: Effect.currentSpan.pipe(Effect.orDie),
22
- locale: LocaleRef,
23
- namespace: storeId
24
- })
25
- .pipe(
26
- Effect.map(({ locale, namespace, span }) =>
27
- RequestContext.make({
28
- span: Tracer.externalSpan(span),
29
- locale,
30
- namespace,
31
- name: NonEmptyString255(span.name)
32
- })
33
- )
34
- )
35
-
36
- export const getRC = Effect.all({
37
- locale: LocaleRef,
38
- namespace: storeId
39
- })
40
-
41
- const withRequestSpan = (name = "request", options?: Tracer.SpanOptions) => <R, E, A>(f: Effect.Effect<A, E, R>) =>
42
- Effect.andThen(
43
- getRC,
44
- (ctx) =>
45
- f.pipe(
46
- Effect.withSpan(name, {
47
- ...options,
48
- attributes: { ...spanAttributes({ ...ctx, name: NonEmptyString255(name) }), ...options?.attributes }
49
- }, {
50
- captureStackTrace: options?.captureStackTrace ?? false
51
- }),
52
- // TODO: false
53
- // request context info is picked up directly in the logger for annotations.
54
- Effect.withLogSpan(name)
55
- )
56
- )
57
-
58
- export interface SetupRequestOptions {
59
- readonly withTransaction?: boolean
60
- }
61
-
62
- // Build `layer` against the ambient (request) scope rather than a sub-scope of the
63
- // returned Effect. Required when the returned value is a streaming HttpServerResponse:
64
- // the response body keeps producing chunks (and using layer-provided state) after the
65
- // Effect returns, so a sub-scope would close too early and run finalizers mid-stream.
66
- export const provideOnRequestScope =
67
- <ROut, E2, RIn>(layer: Layer.Layer<ROut, E2, RIn>) => <A, E, R>(self: Effect.Effect<A, E, R>) =>
68
- Effect.gen(function*() {
69
- const requestScope = yield* Effect.scope
70
- // Fresh MemoMap per request: `Layer.buildWithScope` would otherwise reuse
71
- // the ambient MemoMap living on the HTTP server fiber, sharing the built
72
- // value (e.g. ContextMap) across every request handled by that server.
73
- const memoMap = yield* Layer.makeMemoMap
74
- const ctx = yield* Layer.buildWithMemoMap(layer, memoMap, requestScope)
75
- return yield* Effect.provide(self, ctx)
76
- })
77
-
78
- export const setupRequestContextFromCurrent =
79
- (name = "request", options?: Tracer.SpanOptions & SetupRequestOptions) => <R, E, A>(self: Effect.Effect<A, E, R>) =>
80
- self
81
- .pipe(
82
- options?.withTransaction === true ? withSqlTransaction : (_) => _,
83
- withRequestSpan(name, options),
84
- Effect.provide(ContextMapContainer.layer, { local: true })
85
- )
86
-
87
- // Streaming variant: binds ContextMapContainer to the ambient (request) scope so its
88
- // finalizer (clear()) runs only after the response body is fully drained, not when the
89
- // outer Effect returns its HttpServerResponse value. Use for handlers that return a
90
- // streaming HttpServerResponse (e.g. SSE) — see RequestContextMiddleware for context.
91
- export const setupStreamingRequestContextFromCurrent =
92
- (name = "request", options?: Tracer.SpanOptions & SetupRequestOptions) => <R, E, A>(self: Effect.Effect<A, E, R>) =>
93
- self.pipe(
94
- options?.withTransaction === true ? withSqlTransaction : (_) => _,
95
- withRequestSpan(name, options),
96
- provideOnRequestScope(ContextMapContainer.layer)
97
- )
98
-
99
- // TODO: consider integrating Effect.withParentSpan
100
- export function setupRequestContext<R, E, A>(
101
- self: Effect.Effect<A, E, R>,
102
- requestContext: RequestContext,
103
- options?: SetupRequestOptions
104
- ) {
105
- const layer = Layer.mergeAll(
106
- ContextMapContainer.layer,
107
- Layer.succeed(LocaleRef, requestContext.locale),
108
- Layer.succeed(storeId, requestContext.namespace)
109
- )
110
- return self
111
- .pipe(
112
- options?.withTransaction === true ? withSqlTransaction : (_) => _,
113
- withRequestSpan(requestContext.name),
114
- Effect.provide(layer, { local: true })
115
- )
116
- }
117
-
118
- export function setupRequestContextWithCustomSpan<R, E, A>(
119
- self: Effect.Effect<A, E, R>,
120
- requestContext: RequestContext,
121
- name: string,
122
- options?: Tracer.SpanOptions & SetupRequestOptions
123
- ) {
124
- const layer = Layer.mergeAll(
125
- ContextMapContainer.layer,
126
- Layer.succeed(LocaleRef, requestContext.locale),
127
- Layer.succeed(storeId, requestContext.namespace)
128
- )
129
- return self
130
- .pipe(
131
- options?.withTransaction === true ? withSqlTransaction : (_) => _,
132
- withRequestSpan(name, options),
133
- Effect.provide(layer, { local: true })
134
- )
135
- }