@effect-app/infra 0.235.1 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +22 -0
- package/_cjs/api/routing/defaultErrorHandler.cjs +2 -2
- package/_cjs/api/routing/defaultErrorHandler.cjs.map +1 -1
- package/_cjs/rateLimit.cjs +3 -3
- package/_cjs/rateLimit.cjs.map +1 -1
- package/_cjs/services/Emailer/Sendgrid.cjs +2 -2
- package/_cjs/services/Emailer/Sendgrid.cjs.map +1 -1
- package/_cjs/services/Operations.cjs +1 -1
- package/_cjs/services/Operations.cjs.map +1 -1
- package/_cjs/services/Repository/ext.cjs +1 -1
- package/_cjs/services/Repository/ext.cjs.map +1 -1
- package/_cjs/services/RepositoryBase.cjs +10 -10
- package/_cjs/services/RepositoryBase.cjs.map +1 -1
- package/_cjs/services/Store/Cosmos/query.cjs +2 -2
- package/_cjs/services/Store/Cosmos/query.cjs.map +1 -1
- package/_cjs/services/Store/Cosmos.cjs +1 -1
- package/_cjs/services/Store/Cosmos.cjs.map +1 -1
- package/_cjs/services/Store/Memory.cjs +6 -6
- package/_cjs/services/Store/Memory.cjs.map +1 -1
- package/_cjs/services/Store/codeFilter.cjs +1 -1
- package/_cjs/services/Store/codeFilter.cjs.map +1 -1
- package/_cjs/services/Store/filterApi/query.cjs +1 -1
- package/_cjs/services/Store/filterApi/query.cjs.map +1 -1
- package/dist/api/routing/defaultErrorHandler.js +2 -2
- package/dist/api/routing/match.d.ts +1 -1
- package/dist/rateLimit.d.ts.map +1 -1
- package/dist/rateLimit.js +6 -6
- package/dist/services/Emailer/Sendgrid.js +3 -3
- package/dist/services/Operations.js +1 -1
- package/dist/services/Repository/ext.d.ts.map +1 -1
- package/dist/services/Repository/ext.js +3 -3
- package/dist/services/RepositoryBase.d.ts.map +1 -1
- package/dist/services/RepositoryBase.js +11 -11
- package/dist/services/Store/Cosmos/query.d.ts.map +1 -1
- package/dist/services/Store/Cosmos/query.js +4 -4
- package/dist/services/Store/Cosmos.d.ts.map +1 -1
- package/dist/services/Store/Cosmos.js +3 -3
- package/dist/services/Store/Memory.d.ts.map +1 -1
- package/dist/services/Store/Memory.js +8 -8
- package/dist/services/Store/codeFilter.js +3 -3
- package/dist/services/Store/filterApi/query.js +3 -3
- package/package.json +8 -8
- package/src/api/routing/defaultErrorHandler.ts +2 -2
- package/src/rateLimit.ts +5 -5
- package/src/services/Emailer/Sendgrid.ts +2 -2
- package/src/services/Operations.ts +1 -1
- package/src/services/Repository/ext.ts +2 -2
- package/src/services/RepositoryBase.ts +12 -13
- package/src/services/Store/Cosmos/query.ts +3 -3
- package/src/services/Store/Cosmos.ts +2 -2
- package/src/services/Store/Memory.ts +8 -8
- package/src/services/Store/Redis.ts.bak +1 -1
- package/src/services/Store/codeFilter.ts +2 -2
- package/src/services/Store/filterApi/query.ts +2 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@effect-app/infra",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"dependencies": {
|
|
@@ -18,10 +18,10 @@
|
|
|
18
18
|
"proper-lockfile": "^4.1.2",
|
|
19
19
|
"pure-rand": "6.1.0",
|
|
20
20
|
"redlock": "^4.2.0",
|
|
21
|
-
"effect-app": "0.
|
|
22
|
-
"
|
|
23
|
-
"@effect-app/schema": "0.
|
|
24
|
-
"@effect-app/infra-adapters": "0.
|
|
21
|
+
"@effect-app/core": "1.0.0",
|
|
22
|
+
"effect-app": "1.0.0",
|
|
23
|
+
"@effect-app/schema": "1.0.0",
|
|
24
|
+
"@effect-app/infra-adapters": "1.0.0"
|
|
25
25
|
},
|
|
26
26
|
"devDependencies": {
|
|
27
27
|
"@babel/cli": "^7.24.1",
|
|
@@ -42,9 +42,9 @@
|
|
|
42
42
|
},
|
|
43
43
|
"peerDependencies": {
|
|
44
44
|
"express": "^4.19.2",
|
|
45
|
-
"@effect/platform": "^0.
|
|
46
|
-
"@effect/schema": "^0.
|
|
47
|
-
"effect": "^
|
|
45
|
+
"@effect/platform": "^0.49.0",
|
|
46
|
+
"@effect/schema": "^0.66.0",
|
|
47
|
+
"effect": "^3.0.0"
|
|
48
48
|
},
|
|
49
49
|
"typesVersions": {
|
|
50
50
|
"*": {
|
|
@@ -38,7 +38,7 @@ export function defaultBasicErrorHandler<R>(
|
|
|
38
38
|
const sendError = (code: number) => (body: unknown) =>
|
|
39
39
|
Effect.sync(() => setBody(res, HttpBody.unsafeJson(body)).pipe(setStatus(code)))
|
|
40
40
|
return r2.pipe(
|
|
41
|
-
Effect.tapErrorCause((cause) => Cause.isFailure(cause) ? logRequestError(cause) : Effect.
|
|
41
|
+
Effect.tapErrorCause((cause) => Cause.isFailure(cause) ? logRequestError(cause) : Effect.void),
|
|
42
42
|
Effect.catchTag("ValidationError", (err) => sendError(400)(err.errors)),
|
|
43
43
|
Effect
|
|
44
44
|
// final catch all; expecting never so that unhandled known errors will show up
|
|
@@ -75,7 +75,7 @@ export function defaultErrorHandler<R>(
|
|
|
75
75
|
)
|
|
76
76
|
return r3
|
|
77
77
|
.pipe(
|
|
78
|
-
Effect.tapErrorCause((cause) => Cause.isFailure(cause) ? logRequestError(cause) : Effect.
|
|
78
|
+
Effect.tapErrorCause((cause) => Cause.isFailure(cause) ? logRequestError(cause) : Effect.void),
|
|
79
79
|
Effect
|
|
80
80
|
.catchTags({
|
|
81
81
|
"JWTError": (err) =>
|
package/src/rateLimit.ts
CHANGED
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
|
|
26
26
|
import type { Semaphore } from "@effect-app/core/Effect"
|
|
27
27
|
import type { Duration, NonEmptyArray } from "effect-app"
|
|
28
|
-
import {
|
|
28
|
+
import { Array, Effect } from "effect-app"
|
|
29
29
|
|
|
30
30
|
/**
|
|
31
31
|
* Executes the specified effect, acquiring the specified number of permits
|
|
@@ -63,7 +63,7 @@ export function batchPar<R, E, A, R2, E2, A2, T>(
|
|
|
63
63
|
) {
|
|
64
64
|
return (items: Iterable<T>) =>
|
|
65
65
|
Effect.forEach(
|
|
66
|
-
|
|
66
|
+
Array.chunk_(items, n),
|
|
67
67
|
(_, i) =>
|
|
68
68
|
Effect
|
|
69
69
|
.forEach(_, (_, j) => forEachItem(_, j, i), { concurrency: "inherit" })
|
|
@@ -83,7 +83,7 @@ export function batch<R, E, A, R2, E2, A2, T>(
|
|
|
83
83
|
) {
|
|
84
84
|
return (items: Iterable<T>) =>
|
|
85
85
|
Effect.forEach(
|
|
86
|
-
|
|
86
|
+
Array.chunk_(items, n),
|
|
87
87
|
(_, i) =>
|
|
88
88
|
Effect
|
|
89
89
|
.forEach(_, (_, j) => forEachItem(_, j, i), { concurrency: "inherit" })
|
|
@@ -125,10 +125,10 @@ export function naiveRateLimit(
|
|
|
125
125
|
forEachBatch: (a: A[]) => Effect<A2, E2, R2>
|
|
126
126
|
) =>
|
|
127
127
|
Effect.forEach(
|
|
128
|
-
|
|
128
|
+
Array.chunk_(items, n),
|
|
129
129
|
(batch, i) =>
|
|
130
130
|
((i === 0)
|
|
131
|
-
? Effect.
|
|
131
|
+
? Effect.void
|
|
132
132
|
: Effect.sleep(d))
|
|
133
133
|
.pipe(Effect.zipRight(
|
|
134
134
|
Effect
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { dropUndefinedT } from "@effect-app/core/utils"
|
|
2
2
|
import type { EmailData } from "@sendgrid/helpers/classes/email-address.js"
|
|
3
3
|
import sgMail from "@sendgrid/mail"
|
|
4
|
-
import { Effect, Equivalence,
|
|
4
|
+
import { Array, Effect, Equivalence, Secret } from "effect-app"
|
|
5
5
|
import { inspect } from "util"
|
|
6
6
|
import { Emailer } from "./service.js"
|
|
7
7
|
import type { EmailMsg, EmailMsgOptionalFrom, SendgridConfig } from "./service.js"
|
|
@@ -106,7 +106,7 @@ const eq = Equivalence.mapInput(
|
|
|
106
106
|
// https://stackoverflow.com/a/53603076/11595834
|
|
107
107
|
function renderFakeIfTest(addr: EmailData | EmailData[], makeId: () => number) {
|
|
108
108
|
return Array.isArray(addr)
|
|
109
|
-
?
|
|
109
|
+
? Array.dedupeWith(
|
|
110
110
|
addr
|
|
111
111
|
.map((x) => (isTestAddress(x) ? renderFake(x, makeId) : x)),
|
|
112
112
|
eq
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
2
|
// Update = Must return updated items
|
|
3
3
|
// Modify = Must `set` updated items, and can return anything.
|
|
4
|
-
import {
|
|
4
|
+
import { Array, Effect } from "effect-app"
|
|
5
5
|
import type { NonEmptyArray } from "effect-app"
|
|
6
6
|
import { type FixEnv, runTerm } from "effect-app/Pure"
|
|
7
7
|
import { NotFoundError } from "../../errors.js"
|
|
@@ -166,7 +166,7 @@ export function saveManyWithPureBatched_<
|
|
|
166
166
|
batchSize = 100
|
|
167
167
|
) {
|
|
168
168
|
return Effect.forEach(
|
|
169
|
-
|
|
169
|
+
Array.chunk_(items, batchSize),
|
|
170
170
|
(batch) =>
|
|
171
171
|
saveAllWithEffectInt(
|
|
172
172
|
self,
|
|
@@ -24,6 +24,7 @@ import type { ParseResult, Schema } from "@effect-app/schema"
|
|
|
24
24
|
import { NonNegativeInt } from "@effect-app/schema"
|
|
25
25
|
import type { NonEmptyArray, NonEmptyReadonlyArray } from "effect-app"
|
|
26
26
|
import {
|
|
27
|
+
Array,
|
|
27
28
|
Chunk,
|
|
28
29
|
Context,
|
|
29
30
|
Effect,
|
|
@@ -32,7 +33,6 @@ import {
|
|
|
32
33
|
Option,
|
|
33
34
|
pipe,
|
|
34
35
|
PubSub,
|
|
35
|
-
ReadonlyArray,
|
|
36
36
|
Request,
|
|
37
37
|
RequestResolver,
|
|
38
38
|
S,
|
|
@@ -40,7 +40,6 @@ import {
|
|
|
40
40
|
} from "effect-app"
|
|
41
41
|
import { runTerm } from "effect-app/Pure"
|
|
42
42
|
import type { FixEnv, PureEnv } from "effect-app/Pure"
|
|
43
|
-
import type { NoInfer } from "effect/Types"
|
|
44
43
|
import { type InvalidStateError, NotFoundError, type OptimisticConcurrencyException } from "../errors.js"
|
|
45
44
|
import type { FieldValues } from "../filter/types.js"
|
|
46
45
|
import { make as makeQuery } from "./query.js"
|
|
@@ -239,8 +238,8 @@ export class RepositoryBaseC3<
|
|
|
239
238
|
Effect.andThen((_) =>
|
|
240
239
|
Array.isArray(_)
|
|
241
240
|
? batch === undefined
|
|
242
|
-
? saveManyWithPure_(this, _, pure as any)
|
|
243
|
-
: saveManyWithPureBatched_(this, _, pure as any, batch === "batched" ? 100 : batch)
|
|
241
|
+
? saveManyWithPure_(this, _ as readonly T[], pure as any)
|
|
242
|
+
: saveManyWithPureBatched_(this, _ as readonly T[], pure as any, batch === "batched" ? 100 : batch)
|
|
244
243
|
: saveWithPure_(this, _ as any, pure as any)
|
|
245
244
|
)
|
|
246
245
|
) as any
|
|
@@ -278,7 +277,7 @@ export class RepositoryBaseC3<
|
|
|
278
277
|
} = (items, pure, batch?: "batched" | number) =>
|
|
279
278
|
batch
|
|
280
279
|
? Effect.forEach(
|
|
281
|
-
|
|
280
|
+
Array.chunk_(items, batch === "batched" ? 100 : batch),
|
|
282
281
|
(batch) =>
|
|
283
282
|
saveAllWithEffectInt(
|
|
284
283
|
this,
|
|
@@ -392,7 +391,7 @@ export function makeRepo<
|
|
|
392
391
|
const pubCfg = yield* $(Effect.context<R2>())
|
|
393
392
|
const pub = "publishEvents" in args
|
|
394
393
|
? flow(args.publishEvents, Effect.provide(pubCfg))
|
|
395
|
-
: () => Effect.
|
|
394
|
+
: () => Effect.void
|
|
396
395
|
const changeFeed = yield* $(PubSub.unbounded<[T[], "save" | "remove"]>())
|
|
397
396
|
|
|
398
397
|
const allE = cms
|
|
@@ -466,10 +465,10 @@ export function makeRepo<
|
|
|
466
465
|
ret.forEach((_) => set(_.id, _._etag))
|
|
467
466
|
})
|
|
468
467
|
)
|
|
469
|
-
.pipe(Effect.
|
|
468
|
+
.pipe(Effect.asVoid)
|
|
470
469
|
|
|
471
470
|
const saveAll = (a: Iterable<T>) =>
|
|
472
|
-
encodeMany(Array.
|
|
471
|
+
encodeMany(Array.fromIterable(a))
|
|
473
472
|
.pipe(
|
|
474
473
|
Effect.orDie,
|
|
475
474
|
Effect.andThen(saveAllE)
|
|
@@ -485,7 +484,7 @@ export function makeRepo<
|
|
|
485
484
|
// TODO: for full consistency the events should be stored within the same database transaction, and then picked up.
|
|
486
485
|
(_) => Effect.flatMapOption(_, pub),
|
|
487
486
|
Effect.andThen(changeFeed.publish([Chunk.toArray(it), "save"])),
|
|
488
|
-
Effect.
|
|
487
|
+
Effect.asVoid
|
|
489
488
|
)
|
|
490
489
|
})
|
|
491
490
|
.pipe(Effect.withSpan("saveAndPublish"))
|
|
@@ -533,7 +532,7 @@ export function makeRepo<
|
|
|
533
532
|
.filter(args)
|
|
534
533
|
.pipe(Effect.tap((items) =>
|
|
535
534
|
args.select
|
|
536
|
-
? Effect.
|
|
535
|
+
? Effect.void
|
|
537
536
|
: Effect.map(cms, ({ set }) => items.forEach((_) => set((_ as Encoded).id, (_ as PM)._etag)))
|
|
538
537
|
))
|
|
539
538
|
|
|
@@ -555,7 +554,7 @@ export function makeRepo<
|
|
|
555
554
|
.pipe(
|
|
556
555
|
Effect.flatMap(flow(
|
|
557
556
|
S.decode(S.Array(a.schema)),
|
|
558
|
-
Effect.map(
|
|
557
|
+
Effect.map(Array.getSomes),
|
|
559
558
|
Effect.provide(rctx)
|
|
560
559
|
))
|
|
561
560
|
)
|
|
@@ -574,7 +573,7 @@ export function makeRepo<
|
|
|
574
573
|
? Effect.andThen(
|
|
575
574
|
eff,
|
|
576
575
|
flow(
|
|
577
|
-
|
|
576
|
+
Array.head,
|
|
578
577
|
Effect.mapError(() => new NotFoundError({ id: "query", /* TODO */ type: name }))
|
|
579
578
|
)
|
|
580
579
|
)
|
|
@@ -1051,7 +1050,7 @@ export const makeRequest = <
|
|
|
1051
1050
|
Effect.forEach(requests, (r) =>
|
|
1052
1051
|
Request.complete(
|
|
1053
1052
|
r,
|
|
1054
|
-
|
|
1053
|
+
Array
|
|
1055
1054
|
.findFirst(items, (_) => _.id === r.id)
|
|
1056
1055
|
.pipe(Option.match({
|
|
1057
1056
|
onNone: () => Exit.fail(new NotFoundError({ type: repo.itemType, id: r.id })),
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Effect, Equivalence, pipe
|
|
1
|
+
import { Array, Effect, Equivalence, pipe } from "effect-app"
|
|
2
2
|
import type { NonEmptyReadonlyArray } from "effect-app"
|
|
3
3
|
import { assertUnreachable } from "effect-app/utils"
|
|
4
4
|
import type { FilterR, FilterResult } from "../filterApi/query.js"
|
|
@@ -100,7 +100,7 @@ export function buildWhereCosmosQuery3(
|
|
|
100
100
|
let s = ""
|
|
101
101
|
let l = 0
|
|
102
102
|
const printN = (n: number) => {
|
|
103
|
-
return n === 0 ? "" :
|
|
103
|
+
return n === 0 ? "" : Array.range(1, n).map(() => " ").join("")
|
|
104
104
|
}
|
|
105
105
|
for (const e of state) {
|
|
106
106
|
switch (e.t) {
|
|
@@ -175,7 +175,7 @@ export function buildWhereCosmosQuery3(
|
|
|
175
175
|
.filter((_) => _.path.includes(".-1."))
|
|
176
176
|
.map((_) => _.path.split(".-1.")[0])
|
|
177
177
|
.map((_) => `JOIN ${_} IN f.${_}`),
|
|
178
|
-
|
|
178
|
+
Array.dedupeWith(Equivalence.string)
|
|
179
179
|
)
|
|
180
180
|
.join("\n")
|
|
181
181
|
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import { toNonEmptyArray } from "@effect-app/core/Array"
|
|
4
4
|
import { CosmosClient, CosmosClientLayer } from "@effect-app/infra-adapters/cosmos-client"
|
|
5
|
-
import { Chunk, Duration, Effect, Layer, Option, pipe,
|
|
5
|
+
import { Array, Chunk, Duration, Effect, Layer, Option, pipe, Secret, Struct } from "effect-app"
|
|
6
6
|
import type { NonEmptyReadonlyArray } from "effect-app"
|
|
7
7
|
import { dropUndefinedT } from "effect-app/utils"
|
|
8
8
|
import { OptimisticConcurrencyException } from "../../errors.js"
|
|
@@ -75,7 +75,7 @@ function makeCosmosStore({ prefix }: StorageConfig) {
|
|
|
75
75
|
})
|
|
76
76
|
] as const
|
|
77
77
|
)
|
|
78
|
-
const batches = Chunk.toReadonlyArray(
|
|
78
|
+
const batches = Chunk.toReadonlyArray(Array.chunk_(b, config?.maxBulkSize ?? 10))
|
|
79
79
|
|
|
80
80
|
const batchResult = yield* $(
|
|
81
81
|
Effect.forEach(
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
2
|
|
|
3
|
-
import { Effect, FiberRef, flow, Option, Order, pipe,
|
|
3
|
+
import { Array, Effect, FiberRef, flow, Option, Order, pipe, Ref, Struct } from "effect-app"
|
|
4
4
|
import type { NonEmptyArray, NonEmptyReadonlyArray } from "effect-app"
|
|
5
5
|
import { get } from "effect-app/utils"
|
|
6
6
|
import type { RequestContext } from "../../RequestContext.js"
|
|
@@ -30,24 +30,24 @@ export function memFilter<T extends { id: string }, U extends keyof T = never>(f
|
|
|
30
30
|
})
|
|
31
31
|
))
|
|
32
32
|
if (Option.isSome(ords)) {
|
|
33
|
-
c =
|
|
33
|
+
c = Array.sortBy(...ords.value)(c)
|
|
34
34
|
}
|
|
35
35
|
if (!skip && limit === 1) {
|
|
36
36
|
return select(
|
|
37
|
-
|
|
38
|
-
Option.map(
|
|
37
|
+
Array.findFirst(c, f.filter ? codeFilter(f.filter) : (_) => Option.some(_)).pipe(
|
|
38
|
+
Option.map(Array.make),
|
|
39
39
|
Option.getOrElse(
|
|
40
40
|
() => []
|
|
41
41
|
)
|
|
42
42
|
)
|
|
43
43
|
)
|
|
44
44
|
}
|
|
45
|
-
let r = f.filter ?
|
|
45
|
+
let r = f.filter ? Array.filterMap(c, codeFilter(f.filter)) : c
|
|
46
46
|
if (skip) {
|
|
47
|
-
r =
|
|
47
|
+
r = Array.drop(r, skip)
|
|
48
48
|
}
|
|
49
49
|
if (limit !== undefined) {
|
|
50
|
-
r =
|
|
50
|
+
r = Array.take(r, limit)
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
return select(r)
|
|
@@ -96,7 +96,7 @@ export function makeMemoryStoreInt<Id extends string, Encoded extends { id: Id }
|
|
|
96
96
|
const withPermit = sem.withPermits(1)
|
|
97
97
|
const values = Effect.map(Ref.get(store), (s) => s.values())
|
|
98
98
|
|
|
99
|
-
const all = Effect.map(values,
|
|
99
|
+
const all = Effect.map(values, Array.fromIterable)
|
|
100
100
|
|
|
101
101
|
const batchSet = (items: NonEmptyReadonlyArray<PM>) =>
|
|
102
102
|
Effect
|
|
@@ -43,7 +43,7 @@ function makeRedisStore({ prefix }: StorageConfig) {
|
|
|
43
43
|
const withPermit = sem.withPermits(1)
|
|
44
44
|
|
|
45
45
|
const asMap = get.map((x) => new Map(x.map((x) => [x.id, x] as const)))
|
|
46
|
-
const all = get.map(
|
|
46
|
+
const all = get.map(Array.fromIterable)
|
|
47
47
|
const batchSet = (items: NonEmptyReadonlyArray<PM>) =>
|
|
48
48
|
Effect
|
|
49
49
|
.forEach(items, (e) => s.find(e.id).flatMap((current) => updateETag(e, current)))
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Array } from "effect-app"
|
|
2
2
|
import { assertUnreachable, get } from "effect-app/utils"
|
|
3
3
|
import type { FilterR, FilterResult } from "./filterApi/query.js"
|
|
4
4
|
import { compare, greaterThan, greaterThanExclusive, lowerThan, lowerThanExclusive } from "./utils.js"
|
|
@@ -58,7 +58,7 @@ export const codeFilter3_ = <E>(state: readonly FilterResult[], sut: E, statemen
|
|
|
58
58
|
let s = ""
|
|
59
59
|
let l = 0
|
|
60
60
|
const printN = (n: number) => {
|
|
61
|
-
return n === 0 ? "" :
|
|
61
|
+
return n === 0 ? "" : Array.range(1, n).map(() => " ").join("")
|
|
62
62
|
}
|
|
63
63
|
// TODO: path str updates
|
|
64
64
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Array } from "effect-app"
|
|
2
2
|
import type { FieldValues } from "../../../filter/types.js"
|
|
3
3
|
import type { FieldPath, FieldPathValue } from "../../../filter/types/path/eager.js"
|
|
4
4
|
import type { Filter, Ops } from "./proxy.js"
|
|
@@ -40,7 +40,7 @@ export const print = (state: readonly FilterResult[]) => {
|
|
|
40
40
|
let s = ""
|
|
41
41
|
let l = 0
|
|
42
42
|
const printN = (n: number) => {
|
|
43
|
-
return n === 0 ? "" :
|
|
43
|
+
return n === 0 ? "" : Array.range(1, n).map(() => " ").join("")
|
|
44
44
|
}
|
|
45
45
|
for (const e of state) {
|
|
46
46
|
switch (e.t) {
|