Skip to content

Commit 272218f

Browse files
committed
fix #491 - useSubmission with "with" actions
1 parent d82fa85 commit 272218f

File tree

2 files changed

+23
-16
lines changed

2 files changed

+23
-16
lines changed

.changeset/serious-squids-agree.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@solidjs/router": patch
3+
---
4+
5+
fix #491 - useSubmission with "with" actions

src/data/action.ts

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,26 +5,26 @@ import type { RouterContext, Submission, SubmissionStub, Navigator, NarrowRespon
55
import { mockBase } from "../utils.js";
66
import { cacheKeyOp, hashKey, revalidate, cache } from "./cache.js";
77

8-
export type Action<T extends Array<any>, U> = (T extends [FormData] | []
8+
export type Action<T extends Array<any>, U, V = T> = (T extends [FormData] | []
99
? JSX.SerializableAttributeValue
1010
: unknown) &
1111
((...vars: T) => Promise<NarrowResponse<U>>) & {
1212
url: string;
1313
with<A extends any[], B extends any[]>(
1414
this: (this: any, ...args: [...A, ...B]) => Promise<NarrowResponse<U>>,
1515
...args: A
16-
): Action<B, U>;
16+
): Action<B, U, V>;
1717
};
1818

1919
export const actions = /* #__PURE__ */ new Map<string, Action<any, any>>();
2020

21-
export function useSubmissions<T extends Array<any>, U>(
22-
fn: Action<T, U>,
23-
filter?: (arg: T) => boolean
21+
export function useSubmissions<T extends Array<any>, U, V>(
22+
fn: Action<T, U, V>,
23+
filter?: (input: V) => boolean
2424
): Submission<T, NarrowResponse<U>>[] & { pending: boolean } {
2525
const router = useRouter();
2626
const subs = createMemo(() =>
27-
router.submissions[0]().filter(s => s.url === fn.toString() && (!filter || filter(s.input)))
27+
router.submissions[0]().filter(s => s.url === (fn as any).base && (!filter || filter(s.input)))
2828
);
2929
return new Proxy<Submission<any, any>[] & { pending: boolean }>([] as any, {
3030
get(_, property) {
@@ -38,9 +38,9 @@ export function useSubmissions<T extends Array<any>, U>(
3838
});
3939
}
4040

41-
export function useSubmission<T extends Array<any>, U>(
42-
fn: Action<T, U>,
43-
filter?: (arg: T) => boolean
41+
export function useSubmission<T extends Array<any>, U, V>(
42+
fn: Action<T, U, V>,
43+
filter?: (input: V) => boolean
4444
): Submission<T, NarrowResponse<U>> | SubmissionStub {
4545
const submissions = useSubmissions(fn, filter);
4646
return new Proxy(
@@ -54,15 +54,15 @@ export function useSubmission<T extends Array<any>, U>(
5454
) as Submission<T, NarrowResponse<U>>;
5555
}
5656

57-
export function useAction<T extends Array<any>, U>(action: Action<T, U>) {
57+
export function useAction<T extends Array<any>, U, V>(action: Action<T, U, V>) {
5858
const r = useRouter();
59-
return (...args: Parameters<Action<T, U>>) => action.apply({ r }, args);
59+
return (...args: Parameters<Action<T, U, V>>) => action.apply({ r }, args);
6060
}
6161

6262
export function action<T extends Array<any>, U = void>(
6363
fn: (...args: T) => Promise<U>,
6464
name?: string
65-
): Action<T, U> {
65+
): Action<T, U, T> {
6666
function mutate(this: { r: RouterContext; f?: HTMLFormElement }, ...variables: T) {
6767
const router = this.r;
6868
const form = this.f;
@@ -113,10 +113,11 @@ export function action<T extends Array<any>, U = void>(
113113
(fn as any).url ||
114114
(name && `https://action/${name}`) ||
115115
(!isServer ? `https://action/${hashString(fn.toString())}` : "");
116+
mutate.base = url;
116117
return toAction(mutate, url);
117118
}
118119

119-
function toAction<T extends Array<any>, U>(fn: Function, url: string): Action<T, U> {
120+
function toAction<T extends Array<any>, U, V = T>(fn: Function, url: string): Action<T, U, V> {
120121
fn.toString = () => {
121122
if (!url) throw new Error("Client Actions need explicit names if server rendered");
122123
return url;
@@ -128,19 +129,20 @@ function toAction<T extends Array<any>, U>(fn: Function, url: string): Action<T,
128129
const newFn = function (this: RouterContext, ...passedArgs: B): U {
129130
return fn.call(this, ...args, ...passedArgs);
130131
};
132+
newFn.base = (fn as any).base;
131133
const uri = new URL(url, mockBase);
132134
uri.searchParams.set("args", hashKey(args));
133-
return toAction<B, U>(
135+
return toAction<B, U, V>(
134136
newFn as any,
135137
(uri.origin === "https://action" ? uri.origin : "") + uri.pathname + uri.search
136138
);
137139
};
138140
(fn as any).url = url;
139141
if (!isServer) {
140-
actions.set(url, fn as Action<T, U>);
142+
actions.set(url, fn as Action<T, U, V>);
141143
getOwner() && onCleanup(() => actions.delete(url));
142144
}
143-
return fn as Action<T, U>;
145+
return fn as Action<T, U, V>;
144146
}
145147

146148
const hashString = (s: string) =>

0 commit comments

Comments
 (0)