Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 14 additions & 3 deletions .github/workflows/verify.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,11 @@ permissions:
contents: read

jobs:
test:
lint:
runs-on: ubuntu-latest

steps:
- name: checkout
uses: actions/checkout@v3
uses: actions/checkout@v4

- name: setup deno
uses: denoland/setup-deno@v2
Expand All @@ -28,5 +27,17 @@ jobs:
- name: lint
run: deno lint

test:
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: test
run: deno task test
2 changes: 1 addition & 1 deletion deno.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
"deno-dom/constructor-lock": "https://deno.land/x/deno_dom@v0.1.41/src/constructor-lock.ts",
"esbuild": "npm:esbuild@0.24.2",
"esbuild-deno-loader": "jsr:@luca/esbuild-deno-loader@0.11.1",
"effection": "jsr:@effection/effection@3.1.0",
"effection": "jsr:@effection/effection@3.6.1",
"@std/assert": "jsr:@std/assert@1.0.10",
"@std/path": "jsr:@std/path@1.0.8",
"@std/http": "jsr:@std/http@1.0.12",
Expand Down
17 changes: 8 additions & 9 deletions deno.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions lib/render.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,17 @@ export const CurrentSlot = createContext<Slot>("slot");
export const CurrentDocument = createContext<Document>("document");

export function* useDocument() {
return yield* CurrentDocument;
return yield* CurrentDocument.expect();
}

type ASTNode = JSXElement;

export function render(jsx: JSXElement): Operation<void> {
return {
*[Symbol.iterator]() {
let doc = yield* CurrentDocument;
let doc = yield* CurrentDocument.expect();
let nodes = toNodes(jsx, doc);
let slot = yield* CurrentSlot;
let slot = yield* CurrentSlot.expect();
slot.replace(...nodes);
},
};
Expand Down
2 changes: 1 addition & 1 deletion lib/revolution.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ const RevolutionOptions: Context<RevolutionOptions> = createContext<
);

export function* useRevolutionOptions(): Operation<RevolutionOptions> {
return yield* RevolutionOptions;
return yield* RevolutionOptions.expect();
}

function createApp({
Expand Down
2 changes: 1 addition & 1 deletion lib/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { match, type MatchResult, type ParamData } from "path-to-regexp";
import { concat } from "./middleware.ts";
import type { Middleware } from "./types.ts";

const ParamsContext = createContext<MatchResult<ParamData>["params"]>(
export const ParamsContext = createContext<MatchResult<ParamData>["params"]>(
"revolution.params",
);

Expand Down
38 changes: 21 additions & 17 deletions lib/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import type { Operation } from "effection";
import type { Handler } from "./types.ts";

import { action, call, once, race, resource, useScope } from "effection";
import { getframe } from "effection";
import { ParamsContext } from "./route.ts";

export interface ServerInfo {
hostname: string;
Expand All @@ -16,7 +16,7 @@ export interface ServerOptions {

interface Driver {
operation(): Operation<void>;
context: Record<string, unknown>;
params: Record<string, string | undefined> | undefined;
}
export const _driver = Symbol.for("revolution.driver");

Expand All @@ -38,8 +38,10 @@ export function useServer(options: ServerOptions): Operation<ServerInfo> {

if (driver) {
scope.run(function* () {
let frame = yield* getframe();
Object.assign(frame.context, driver.context);
// Restore the captured params context if it was set
if (driver.params) {
yield* ParamsContext.set(driver.params);
}

try {
yield* race([aborted(request), driver.operation()]);
Expand All @@ -55,17 +57,17 @@ export function useServer(options: ServerOptions): Operation<ServerInfo> {
return response;
});

let info = yield* action<ServerInfo>(
function* (resolve) {
server = Deno.serve({
handler,
port: options.port,
onListen(info) {
resolve(info);
},
});
},
);
let info = yield* action<ServerInfo>((resolve, _reject) => {
server = Deno.serve({
handler,
port: options.port,
onListen(info) {
resolve(info);
},
});
// Return cleanup function (required by both effection v3 and v4)
return () => {};
});
try {
yield* provide(info);
} finally {
Expand All @@ -89,11 +91,13 @@ export function* drive(
response: Response,
operation: () => Operation<void>,
): Operation<Response> {
let { context } = yield* getframe();
// Capture the current params context so it can be restored in the driver scope
let params = yield* ParamsContext.get();

return Object.create(response, {
[_driver]: {
enumerable: false,
value: { context, operation },
value: { params, operation },
},
});
}
Expand Down
4 changes: 4 additions & 0 deletions tasks/build-npm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ await build({
target: "ES2020",
sourceMap: true,
},

package: {
// package.json properties
name: "@frontside/revolution",
Expand All @@ -47,6 +48,9 @@ await build({
node: ">= 18",
},
sideEffects: false,
peerDependencies: {
effection: "^3.0.0 || ^4.0.0",
},
},
});

Expand Down
6 changes: 5 additions & 1 deletion test/suite.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,10 @@ declare global {

Object.defineProperty(Promise.prototype, Symbol.iterator, {
get<T>(this: Promise<T>) {
return call(this)[Symbol.iterator];
// Wrap the promise in a function for v4 compatibility
// v3 accepted call(promise) directly, v4 requires call(() => promise)
// deno-lint-ignore no-this-alias
const promise = this;
return call(() => promise)[Symbol.iterator];
},
});