### Stream.onStart Example Source: https://github.com/tim-smart/effect-io-ai/blob/main/effect/Stream-onStart.md Demonstrates how to use Stream.onStart to execute an effect when a stream begins. The example shows logging a message at the start of the stream processing. ```typescript import { Console, Effect, Stream } from "effect" const stream = Stream.make(1, 2, 3).pipe( Stream.onStart(Console.log("Stream started")), Stream.map((n) => n * 2), Stream.tap((n) => Console.log(`after mapping: ${n}`)) ) Effect.runPromise(Stream.runCollect(stream)).then(console.log) // Stream started // after mapping: 2 // after mapping: 4 // after mapping: 6 // { _id: 'Chunk', values: [ 2, 4, 6 ] } ``` -------------------------------- ### Effect.provide Example Source: https://github.com/tim-smart/effect-io-ai/blob/main/effect/Effect-provide.md Demonstrates how to use `Effect.provide` to supply a `DatabaseLive` layer to a program that queries a database. The example shows the setup of a `Database` service and its live implementation, followed by running the program. ```typescript import { Context, Effect, Layer } from "effect" class Database extends Context.Tag("Database")< Database, { readonly query: (sql: string) => Effect.Effect> } >() {} const DatabaseLive = Layer.succeed( Database, { // Simulate a database query query: (sql: string) => Effect.log(`Executing query: ${sql}`).pipe(Effect.as([])) } ) // ┌─── Effect // ▼ const program = Effect.gen(function*() { const database = yield* Database const result = yield* database.query("SELECT * FROM users") return result }) // ┌─── Effect // ▼ const runnable = Effect.provide(program, DatabaseLive) Effect.runPromise(runnable).then(console.log) // Output: // timestamp=... level=INFO fiber=#0 message="Executing query: SELECT * FROM users" // [] ``` -------------------------------- ### NodeHttpServer layerTest Example Source: https://github.com/tim-smart/effect-io-ai/blob/main/effect/NodeHttpServer-layerTest.md Demonstrates how to use NodeHttpServer.layerTest to start an HTTP server for testing. It sets up a server, makes a request to it, and asserts the response status. ```typescript import * as assert from "node:assert" import { HttpClient, HttpRouter, HttpServer } from "@effect/platform" import { NodeHttpServer } from "@effect/platform-node" import { Effect } from "effect" Effect.gen(function*() { yield* HttpServer.serveEffect(HttpRouter.empty) const response = yield* HttpClient.get("/") assert.strictEqual(response.status, 404) }).pipe(Effect.provide(NodeHttpServer.layerTest)) ``` -------------------------------- ### Stream.take Example Source: https://github.com/tim-smart/effect-io-ai/blob/main/effect/Stream-take.md Demonstrates how to use Stream.take to get the first 5 elements from an infinite stream of numbers. ```typescript import { Effect, Stream } from "effect" const stream = Stream.take(Stream.iterate(0, (n) => n + 1), 5) Effect.runPromise(Stream.runCollect(stream)).then(console.log) // { _id: 'Chunk', values: [ 0, 1, 2, 3, 4 ] } ``` -------------------------------- ### Create and Use RcMap Source: https://github.com/tim-smart/effect-io-ai/blob/main/effect/RcMap-make.md Demonstrates how to create an RcMap and manage reference-counted resources. Resources are acquired on the first 'get' call and released when the scope closes. This example shows acquiring the same resource twice, resulting in a single acquisition. ```ts import { Effect, RcMap } from "effect" Effect.gen(function*() { const map = yield* RcMap.make({ lookup: (key: string) => Effect.acquireRelease( Effect.succeed(`acquired ${key}`), () => Effect.log(`releasing ${key}`) ) }) // Get "foo" from the map twice, which will only acquire it once. // It will then be released once the scope closes. yield* RcMap.get(map, "foo").pipe( Effect.andThen(RcMap.get(map, "foo")), Effect.scoped ) }) ``` -------------------------------- ### Stream.tap Example Source: https://github.com/tim-smart/effect-io-ai/blob/main/effect/Stream-tap.md Demonstrates how to use Stream.tap to add logging effects before and after mapping elements in a stream. The example shows the stream processing and the final collected output. ```ts import { Console, Effect, Stream } from "effect" const stream = Stream.make(1, 2, 3).pipe( Stream.tap((n) => Console.log(`before mapping: ${n}`)), Stream.map((n) => n * 2), Stream.tap((n) => Console.log(`after mapping: ${n}`)) ) Effect.runPromise(Stream.runCollect(stream)).then(console.log) // before mapping: 1 // after mapping: 2 // before mapping: 2 // after mapping: 4 // before mapping: 3 // after mapping: 6 // { _id: 'Chunk', values: [ 2, 4, 6 ] } ``` -------------------------------- ### Effect.using Example Source: https://github.com/tim-smart/effect-io-ai/blob/main/effect/Effect-using.md Demonstrates how to use `Effect.using` to scope resource acquisition and release to the lifetime of another effect. The example shows acquiring a resource, using it, and ensuring its release upon completion. ```ts import { Console, Effect } from "effect" const acquire = Console.log("Acquiring resource").pipe( Effect.as(1), Effect.tap(Effect.addFinalizer(() => Console.log("Releasing resource"))) ) const use = (resource: number) => Console.log(`Using resource: ${resource}`) const program = acquire.pipe(Effect.using(use)) Effect.runFork(program) // Output: // Acquiring resource // Using resource: 1 // Releasing resource ``` -------------------------------- ### Get Earliest Interval Start Time Source: https://github.com/tim-smart/effect-io-ai/blob/main/effect/ScheduleIntervals-start.md Retrieves the starting timestamp of the earliest interval from a collection of intervals. This function is part of the ScheduleIntervals module in the Effect-TS library. ```ts declare const start: (self: Intervals) => number ``` -------------------------------- ### Trie.keysWithPrefix Example Source: https://github.com/tim-smart/effect-io-ai/blob/main/effect/Trie-keysWithPrefix.md Demonstrates how to use Trie.keysWithPrefix to find all keys in a Trie that start with a specific prefix. It initializes a Trie with several string-number pairs and then retrieves keys starting with 'she'. ```ts import * as assert from "node:assert" import { Trie } from "effect" const trie = Trie.empty().pipe( Trie.insert("she", 0), Trie.insert("shells", 1), Trie.insert("sea", 2), Trie.insert("shore", 3) ) const result = Array.from(Trie.keysWithPrefix(trie, "she")) assert.deepStrictEqual(result, ["she", "shells"]) ``` -------------------------------- ### Effect.acquireRelease Example Source: https://github.com/tim-smart/effect-io-ai/blob/main/effect/Effect-acquireRelease.md Demonstrates how to use Effect.acquireRelease to manage a resource, including acquisition and release logic, with proper error handling. ```ts import { Effect, Exit } from "effect" // Define an interface for a resource interface MyResource { readonly contents: string readonly close: () => Promise } // Simulate resource acquisition const getMyResource = (): Promise => Promise.resolve({ contents: "lorem ipsum", close: () => new Promise((resolve) => { console.log("Resource released") resolve() }) }) // Define how the resource is acquired const acquire = Effect.tryPromise({ try: () => getMyResource().then((res) => { console.log("Resource acquired") return res }), catch: () => new Error("getMyResourceError") }) // Define how the resource is released const release = (res: MyResource) => Effect.promise(() => res.close()) // Create the resource management workflow // // ┌─── Effect // ▼ const resource = Effect.acquireRelease(acquire, release) ``` -------------------------------- ### Doc.column Example Usage Source: https://github.com/tim-smart/effect-io-ai/blob/main/effect/Doc-column.md Demonstrates how to use Doc.column to create documents whose layout depends on the starting column. It includes examples of horizontal and vertical spacing, and indentation. ```ts import * as assert from "node:assert" import * as Doc from "@effect/printer/Doc" import * as String from "effect/String" // Example 1: const example1 = Doc.column((l) => Doc.hsep([Doc.text("Columns are"), Doc.text(`${l}-based`)]) ) assert.strictEqual( Doc.render(example1, { style: "pretty" }), "Columns are 0-based" ) // Example 2: const doc = Doc.hsep([ Doc.text("prefix"), Doc.column((l) => Doc.text(`| <- column ${l}`)) ]) const example2 = Doc.vsep([0, 4, 8].map((n) => Doc.indent(n)(doc))) assert.strictEqual( Doc.render(example2, { style: "pretty" }), String.stripMargin( `|prefix | <- column 7 | prefix | <- column 11 | prefix | <- column 15` ) ) ``` -------------------------------- ### Effect.acquireUseRelease Example Source: https://github.com/tim-smart/effect-io-ai/blob/main/effect/Effect-acquireUseRelease.md Demonstrates how to use Effect.acquireUseRelease to manage a resource's lifecycle, ensuring acquisition, usage, and guaranteed release. ```typescript import { Effect, Console } from "effect" // Define an interface for a resource interface MyResource { readonly contents: string readonly close: () => Promise } // Simulate resource acquisition const getMyResource = (): Promise => Promise.resolve({ contents: "lorem ipsum", close: () => new Promise((resolve) => { console.log("Resource released") resolve() }) }) // Define how the resource is acquired const acquire = Effect.tryPromise({ try: () => getMyResource().then((res) => { console.log("Resource acquired") return res }), catch: () => new Error("getMyResourceError") }) // Define how the resource is released const release = (res: MyResource) => Effect.promise(() => res.close()) const use = (res: MyResource) => Console.log(`content is ${res.contents}`) // ┌─── Effect // ▼ const program = Effect.acquireUseRelease(acquire, use, release) Effect.runPromise(program) // Output: // Resource acquired // content is lorem ipsum // Resource released ``` -------------------------------- ### Effect Option Do Simulation Example Source: https://github.com/tim-smart/effect-io-ai/blob/main/effect/Option-bindTo.md Demonstrates the 'do simulation' pattern in Effect's Option module, showing how to use bind and let to declare variables and perform operations declaratively. It includes binding Option values, defining simple variables, and filtering based on accumulated values. ```ts import * as assert from "node:assert" import { Option, pipe } from "effect" const result = pipe( Option.Do, Option.bind("x", () => Option.some(2)), Option.bind("y", () => Option.some(3)), Option.let("sum", ({ x, y }) => x + y), Option.filter(({ x, y }) => x * y > 5) ) assert.deepStrictEqual(result, Option.some({ x: 2, y: 3, sum: 5 })) ``` -------------------------------- ### Stream.takeRight Example Source: https://github.com/tim-smart/effect-io-ai/blob/main/effect/Stream-takeRight.md Demonstrates how to use Stream.takeRight to get the last 3 elements from a stream of numbers. The example imports necessary components from 'effect' and uses Effect.runPromise to collect and log the result. ```typescript import { Effect, Stream } from "effect" const stream = Stream.takeRight(Stream.make(1, 2, 3, 4, 5, 6), 3) Effect.runPromise(Stream.runCollect(stream)).then(console.log) // { _id: 'Chunk', values: [ 4, 5, 6 ] } ``` -------------------------------- ### Create and Use an ExecutionPlan Source: https://github.com/tim-smart/effect-io-ai/blob/main/effect/ExecutionPlan-ExecutionPlan.md Demonstrates how to create an ExecutionPlan with multiple resource provision steps, each with its own retry attempts and schedules. It also shows how to apply this plan to an Effect computation using `Effect.withExecutionPlan`. ```ts import { type AiLanguageModel } from "@effect/ai" import type { Layer } from "effect" import { Effect, ExecutionPlan, Schedule } from "effect" declare const layerBad: Layer.Layer declare const layerGood: Layer.Layer const ThePlan = ExecutionPlan.make( { // First try with the bad layer 2 times with a 3 second delay between attempts provide: layerBad, attempts: 2, schedule: Schedule.spaced(3000) }, // Then try with the bad layer 3 times with a 1 second delay between attempts { provide: layerBad, attempts: 3, schedule: Schedule.spaced(1000) }, // Finally try with the good layer. // // If `attempts` is omitted, the plan will only attempt once, unless a schedule is provided. { provide: layerGood } ) declare const effect: Effect.Effect< void, never, AiLanguageModel.AiLanguageModel > const withPlan: Effect.Effect = Effect.withExecutionPlan(effect, ThePlan) ``` -------------------------------- ### McpServer.layerHttp Implementation Example Source: https://github.com/tim-smart/effect-io-ai/blob/main/effect/McpServer-layerHttp.md This example demonstrates how to use McpServer.layerHttp to set up an HTTP server. It defines a resource template for a README file and a test prompt, then merges them into a server layer. The server is configured with a name, version, and path, and runs on port 3000. ```ts import { McpSchema, McpServer } from "@effect/ai" import { HttpRouter } from "@effect/platform" import { NodeHttpServer, NodeRuntime } from "@effect/platform-node" import { Effect, Layer, Schema } from "effect" import { createServer } from "node:http" const idParam = McpSchema.param("id", Schema.NumberFromString) // Define a resource template for a README file const ReadmeTemplate = McpServer.resource`file://readme/${idParam}`({ name: "README Template", // You can add auto-completion for the ID parameter completion: { id: (_) => Effect.succeed([1, 2, 3, 4, 5]) }, content: Effect.fn(function*(_uri, id) { return `# MCP Server Demo - ID: ${id}` }) }) // Define a test prompt with parameters const TestPrompt = McpServer.prompt({ name: "Test Prompt", description: "A test prompt to demonstrate MCP server capabilities", parameters: Schema.Struct({ flightNumber: Schema.String }), completion: { flightNumber: () => Effect.succeed(["FL123", "FL456", "FL789"]) }, content: ({ flightNumber }) => Effect.succeed(`Get the booking details for flight number: ${flightNumber}`) }) // Merge all the resources and prompts into a single server layer const ServerLayer = Layer.mergeAll( ReadmeTemplate, TestPrompt, HttpRouter.Default.serve() ).pipe( // Provide the MCP server implementation Layer.provide(McpServer.layerHttp({ name: "Demo Server", version: "1.0.0", path: "/mcp" })), Layer.provide(NodeHttpServer.layer(createServer, { port: 3000 })) ) Layer.launch(ServerLayer).pipe(NodeRuntime.runMain) ``` -------------------------------- ### Customize HTTP Span Names Source: https://github.com/tim-smart/effect-io-ai/blob/main/effect/HttpMiddleware-withSpanNameGenerator.md Demonstrates how to use `HttpMiddleware.withSpanNameGenerator` to set custom span names for HTTP requests. This example configures the span name to be 'GET [request URL]' for all incoming GET requests. ```ts import { HttpMiddleware, HttpRouter, HttpServer, HttpServerResponse } from "@effect/platform" import { NodeHttpServer, NodeRuntime } from "@effect/platform-node" import { Layer } from "effect" import { createServer } from "http" HttpRouter.empty.pipe( HttpRouter.get("/", HttpServerResponse.empty()), HttpServer.serve(), // Customize the span names for this HttpApp HttpMiddleware.withSpanNameGenerator((request) => `GET ${request.url}`), Layer.provide(NodeHttpServer.layer(createServer, { port: 3000 })), Layer.launch, NodeRuntime.runMain ) ``` -------------------------------- ### Effect.firstSuccessOf Example Source: https://github.com/tim-smart/effect-io-ai/blob/main/effect/Effect-firstSuccessOf.md Demonstrates how to use `firstSuccessOf` to find a working configuration from multiple sources, prioritizing a master configuration and then falling back to other nodes. ```typescript import { Effect, Console } from "effect" interface Config { host: string port: number apiKey: string } // Create a configuration object with sample values const makeConfig = (name: string): Config => ({ host: `${name}.example.com`, port: 8080, apiKey: "12345-abcde" }) // Simulate retrieving configuration from a remote node const remoteConfig = (name: string): Effect.Effect => Effect.gen(function* () { // Simulate node3 being the only one with available config if (name === "node3") { yield* Console.log(`Config for ${name} found`) return makeConfig(name) } else { yield* Console.log(`Unavailable config for ${name}`) return yield* Effect.fail(new Error(`Config not found for ${name}`)) } }) // Define the master configuration and potential fallback nodes const masterConfig = remoteConfig("master") const nodeConfigs = ["node1", "node2", "node3", "node4"].map(remoteConfig) // Attempt to find a working configuration, // starting with the master and then falling back to other nodes const config = Effect.firstSuccessOf([masterConfig, ...nodeConfigs]) // Run the effect to retrieve the configuration const result = Effect.runSync(config) console.log(result) // Output: // Unavailable config for master // Unavailable config for node1 // Unavailable config for node2 // Config for node3 found // { host: 'node3.example.com', port: 8080, apiKey: '12345-abcde' } ``` -------------------------------- ### Find First Index Where From STM Source: https://github.com/tim-smart/effect-io-ai/blob/main/effect/TArray-findFirstIndexWhereFromSTM.md Starting at a specified index, this function gets the index of the next entry that matches a transactional predicate. It is part of the TArray module and requires a predicate function that returns an STM boolean and a starting index. ```ts declare const findFirstIndexWhereFromSTM: { (predicate: (value: A) => STM.STM, from: number): (self: TArray) => STM.STM, E, R>; (self: TArray, predicate: (value: A) => STM.STM, from: number): STM.STM, E, R>; } // Example Usage: // Assuming `myTArray` is a TArray and `isEvenSTM` is an STM function that returns true if a number is even. // const result = TArray.findFirstIndexWhereFromSTM(myTArray, isEvenSTM, 0); // This would return an STM> representing the index of the first even number found from index 0. ``` -------------------------------- ### Option.lift2 Example Source: https://github.com/tim-smart/effect-io-ai/blob/main/effect/Option-lift2.md Demonstrates how to use Option.lift2 to apply a binary function to two Option values. It shows cases where both options are Some and where one is None. ```ts import { Option } from "effect" // A binary function to add two numbers const add = (a: number, b: number): number => a + b // Lift the `add` function to work with `Option` values const addOptions = Option.lift2(add) // Both `Option`s are `Some` console.log(addOptions(Option.some(2), Option.some(3))) // Output: { _id: 'Option', _tag: 'Some', value: 5 } // One `Option` is `None` console.log(addOptions(Option.some(2), Option.none())) // Output: { _id: 'Option', _tag: 'None' } ``` -------------------------------- ### Match.value Example Source: https://github.com/tim-smart/effect-io-ai/blob/main/effect/Match-value.md Demonstrates how to create a matcher from a specific object value and use it for pattern matching based on object properties. It includes matching a user by name and providing a fallback. ```ts import { Match } from "effect" const input = { name: "John", age: 30 } // Create a matcher for the specific object const result = Match.value(input).pipe( // Match when the 'name' property is "John" Match.when( { name: "John" }, (user) => `${user.name} is ${user.age} years old` ), // Provide a fallback if no match is found Match.orElse(() => "Oh, not John") ) console.log(result) // Output: "John is 30 years old" ``` -------------------------------- ### Effect.head Example Source: https://github.com/tim-smart/effect-io-ai/blob/main/effect/Effect-head.md Demonstrates how to use Effect.head to get the first element from an iterable within an Effect. Handles potential empty collections. ```typescript import { Effect } from "effect" // Simulate an async operation const fetchNumbers = Effect.succeed([1, 2, 3]).pipe(Effect.delay("100 millis")) const program = Effect.gen(function*() { const firstElement = yield* Effect.head(fetchNumbers) console.log(firstElement) }) Effect.runFork(program) // Output: 1 ``` -------------------------------- ### Create Execution Plan with Multiple Steps Source: https://github.com/tim-smart/effect-io-ai/blob/main/effect/ExecutionPlan-make.md Demonstrates how to create an ExecutionPlan using `ExecutionPlan.make`. This plan defines a sequence of resource provision attempts, each with its own retry count and schedule. It first tries a 'bad' layer twice with a 3-second delay, then the 'bad' layer three times with a 1-second delay, and finally a 'good' layer once. ```ts import { type AiLanguageModel } from "@effect/ai" import type { Layer } from "effect" import { Effect, ExecutionPlan, Schedule } from "effect" declare const layerBad: Layer.Layer declare const layerGood: Layer.Layer const ThePlan = ExecutionPlan.make( { // First try with the bad layer 2 times with a 3 second delay between attempts provide: layerBad, attempts: 2, schedule: Schedule.spaced(3000) }, // Then try with the bad layer 3 times with a 1 second delay between attempts { provide: layerBad, attempts: 3, schedule: Schedule.scaled(1000) }, // Finally try with the good layer. // // If `attempts` is omitted, the plan will only attempt once, unless a schedule is provided. { provide: layerGood } ) declare const effect: Effect.Effect< void, never, AiLanguageModel.AiLanguageModel > const withPlan: Effect.Effect = Effect.withExecutionPlan(effect, ThePlan) ``` -------------------------------- ### Match.tagStartsWith Example Source: https://github.com/tim-smart/effect-io-ai/blob/main/effect/Match-tagStartsWith.md Demonstrates how to use Match.tagStartsWith to match values where the '_tag' field starts with a given prefix. This is useful for handling hierarchical or namespaced tags. ```ts import { Match, pipe } from "effect" const match = pipe( Match.type<{ _tag: "A" } | { _tag: "B" } | { _tag: "A.A" } | {}>(), Match.tagStartsWith("A", (_) => 1 as const), Match.tagStartsWith("B", (_) => 2 as const), Match.orElse((_) => 3 as const) ) console.log(match({ _tag: "A" })) // 1 console.log(match({ _tag: "B" })) // 2 console.log(match({ _tag: "A.A" })) // 1 ``` -------------------------------- ### Effect Either.Do Simulation Example Source: https://github.com/tim-smart/effect-io-ai/blob/main/effect/Either-Do.md Demonstrates the declarative style of Either.Do using bind and let functions to define variables and perform operations within a scope. It shows how to bind Either values and simple values, accumulating results. ```ts import * as assert from "node:assert" import { Either, pipe } from "effect" const result = pipe( Either.Do, Either.bind("x", () => Either.right(2)), Either.bind("y", () => Either.right(3)), Either.let("sum", ({ x, y }) => x + y) ) assert.deepStrictEqual(result, Either.right({ x: 2, y: 3, sum: 5 })) ``` -------------------------------- ### Effect.makeLatch Example Source: https://github.com/tim-smart/effect-io-ai/blob/main/effect/Effect-makeLatch.md Demonstrates creating a Latch and using it to control the execution of another fiber. The latch starts closed and is opened after a delay, allowing the forked fiber to proceed. ```ts import { Console, Effect } from "effect" const program = Effect.gen(function*() { // Create a latch, starting in the closed state const latch = yield* Effect.makeLatch(false) // Fork a fiber that logs "open sesame" when the latch is opened const fiber = yield* Console.log("open sesame").pipe( latch.whenOpen, Effect.fork ) yield* Effect.sleep("1 second") // Open the latch yield* latch.open yield* fiber.await }) Effect.runFork(program) // Output: open sesame (after 1 second) ``` -------------------------------- ### Stream Buffer Example Source: https://github.com/tim-smart/effect-io-ai/blob/main/effect/Stream-buffer.md Demonstrates how to use the Stream.buffer combinator to manage a faster producer with a slower consumer. It includes logging before and after buffering and applies a spaced schedule. ```ts import { Console, Effect, Schedule, Stream } from "effect" const stream = Stream.range(1, 10).pipe( Stream.tap((n) => Console.log(`before buffering: ${n}`)), Stream.buffer({ capacity: 4 }), Stream.tap((n) => Console.log(`after buffering: ${n}`)), Stream.schedule(Schedule.spaced("5 seconds")) ) Effect.runPromise(Stream.runCollect(stream)).then(console.log) ``` -------------------------------- ### Array.scan Example Source: https://github.com/tim-smart/effect-io-ai/blob/main/effect/Array-scan.md Demonstrates how to use Array.scan to accumulate values from an iterable, starting with an initial value and applying a function to each element. The result is an array of intermediate accumulations. ```ts import { Array } from "effect"; const result = Array.scan([1, 2, 3, 4], 0, (acc, value) => acc + value) console.log(result) // [0, 1, 3, 6, 10] ``` -------------------------------- ### Effect.zipRight Example Source: https://github.com/tim-smart/effect-io-ai/blob/main/effect/Effect-zipRight.md Demonstrates how to use Effect.zipRight to execute two tasks sequentially, logging their completion and returning the result of the second task. ```ts import { Effect } from "effect" const task1 = Effect.succeed(1).pipe( Effect.delay("200 millis"), Effect.tap(Effect.log("task1 done")) ) const task2 = Effect.succeed("hello").pipe( Effect.delay("100 millis"), Effect.tap(Effect.log("task2 done")) ) const program = Effect.zipRight(task1, task2) Effect.runPromise(program).then(console.log) // Output: // timestamp=... level=INFO fiber=#0 message="task1 done" // timestamp=... level=INFO fiber=#0 message="task2 done" // hello ``` -------------------------------- ### Effect.clockWith Usage Example Source: https://github.com/tim-smart/effect-io-ai/blob/main/effect/Effect-clockWith.md Demonstrates how to use `Effect.clockWith` to get the current time in milliseconds and log it to the console. This function requires the `Effect` and `Console` modules from the 'effect' package. ```ts import { Console, Effect } from "effect" const program = Effect.clockWith((clock) => clock.currentTimeMillis.pipe( Effect.map((currentTime) => `Current time is: ${currentTime}`), Effect.tap(Console.log) ) ) Effect.runFork(program) ``` -------------------------------- ### Context.mergeAll Example Source: https://github.com/tim-smart/effect-io-ai/blob/main/effect/Context-mergeAll.md Demonstrates how to use Context.mergeAll to combine multiple contexts, each providing different services (Port, Timeout, Host), into a single context from which these services can be retrieved. ```ts import * as assert from "node:assert" import { Context } from "effect" const Port = Context.GenericTag<{ PORT: number }>( "Port" ) const Timeout = Context.GenericTag<{ TIMEOUT: number }>( "Timeout" ) const Host = Context.GenericTag<{ HOST: string }>( "Host" ) const firstContext = Context.make(Port, { PORT: 8080 }) const secondContext = Context.make(Timeout, { TIMEOUT: 5000 }) const thirdContext = Context.make(Host, { HOST: "localhost" }) const Services = Context.mergeAll(firstContext, secondContext, thirdContext) assert.deepStrictEqual(Context.get(Services, Port), { PORT: 8080 }) assert.deepStrictEqual(Context.get(Services, Timeout), { TIMEOUT: 5000 }) assert.deepStrictEqual(Context.get(Services, Host), { HOST: "localhost" }) ``` -------------------------------- ### Trie.removeMany Example Source: https://github.com/tim-smart/effect-io-ai/blob/main/effect/Trie-removeMany.md Demonstrates how to use Trie.removeMany to remove multiple keys from a Trie. It shows the setup of a Trie with sample data and asserts the correctness of the removal operation. ```ts import * as assert from "node:assert" import { Trie, Equal } from "effect" const trie = Trie.empty().pipe( Trie.insert("shells", 0), Trie.insert("sells", 1), Trie.insert("she", 2) ) assert.equal( Equal.equals(trie.pipe(Trie.removeMany(["she", "sells"])), Trie.empty().pipe(Trie.insert("shells", 0))), true ) ``` -------------------------------- ### Trie.entriesWithPrefix Example Source: https://github.com/tim-smart/effect-io-ai/blob/main/effect/Trie-entriesWithPrefix.md Demonstrates how to use Trie.entriesWithPrefix to find entries starting with 'she'. It inserts several key-value pairs into a Trie and then retrieves and asserts the entries that match the prefix. ```typescript import * as assert from "node:assert" import { Trie } from "effect" const trie = Trie.empty().pipe( Trie.insert("she", 0), Trie.insert("shells", 1), Trie.insert("sea", 2), Trie.insert("shore", 3) ) const result = Array.from(Trie.entriesWithPrefix(trie, "she")) assert.deepStrictEqual(result, [["she", 0], ["shells", 1]]) ``` -------------------------------- ### HashSet.partition with Refinement Example Source: https://github.com/tim-smart/effect-io-ai/blob/main/effect/HashSet-partition.md Illustrates using HashSet.partition with a refinement type to partition elements into sets of specific types (e.g., strings and numbers). Supports both pipeable and data-first API styles. ```ts import { HashSet, pipe, Predicate } from "effect" const stringRefinement: Predicate.Refinement = ( value ) => typeof value === "string" // with `data-last`, a.k.a. `pipeable` API pipe( HashSet.make(1, "unos", 2, "two", 3, "trois", 4, "vier"), HashSet.partition(stringRefinement) ) // or with the pipe method HashSet.make(1, "unos", 2, "two", 3, "trois", 4, "vier").pipe( HashSet.partition(stringRefinement) ) // or with `data-first` API HashSet.partition( HashSet.make(1, "unos", 2, "two", 3, "trois", 4, "vier"), stringRefinement ) ``` -------------------------------- ### Effect.Do Simulation Example Source: https://github.com/tim-smart/effect-io-ai/blob/main/effect/Effect-Do.md Demonstrates the usage of Effect.Do for declarative programming. It shows how to use 'bind' to associate Effect values with variables and 'let' to define simple variables within the simulation scope. ```ts import * as assert from "node:assert" import { Effect, pipe } from "effect" const result = pipe( Effect.Do, Effect.bind("x", () => Effect.succeed(2)), Effect.bind("y", () => Effect.succeed(3)), Effect.let("sum", ({ x, y }) => x + y) ) assert.deepStrictEqual(Effect.runSync(result), { x: 2, y: 3, sum: 5 }) ``` -------------------------------- ### Stream.acquireRelease Example Source: https://github.com/tim-smart/effect-io-ai/blob/main/effect/Stream-acquireRelease.md Demonstrates how to use Stream.acquireRelease to manage a resource (simulated file operations) and consume its data. The resource is acquired before the stream starts and released after it's consumed. ```ts import { Console, Effect, Stream } from "effect" // Simulating File operations const open = (filename: string) => Effect.gen(function*() { yield* Console.log(`Opening ${filename}`) return { getLines: Effect.succeed(["Line 1", "Line 2", "Line 3"]), close: Console.log(`Closing ${filename}`) } }) const stream = Stream.acquireRelease( open("file.txt"), (file) => file.close ).pipe(Stream.flatMap((file) => file.getLines)) Effect.runPromise(Stream.runCollect(stream)).then(console.log) // Opening file.txt // Closing file.txt // { _id: 'Chunk', values: [ [ 'Line 1', 'Line 2', 'Line 3' ] ] } ``` -------------------------------- ### Effect.runSync - Synchronous Logging Example Source: https://github.com/tim-smart/effect-io-ai/blob/main/effect/Effect-runSync.md Demonstrates the correct usage of Effect.runSync with a simple synchronous effect that logs a message and returns a value. ```ts import { Effect } from "effect" const program = Effect.sync(() => { console.log("Hello, World!") return 1 }) const result = Effect.runSync(program) // Output: Hello, World! console.log(result) // Output: 1 ``` -------------------------------- ### DateTime.startOf Usage Example Source: https://github.com/tim-smart/effect-io-ai/blob/main/effect/DateTime-startOf.md Demonstrates how to use the DateTime.startOf function to convert a DateTime to the start of the day and format it as an ISO string. Requires importing the DateTime module from 'effect'. ```ts import { DateTime } from "effect" // returns "2024-01-01T00:00:00Z" DateTime.unsafeMake("2024-01-01T12:00:00Z").pipe( DateTime.startOf("day"), DateTime.formatIso ) ``` -------------------------------- ### Array.scanRight Example Source: https://github.com/tim-smart/effect-io-ai/blob/main/effect/Array-scanRight.md Demonstrates how to use Array.scanRight to accumulate values from an array starting from the right. The function takes an initial accumulator value and a function to combine the accumulator and the current element. ```ts import { Array } from "effect"; const result = Array.scanRight([1, 2, 3, 4], 0, (acc, value) => acc + value) console.log(result) // [10, 9, 7, 4, 0] ``` -------------------------------- ### Effect.allWith Example Source: https://github.com/tim-smart/effect-io-ai/blob/main/effect/Effect-allWith.md Demonstrates how to use Effect.allWith to run two effects concurrently and log their completion. It showcases the data-last approach suitable for pipelines. ```typescript import { Effect, pipe } from "effect" const task1 = Effect.succeed(1).pipe( Effect.delay("200 millis"), Effect.tap(Effect.log("task1 done")) ) const task2 = Effect.succeed("hello").pipe( Effect.delay("100 millis"), Effect.tap(Effect.log("task2 done")) ) const program = pipe( [task1, task2], // Run both effects concurrently using the concurrent option Effect.allWith({ concurrency: 2 }) ) Effect.runPromise(program).then(console.log) // Output: // timestamp=... level=INFO fiber=#3 message="task2 done" // timestamp=... level=INFO fiber=#2 message="task1 done" // [ 1, 'hello' ] ``` -------------------------------- ### Effect.withEarlyRelease Example Source: https://github.com/tim-smart/effect-io-ai/blob/main/effect/Effect-withEarlyRelease.md Demonstrates how to use `withEarlyRelease` to acquire a resource, use it, and then manually release it. It shows acquiring a resource, getting its value and a finalizer, using the value, sleeping, and then executing the finalizer. ```typescript import { Console, Effect } from "effect" const acquire = Console.log("Acquiring resource").pipe( Effect.as(1), Effect.tap(Effect.addFinalizer(() => Console.log("Releasing resource"))) ) const program = Effect.gen(function*() { const [finalizer, resource] = yield* Effect.withEarlyRelease(acquire) console.log(`Using resource: ${resource}`) yield* Effect.sleep("1 second") yield* finalizer }) Effect.runFork(program.pipe(Effect.scoped)) // Output: // Acquiring resource // Using resource: 1 // Releasing resource ``` -------------------------------- ### HashSet Reduce Example Source: https://github.com/tim-smart/effect-io-ai/blob/main/effect/HashSet-reduce.md Demonstrates how to use the HashSet.reduce function with both pipeable (data-last) and data-first APIs. It shows summing elements in a HashSet. ```ts import { HashSet, pipe } from "effect" const sum = (a: number, b: number): number => a + b // with `data-last`, a.k.a. `pipeable` API pipe(HashSet.make(0, 1, 2), HashSet.reduce(0, sum)) // or with the pipe method HashSet.make(0, 1, 2).pipe(HashSet.reduce(0, sum)) // or with `data-first` API HashSet.reduce(HashSet.make(0, 1, 2), 0, sum) ``` -------------------------------- ### Effect.iterate Example Source: https://github.com/tim-smart/effect-io-ai/blob/main/effect/Effect-iterate.md Demonstrates how to use Effect.iterate for effectful iteration. It starts with an initial value, continues iterating as long as the condition (result <= 5) is met, and updates the state by adding 1 in each iteration. ```ts import { Effect } from "effect" const result = Effect.iterate( // Initial result 1, { // Condition to continue iterating while: (result) => result <= 5, // Operation to change the result body: (result) => Effect.succeed(result + 1) } ) Effect.runPromise(result).then(console.log) // Output: 6 ``` -------------------------------- ### Pool.make API Documentation Source: https://github.com/tim-smart/effect-io-ai/blob/main/effect/Pool-make.md Provides detailed API documentation for the 'Pool.make' function. Explains parameters like 'acquire' (the effect to acquire resources), 'size' (the fixed pool size), 'concurrency' (level of concurrent access per item), and 'targetUtilization' (when to create new items). ```APIDOC Pool.make: Creates a new pool of the specified fixed size. The pool is returned in a Scope, which governs its lifetime. Parameters: options: An object containing the pool configuration. acquire: Effect.Effect - The effect to acquire a resource. size: number - The fixed size of the pool. concurrency?: number - The level of concurrent access per pool item (defaults to 1). targetUtilization?: number - A value between 0 and 1 determining when to create new pool items (e.g., 0.5 means create new items when existing items are 50% utilized). Returns: Effect.Effect, never, Scope.Scope | R> - An effect that yields the created pool, managed within a Scope. Example Usage: // Create a pool of 10 database connections const pool = Effect.runSync(Pool.make({ acquire: acquireDatabaseConnection, size: 10, concurrency: 5, targetUtilization: 0.75 })); Related Functions: - Pool.shutdown: Shuts down the pool and releases all acquired resources. ``` -------------------------------- ### Run Effect in Background with Fiber Source: https://github.com/tim-smart/effect-io-ai/blob/main/effect/Effect-runFork.md Demonstrates how to run an Effect in the background using `runFork`. The example shows starting a repeating log effect and then interrupting it after a delay using the returned Fiber. ```ts import { Effect, Console, Schedule, Fiber } from "effect" // ┌─── Effect // ▼ const program = Effect.repeat( Console.log("running..."), Schedule.spaced("200 millis") ) // ┌─── RuntimeFiber // ▼ const fiber = Effect.runFork(program) setTimeout(() => { Effect.runFork(Fiber.interrupt(fiber)) }, 500) ``` -------------------------------- ### Option.Do Simulation Example Source: https://github.com/tim-smart/effect-io-ai/blob/main/effect/Option-Do.md Demonstrates the usage of Option.Do for declarative variable definition and manipulation using bind and let functions within the Effect library. ```ts import * as assert from "node:assert" import { Option, pipe } from "effect" const result = pipe( Option.Do, Option.bind("x", () => Option.some(2)), Option.bind("y", () => Option.some(3)), Option.let("sum", ({ x, y }) => x + y), Option.filter(({ x, y }) => x * y > 5) ) assert.deepStrictEqual(result, Option.some({ x: 2, y: 3, sum: 5 })) ```