Merge commit '36c66dd290d3ce6eb1ccd310d0c658d4a32bb8eb' as 'repos/effect'

This commit is contained in:
-Puter
2026-07-19 03:25:10 +05:30
parent dd1071cc10
commit 2daf979036
2214 changed files with 673090 additions and 0 deletions

View File

@@ -0,0 +1 @@
outside root

View File

@@ -0,0 +1 @@
initial conditional body

View File

@@ -0,0 +1 @@
<html><body>custom home</body></html>

View File

@@ -0,0 +1 @@
binary-ish

View File

@@ -0,0 +1 @@
<html><body>guide index</body></html>

View File

@@ -0,0 +1 @@
hello static file

View File

@@ -0,0 +1 @@
<html><body>root index</body></html>

View File

@@ -0,0 +1 @@
0123456789abcdefghijklmnopqrstuvwxyz

View File

@@ -0,0 +1,64 @@
import { MysqlClient } from "@effect/sql-mysql2"
import type { StartedMySqlContainer } from "@testcontainers/mysql"
import { MySqlContainer } from "@testcontainers/mysql"
import { Context, Data, Effect, Layer, Redacted, String } from "effect"
export class ContainerError extends Data.TaggedError("ContainerError")<{
cause: unknown
}> {}
export class MysqlContainer extends Context.Service<
MysqlContainer,
StartedMySqlContainer
>()("test/MysqlContainer") {
static readonly layer = Layer.effect(this)(
Effect.acquireRelease(
Effect.tryPromise({
try: () => new MySqlContainer("mysql:lts").start(),
catch: (cause) => new ContainerError({ cause })
}),
(container) => Effect.promise(() => container.stop())
)
)
static client = Layer.unwrap(
Effect.gen(function*() {
const container = yield* MysqlContainer
return MysqlClient.layer({
url: Redacted.make(container.getConnectionUri())
})
})
)
static layerClient = this.client.pipe(Layer.provide(this.layer))
static layerClientWithTransforms = Layer.unwrap(
Effect.gen(function*() {
const container = yield* MysqlContainer
return MysqlClient.layer({
url: Redacted.make(container.getConnectionUri()),
transformQueryNames: String.camelToSnake,
transformResultNames: String.snakeToCamel
})
})
).pipe(Layer.provide(this.layer))
static layerVitest = Layer.effect(
this,
Effect.acquireRelease(
Effect.tryPromise({
try: () =>
new MySqlContainer("vitess/vttestserver:mysql80").withEnvironment({
KEYSPACES: "test,unsharded",
NUM_SHARDS: "1,1",
MYSQL_BIND_HOST: "0.0.0.0",
PORT: "3303"
}).start(),
catch: (cause) => new ContainerError({ cause })
}),
(container) => Effect.promise(() => container.stop())
)
)
static layerClientVitess = this.client.pipe(Layer.provide(this.layerVitest))
}

View File

@@ -0,0 +1,39 @@
import { PgClient } from "@effect/sql-pg"
import { PostgreSqlContainer } from "@testcontainers/postgresql"
import { Context, Data, Effect, Layer, Redacted, String } from "effect"
export class ContainerError extends Data.TaggedError("ContainerError")<{
cause: unknown
}> {}
export class PgContainer extends Context.Service<PgContainer>()("test/PgContainer", {
make: Effect.acquireRelease(
Effect.tryPromise({
try: () => new PostgreSqlContainer("postgres:alpine").start(),
catch: (cause) => new ContainerError({ cause })
}),
(container) => Effect.promise(() => container.stop())
)
}) {
static readonly layer = Layer.effect(this)(this.make)
static layerClient = Layer.unwrap(
Effect.gen(function*() {
const container = yield* PgContainer
return PgClient.layer({
url: Redacted.make(container.getConnectionUri())
})
})
).pipe(Layer.provide(this.layer))
static layerClientWithTransforms = Layer.unwrap(
Effect.gen(function*() {
const container = yield* PgContainer
return PgClient.layer({
url: Redacted.make(container.getConnectionUri()),
transformResultNames: String.snakeToCamel,
transformQueryNames: String.camelToSnake
})
})
).pipe(Layer.provide(this.layer))
}

View File

@@ -0,0 +1,149 @@
import { assert, describe, it } from "@effect/vitest"
import { Cause, Context, Effect, Fiber, Option, Stream } from "effect"
// @ts-ignore
// oxlint-disable-next-line @typescript-eslint/no-unused-vars
import { NodeInspectSymbol } from "effect/Inspectable"
import * as Layer from "effect/Layer"
import * as RpcClient from "effect/unstable/rpc/RpcClient"
import type { RpcClientError } from "effect/unstable/rpc/RpcClientError"
import type * as RpcGroup from "effect/unstable/rpc/RpcGroup"
import * as RpcServer from "effect/unstable/rpc/RpcServer"
import * as RpcTest from "effect/unstable/rpc/RpcTest"
import { AuthClient, AuthLive, TimingLive, User, UserRpcs, UsersLive } from "./rpc-schemas.ts"
export class UsersClient extends Context.Service<
UsersClient,
RpcClient.RpcClient<RpcGroup.Rpcs<typeof UserRpcs>, RpcClientError>
>()("UsersClient") {
static readonly layer = Layer.effect(UsersClient)(RpcClient.make(UserRpcs)).pipe(
Layer.provide(AuthClient)
)
static layerTest = Layer.effect(UsersClient)(RpcTest.makeClient(UserRpcs)).pipe(
Layer.provide([UsersLive, AuthLive, TimingLive, AuthClient])
)
}
export const e2eSuite = <E>(
name: string,
layer: Layer.Layer<UsersClient | RpcServer.Protocol, E>,
concurrent = true
) => {
describe(name, { concurrent, timeout: 30_000 }, () => {
it.effect("should get user", () =>
Effect.gen(function*() {
const client = yield* UsersClient
const user = yield* client.GetUser({ id: "1" })
assert.instanceOf(user, User)
assert.deepStrictEqual(user, new User({ id: "1", name: "Logged in user" }))
}).pipe(Effect.provide(layer)))
it.effect("should get deferred user", () =>
Effect.gen(function*() {
const client = yield* UsersClient
const user = yield* client.GetUserDeferred({ id: "1" })
assert.instanceOf(user, User)
assert.deepStrictEqual(user, new User({ id: "1", name: "John" }))
}).pipe(Effect.provide(layer)))
it.effect("nested method", () =>
Effect.gen(function*() {
const client = yield* UsersClient
yield* client["nested.test"]()
}).pipe(Effect.provide(layer)))
it.effect("should not flatten Option", () =>
Effect.gen(function*() {
const client = yield* UsersClient
const user = yield* client.GetUserOption({ id: "1" })
assert.deepStrictEqual(user, Option.some(new User({ id: "1", name: "John" })))
}).pipe(Effect.provide(layer)))
it.effect("headers", () =>
Effect.gen(function*() {
const client = yield* UsersClient
const user = yield* client.GetUser({ id: "1" })
assert.instanceOf(user, User)
assert.deepStrictEqual(user, new User({ id: "123", name: "Logged in user" }))
}).pipe(
RpcClient.withHeaders({ userId: "123" }),
Effect.provide(layer)
))
it.live("Stream", () =>
Effect.gen(function*() {
const client = yield* UsersClient
const users: Array<User> = []
yield* client.StreamUsers({ id: "1" }).pipe(
Stream.take(5),
Stream.runForEach((user) =>
Effect.sync(() => {
users.push(user)
})
),
Effect.forkChild
)
yield* Effect.sleep(2000)
assert.lengthOf(users, 5)
// test interrupts
const interrupts = yield* client.GetInterrupts()
assert.equal(interrupts, 1)
const { supportsAck } = yield* RpcServer.Protocol
// test backpressure
if (supportsAck) {
const emits = yield* client.GetEmits()
assert.equal(emits, 5)
}
}).pipe(Effect.provide(layer)), { timeout: 20000 })
it.effect("defect", () =>
Effect.gen(function*() {
const client = yield* UsersClient
const cause = yield* client.ProduceDefect().pipe(
Effect.sandbox,
Effect.flip
)
assert.deepStrictEqual(cause, Cause.die("boom"))
}).pipe(
RpcClient.withHeaders({ userId: "123" }),
Effect.provide(layer)
))
it.live("never", () =>
Effect.gen(function*() {
const client = yield* UsersClient
const fiber = yield* client.Never().pipe(
Effect.forkChild
)
yield* Effect.sleep(500)
assert.isUndefined(fiber.pollUnsafe())
yield* Fiber.interrupt(fiber)
yield* Effect.sleep(100)
const { supportsAck } = yield* RpcServer.Protocol
if (supportsAck) {
const interrupts = yield* client.GetInterrupts()
assert.equal(interrupts, 1)
}
}).pipe(
RpcClient.withHeaders({ userId: "123" }),
Effect.provide(layer)
))
it.effect("timing middleware", () =>
Effect.gen(function*() {
const client = yield* UsersClient
const result = yield* client.TimedMethod({ shouldFail: false })
assert.equal(result, 1)
yield* client.TimedMethod({ shouldFail: true }).pipe(Effect.exit)
const { count, defect, success } = yield* client.GetTimingMiddlewareMetrics()
assert.notEqual(count, 0)
assert.notEqual(defect, 0)
assert.notEqual(success, 0)
}).pipe(Effect.provide(layer)))
})
}

View File

@@ -0,0 +1,175 @@
import { Context, Deferred, Effect, Layer, Metric, Option, Queue, Schema } from "effect"
import { Headers } from "effect/unstable/http"
import * as Rpc from "effect/unstable/rpc/Rpc"
import * as RpcGroup from "effect/unstable/rpc/RpcGroup"
import * as RpcMiddleware from "effect/unstable/rpc/RpcMiddleware"
import * as RpcServer from "effect/unstable/rpc/RpcServer"
export class User extends Schema.Class<User>("User")({
id: Schema.String,
name: Schema.String
}) {}
class StreamUsers extends Rpc.make("StreamUsers", {
success: User,
payload: {
id: Schema.String
},
stream: true
}) {}
class CurrentUser extends Context.Service<CurrentUser, User>()("CurrentUser") {}
class Unauthorized extends Schema.ErrorClass<Unauthorized>("Unauthorized")({
_tag: Schema.tag("Unauthorized")
}) {}
class AuthMiddleware extends RpcMiddleware.Service<AuthMiddleware, {
provides: CurrentUser
}>()("AuthMiddleware", {
error: Unauthorized,
requiredForClient: true
}) {}
class TimingMiddleware extends RpcMiddleware.Service<TimingMiddleware>()("TimingMiddleware") {}
class GetUser extends Rpc.make("GetUser", {
success: User,
payload: { id: Schema.String }
}) {}
export const UserRpcs = RpcGroup.make(
GetUser,
Rpc.make("GetUserDeferred", {
success: User,
payload: { id: Schema.String }
}),
Rpc.make("GetUserOption", {
success: Schema.Option(User),
payload: { id: Schema.String }
}),
StreamUsers,
Rpc.make("GetInterrupts", {
success: Schema.Number
}),
Rpc.make("GetEmits", {
success: Schema.Number
}),
Rpc.make("ProduceDefect"),
Rpc.make("ProduceDefectCustom", {
defect: Schema.Defect({ includeStack: true })
}),
Rpc.make("Never"),
Rpc.make("nested.test"),
Rpc.make("TimedMethod", {
payload: {
shouldFail: Schema.Boolean
},
success: Schema.Number
}).middleware(TimingMiddleware),
Rpc.make("GetTimingMiddlewareMetrics", {
success: Schema.Struct({
success: Schema.Number,
defect: Schema.Number,
count: Schema.Number
})
})
).middleware(AuthMiddleware)
export const AuthLive = Layer.succeed(AuthMiddleware)(
AuthMiddleware.of((effect, options) =>
Effect.provideService(
effect,
CurrentUser,
new User({ id: options.headers.userid ?? "1", name: options.headers.name ?? "Fallback name" })
)
)
)
const rpcSuccesses = Metric.counter("rpc_middleware_success")
const rpcDefects = Metric.counter("rpc_middleware_defects")
const rpcCount = Metric.counter("rpc_middleware_count")
export const TimingLive = Layer.succeed(TimingMiddleware)(
TimingMiddleware.of((effect) =>
effect.pipe(
Effect.tap(Metric.update(rpcSuccesses, 1)),
Effect.tapDefect(() => Metric.update(rpcDefects, 1)),
Effect.ensuring(Metric.update(rpcCount, 1))
)
)
)
export const UsersLive = UserRpcs.toLayer(Effect.gen(function*() {
let interrupts = 0
let emits = 0
return UserRpcs.of({
GetUser: (_) =>
CurrentUser.pipe(
Rpc.fork
),
GetUserDeferred(_) {
const deferred = Deferred.makeUnsafe<User>()
Deferred.doneUnsafe(deferred, Effect.succeed(new User({ id: "1", name: "John" })))
return Effect.succeed(deferred)
},
GetUserOption: Effect.fnUntraced(function*(req) {
return Option.some(new User({ id: req.id, name: "John" }))
}),
StreamUsers: Effect.fnUntraced(function*(req, _) {
const mailbox = yield* Queue.bounded<User>(0)
yield* Effect.addFinalizer(() =>
Effect.sync(() => {
interrupts++
})
)
yield* Queue.offer(mailbox, new User({ id: req.id, name: "John" })).pipe(
Effect.tap(() =>
Effect.sync(() => {
emits++
})
),
Effect.delay(100),
Effect.forever,
Effect.forkScoped
)
return mailbox
}),
GetInterrupts: () => Effect.sync(() => interrupts),
GetEmits: () => Effect.sync(() => emits),
ProduceDefect: () => Effect.die("boom"),
ProduceDefectCustom: () =>
Effect.die({
message: "detailed error",
stack: "Error: detailed error\n at handler.ts:1",
name: "CustomDefect"
}),
Never: () => Effect.never.pipe(Effect.onInterrupt(() => Effect.sync(() => interrupts++))),
"nested.test": () => Effect.void,
TimedMethod: (_) => _.shouldFail ? Effect.die("boom") : Effect.succeed(1),
GetTimingMiddlewareMetrics: () =>
Effect.all({
defect: Metric.value(rpcDefects).pipe(Effect.map((_) => _.count)),
success: Metric.value(rpcSuccesses).pipe(Effect.map((_) => _.count)),
count: Metric.value(rpcCount).pipe(Effect.map((_) => _.count))
})
})
}))
export const RpcLive = RpcServer.layer(UserRpcs, {
disableFatalDefects: true
}).pipe(
Layer.provide([
UsersLive,
AuthLive,
TimingLive
])
)
export const AuthClient = RpcMiddleware.layerClient(AuthMiddleware, ({ next, request }) =>
next({
...request,
headers: Headers.set(request.headers, "name", "Logged in user")
}))

View File

@@ -0,0 +1 @@
lorem ipsum dolar sit amet