diff --git a/.github/workflows/npm-release.yml b/.github/workflows/npm-release.yml deleted file mode 100644 index 74b7003c..00000000 --- a/.github/workflows/npm-release.yml +++ /dev/null @@ -1,46 +0,0 @@ -# This workflow will install Deno then run Deno lint and test. -# For more information see: https://github.com/denoland/setup-deno - -name: Release to NPM - -on: - push: - tags: - - "effection-v*" - -permissions: - contents: read - -jobs: - release: - runs-on: ubuntu-latest - - steps: - - name: checkout - uses: actions/checkout@v3 - - - name: setup deno - uses: denoland/setup-deno@v2 - with: - deno-version: v2.x - - - name: Get Version - id: vars - run: echo ::set-output name=version::$(echo ${{github.ref_name}} | sed 's/^effection-v//') - - - name: Setup Node - uses: actions/setup-node@v2 - with: - node-version: 14.x - registry-url: https://registry.npmjs.com - - - name: Build - run: deno task build:npm $NPM_VERSION - env: - NPM_VERSION: ${{steps.vars.outputs.version}} - - - name: Publish - run: npm publish --access=public --tag=next - working-directory: ./build/npm - env: - NODE_AUTH_TOKEN: ${{secrets.NPM_AUTH_TOKEN}} diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 00000000..c485089d --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,64 @@ +name: Publish + +on: + push: + tags: + - "effection-v*" + +permissions: + contents: read + id-token: write + +jobs: + publish-npm: + runs-on: ubuntu-latest + + steps: + - name: checkout + uses: actions/checkout@v4 + + - name: setup deno + uses: denoland/setup-deno@v2 + with: + deno-version: v2.x + + - name: Get Version + id: vars + run: echo ::set-output name=version::$(echo ${{github.ref_name}} | sed 's/^effection-v//') + + - name: Setup Node + uses: actions/setup-node@v4.1.0 + with: + node-version: 18.x + registry-url: https://registry.npmjs.com + + - name: Build NPM + run: deno task build:npm ${{steps.vars.outputs.version}} + + - name: Publish NPM + run: npm publish --access=public + working-directory: ./build/npm + env: + NODE_AUTH_TOKEN: ${{secrets.NPM_AUTH_TOKEN}} + + publish-jsr: + runs-on: ubuntu-latest + + steps: + - name: checkout + uses: actions/checkout@v4 + + - name: setup deno + uses: denoland/setup-deno@v2 + with: + deno-version: v2.x + + - name: Get Version + id: vars + run: echo ::set-output name=version::$(echo ${{github.ref_name}} | sed 's/^effection-v//') + + - name: Build JSR + run: deno task build:jsr ${{steps.vars.outputs.version}} + + - name: Publish JSR + run: npx jsr publish --allow-dirty --token=${{secrets.JSR_TOKEN}} diff --git a/.gitignore b/.gitignore index 0e1ef1b4..7883eb9b 100755 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,4 @@ # Local Netlify folder .netlify -/build/ +/build/ \ No newline at end of file diff --git a/deno.json b/deno.json index 2ed8c319..7586f8da 100644 --- a/deno.json +++ b/deno.json @@ -1,10 +1,17 @@ { + "name": "@effection/effection", + "exports": "./mod.ts", + "license": "ISC", + "publish": { + "include": ["lib", "mod.ts", "README.md"] + }, "lock": false, "tasks": { "test": "deno test --allow-run=deno", "test:node": "deno task build:npm 0.0.0 && node test/main/node.mjs hello world", "build:npm": "deno run -A tasks/build-npm.ts", - "bench": "deno run -A tasks/bench.ts" + "bench": "deno run -A tasks/bench.ts", + "build:jsr": "deno run -A tasks/build-jsr.ts" }, "lint": { "rules": { diff --git a/lib/action.ts b/lib/action.ts index 19d22b53..69bdbc07 100644 --- a/lib/action.ts +++ b/lib/action.ts @@ -1,5 +1,5 @@ import { Err, Ok } from "./result.ts"; -import { Effect, Operation } from "./types.ts"; +import type { Effect, Operation } from "./types.ts"; interface Resolver { (resolve: (value: T) => void, reject: (error: Error) => void): () => void; diff --git a/lib/call.ts b/lib/call.ts index 8840849c..d15e9bf1 100644 --- a/lib/call.ts +++ b/lib/call.ts @@ -1,6 +1,6 @@ import { constant } from "./constant.ts"; import { action } from "./action.ts"; -import { Operation } from "./types.ts"; +import type { Operation } from "./types.ts"; /** * A uniform integration type representing anything that can be evaluated diff --git a/lib/callcc.ts b/lib/callcc.ts index 881e8fab..606fdd02 100644 --- a/lib/callcc.ts +++ b/lib/callcc.ts @@ -1,6 +1,6 @@ import { lift } from "./lift.ts"; -import { Err, Ok, Result, unbox } from "./result.ts"; -import { Operation } from "./types.ts"; +import { Err, Ok, type Result, unbox } from "./result.ts"; +import type { Operation } from "./types.ts"; import { withResolvers } from "./with-resolvers.ts"; import { spawn } from "./spawn.ts"; import { encapsulate } from "./task.ts"; diff --git a/lib/context.ts b/lib/context.ts index f76e1db9..df56a9ec 100644 --- a/lib/context.ts +++ b/lib/context.ts @@ -1,4 +1,4 @@ -import { Context, Effect, Operation, Scope } from "./types.ts"; +import type { Context, Effect, Operation, Scope } from "./types.ts"; import { Ok } from "./result.ts"; import { Do } from "./do.ts"; diff --git a/lib/contexts.ts b/lib/contexts.ts index fdc3d3c5..7e3b80e4 100644 --- a/lib/contexts.ts +++ b/lib/contexts.ts @@ -1,5 +1,5 @@ import { createContext } from "./context.ts"; -import { Coroutine, Scope } from "./types.ts"; +import type { Coroutine, Scope } from "./types.ts"; export const Routine = createContext>( "@effection/coroutine", diff --git a/lib/coroutine.ts b/lib/coroutine.ts index 9a263492..6e5d3852 100644 --- a/lib/coroutine.ts +++ b/lib/coroutine.ts @@ -1,7 +1,7 @@ import { Generation } from "./contexts.ts"; import { ReducerContext } from "./reducer.ts"; import { Ok } from "./result.ts"; -import { Coroutine, Operation, Scope, Subscriber } from "./types.ts"; +import type { Coroutine, Operation, Scope, Subscriber } from "./types.ts"; export interface CoroutineOptions { scope: Scope; diff --git a/lib/do.ts b/lib/do.ts index b717c4e3..f6c9b64c 100644 --- a/lib/do.ts +++ b/lib/do.ts @@ -1,5 +1,5 @@ -import { Result } from "./result.ts"; -import { Effect, Operation } from "./types.ts"; +import type { Result } from "./result.ts"; +import type { Effect, Operation } from "./types.ts"; /** * Perform a single Effect as an Operation diff --git a/lib/drain.ts b/lib/drain.ts index 2f0be08e..c9e47e08 100644 --- a/lib/drain.ts +++ b/lib/drain.ts @@ -1,5 +1,5 @@ -import { Result } from "./result.ts"; -import { Subscriber } from "./types.ts"; +import type { Result } from "./result.ts"; +import type { Subscriber } from "./types.ts"; export function drain(end: (result: Result) => void): Subscriber { return (next) => { diff --git a/lib/each.ts b/lib/each.ts index a5127ec7..a7e90f18 100644 --- a/lib/each.ts +++ b/lib/each.ts @@ -86,7 +86,7 @@ export function each(stream: Stream): Operation> { }; } -each.next = function next() { +each.next = function next(): Operation { return { name: "each.next()", *[Symbol.iterator]() { diff --git a/lib/ensure.ts b/lib/ensure.ts index 4d331adb..a068c595 100644 --- a/lib/ensure.ts +++ b/lib/ensure.ts @@ -1,4 +1,4 @@ -import { Operation } from "./types.ts"; +import type { Operation } from "./types.ts"; import { resource } from "./resource.ts"; /** diff --git a/lib/lazy-promise.ts b/lib/lazy-promise.ts index 1c08e788..6650b3e6 100644 --- a/lib/lazy-promise.ts +++ b/lib/lazy-promise.ts @@ -1,4 +1,4 @@ -import { Err, Ok, Result } from "./result.ts"; +import { Err, Ok, type Result } from "./result.ts"; type PromiseWithResolvers = ReturnType>; diff --git a/lib/lift.ts b/lib/lift.ts index 25934da5..f671a816 100644 --- a/lib/lift.ts +++ b/lib/lift.ts @@ -1,5 +1,5 @@ import { action } from "./action.ts"; -import { type Operation } from "./types.ts"; +import type { Operation } from "./types.ts"; /** * Convert a simple function into an {@link Operation} diff --git a/lib/main.ts b/lib/main.ts index 598cc536..aaafb69d 100644 --- a/lib/main.ts +++ b/lib/main.ts @@ -1,5 +1,5 @@ import { createContext } from "./context.ts"; -import { type Operation } from "./types.ts"; +import type { Operation } from "./types.ts"; import { callcc } from "./callcc.ts"; import { run } from "./run.ts"; import { useScope } from "./scope.ts"; diff --git a/lib/race.ts b/lib/race.ts index b37aa199..bf6f6f40 100644 --- a/lib/race.ts +++ b/lib/race.ts @@ -2,7 +2,7 @@ import { spawn } from "./spawn.ts"; import { encapsulate, trap } from "./task.ts"; import type { Operation, Task, Yielded } from "./types.ts"; import { withResolvers } from "./with-resolvers.ts"; -import { Err, Ok, Result } from "./result.ts"; +import { Err, Ok, type Result } from "./result.ts"; //import { useScope } from "./scope.ts"; //import { transfer } from "./scope.ts"; diff --git a/lib/reducer.ts b/lib/reducer.ts index ba7c7ca0..4753bade 100644 --- a/lib/reducer.ts +++ b/lib/reducer.ts @@ -1,6 +1,6 @@ import { createContext } from "./context.ts"; -import { Err, Ok, Result } from "./result.ts"; -import { Coroutine, Subscriber } from "./types.ts"; +import { Err, Ok, type Result } from "./result.ts"; +import type { Coroutine, Subscriber } from "./types.ts"; export class Reducer { reducing = false; diff --git a/lib/resource.ts b/lib/resource.ts index 562272c0..f877d56c 100644 --- a/lib/resource.ts +++ b/lib/resource.ts @@ -1,6 +1,6 @@ import { suspend } from "./suspend.ts"; import { spawn } from "./spawn.ts"; -import { Operation } from "./types.ts"; +import type { Operation } from "./types.ts"; import { trap } from "./task.ts"; import { Ok } from "./result.ts"; import { useCoroutine } from "./coroutine.ts"; diff --git a/lib/run.ts b/lib/run.ts index 8db08c6a..96f9ec0a 100644 --- a/lib/run.ts +++ b/lib/run.ts @@ -1,4 +1,4 @@ -import { Operation, Task } from "./types.ts"; +import type { Operation, Task } from "./types.ts"; import { global } from "./scope.ts"; diff --git a/lib/scope.ts b/lib/scope.ts index 34547b13..a05fc302 100644 --- a/lib/scope.ts +++ b/lib/scope.ts @@ -1,9 +1,18 @@ import { Children, Generation } from "./contexts.ts"; -import { Context, Effect, Future, Operation, Scope, Task } from "./types.ts"; +import type { + Context, + Effect, + Future, + Operation, + Scope, + Task, +} from "./types.ts"; import { Err, Ok, unbox } from "./result.ts"; import { createTask } from "./task.ts"; -export const [global] = createScopeInternal(); +const scope: [ScopeInternal, () => Operation] = createScopeInternal(); + +export const global = scope[0]; export function createScope( parent: Scope = global, diff --git a/lib/signal.ts b/lib/signal.ts index 621caf9a..9c5ce801 100644 --- a/lib/signal.ts +++ b/lib/signal.ts @@ -3,6 +3,7 @@ import type { Stream, Subscription } from "./types.ts"; import { createQueue, type Queue } from "./queue.ts"; import { resource } from "./resource.ts"; import { createContext } from "./context.ts"; +import type { Context } from "./types.ts"; /** * Convert plain JavaScript function calls into a {@link Stream} that can @@ -81,7 +82,7 @@ export interface Signal extends Stream { * } * ``` */ -export const SignalQueueFactory = createContext( +export const SignalQueueFactory: Context = createContext( "Signal.createQueue", createQueue, ); diff --git a/lib/sleep.ts b/lib/sleep.ts index 5a914fda..dbc9e148 100644 --- a/lib/sleep.ts +++ b/lib/sleep.ts @@ -1,4 +1,4 @@ -import { Operation } from "./types.ts"; +import type { Operation } from "./types.ts"; import { action } from "./action.ts"; /** diff --git a/lib/spawn.ts b/lib/spawn.ts index 286f5c99..93df33ac 100644 --- a/lib/spawn.ts +++ b/lib/spawn.ts @@ -1,6 +1,6 @@ import { Ok } from "./result.ts"; -import { ScopeInternal } from "./scope.ts"; -import { createTask, NewTask } from "./task.ts"; +import type { ScopeInternal } from "./scope.ts"; +import { createTask, type NewTask } from "./task.ts"; import type { Effect, Operation, Task } from "./types.ts"; export function* spawn(op: () => Operation): Operation> { diff --git a/lib/suspend.ts b/lib/suspend.ts index f21918be..2b91b7e5 100644 --- a/lib/suspend.ts +++ b/lib/suspend.ts @@ -1,5 +1,5 @@ import { action } from "./action.ts"; -import { Operation } from "./types.ts"; +import type { Operation } from "./types.ts"; export function suspend(): Operation { return action(() => () => {}, "suspend"); diff --git a/lib/task.ts b/lib/task.ts index 3399c919..fbd326b4 100644 --- a/lib/task.ts +++ b/lib/task.ts @@ -3,8 +3,8 @@ import { Routine } from "./contexts.ts"; import { createCoroutine } from "./coroutine.ts"; import { drain } from "./drain.ts"; import { lazyPromise, lazyPromiseWithResolvers } from "./lazy-promise.ts"; -import { Just, Maybe, Nothing } from "./maybe.ts"; -import { Err, Ok, Result, unbox } from "./result.ts"; +import { Just, type Maybe, Nothing } from "./maybe.ts"; +import { Err, Ok, type Result, unbox } from "./result.ts"; import { createScopeInternal, type ScopeInternal } from "./scope.ts"; import type { Coroutine, Operation, Resolve, Scope, Task } from "./types.ts"; import { withResolvers } from "./with-resolvers.ts"; diff --git a/lib/with-resolvers.ts b/lib/with-resolvers.ts index 8ee755cd..bfff80d1 100644 --- a/lib/with-resolvers.ts +++ b/lib/with-resolvers.ts @@ -1,4 +1,4 @@ -import { Err, Ok, Result } from "./result.ts"; +import { Err, Ok, type Result } from "./result.ts"; import { action } from "./action.ts"; import type { Operation } from "./types.ts"; diff --git a/tasks/bench.ts b/tasks/bench.ts index 278257c2..4bc1cb68 100644 --- a/tasks/bench.ts +++ b/tasks/bench.ts @@ -5,14 +5,14 @@ import { createQueue, each, main, - Operation, + type Operation, spawn, - Task, + type Task, withResolvers, } from "../mod.ts"; import { useWorker } from "./bench/worker.ts"; import scenarios from "./bench/scenarios.ts"; -import { +import type { BenchmarkDoneEvent, BenchmarkOptions, BenchmarkWorkerEvent, diff --git a/tasks/bench/scenarios/effection.events.ts b/tasks/bench/scenarios/effection.events.ts index f39243ad..23073658 100644 --- a/tasks/bench/scenarios/effection.events.ts +++ b/tasks/bench/scenarios/effection.events.ts @@ -1,5 +1,5 @@ import { scenario } from "./scenario.ts"; -import { each, on, Operation, sleep, spawn } from "../../../mod.ts"; +import { each, on, type Operation, sleep, spawn } from "../../../mod.ts"; await scenario("effection.events", start); diff --git a/tasks/bench/scenarios/effection.recursion.ts b/tasks/bench/scenarios/effection.recursion.ts index 567b77d3..f6c5dbf2 100644 --- a/tasks/bench/scenarios/effection.recursion.ts +++ b/tasks/bench/scenarios/effection.recursion.ts @@ -1,4 +1,4 @@ -import { call, Operation } from "../../../mod.ts"; +import { call, type Operation } from "../../../mod.ts"; import { scenario } from "./scenario.ts"; await scenario("effection.recursion", recurse); diff --git a/tasks/bench/scenarios/rxjs.events.ts b/tasks/bench/scenarios/rxjs.events.ts index 72e4483b..71c57506 100644 --- a/tasks/bench/scenarios/rxjs.events.ts +++ b/tasks/bench/scenarios/rxjs.events.ts @@ -1,6 +1,6 @@ import { fromEvent, Observable, Subject, takeUntil } from "npm:rxjs"; import { scenario } from "./scenario.ts"; -import { action, Operation, sleep, spawn } from "../../../mod.ts"; +import { action, type Operation, sleep, spawn } from "../../../mod.ts"; await scenario("rxjs.events", run); diff --git a/tasks/bench/scenarios/rxjs.recursion.ts b/tasks/bench/scenarios/rxjs.recursion.ts index c5a2b27b..a571ec78 100644 --- a/tasks/bench/scenarios/rxjs.recursion.ts +++ b/tasks/bench/scenarios/rxjs.recursion.ts @@ -1,6 +1,6 @@ import { defer, from, Observable, repeat } from "npm:rxjs"; import { scenario } from "./scenario.ts"; -import { action, Operation } from "../../../mod.ts"; +import { action, type Operation } from "../../../mod.ts"; await scenario("rxjs.recursion", run); diff --git a/tasks/bench/scenarios/scenario.ts b/tasks/bench/scenarios/scenario.ts index 4debc3f5..ebfff264 100644 --- a/tasks/bench/scenarios/scenario.ts +++ b/tasks/bench/scenarios/scenario.ts @@ -1,8 +1,14 @@ import { callcc } from "../../../lib/callcc.ts"; import { Err, Ok } from "../../../lib/result.ts"; import { encapsulate } from "../../../lib/task.ts"; -import { createChannel, each, main, Operation, spawn } from "../../../mod.ts"; import { + createChannel, + each, + main, + type Operation, + spawn, +} from "../../../mod.ts"; +import type { BenchmarkOptions, BenchmarkWorkerEvent, WorkerCommand, diff --git a/tasks/bench/types.ts b/tasks/bench/types.ts index 8d544ecb..3bb53017 100644 --- a/tasks/bench/types.ts +++ b/tasks/bench/types.ts @@ -1,4 +1,4 @@ -import { Result } from "../../lib/result.ts"; +import type { Result } from "../../lib/result.ts"; export type WorkerCommand = BenchmarkOptions | Close; diff --git a/tasks/bench/worker.ts b/tasks/bench/worker.ts index 47fdb6c0..e694ca5f 100644 --- a/tasks/bench/worker.ts +++ b/tasks/bench/worker.ts @@ -2,10 +2,10 @@ import { createQueue, each, on, - Operation, + type Operation, resource, spawn, - Stream, + type Stream, } from "../../mod.ts"; export interface WorkerResource { diff --git a/tasks/build-jsr.ts b/tasks/build-jsr.ts new file mode 100644 index 00000000..387d31d0 --- /dev/null +++ b/tasks/build-jsr.ts @@ -0,0 +1,14 @@ +import jsonDeno from "../deno.json" with { type: "json" }; + +let [version] = Deno.args; +if (!version) { + throw new Error("a version argument is required to build the npm package"); +} + +await Deno.writeTextFile( + new URL("../deno.json", import.meta.url), + JSON.stringify({ + ...jsonDeno, + version, + }), +); diff --git a/tasks/build-npm.ts b/tasks/build-npm.ts index 5b2ab936..529938c6 100644 --- a/tasks/build-npm.ts +++ b/tasks/build-npm.ts @@ -1,7 +1,4 @@ -import { - build, - emptyDir, -} from "https://deno.land/x/dnt@0.36.0/mod.ts?pin=v123"; +import { build, emptyDir } from "jsr:@deno/dnt@0.41.3"; const outDir = "./build/npm"; @@ -21,7 +18,7 @@ await build({ test: false, typeCheck: false, compilerOptions: { - lib: ["esnext", "dom"], + lib: ["ESNext", "DOM"], target: "ES2020", sourceMap: true, }, @@ -31,8 +28,8 @@ await build({ version, description: "Structured concurrency and effects for JavaScript", license: "ISC", + author: "engineering@frontside.com", repository: { - author: "engineering@frontside.com", type: "git", url: "git+https://github.com/thefrontside/effection.git", }, diff --git a/test/each.test.ts b/test/each.test.ts index b794d31f..00873072 100644 --- a/test/each.test.ts +++ b/test/each.test.ts @@ -1,5 +1,12 @@ import { describe, expect, it } from "./suite.ts"; -import { createQueue, each, resource, run, spawn, Stream } from "../mod.ts"; +import { + createQueue, + each, + resource, + run, + spawn, + type Stream, +} from "../mod.ts"; describe("each", () => { it("can be used to iterate a stream", async () => { diff --git a/test/resource.test.ts b/test/resource.test.ts index 9475854a..54731712 100644 --- a/test/resource.test.ts +++ b/test/resource.test.ts @@ -1,5 +1,12 @@ import { describe, expect, it } from "./suite.ts"; -import { Operation, resource, run, sleep, spawn, suspend } from "../mod.ts"; +import { + type Operation, + resource, + run, + sleep, + spawn, + suspend, +} from "../mod.ts"; type State = { status: string }; diff --git a/test/suite.ts b/test/suite.ts index 542a3e08..cd97005d 100644 --- a/test/suite.ts +++ b/test/suite.ts @@ -1,6 +1,6 @@ import { call, resource, sleep, spawn } from "../mod.ts"; -import { Operation } from "../lib/types.ts"; +import type { Operation } from "../lib/types.ts"; export { afterEach,