Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/sandromaglione/effect-getting-started

Example apps to get started using all the features of effect: Context, Layer, Runtime, Scope and more 🪄
https://github.com/sandromaglione/effect-getting-started

effect effect-ts functional-programming

Last synced: about 11 hours ago
JSON representation

Example apps to get started using all the features of effect: Context, Layer, Runtime, Scope and more 🪄

Awesome Lists containing this project

README

        

# How to `effect`



GitHub: SandroMaglione


Twitter: SandroMaglione

***

This project is part of my weekly newsletter at [**sandromaglione.com**](https://www.sandromaglione.com/newsletter?ref=Github&utm_medium=newsletter_project&utm_term=xstate&utm_term=effect).


sandromaglione.com Newsletter weekly project

## Project structure
This is a collection of examples of how to use [`effect`](https://github.com/Effect-TS/effect).

This is a **deep** dive exploration of the features and *internals* offered by `effect`.

## How to use
Install:

```bash
pnpm install
```

Then you can run each script (take a look at `package.json` for the list of all the scripts you can run):

```bash
pnpm run index
```

> **Note**: The convention is that files that start with a lowercase letter are runnable scripts

Take a look also at [`test`](/test/).

***

## Notes

### Base64
No need to install extra libraries like `js-base64`. The `Encoding` module provides encoding/decoding of base64.

### `Context` (`Tag`)
Inside [`GlobalValue`](https://github.com/Effect-TS/effect/blob/main/packages/effect/src/GlobalValue.ts#L17) Effect stores a `globalStore` of type `Map`.

Inside this store the `Context` module registers a [`tagRegistry`](https://github.com/Effect-TS/effect/blob/14e4393ebe3ba2635c73297bf7cd6750c883e669/packages/effect/src/internal/context.ts#L59):

```ts
const tagRegistry = globalValue("effect/Context/Tag/tagRegistry", () => new Map>())
```

Inside this registry Effect collects all `Tag`s, created using `Context.Tag` by calling the *internal* [`makeTag`](https://github.com/Effect-TS/effect/blob/14e4393ebe3ba2635c73297bf7cd6750c883e669/packages/effect/src/internal/context.ts#L62).

> [!Note]
> When you pass an `identifier` to `Context.Tag` you specify a key for the `tagRegistry`. Effect [checks the registry](https://github.com/Effect-TS/effect/blob/14e4393ebe3ba2635c73297bf7cd6750c883e669/packages/effect/src/internal/context.ts#L63-L65) when accessing and creating a new tag.

A `Tag` is an instance of [`Pipeable`](https://github.com/Effect-TS/effect/blob/main/packages/effect/src/Pipeable.ts#L9). This allows to chain `.pipe` to an instance of `Tag` to extract the methods of a service:

```ts
interface Base64Service {
readonly decode: (
source: string
) => Effect.Effect;
}

export const Base64Service = Context.Tag("@app/Base64Service");

/** Use `pipe` to extract the methods from the service 👆 */
const result = Base64.Base64Service.pipe(
Effect.flatMap((base64) => base64.decode("Zm9vYmFy")),
Effect.provide(Base64.Base64ServiceLive), // 👈 Then provide a valid instance
Effect.runSync
);
```

`Tag` (`Context`) is also a valid [instance of `Effect`](https://github.com/Effect-TS/effect/blob/14e4393ebe3ba2635c73297bf7cd6750c883e669/packages/effect/src/Effect.ts#L150-L157). This allows to use methods such as `flatMap`.

### `ContextProto`
An instance of `Context` is created by copying a [context prototype](https://github.com/Effect-TS/effect/blob/14e4393ebe3ba2635c73297bf7cd6750c883e669/packages/effect/src/internal/context.ts#L87-L122) (using [`Object.create`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create) inside the *internal* [`makeContext`](https://github.com/Effect-TS/effect/blob/14e4393ebe3ba2635c73297bf7cd6750c883e669/packages/effect/src/internal/context.ts#L125-L129))

### `Iterable`
The [Iteration protocols](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols) define an `Iterable` interface:

```ts
interface Iterator {
next(...args: [] | [TNext]): IteratorResult;
return?(value?: TReturn): IteratorResult;
throw?(e?: any): IteratorResult;
}

interface Iterable {
[Symbol.iterator](): Iterator;
}
```

The `Effect` type [defines an iterator](https://github.com/Effect-TS/effect/blob/14e4393ebe3ba2635c73297bf7cd6750c883e669/packages/effect/src/Effect.ts#L1123). This allows to use `yield*` in `Effect.gen` ([`EffectGen`](https://github.com/Effect-TS/effect/blob/14e4393ebe3ba2635c73297bf7cd6750c883e669/packages/effect/src/internal/core-effect.ts#L778-L784) and [`SingleShotGen`](https://github.com/Effect-TS/effect/blob/14e4393ebe3ba2635c73297bf7cd6750c883e669/packages/effect/src/Utils.ts#L102-L146)).

This is also used by Effect to define methods such as [`map`](https://github.com/Effect-TS/effect/blob/14e4393ebe3ba2635c73297bf7cd6750c883e669/packages/effect/src/internal/Iterable.ts#L43-L54).