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
2 changes: 1 addition & 1 deletion examples/chat/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
},
"dependencies": {
"@anthropic-ai/sdk": "^0.133.0",
"@solidjs/router": "2.0.0-next.40",
"@solidjs/router": "2.0.0-next.41",
"@solidjs/web": "workspace:*",
"highlight.js": "^11.11.1",
"marked": "^12.0.2",
Expand Down
4 changes: 2 additions & 2 deletions examples/chat/src/components/composer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
// its id is among them — by derivation, in the same update that brings the
// server's own row.
import { createSignal, For, latest, Show } from "solid-js";
import { action } from "@solidjs/router";
import { formAction } from "@solidjs/router";
import { redirect } from "@solidjs/web";
import * as db from "~/server/db";
import * as generations from "~/server/generations";
Expand All @@ -18,7 +18,7 @@ const mintId = () => Math.random().toString(36).slice(2, 12).padEnd(10, "0");
// Stores the prompt, starts the reply as a job, and returns: the reply is
// written by the job, not by this request. From the front page there is no
// thread yet, so this makes one and goes to it.
export const sendMessage = action(async (form: FormData) => {
export const sendMessage = formAction(async (form: FormData) => {
"use server";
const threadId = String(form.get("threadId") ?? "") || null;
try {
Expand Down
10 changes: 5 additions & 5 deletions examples/chat/src/routes/thread.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import { createMemo, For, Loading, onCleanup } from "solid-js";
import { dynamicComponent, getRequestEvent, redirect } from "@solidjs/web";
import { GET, live } from "@solidjs/web/server-functions";
import type { Slot } from "@solidjs/web/frames";
import { action, liveQuery, type RouteSectionProps } from "@solidjs/router";
import { formAction, liveQuery, type RouteSectionProps } from "@solidjs/router";
import Composer from "~/components/composer";
import CopyCode from "~/components/copy-code";
import * as db from "~/server/db";
Expand All @@ -29,14 +29,14 @@ type CopySlot = Slot<{ code: string }>;

// Stops the reply being written. A plain form posts it, so it works before
// the page's JavaScript has loaded; the thread's own stream shows the result.
const stopGeneration = action(async (replyId: string) => {
const stopGeneration = formAction(async (replyId: string) => {
"use server";
generations.stop(replyId);
}, "stopGeneration");

// Writes the last reply again: Regenerate on a finished one, Retry on a
// failed one. Like sending, it starts a job and returns.
const regenerate = action(async (replyId: string) => {
const regenerate = formAction(async (replyId: string) => {
"use server";
try {
const { threadId } = await db.restart(replyId);
Expand All @@ -47,7 +47,7 @@ const regenerate = action(async (replyId: string) => {
}
}, "regenerate");

const renameThread = action(async (id: string, form: FormData) => {
const renameThread = formAction(async (id: string, form: FormData) => {
"use server";
try {
await db.renameThread(id, String(form.get("title") ?? ""));
Expand All @@ -58,7 +58,7 @@ const renameThread = action(async (id: string, form: FormData) => {
}, "renameThread");

// Deleting leaves nothing to look at, so it answers with where to go.
const deleteThread = action(async (id: string) => {
const deleteThread = formAction(async (id: string) => {
"use server";
const writing = await db.deleteThread(id);
if (writing) generations.stop(writing);
Expand Down
2 changes: 1 addition & 1 deletion examples/hackernews-spa/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"typecheck": "tsc --noEmit"
},
"dependencies": {
"@solidjs/router": "2.0.0-next.40",
"@solidjs/router": "2.0.0-next.41",
"@solidjs/web": "workspace:*",
"solid-js": "workspace:*"
},
Expand Down
2 changes: 1 addition & 1 deletion examples/hackernews/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"typecheck": "tsc --noEmit"
},
"dependencies": {
"@solidjs/router": "2.0.0-next.40",
"@solidjs/router": "2.0.0-next.41",
"@solidjs/web": "workspace:*",
"solid-js": "workspace:*"
},
Expand Down
2 changes: 1 addition & 1 deletion examples/notes/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"typecheck": "tsc --noEmit"
},
"dependencies": {
"@solidjs/router": "2.0.0-next.40",
"@solidjs/router": "2.0.0-next.41",
"@solidjs/web": "workspace:*",
"date-fns": "^3.6.0",
"marked": "^12.0.2",
Expand Down
6 changes: 3 additions & 3 deletions examples/notes/src/components/NoteEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@
// the regions that actually show. The live preview reuses the same
// NotePreview the note's server component renders — the shared-module half of
// the demo.
import { action } from "@solidjs/router";
import { formAction } from "@solidjs/router";
import { createSignal, untrack } from "solid-js";
import { redirect } from "@solidjs/web";
import * as db from "~/server/db";
import NotePreview from "./NotePreview";

const saveNote = action(async (id: number | undefined, formData: FormData) => {
const saveNote = formAction(async (id: number | undefined, formData: FormData) => {
"use server";
const saved = await db.saveNote(
id,
Expand All @@ -32,7 +32,7 @@ const saveNote = action(async (id: number | undefined, formData: FormData) => {
return redirect(`/notes/${saved}`);
});

const deleteNote = action(async (id: number) => {
const deleteNote = formAction(async (id: number) => {
"use server";
await db.deleteNote(id);
return redirect("/");
Expand Down
2 changes: 1 addition & 1 deletion examples/server-dbmon/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"typecheck": "tsc --noEmit"
},
"dependencies": {
"@solidjs/router": "2.0.0-next.40",
"@solidjs/router": "2.0.0-next.41",
"@solidjs/web": "workspace:*",
"solid-js": "workspace:*"
},
Expand Down
2 changes: 1 addition & 1 deletion examples/todos-server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"typecheck": "tsc --noEmit"
},
"dependencies": {
"@solidjs/router": "2.0.0-next.40",
"@solidjs/router": "2.0.0-next.41",
"@solidjs/web": "workspace:*",
"solid-js": "workspace:*",
"unstorage": "^1.17.5"
Expand Down
12 changes: 6 additions & 6 deletions examples/todos-server/src/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
// fresh markup in one round trip. A failed save answers `{ error }` rather
// than throwing, so the failure is typed where the client reads it; the
// server words it, because only the server knows the todo's title.
import { action } from "@solidjs/router";
import { formAction } from "@solidjs/router";
import * as db from "~/server/db";

/** The `completed` a toggle form submitted: the button's value. */
Expand All @@ -21,33 +21,33 @@ async function titleOf(id: string) {
return todo ? `“${todo.title}”` : "a todo";
}

export const addTodo = action(async (form: FormData) => {
export const addTodo = formAction(async (form: FormData) => {
"use server";
const title = String(form.get("title") ?? "").trim();
if (!title) return { error: "A todo needs a title" };
return db.addTodo(title);
});

export const toggleTodo = action(async (id: string, form: FormData) => {
export const toggleTodo = formAction(async (id: string, form: FormData) => {
"use server";
const completed = completedOf(form);
if (await db.toggleTodo(id, completed))
return { error: `Couldn't ${completed ? "complete" : "reopen"} ${await titleOf(id)}` };
});

export const removeTodo = action(async (id: string) => {
export const removeTodo = formAction(async (id: string) => {
"use server";
if (await db.removeTodo(id)) return { error: `Couldn't delete ${await titleOf(id)}` };
});

export const toggleAll = action(async (form: FormData) => {
export const toggleAll = formAction(async (form: FormData) => {
"use server";
const completed = completedOf(form);
if (await db.toggleAll(completed))
return { error: `Couldn't mark everything ${completed ? "complete" : "active"}` };
});

export const clearCompleted = action(async () => {
export const clearCompleted = formAction(async () => {
"use server";
if (await db.clearCompleted()) return { error: "Couldn't clear completed" };
});
6 changes: 3 additions & 3 deletions packages/web/src/response.ts
Original file line number Diff line number Diff line change
Expand Up @@ -153,9 +153,9 @@ export interface ResponseHelperInit extends ResponseInit {
* The cache keys the mutation invalidated, sent as the `X-Revalidate`
* header for the client's integrations to apply. Three declarations, three
* scopes: omitted sends no header — the host's default (Solid Router
* revalidates everything after an action; a router without that
* convention reloads only what it owns); an empty list sends an empty
* header — nothing, explicitly; `REVALIDATE_ALL` (`"*"`) — every entry,
* revalidates everything after any mutation, form action or direct call;
* a router without that convention reloads only what it owns); an empty
* list (or `""`) sends an empty header — nothing, explicitly; `REVALIDATE_ALL` (`"*"`) — every entry,
* whatever the host's default. How named keys are matched (prefixes,
* namespaces) is each integration's business.
*/
Expand Down
30 changes: 15 additions & 15 deletions pnpm-lock.yaml

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

Loading