@effect-app/infra 4.0.0-beta.250 → 4.0.0-beta.251
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.
- package/CHANGELOG.md +8 -0
- package/dist/QueueMaker/SQLQueue.d.ts +1 -1
- package/dist/QueueMaker/SQLQueue.d.ts.map +1 -1
- package/dist/QueueMaker/SQLQueue.js +2 -2
- package/dist/QueueMaker/memQueue.d.ts +1 -1
- package/dist/QueueMaker/memQueue.d.ts.map +1 -1
- package/dist/QueueMaker/memQueue.js +2 -2
- package/dist/QueueMaker/sbqueue.d.ts +1 -1
- package/dist/QueueMaker/sbqueue.d.ts.map +1 -1
- package/dist/QueueMaker/sbqueue.js +2 -2
- package/dist/Store/Cosmos.d.ts +1 -1
- package/dist/Store/Cosmos.d.ts.map +1 -1
- package/dist/Store/Cosmos.js +2 -3
- package/dist/Store/Disk.d.ts +1 -1
- package/dist/Store/Disk.d.ts.map +1 -1
- package/dist/Store/Disk.js +3 -3
- package/dist/Store/Memory.d.ts +1 -7
- package/dist/Store/Memory.d.ts.map +1 -1
- package/dist/Store/Memory.js +2 -7
- package/dist/Store/SQL/Pg.d.ts +1 -1
- package/dist/Store/SQL/Pg.d.ts.map +1 -1
- package/dist/Store/SQL/Pg.js +2 -3
- package/dist/Store/SQL.d.ts +1 -1
- package/dist/Store/SQL.d.ts.map +1 -1
- package/dist/Store/SQL.js +2 -3
- package/dist/errorReporter.d.ts +1 -1
- package/dist/errorReporter.d.ts.map +1 -1
- package/dist/errorReporter.js +2 -2
- package/dist/internal/RequestContextMiddleware.d.ts +1 -1
- package/dist/internal/RequestContextMiddleware.d.ts.map +1 -1
- package/dist/internal/RequestContextMiddleware.js +3 -4
- package/dist/internal/events.d.ts +1 -1
- package/dist/internal/events.d.ts.map +1 -1
- package/dist/internal/events.js +3 -3
- package/dist/logger/shared.d.ts +1 -1
- package/dist/logger/shared.d.ts.map +1 -1
- package/dist/logger/shared.js +2 -2
- package/package.json +2 -6
- package/src/QueueMaker/SQLQueue.ts +1 -1
- package/src/QueueMaker/memQueue.ts +1 -1
- package/src/QueueMaker/sbqueue.ts +1 -1
- package/src/Store/Cosmos.ts +1 -2
- package/src/Store/Disk.ts +2 -2
- package/src/Store/Memory.ts +1 -6
- package/src/Store/SQL/Pg.ts +1 -2
- package/src/Store/SQL.ts +1 -2
- package/src/errorReporter.ts +1 -1
- package/src/internal/RequestContextMiddleware.ts +2 -3
- package/src/internal/events.ts +2 -2
- package/src/logger/shared.ts +1 -1
- package/test/dist/rawQuery.test.d.ts.map +1 -1
- package/test/query.test.ts +1 -1
- package/test/rawQuery.test.ts +1 -1
- package/test/repository-ext.test.ts +1 -1
- package/test/validateSample.test.ts +1 -1
- package/dist/setupRequest.d.ts +0 -19
- package/dist/setupRequest.d.ts.map +0 -1
- package/dist/setupRequest.js +0 -70
- package/src/setupRequest.ts +0 -135
package/dist/logger/shared.d.ts
CHANGED
|
@@ -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,
|
|
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;
|
|
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"}
|
package/dist/logger/shared.js
CHANGED
|
@@ -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 "
|
|
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,
|
|
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.
|
|
3
|
+
"version": "4.0.0-beta.251",
|
|
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.
|
|
16
|
+
"effect-app": "4.0.0-beta.251"
|
|
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<
|
package/src/Store/Cosmos.ts
CHANGED
|
@@ -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
|
|
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,
|
package/src/Store/Memory.ts
CHANGED
|
@@ -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 {
|
|
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")
|
package/src/Store/SQL/Pg.ts
CHANGED
|
@@ -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
|
|
package/src/errorReporter.ts
CHANGED
|
@@ -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 {
|
|
7
|
-
import {
|
|
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) =>
|
package/src/internal/events.ts
CHANGED
|
@@ -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")
|
package/src/logger/shared.ts
CHANGED
|
@@ -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":"
|
|
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"}
|
package/test/query.test.ts
CHANGED
|
@@ -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
|
|
package/test/rawQuery.test.ts
CHANGED
|
@@ -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 "
|
|
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)
|
package/dist/setupRequest.d.ts
DELETED
|
@@ -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"}
|
package/dist/setupRequest.js
DELETED
|
@@ -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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
|
package/src/setupRequest.ts
DELETED
|
@@ -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
|
-
}
|