Skip to content

Instantly share code, notes, and snippets.

@cowboyd
cowboyd / heartbeat.ts
Last active November 7, 2023 17:12
Run an operation on a heartbeat, only one operation at a time
import {
call,
createSignal,
each,
type Operation,
spawn,
type Stream,
suspend,
} from "effection";
@cowboyd
cowboyd / buffer.ts
Created November 3, 2023 15:31
A combinator to buffer any stream
import { type Stream, createQueue, spawn } from "effection";
/*/
* @example
* let clicks: Stream<MousEvent> = pipe(on(button, 'click'), buffer(100));
*/
export function buffer<T, TClose>(limit: number): (stream: Stream<T, TClose>) => Stream<T, TClose> {
return function(stream) {
return {
@cowboyd
cowboyd / match-signal.ts
Created November 1, 2023 19:56
Cheat to win by setting a match context that avoids invoking the continuation
import {
createContext,
type Queue,
resource,
type Signal,
type Stream,
} from "https://deno.land/x/effection@3.0.0-beta.0/mod.ts";
type Predicate = (value: unknown) => boolean;
@cowboyd
cowboyd / use-websocket.ts
Created October 31, 2023 15:35
Effection WebSocket Resource
import { type Stream, type Operation, action, each, once, resource, spawn, createChannel, createSignal } from "effection";
export interface WebSocketHandle extends Stream<MessageEvent, CloseEvent> {
send(value: string): Operation<void>;
close(code?: number, reason?: string): Operation<void>;
}
export function useWebSocket(url: string | URL, protocols?: string | string[]) {
return resource<WebSocketHandle>(function*(provide) {
let input = createChannel<string, {code?: number; reason?: string}>();
@cowboyd
cowboyd / product-search.hbs
Last active October 30, 2023 17:30 — forked from nelstrom/product-search.hbs
Messing around with Effection. Trying to create a scope, which is torn down with the component. And trying to run a task in that scope in response to user interaction.
<div>
<h1>Product search</h1>
<input {{on 'input' this.doSearch}} value={{this.query}} />
</div>
@cowboyd
cowboyd / heartbeat.ts
Last active October 27, 2023 13:51
An Effection operation that takes any operation and runs it periodically on a heart beat
import { action, spawn, sleep, type Operation } from "effection";
export function* heartbeat(duration: number, op: () => Operation<unknown>): Operation<void> {
while (true) {
// this action captures a return point.
yield* action(function* (restart) {
// wait for the duration and return to the next loop iteration
yield* spawn(function*() {
yield* sleep(duration);
@cowboyd
cowboyd / use-resource.ts
Last active October 10, 2023 20:49
useResource hook to use Effection v3 resource.
import { run, type Operation } from "effection";
import { useEffect, useState, type DependencyList } from "react";
export type ResourceHandle<T> = {
type: 'pending';
} | {
type: 'resolved';
value: T;
} | {
type: 'rejected';
@cowboyd
cowboyd / event.ts
Last active September 19, 2023 14:35
Simple Event Notification using Delimited Continuations
import { type Computation, shift, reset } from "../deps.ts";
import { type Resolve } from "../types.ts";
export function* creatEvent<T>(): Computation<[Resolve<T>, Computation<T>]> {
let result: { value: T } | void = void 0;
let listeners: Resolve<T>[] = [];
let resolve = yield* reset<Resolve<T>>(function*() {
let value = yield* shift<T>(function*(k) {
return k.tail;
@cowboyd
cowboyd / 01-sleep.mjs
Last active September 19, 2023 11:07
Austin JS Structured Concurrency Talk, code samples
async function sleep(duration) {
await new Promise(resolve => setTimeout(resolve, duration));
}
async function main() {
await sleep(1000);
}
await main();
@cowboyd
cowboyd / benchmark.ts
Created September 18, 2023 19:41
Benchmark Effection memory pressure
import { each, main, sleep, spawn, createSignal } from "./mod.ts";
await main(function*() {
let perf = globalThis.performance;
let signal = createSignal<string>();
for (let i = 0; i < 1000; i ++) {
yield* spawn(function*() {