Skip to content

Commit

Permalink
refactor(vue): minor cleanup (#39)
Browse files Browse the repository at this point in the history
* refactor(vue): cleanup

* chore: PropType
  • Loading branch information
hi-ogawa authored Apr 18, 2024
1 parent 4531262 commit 6398cbf
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 46 deletions.
1 change: 1 addition & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,4 @@ jobs:
- run: pnpm -C examples/vue-ssr-extra test-e2e
- run: pnpm -C examples/vue-ssr-extra build
- run: pnpm -C examples/vue-ssr-extra test-e2e-preview
- run: pnpm -C examples/vue-ssr-extra tsc
8 changes: 6 additions & 2 deletions examples/vue-ssr-extra/src/features/server-action/client.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import { tinyassert } from "@hiogawa/utils";
import { ACTION_PATH, registerServerReference } from "./shared";
import {
ACTION_PATH,
registerServerReference,
type ServerActionPayload,
} from "./shared";

export function createServerReference(id: string, name: string) {
const action = async (...args: unknown[]) => {
Expand All @@ -25,7 +29,7 @@ function encodeActionPayload(
};
} else {
return {
body: JSON.stringify({ id, name, args }),
body: JSON.stringify({ id, name, args } satisfies ServerActionPayload),
headers: {
"content-type": "application/json",
},
Expand Down
23 changes: 22 additions & 1 deletion examples/vue-ssr-extra/src/features/server-action/server.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { tinyassert } from "@hiogawa/utils";
import { ACTION_PATH, decodeActionRequest } from "./shared";
import { ACTION_PATH, type ServerActionPayload } from "./shared";

export async function serverActionHandler({ request }: { request: Request }) {
const url = new URL(request.url);
Expand Down Expand Up @@ -34,3 +34,24 @@ async function importServerReference(id: string) {
return importReference();
}
}

async function decodeActionRequest(
request: Request,
): Promise<ServerActionPayload> {
const contentType = request.headers.get("content-type");
tinyassert(contentType);
if (contentType === "application/json") {
return request.json();
} else {
const formData = await request.formData();
const id = formData.get("__id");
const name = formData.get("__name");
tinyassert(typeof id === "string");
tinyassert(typeof name === "string");
return {
id,
name,
args: [formData],
};
}
}
47 changes: 4 additions & 43 deletions examples/vue-ssr-extra/src/features/server-action/shared.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { tinyassert } from "@hiogawa/utils";
import { defineComponent, h, ref } from "vue";
import { defineComponent, h, ref, type PropType } from "vue";

export const ACTION_PATH = "/__action";

type FormAction<T = any> = (v: FormData) => Promise<T>;

type ServerActionPayload = {
export type ServerActionPayload = {
id: string;
name: string;
args: unknown[];
Expand All @@ -27,7 +27,7 @@ export function registerServerReference<T extends object>(
export const Form = defineComponent({
props: {
action: {
type: Function,
type: Function as PropType<FormAction>,
required: true,
},
},
Expand Down Expand Up @@ -84,50 +84,11 @@ export function useEnhance<T>(
const status = ref<"idle" | "pending" | "success">("idle");
const enhanced: FormAction<void> = async (v) => {
status.value = "pending";
// TODO: what if unmounted before finishing action?
const result = await action(v);
options?.onSuccess(result);
status.value = "success";
};
const newAction = registerServerReference(enhanced, meta.__id, meta.__name);
return [newAction, { status }] as const;
}

export function encodeActionRequest(
id: string,
name: string,
args: unknown[],
): RequestInit {
if (args.length === 1 && args[0] instanceof FormData) {
return {
body: args[0],
};
} else {
return {
body: JSON.stringify({ id, name, args } satisfies ServerActionPayload),
headers: {
"content-type": "application/json",
},
};
}
}

export async function decodeActionRequest(
request: Request,
): Promise<ServerActionPayload> {
const contentType = request.headers.get("content-type");
tinyassert(contentType);
if (contentType === "application/json") {
return request.json();
} else {
const formData = await request.formData();
const id = formData.get("__id");
const name = formData.get("__name");
tinyassert(typeof id === "string");
tinyassert(typeof name === "string");
return {
id,
name,
args: [formData],
};
}
}

0 comments on commit 6398cbf

Please sign in to comment.