Skip to content

Instantly share code, notes, and snippets.

@cowboyd
cowboyd / console.ts
Last active January 9, 2024 14:18
Effection console effect
// deno-lint-ignore-file no-explicit-any
import { createContext, type Operation } from "./mod.ts";
export interface Console {
// Logging
assert(condition?: boolean, ...data: any[]): Operation<void>;
clear(): Operation<void>;
debug(...data: any[]): Operation<void>;
error(...data: any[]): Operation<void>;
@cowboyd
cowboyd / use-restartable.ts
Last active January 6, 2024 02:03
Implement a restartable operation from any operation
import {
createChannel,
each,
Operation,
resource,
spawn,
Task,
} from "effection";
export function useRestartable<TArgs extends unknown[]>(
@cowboyd
cowboyd / get-user.ts
Created December 19, 2023 14:43
Operations resolve whenever they are ready to continue be it synchronously or asynchronously
import { call } from "effection";
function* getUser2(id: number) {
if (cachedUser) return cachedUser;
let response = yield* call(fetch(`/users/${id}`));
return yield* call(response.json());
}
@cowboyd
cowboyd / timer.tsx
Created December 11, 2023 15:11
Timer Example
import { createSignal, call, first, each, spawn, sleep, type Operation } from "effection";
import { render } from "$revolution";
export default function* TimerIsland(): Operation<void> {
let reset = createSignal<void>();
let start = createSignal<void>();
let stop = createSignal<void>();
let elapsed = 0;
let t0 = performance.now();
@cowboyd
cowboyd / browser.test.ts
Created November 17, 2023 22:49
A trivial test case launching the astral browser
import { describe, it } from "https://deno.land/[email protected]/testing/bdd.ts"
import { launch } from "https://deno.land/x/[email protected]/mod.ts";
describe("browser", () => {
it("launches, sleeps, and closes", async () => {
let browser = await launch();
await new Promise((resolve) => setTimeout(resolve, 2000));
browser.close();
});
});
@cowboyd
cowboyd / rebase.ts
Created November 12, 2023 03:03
revolution html middleware that rebases a document at a different url
import { posixNormalize } from "https://deno.land/[email protected]/path/_normalize.ts";
import { selectAll } from "npm:[email protected]";
import type { Element } from "hastx/jsx-runtime";
/**
* Rebase an HTML document at a different URL. This replaces all `<a href>` and
* `<img src>` attributes that contain an absolute path. Any path that is
* relative or contains a fully qualitfied URL will be left alone.
*
@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/[email protected]/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}>();