Skip to content

Commit

Permalink
feat: add store
Browse files Browse the repository at this point in the history
  • Loading branch information
ynwd committed Sep 15, 2024
1 parent 473ea03 commit c75fff3
Show file tree
Hide file tree
Showing 32 changed files with 481 additions and 126 deletions.
2 changes: 1 addition & 1 deletion components/button.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { ComponentChildren } from "https://esm.sh/preact@10.23.2";
import type { ComponentChildren } from "https://esm.sh/preact@10.24.0";

export default function Button(props: { children: ComponentChildren }) {
return (
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
21 changes: 21 additions & 0 deletions core/server/deps.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
export { STATUS_CODE, STATUS_TEXT } from "jsr:@std/http@^1.0.6";

export * from "jsr:@std/media-types@^1.0.2";
export * from "jsr:@std/path@^1.0.1";

export { encodeHex } from "jsr:@std/encoding@^1.0.1/hex";
export { assertEquals } from "jsr:@std/assert@^1.0.5";
export { assertExists } from "jsr:@std/assert@^1.0.5";
export { assert } from "jsr:@std/assert@^1.0.5";

export { h } from "https://esm.sh/[email protected]";
export type {
ComponentChild,
ComponentChildren,
JSX,
VNode,
} from "https://esm.sh/[email protected]";
export {
renderToString,
renderToStringAsync,
} from "https://esm.sh/[email protected][email protected]";
File renamed without changes.
26 changes: 14 additions & 12 deletions http/server/mod.ts → core/server/mod.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import {
Static,
} from "./types.ts";
import { EsbuildMod } from "../build/esbuildMod.ts";
import { Store } from "./store.ts";

export function checkReferer(req: Request) {
const referer = req.headers.get("referer");
Expand Down Expand Up @@ -77,7 +78,7 @@ const createResponse = (
};

export default class Server implements Fastro {
constructor(options?: Record<string, any>) {
constructor(options?: Map<string, any>) {
this.serverOptions = options ?? {};
this.#handler = this.#createHandler();
this.#addPropsEndpoint();
Expand Down Expand Up @@ -303,10 +304,10 @@ if (root) fetchProps(root);
}
}

#getParamsHandler<T extends Record<string, Handler>>(
#getParamsHandler<T extends Map<string, Handler>>(
req: Request,
data: T,
): [Handler, Record<string, string | undefined> | undefined] | undefined {
): [Handler, Map<string, string | undefined> | undefined] | undefined {
for (const [key, handler] of Object.entries(data)) {
const [method, path] = key.split("-");
const pattern = new URLPattern({ pathname: path });
Expand All @@ -318,10 +319,10 @@ if (root) fetchProps(root);
}
}

#getParamsPage<T extends Record<string, Page>>(
#getParamsPage<T extends Map<string, Page>>(
req: Request,
data: T,
): [Page, Record<string, string | undefined> | undefined] | undefined {
): [Page, Map<string, string | undefined> | undefined] | undefined {
for (const [path, page] of Object.entries(data)) {
const pattern = new URLPattern({ pathname: path });
if (path.includes(":") && pattern.test(req.url)) {
Expand Down Expand Up @@ -381,7 +382,7 @@ if (root) fetchProps(root);
const url = new URL(req.url);
let key = url.pathname;
let page: Page = this.#routePage[key];
let params: Record<string, string | undefined> | undefined = undefined;
let params: Map<string, string | undefined> | undefined = undefined;
if (!page) {
const res = this.#getParamsPage(req, this.#routePage);
if (res) {
Expand Down Expand Up @@ -472,14 +473,14 @@ if (root) fetchProps(root);
#iterableToRecord(
params: URLSearchParams,
) {
const record: Record<string, string> = {};
const record: Map<string, string> = {};
params.forEach((v, k) => (record[k] = v));
return record;
}

#transformRequest = (
req: Request,
params?: Record<string, string | undefined>,
params?: Map<string, string | undefined>,
url?: URL,
) => {
const u = url ?? new URL(req.url);
Expand All @@ -493,7 +494,7 @@ if (root) fetchProps(root);
#transformCtx = (
info: Deno.ServeHandlerInfo,
url: URL,
options: Record<string, any>,
options: Map<string, any>,
) => {
const ctx = options as Context;
const r = new Render(this);
Expand All @@ -517,7 +518,7 @@ if (root) fetchProps(root);
const url = new URL(req.url);
const key = req.method + "-" + url.pathname;
let handler = this.#routeHandler[key];
let params: Record<string, string | undefined> | undefined;
let params: Map<string, string | undefined> | undefined;
if (!handler) {
const res = this.#getParamsHandler(req, this.#routeHandler);
if (res) {
Expand Down Expand Up @@ -645,11 +646,11 @@ if (root) fetchProps(root);
}
};

getPages(): Record<string, Page> {
getPages(): Map<string, Page> {
return this.#routePage;
}

getRoutes(): Record<string, Handler> {
getRoutes(): Map<string, Handler> {
return this.#routeHandler;
}

Expand All @@ -670,4 +671,5 @@ if (root) fetchProps(root);
#maxAge = 0;
#nonce = "";
serverOptions: Record<string, any> = {};
store = new Store<string, any>();
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { assert, assertEquals, assertExists } from "@app/http/server/deps.ts";
import { assert, assertEquals, assertExists } from "@app/core/server/deps.ts";
import fastro from "@app/mod.ts";
import hello from "@app/modules/web/hello.page.tsx";
import dear from "@app/modules/web/dear.page.tsx";
Expand Down
File renamed without changes.
82 changes: 82 additions & 0 deletions core/server/store.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import { assert, assertEquals } from "./deps.ts";
import { Store } from "./store.ts";

Deno.test("ExpiringMap: should set and get a value", async () => {
const expiringMap = new Store<string, string>(1000); // 1 second TTL
expiringMap.set("key1", "value1");
assertEquals(await expiringMap.get("key1"), "value1");
});

Deno.test("ExpiringMap: should return undefined for expired keys", async () => {
const expiringMap = new Store<string, string>(100);
expiringMap.set("key1", "value1");
await new Promise((resolve) => setTimeout(resolve, 200));
assertEquals(await expiringMap.get("key1"), undefined);
});

Deno.test("ExpiringMap: should check if a key exists", async () => {
const expiringMap = new Store<string, string>(100);
expiringMap.set("key1", "value1");
assert(expiringMap.has("key1"));
await new Promise((resolve) => setTimeout(resolve, 200));
assert(!expiringMap.has("key1"));
});

Deno.test("ExpiringMap: should delete a key", async () => {
const expiringMap = new Store<string, string>();
expiringMap.set("key1", "value1");
assert(expiringMap.delete("key1"));
assertEquals(await expiringMap.get("key1"), undefined);
});

Deno.test("ExpiringMap: should clear all entries", () => {
const expiringMap = new Store<string, string>();
expiringMap.set("key1", "value1");
expiringMap.set("key2", "value2");
expiringMap.clear();
assertEquals(expiringMap.size(), 0);
});

Deno.test("ExpiringMap: should get the size of the map", () => {
const expiringMap = new Store<string, string>();
expiringMap.set("key1", "value1");
expiringMap.set("key2", "value2");
assertEquals(expiringMap.size(), 2);
});

Deno.test("ExpiringMap: should iterate over valid entries using forEach", () => {
const expiringMap = new Store<string, string>(1000);
expiringMap.set("key1", "value1");
expiringMap.set("key2", "value2");

const entries: [string, string][] = [];
expiringMap.forEach((value, key) => {
entries.push([key, value]);
});

assertEquals(entries.length, 2);
assertEquals(entries, [["key1", "value1"], ["key2", "value2"]]);
});

Deno.test("ExpiringMap: should set a key with custom TTL", async () => {
const expiringMap = new Store<string, string>(2000);
expiringMap.set("key1", "value1", 1000);
assertEquals(await expiringMap.get("key1"), "value1");
await new Promise((resolve) => setTimeout(resolve, 1100));
assertEquals(await expiringMap.get("key1"), undefined);
});

Deno.test("ExpiringMap: save it to github", async () => {
const token = Deno.env.get("GITHUB_TOKEN");
if (!token) return;
const expiringMap = new Store<string, number>(2000, {
owner: "fastrodev",
repo: "fastro",
path: "modules/store/records.json",
token,
});
const d = new Date();
expiringMap.set("key1", d.getTime(), 1000);
const c = await expiringMap.commit();
assertEquals(c?.data.content?.name, "records.json");
});
Loading

0 comments on commit c75fff3

Please sign in to comment.