Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement Effect.Service and allow multiple layers to be provided in Effect.provide #3690

Merged
merged 32 commits into from
Oct 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
4bc3c78
Implement Effect.Service as a Tag and Layer with Opaque Type and Supp…
mikearnaldi Sep 26, 2024
d8244be
add proxy option
mikearnaldi Sep 26, 2024
83ed442
default proxy to false
mikearnaldi Sep 26, 2024
1d9aa4c
fix type extractor
mikearnaldi Sep 26, 2024
fea183a
fix again
mikearnaldi Sep 26, 2024
aca1e33
allow _tag to be used
mikearnaldi Sep 26, 2024
69b2cf4
avoid extending Tag.of
mikearnaldi Sep 26, 2024
6f2ef83
play with Effect.Service
tim-smart Sep 27, 2024
b398cc9
wip
tim-smart Sep 28, 2024
540f5e4
use opaque type and rename layers
tim-smart Sep 29, 2024
218dc3b
fix prototypes
tim-smart Sep 29, 2024
1656104
improve _tag validation
tim-smart Sep 29, 2024
8d93927
support values with custom prototype
tim-smart Sep 30, 2024
42ac51c
patrick
tim-smart Sep 30, 2024
bd02dcd
prototypes
tim-smart Sep 30, 2024
41429df
prevent extraneous keys
tim-smart Oct 1, 2024
7221867
NoExcessProperties
tim-smart Oct 1, 2024
3a46ebe
remove ProhibitedType from autocomplete
tim-smart Oct 1, 2024
87662ea
various fixes
mikearnaldi Oct 1, 2024
13661da
trick lsp to improve auto-complete
mikearnaldi Oct 1, 2024
73800f3
add failing test
patroza Oct 2, 2024
8fd805d
flag as methods as they require this access
patroza Oct 2, 2024
51f4e62
fix scoped
patroza Oct 2, 2024
9482b66
ensure make is a function not a method
mikearnaldi Oct 2, 2024
b7efe5e
make phantom a symbol to avoid showing in candidates when typing p
mikearnaldi Oct 2, 2024
7255ad3
fix auto-complete on typing
mikearnaldi Oct 3, 2024
a7387ba
remove tag as layer, use Default
mikearnaldi Oct 3, 2024
69216c7
fix changeset
mikearnaldi Oct 3, 2024
d017deb
fix changeset
patroza Oct 3, 2024
d6c2012
fix prohibited list
mikearnaldi Oct 3, 2024
3af7f31
replace phantom with brand
mikearnaldi Oct 4, 2024
9ce2e30
use utf-8 character instead of symbol
mikearnaldi Oct 6, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/old-ways-accept.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"effect": minor
---

Support providing an array of layers via Effect.provide and Layer.provide
53 changes: 53 additions & 0 deletions .changeset/twelve-dots-enjoy.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
---
"effect": minor
---

Implement Effect.Service as a Tag and Layer with Opaque Type.

Namely the following is now possible:

```ts
class Prefix extends Effect.Service<Prefix>()("Prefix", {
sync: () => ({
prefix: "PRE"
})
}) {}

class Postfix extends Effect.Service<Postfix>()("Postfix", {
sync: () => ({
postfix: "POST"
})
}) {}

const messages: Array<string> = []

class Logger extends Effect.Service<Logger>()("Logger", {
accessors: true,
effect: Effect.gen(function* () {
const { prefix } = yield* Prefix
const { postfix } = yield* Postfix
return {
info: (message: string) =>
Effect.sync(() => {
messages.push(`[${prefix}][${message}][${postfix}]`)
})
}
}),
dependencies: [Prefix.Default, Postfix.Default]
}) {}

describe("Effect", () => {
it.effect("Service correctly wires dependencies", () =>
Effect.gen(function* () {
const { _tag } = yield* Logger
expect(_tag).toEqual("Logger")
yield* Logger.info("Ok")
expect(messages).toEqual(["[PRE][Ok][POST]"])
const { prefix } = yield* Prefix
expect(prefix).toEqual("PRE")
const { postfix } = yield* Postfix
expect(postfix).toEqual("POST")
}).pipe(Effect.provide([Logger.Default, Prefix.Default, Postfix.Default]))
)
})
```
5 changes: 2 additions & 3 deletions packages/effect/src/Context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ export type TagTypeId = typeof TagTypeId
* @category models
*/
export interface Tag<in out Id, in out Value> extends Pipeable, Inspectable {
readonly _tag: "Tag"
readonly _op: "Tag"
readonly Service: Value
readonly Identifier: Id
Expand Down Expand Up @@ -85,13 +84,13 @@ export declare namespace Tag {
/**
* @since 2.0.0
*/
export type Service<T extends Tag<any, any> | TagClassShape<any, any>> = T extends Tag<any, infer A> ? A
export type Service<T extends Tag<any, any> | TagClassShape<any, any>> = T extends Tag<any, any> ? T["Service"]
: T extends TagClassShape<any, infer A> ? A
: never
/**
* @since 2.0.0
*/
export type Identifier<T extends Tag<any, any> | TagClassShape<any, any>> = T extends Tag<infer A, any> ? A
export type Identifier<T extends Tag<any, any> | TagClassShape<any, any>> = T extends Tag<any, any> ? T["Identifier"]
: T extends TagClassShape<any, any> ? T
: never
}
Expand Down
Loading