From 791815d31f7ffdf95ce2739397177b07a49532a2 Mon Sep 17 00:00:00 2001
From: Ethan Davidson <31261035+EthanThatOneKid@users.noreply.github.com>
Date: Sun, 31 Mar 2024 19:58:05 -0700
Subject: [PATCH 1/4] introduce jsonx components
---
components/components.tsx | 162 ++++++++++++++++++++++++++++++++++++++
components/mod.ts | 4 +
deno.jsonc | 10 ++-
main.tsx | 0
rtx.ts | 18 ++---
5 files changed, 184 insertions(+), 10 deletions(-)
create mode 100644 components/components.tsx
create mode 100644 components/mod.ts
create mode 100644 main.tsx
diff --git a/components/components.tsx b/components/components.tsx
new file mode 100644
index 0000000..f1bbd2b
--- /dev/null
+++ b/components/components.tsx
@@ -0,0 +1,162 @@
+/**
+ * @module
+ *
+ * @example
+ *
+ * ```tsx
+ * if (import.meta.main) {
+ * const router = (
+ *
+ *
+ * new Response(null, {
+ * status: 302,
+ * headers: { Location: "https://deno.com/favicon.ico" },
+ * })}
+ * />
+ * new Response("Hello, World!")} />
+ * new Response("foo")} />
+ * new Response("bar")} />
+ * new Response("baz")} />
+ *
+ * );
+ *
+ * Deno.serve((request) => router.fetch(request));
+ * }
+ * ```
+ */
+
+import type {
+ Handle as IHandle,
+ Method as IMethod,
+ Route as IRoute,
+} from "rtx/mod.ts";
+import { createRouter, Router as CRouter } from "rtx/mod.ts";
+
+// deno run -A components/components.tsx
+//
+if (import.meta.main) {
+ const router = (
+
+
+ new Response(null, {
+ status: 302,
+ headers: { Location: "https://deno.com/favicon.ico" },
+ })}
+ />
+ new Response("Hello, World!")} />
+ new Response("foo")} />
+ new Response("bar")} />
+ new Response("baz")} />
+
+ );
+
+ Deno.serve((request) => router.fetch(request));
+}
+
+/**
+ * ComponentsInterface is the interface for the components.
+ */
+export type ComponentsInterface = Record<
+ Capitalize>,
+ (props: RouteProps) => CRouter
+>;
+
+/**
+ * RouteProps are the props for a route component.
+ */
+export interface RouteProps {
+ pattern: string;
+ handle: IHandle;
+}
+
+/**
+ * Router is the router component.
+ */
+export function Router(props: { children?: unknown[] }): CRouter {
+ const router = createRouter();
+ ((props.children) as CRouter[])
+ ?.forEach((child) => {
+ if (child instanceof CRouter) {
+ router.use(child);
+ return;
+ }
+
+ throw new Error("Invalid child of Router");
+ });
+
+ return router;
+}
+
+/**
+ * Route is the route component.
+ */
+export function Route(props: IRoute): CRouter {
+ return createRouter().with(props);
+}
+
+/**
+ * Connect is the route component for a CONNECT route.
+ */
+export function Connect(props: RouteProps): CRouter {
+ return createRouter().connect(props.pattern, props.handle);
+}
+
+/**
+ * Delete is the route component for a DELETE route.
+ */
+export function Delete(props: RouteProps): CRouter {
+ return createRouter().delete(props.pattern, props.handle);
+}
+
+/**
+ * Get is the route component for a GET route.
+ */
+export function Get(props: RouteProps): CRouter {
+ return createRouter().get(props.pattern, props.handle);
+}
+
+/**
+ * Head is the route component for a HEAD route.
+ */
+export function Head(props: RouteProps): CRouter {
+ return createRouter().head(props.pattern, props.handle);
+}
+
+/**
+ * Options is the route component for a OPTIONS route.
+ */
+export function Options(props: RouteProps): CRouter {
+ return createRouter().options(props.pattern, props.handle);
+}
+
+/**
+ * Patch is the route component for a PATCH route.
+ */
+export function Patch(props: RouteProps): CRouter {
+ return createRouter().patch(props.pattern, props.handle);
+}
+
+/**
+ * Post is the route component for a POST route.
+ */
+export function Post(props: RouteProps): CRouter {
+ return createRouter().post(props.pattern, props.handle);
+}
+
+/**
+ * Put is the route component for a PUT route.
+ */
+export function Put(props: RouteProps): CRouter {
+ return createRouter().put(props.pattern, props.handle);
+}
+
+/**
+ * Trace is the route component for a TRACE route.
+ */
+export function Trace(props: RouteProps): CRouter {
+ return createRouter().trace(props.pattern, props.handle);
+}
diff --git a/components/mod.ts b/components/mod.ts
new file mode 100644
index 0000000..f4d6a1b
--- /dev/null
+++ b/components/mod.ts
@@ -0,0 +1,4 @@
+export * from "./components.tsx";
+
+import * as components from "./components.tsx";
+components satisfies components.ComponentsInterface;
diff --git a/deno.jsonc b/deno.jsonc
index dc03767..fadf0fa 100644
--- a/deno.jsonc
+++ b/deno.jsonc
@@ -2,10 +2,18 @@
"lock": false,
"name": "@fartlabs/rtx",
"version": "0.0.1",
- "exports": "./mod.ts",
+ "exports": {
+ ".": "./mod.ts",
+ "./components": "./components/mod.ts"
+ },
"imports": {
+ "@fartlabs/jsonx": "jsr:@fartlabs/jsonx@^0.0.10",
"rtx/": "./"
},
+ "compilerOptions": {
+ "jsx": "react-jsx",
+ "jsxImportSource": "@fartlabs/jsonx"
+ },
"tasks": {
"example": "deno run --allow-net examples/farm/farm.ts"
}
diff --git a/main.tsx b/main.tsx
new file mode 100644
index 0000000..e69de29
diff --git a/rtx.ts b/rtx.ts
index 0f44b2a..1db72c0 100644
--- a/rtx.ts
+++ b/rtx.ts
@@ -184,21 +184,21 @@ export class Router implements RouterInterface {
/**
* with appends a route to the router.
*/
- public with(
- handle: Handle,
- ): this;
+ public with(route: Route): this;
public with(
match: Match,
handle: Handle,
): this;
public with(
- matchOrHandle: Match | Handle,
+ routeOrMatch: Match | Route,
handle?: Handle,
): this {
- if (typeof matchOrHandle === "function" && handle === undefined) {
- this.routes.push({ handle: matchOrHandle as Handle });
- } else if (handle !== undefined) {
- this.routes.push({ handle, match: matchOrHandle as Match });
+ if (handle === undefined && "handle" in routeOrMatch) {
+ this.routes.push(routeOrMatch);
+ } else if (handle !== undefined && !("handle" in routeOrMatch)) {
+ this.routes.push({ match: routeOrMatch, handle });
+ } else {
+ throw new Error("Invalid arguments");
}
return this;
@@ -234,7 +234,7 @@ export class Router implements RouterInterface {
): this {
return this.with({
method: "CONNECT",
- pattern: new URLPattern({ pathname: pattern }),
+ pattern: pattern ? new URLPattern({ pathname: pattern }) : undefined,
}, handle);
}
From b4b20cde4cd2ea3ee5f0059f4b782912236b03dc Mon Sep 17 00:00:00 2001
From: Ethan Davidson <31261035+EthanThatOneKid@users.noreply.github.com>
Date: Mon, 1 Apr 2024 22:55:50 -0700
Subject: [PATCH 2/4] move core library to `@fartlabs/rt`
---
README.md | 11 +-
components/components.tsx | 162 ----------------
components/mod.ts | 4 -
deno.jsonc | 1 +
examples/farm/farm.ts | 11 --
main.tsx | 0
mod.ts | 7 +-
rtx.ts | 390 ++++++++------------------------------
8 files changed, 94 insertions(+), 492 deletions(-)
delete mode 100644 components/components.tsx
delete mode 100644 components/mod.ts
delete mode 100644 examples/farm/farm.ts
delete mode 100644 main.tsx
diff --git a/README.md b/README.md
index dcc1d74..bb9459f 100644
--- a/README.md
+++ b/README.md
@@ -4,19 +4,14 @@
[![GitHub
Actions][GitHub Actions badge]][GitHub Actions]
-Minimal HTTP router library based on the `URLPattern` API.
+Minimal HTTP router library based on the `URLPattern` API in JSX.
## Usage
-```ts
+```tsx
import { createRouter } from "@fartlabs/rtx";
-const router = createRouter()
- .get("/", () => {
- return new Response("Hello, World!");
- })
- .default(() => new Response("Not found", { status: 404 }));
-
+const router = new Response("Hello, World!")} />;
Deno.serve((request) => router.fetch(request));
```
diff --git a/components/components.tsx b/components/components.tsx
deleted file mode 100644
index f1bbd2b..0000000
--- a/components/components.tsx
+++ /dev/null
@@ -1,162 +0,0 @@
-/**
- * @module
- *
- * @example
- *
- * ```tsx
- * if (import.meta.main) {
- * const router = (
- *
- *
- * new Response(null, {
- * status: 302,
- * headers: { Location: "https://deno.com/favicon.ico" },
- * })}
- * />
- * new Response("Hello, World!")} />
- * new Response("foo")} />
- * new Response("bar")} />
- * new Response("baz")} />
- *
- * );
- *
- * Deno.serve((request) => router.fetch(request));
- * }
- * ```
- */
-
-import type {
- Handle as IHandle,
- Method as IMethod,
- Route as IRoute,
-} from "rtx/mod.ts";
-import { createRouter, Router as CRouter } from "rtx/mod.ts";
-
-// deno run -A components/components.tsx
-//
-if (import.meta.main) {
- const router = (
-
-
- new Response(null, {
- status: 302,
- headers: { Location: "https://deno.com/favicon.ico" },
- })}
- />
- new Response("Hello, World!")} />
- new Response("foo")} />
- new Response("bar")} />
- new Response("baz")} />
-
- );
-
- Deno.serve((request) => router.fetch(request));
-}
-
-/**
- * ComponentsInterface is the interface for the components.
- */
-export type ComponentsInterface = Record<
- Capitalize>,
- (props: RouteProps) => CRouter
->;
-
-/**
- * RouteProps are the props for a route component.
- */
-export interface RouteProps {
- pattern: string;
- handle: IHandle;
-}
-
-/**
- * Router is the router component.
- */
-export function Router(props: { children?: unknown[] }): CRouter {
- const router = createRouter();
- ((props.children) as CRouter[])
- ?.forEach((child) => {
- if (child instanceof CRouter) {
- router.use(child);
- return;
- }
-
- throw new Error("Invalid child of Router");
- });
-
- return router;
-}
-
-/**
- * Route is the route component.
- */
-export function Route(props: IRoute): CRouter {
- return createRouter().with(props);
-}
-
-/**
- * Connect is the route component for a CONNECT route.
- */
-export function Connect(props: RouteProps): CRouter {
- return createRouter().connect(props.pattern, props.handle);
-}
-
-/**
- * Delete is the route component for a DELETE route.
- */
-export function Delete(props: RouteProps): CRouter {
- return createRouter().delete(props.pattern, props.handle);
-}
-
-/**
- * Get is the route component for a GET route.
- */
-export function Get(props: RouteProps): CRouter {
- return createRouter().get(props.pattern, props.handle);
-}
-
-/**
- * Head is the route component for a HEAD route.
- */
-export function Head(props: RouteProps): CRouter {
- return createRouter().head(props.pattern, props.handle);
-}
-
-/**
- * Options is the route component for a OPTIONS route.
- */
-export function Options(props: RouteProps): CRouter {
- return createRouter().options(props.pattern, props.handle);
-}
-
-/**
- * Patch is the route component for a PATCH route.
- */
-export function Patch(props: RouteProps): CRouter {
- return createRouter().patch(props.pattern, props.handle);
-}
-
-/**
- * Post is the route component for a POST route.
- */
-export function Post(props: RouteProps): CRouter {
- return createRouter().post(props.pattern, props.handle);
-}
-
-/**
- * Put is the route component for a PUT route.
- */
-export function Put(props: RouteProps): CRouter {
- return createRouter().put(props.pattern, props.handle);
-}
-
-/**
- * Trace is the route component for a TRACE route.
- */
-export function Trace(props: RouteProps): CRouter {
- return createRouter().trace(props.pattern, props.handle);
-}
diff --git a/components/mod.ts b/components/mod.ts
deleted file mode 100644
index f4d6a1b..0000000
--- a/components/mod.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-export * from "./components.tsx";
-
-import * as components from "./components.tsx";
-components satisfies components.ComponentsInterface;
diff --git a/deno.jsonc b/deno.jsonc
index fadf0fa..b80a956 100644
--- a/deno.jsonc
+++ b/deno.jsonc
@@ -8,6 +8,7 @@
},
"imports": {
"@fartlabs/jsonx": "jsr:@fartlabs/jsonx@^0.0.10",
+ "@fartlabs/rt": "jsr:@fartlabs/rt@^0.0.1",
"rtx/": "./"
},
"compilerOptions": {
diff --git a/examples/farm/farm.ts b/examples/farm/farm.ts
deleted file mode 100644
index 11faaa5..0000000
--- a/examples/farm/farm.ts
+++ /dev/null
@@ -1,11 +0,0 @@
-import { createRouter } from "rtx/mod.ts";
-
-if (import.meta.main) {
- const router = createRouter()
- .get<"id">("/animals/:id", (ctx) => {
- return new Response(`Animal ID: ${ctx.params.id}`);
- })
- .default(() => new Response("Not found", { status: 404 }));
-
- Deno.serve((request) => router.fetch(request));
-}
diff --git a/main.tsx b/main.tsx
deleted file mode 100644
index e69de29..0000000
diff --git a/mod.ts b/mod.ts
index a17f4e6..e02d2ae 100644
--- a/mod.ts
+++ b/mod.ts
@@ -1,7 +1,12 @@
/**
* @module
*
- * rtx is a minimalistic HTTP router library based on the `URLPattern` API.
+ * rtx is a minimalistic HTTP router library based on the `URLPattern` API in
+ * JSX.
*/
+import * as rtx from "./rtx.ts";
+
+rtx satisfies rtx.ComponentsInterface;
+
export * from "./rtx.ts";
diff --git a/rtx.ts b/rtx.ts
index 1db72c0..c246b5e 100644
--- a/rtx.ts
+++ b/rtx.ts
@@ -1,344 +1,122 @@
+import type {
+ Handle as IHandle,
+ Method as IMethod,
+ Route as IRoute,
+} from "@fartlabs/rt";
+import { createRouter, Router as CRouter } from "@fartlabs/rt";
+
/**
- * createRouter creates a new router.
+ * ComponentsInterface is the interface for the components.
*/
-export function createRouter(fn?: (r: Router) => Router): Router {
- const router = new Router();
- if (fn) {
- return fn(router);
- }
-
- return router;
-}
+export type ComponentsInterface = Record<
+ Capitalize>,
+ (props: RouteProps) => CRouter
+>;
/**
- * METHODS is the list of HTTP methods.
+ * RouteProps are the props for a route component.
*/
-export const METHODS = [
- "CONNECT",
- "DELETE",
- "GET",
- "HEAD",
- "OPTIONS",
- "PATCH",
- "POST",
- "PUT",
- "TRACE",
-] as const;
+export interface RouteProps {
+ pattern: string;
+ handle: IHandle;
+}
/**
- * Method is a type which represents an HTTP method.
+ * RouterProps are the props for the router component.
*/
-export type Method = typeof METHODS[number];
+export interface RouterProps {
+ children?: unknown[];
+ default?: IHandle;
+}
/**
- * Match is a type which matches a Request object.
+ * Router is the router component.
*/
-export type Match =
- | ((detail: { request: Request; url: URL }) => Promise)
- | {
- /**
- * pattern is the URL pattern to match on.
- */
- pattern?: URLPattern;
+export function Router(props: RouterProps): CRouter {
+ const router = createRouter();
+ ((props.children) as CRouter[])
+ ?.forEach((child) => {
+ if (child instanceof CRouter) {
+ router.use(child);
+ return;
+ }
- /**
- * method is the HTTP method to match on.
- */
- method?: Method;
- };
+ throw new Error("Invalid child of Router");
+ });
+
+ if (props.default) {
+ router.default(props.default);
+ }
+
+ return router;
+}
/**
- * Handle is called to handle a request.
+ * Route is the route component.
*/
-export interface Handle {
- (ctx: RouterContext): Promise | Response;
+export function Route(props: IRoute): CRouter {
+ return createRouter().with(props);
}
/**
- * Route represents a the pairing of a matcher and a handler.
+ * Connect is the route component for a CONNECT route.
*/
-export interface Route {
- /**
- * handle is called to handle a request.
- */
- handle: Handle;
-
- /**
- * match is called to match a request.
- */
- match?: Match;
+export function Connect(props: RouteProps): CRouter {
+ return createRouter().connect(props.pattern, props.handle);
}
/**
- * Routes is a sequence of routes.
+ * Delete is the route component for a DELETE route.
*/
-export type Routes = Route[];
+export function Delete(props: RouteProps): CRouter {
+ return createRouter().delete(props.pattern, props.handle);
+}
/**
- * RouterContext is the object passed to a router.
+ * Get is the route component for a GET route.
*/
-export interface RouterContext {
- /**
- * request is the original request object.
- */
- request: Request;
-
- /**
- * url is the parsed fully qualified URL of the request.
- */
- url: URL;
-
- /**
- * params is a map of matched parameters from the URL pattern.
- */
- params: { [key in T]: string };
-
- /**
- * next executes the next matched route in the sequence. If no more routes are
- * matched, the default handler is called.
- */
- next: () => Promise;
+export function Get(props: RouteProps): CRouter {
+ return createRouter().get(props.pattern, props.handle);
}
/**
- * RouterInterface is the interface for a router.
+ * Head is the route component for a HEAD route.
*/
-type RouterInterface = Record<
- Lowercase,
- ((pattern: string, handle: Handle) => Router)
->;
+export function Head(props: RouteProps): CRouter {
+ return createRouter().head(props.pattern, props.handle);
+}
/**
- * Router is an HTTP router based on the `URLPattern` API.
+ * Options is the route component for a OPTIONS route.
*/
-export class Router implements RouterInterface {
- public routes: Routes = [];
- public defaultHandle?: Handle;
-
- /**
- * fetch invokes the router for the given request.
- */
- public async fetch(request: Request, i = 0): Promise {
- const url = new URL(request.url);
- while (i < this.routes.length) {
- const route = this.routes[i];
- const matchedMethod = route.match === undefined ||
- typeof route.match !== "function" &&
- (route.match.method === undefined ||
- route.match.method === request.method);
- if (!matchedMethod) {
- i++;
- continue;
- }
-
- const matchedFn = typeof route.match === "function" &&
- await route.match({ request, url });
- const matchedPattern = route.match !== undefined &&
- typeof route.match !== "function" &&
- route.match.pattern !== undefined &&
- route.match.pattern.exec(request.url);
- let params: Record = {};
- if (matchedPattern) {
- params = matchedPattern?.pathname
- ? Object.entries(matchedPattern.pathname.groups)
- .reduce(
- (groups, [key, value]) => {
- if (value !== undefined) {
- groups[key] = value;
- }
-
- return groups;
- },
- {} as { [key: string]: string },
- )
- : {};
- }
-
- // If the route matches, call it and return the response.
- if (route.match === undefined || matchedFn || matchedPattern) {
- return await route.handle({
- request,
- url,
- params,
- next: () => this.fetch(request, i + 1),
- });
- }
-
- i++;
- }
-
- if (this.defaultHandle !== undefined) {
- return await this.defaultHandle({
- request,
- url,
- params: {},
- next: () => {
- throw new Error("next() called from default handler");
- },
- });
- }
-
- throw new Error("Not found");
- }
-
- /**
- * with appends a route to the router.
- */
- public with(route: Route): this;
- public with(
- match: Match,
- handle: Handle,
- ): this;
- public with(
- routeOrMatch: Match | Route,
- handle?: Handle,
- ): this {
- if (handle === undefined && "handle" in routeOrMatch) {
- this.routes.push(routeOrMatch);
- } else if (handle !== undefined && !("handle" in routeOrMatch)) {
- this.routes.push({ match: routeOrMatch, handle });
- } else {
- throw new Error("Invalid arguments");
- }
-
- return this;
- }
-
- /**
- * use appends a sequence of routers to the router.
- */
- public use(data: Routes | Router): this {
- if (data instanceof Router) {
- this.routes.push(...data.routes);
- } else {
- this.routes.push(...data);
- }
-
- return this;
- }
-
- /**
- * default sets the router's default handler.
- */
- public default(handle: Handle | undefined): this {
- this.defaultHandle = handle;
- return this;
- }
-
- /**
- * connect appends a router for the CONNECT method to the router.
- */
- public connect(
- pattern: string,
- handle: Handle,
- ): this {
- return this.with({
- method: "CONNECT",
- pattern: pattern ? new URLPattern({ pathname: pattern }) : undefined,
- }, handle);
- }
-
- /**
- * delete appends a router for the DELETE method to the router.
- */
- public delete(
- pattern: string,
- handle: Handle,
- ): this {
- return this.with({
- method: "DELETE",
- pattern: new URLPattern({ pathname: pattern }),
- }, handle);
- }
-
- /**
- * get appends a router for the GET method to the router.
- */
- public get(
- pattern: string,
- handle: Handle,
- ): this {
- return this.with({
- method: "GET",
- pattern: new URLPattern({ pathname: pattern }),
- }, handle);
- }
-
- /**
- * head appends a router for the HEAD method to the router.
- */
- public head(
- pattern: string,
- handle: Handle,
- ): this {
- return this.with({
- method: "HEAD",
- pattern: new URLPattern({ pathname: pattern }),
- }, handle);
- }
-
- /**
- * options appends a router for the OPTIONS method to the router.
- */
- public options(
- pattern: string,
- handle: Handle,
- ): this {
- return this.with({
- method: "OPTIONS",
- pattern: new URLPattern({ pathname: pattern }),
- }, handle);
- }
+export function Options(props: RouteProps): CRouter {
+ return createRouter().options(props.pattern, props.handle);
+}
- /**
- * patch appends a router for the PATCH method to the router.
- */
- public patch(
- pattern: string,
- handle: Handle,
- ): this {
- return this.with({
- method: "PATCH",
- pattern: new URLPattern({ pathname: pattern }),
- }, handle);
- }
+/**
+ * Patch is the route component for a PATCH route.
+ */
+export function Patch(props: RouteProps): CRouter {
+ return createRouter().patch(props.pattern, props.handle);
+}
- /**
- * post appends a router for the POST method to the router.
- */
- public post(
- pattern: string,
- handle: Handle,
- ): this {
- return this.with({
- method: "POST",
- pattern: new URLPattern({ pathname: pattern }),
- }, handle);
- }
+/**
+ * Post is the route component for a POST route.
+ */
+export function Post(props: RouteProps): CRouter {
+ return createRouter().post(props.pattern, props.handle);
+}
- /**
- * put appends a router for the PUT method to the router.
- */
- public put(
- pattern: string,
- handle: Handle,
- ): this {
- return this.with({
- method: "PUT",
- pattern: new URLPattern({ pathname: pattern }),
- }, handle);
- }
+/**
+ * Put is the route component for a PUT route.
+ */
+export function Put(props: RouteProps): CRouter {
+ return createRouter().put(props.pattern, props.handle);
+}
- /**
- * trace appends a router for the TRACE method to the router.
- */
- public trace(
- pattern: string,
- handle: Handle,
- ): this {
- return this.with({
- method: "TRACE",
- pattern: new URLPattern({ pathname: pattern }),
- }, handle);
- }
+/**
+ * Trace is the route component for a TRACE route.
+ */
+export function Trace(props: RouteProps): CRouter {
+ return createRouter().trace(props.pattern, props.handle);
}
From 33fda54645b2606f55efe9a52ce274a69413c943 Mon Sep 17 00:00:00 2001
From: Ethan Davidson <31261035+EthanThatOneKid@users.noreply.github.com>
Date: Mon, 1 Apr 2024 23:34:03 -0700
Subject: [PATCH 3/4] Update deno.jsonc
---
deno.jsonc | 11 ++---------
1 file changed, 2 insertions(+), 9 deletions(-)
diff --git a/deno.jsonc b/deno.jsonc
index b80a956..6a9bb1a 100644
--- a/deno.jsonc
+++ b/deno.jsonc
@@ -2,20 +2,13 @@
"lock": false,
"name": "@fartlabs/rtx",
"version": "0.0.1",
- "exports": {
- ".": "./mod.ts",
- "./components": "./components/mod.ts"
- },
+ "exports": "./mod.ts",
"imports": {
"@fartlabs/jsonx": "jsr:@fartlabs/jsonx@^0.0.10",
- "@fartlabs/rt": "jsr:@fartlabs/rt@^0.0.1",
- "rtx/": "./"
+ "@fartlabs/rt": "jsr:@fartlabs/rt@^0.0.1"
},
"compilerOptions": {
"jsx": "react-jsx",
"jsxImportSource": "@fartlabs/jsonx"
- },
- "tasks": {
- "example": "deno run --allow-net examples/farm/farm.ts"
}
}
From ef8e9ae36e7e063f2065d9b8cdb0797a5197b33d Mon Sep 17 00:00:00 2001
From: Ethan Davidson <31261035+EthanThatOneKid@users.noreply.github.com>
Date: Mon, 1 Apr 2024 23:37:03 -0700
Subject: [PATCH 4/4] Update README.md
---
README.md | 14 ++++++++++----
1 file changed, 10 insertions(+), 4 deletions(-)
diff --git a/README.md b/README.md
index bb9459f..fe38a9b 100644
--- a/README.md
+++ b/README.md
@@ -4,14 +4,20 @@
[![GitHub
Actions][GitHub Actions badge]][GitHub Actions]
+> [!NOTE]
+>
+> Built with [**@fartlabs/rt**](https://github.com/FartLabs/rt) and
+> [**@fartlabs/jsonx**](https://github.com/FartLabs/jsonx).
+
Minimal HTTP router library based on the `URLPattern` API in JSX.
## Usage
```tsx
-import { createRouter } from "@fartlabs/rtx";
+import { Get } from "@fartlabs/rtx";
const router = new Response("Hello, World!")} />;
+
Deno.serve((request) => router.fetch(request));
```
@@ -41,11 +47,11 @@ Run `deno lint` to lint the code.
---
-Developed with ❤️ by [**@EthanThatOneKid**](https://etok.codes/)
+Developed with ❤️ [**@FartLabs**](https://github.com/FartLabs)
[JSR]: https://jsr.io/@fartlabs/rtx
[JSR badge]: https://jsr.io/badges/@fartlabs/rtx
[JSR score]: https://jsr.io/@fartlabs/rtx/score
[JSR score badge]: https://jsr.io/badges/@fartlabs/rtx/score
-[GitHub Actions]: https://github.com/EthanThatOneKid/rtx/actions/workflows/check.yaml
-[GitHub Actions badge]: https://github.com/EthanThatOneKid/rtx/actions/workflows/check.yaml/badge.svg
+[GitHub Actions]: https://github.com/FartLabs/rtx/actions/workflows/check.yaml
+[GitHub Actions badge]: https://github.com/FartLabs/rtx/actions/workflows/check.yaml/badge.svg