@solidjs/router 0.16.0 → 0.16.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/data/action.js +6 -5
- package/dist/data/createAsync.js +3 -0
- package/dist/data/events.d.ts +8 -1
- package/dist/data/events.js +2 -2
- package/dist/index.d.ts +1 -1
- package/dist/index.jsx +1 -1
- package/dist/routers/HashRouter.js +1 -1
- package/dist/routers/MemoryRouter.js +1 -1
- package/dist/routers/Router.js +1 -1
- package/dist/routing.d.ts +2 -1
- package/dist/routing.js +1 -0
- package/dist/types.d.ts +1 -1
- package/dist/utils.d.ts +1 -0
- package/dist/utils.js +8 -0
- package/package.json +2 -2
- package/dist/src/components.d.ts +0 -31
- package/dist/src/components.jsx +0 -39
- package/dist/src/data/action.d.ts +0 -17
- package/dist/src/data/action.js +0 -163
- package/dist/src/data/action.spec.d.ts +0 -1
- package/dist/src/data/action.spec.js +0 -297
- package/dist/src/data/createAsync.d.ts +0 -32
- package/dist/src/data/createAsync.js +0 -96
- package/dist/src/data/createAsync.spec.d.ts +0 -1
- package/dist/src/data/createAsync.spec.js +0 -196
- package/dist/src/data/events.d.ts +0 -9
- package/dist/src/data/events.js +0 -123
- package/dist/src/data/events.spec.d.ts +0 -1
- package/dist/src/data/events.spec.js +0 -567
- package/dist/src/data/index.d.ts +0 -4
- package/dist/src/data/index.js +0 -4
- package/dist/src/data/query.d.ts +0 -23
- package/dist/src/data/query.js +0 -232
- package/dist/src/data/query.spec.d.ts +0 -1
- package/dist/src/data/query.spec.js +0 -354
- package/dist/src/data/response.d.ts +0 -4
- package/dist/src/data/response.js +0 -42
- package/dist/src/data/response.spec.d.ts +0 -1
- package/dist/src/data/response.spec.js +0 -165
- package/dist/src/index.d.ts +0 -7
- package/dist/src/index.jsx +0 -6
- package/dist/src/lifecycle.d.ts +0 -5
- package/dist/src/lifecycle.js +0 -69
- package/dist/src/routers/HashRouter.d.ts +0 -9
- package/dist/src/routers/HashRouter.js +0 -41
- package/dist/src/routers/MemoryRouter.d.ts +0 -24
- package/dist/src/routers/MemoryRouter.js +0 -57
- package/dist/src/routers/Router.d.ts +0 -9
- package/dist/src/routers/Router.js +0 -45
- package/dist/src/routers/StaticRouter.d.ts +0 -6
- package/dist/src/routers/StaticRouter.js +0 -15
- package/dist/src/routers/components.d.ts +0 -27
- package/dist/src/routers/components.jsx +0 -118
- package/dist/src/routers/createRouter.d.ts +0 -10
- package/dist/src/routers/createRouter.js +0 -41
- package/dist/src/routers/index.d.ts +0 -11
- package/dist/src/routers/index.js +0 -6
- package/dist/src/routing.d.ts +0 -175
- package/dist/src/routing.js +0 -560
- package/dist/src/types.d.ts +0 -200
- package/dist/src/types.js +0 -1
- package/dist/src/utils.d.ts +0 -13
- package/dist/src/utils.js +0 -185
- package/dist/test/helpers.d.ts +0 -6
- package/dist/test/helpers.js +0 -50
package/dist/data/action.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { $TRACK, createMemo, createSignal, onCleanup, getOwner } from "solid-js";
|
|
2
2
|
import { isServer } from "solid-js/web";
|
|
3
3
|
import { useRouter } from "../routing.js";
|
|
4
|
-
import { mockBase } from "../utils.js";
|
|
4
|
+
import { mockBase, setFunctionName } from "../utils.js";
|
|
5
5
|
import { cacheKeyOp, hashKey, revalidate, query } from "./query.js";
|
|
6
6
|
export const actions = /* #__PURE__ */ new Map();
|
|
7
7
|
export function useSubmissions(fn, filter) {
|
|
@@ -53,7 +53,7 @@ export function action(fn, options = {}) {
|
|
|
53
53
|
error: result?.error,
|
|
54
54
|
pending: false,
|
|
55
55
|
retry() {
|
|
56
|
-
return retry = submission.retry();
|
|
56
|
+
return (retry = submission.retry());
|
|
57
57
|
}
|
|
58
58
|
});
|
|
59
59
|
if (retry)
|
|
@@ -93,10 +93,11 @@ export function action(fn, options = {}) {
|
|
|
93
93
|
return p.then(handler(), handler(true));
|
|
94
94
|
}
|
|
95
95
|
const o = typeof options === "string" ? { name: options } : options;
|
|
96
|
-
const
|
|
97
|
-
|
|
98
|
-
(!isServer ? `https://action/${hashString(fn.toString())}` : "");
|
|
96
|
+
const name = o.name || (!isServer ? String(hashString(fn.toString())) : undefined);
|
|
97
|
+
const url = fn.url || (name && `https://action/${name}`) || "";
|
|
99
98
|
mutate.base = url;
|
|
99
|
+
if (name)
|
|
100
|
+
setFunctionName(mutate, name);
|
|
100
101
|
return toAction(mutate, url);
|
|
101
102
|
}
|
|
102
103
|
function toAction(fn, url) {
|
package/dist/data/createAsync.js
CHANGED
|
@@ -4,11 +4,14 @@
|
|
|
4
4
|
import { createResource, sharedConfig, untrack, catchError } from "solid-js";
|
|
5
5
|
import { createStore, reconcile, unwrap } from "solid-js/store";
|
|
6
6
|
import { isServer } from "solid-js/web";
|
|
7
|
+
import { setFunctionName } from "../utils.js";
|
|
7
8
|
export function createAsync(fn, options) {
|
|
8
9
|
let resource;
|
|
9
10
|
let prev = () => !resource || resource.state === "unresolved" ? undefined : resource.latest;
|
|
10
11
|
[resource] = createResource(() => subFetch(fn, catchError(() => untrack(prev), () => undefined)), v => v, options);
|
|
11
12
|
const resultAccessor = (() => resource());
|
|
13
|
+
if (options?.name)
|
|
14
|
+
setFunctionName(resultAccessor, options.name);
|
|
12
15
|
Object.defineProperty(resultAccessor, "latest", {
|
|
13
16
|
get() {
|
|
14
17
|
return resource.latest;
|
package/dist/data/events.d.ts
CHANGED
|
@@ -1,2 +1,9 @@
|
|
|
1
1
|
import type { RouterContext } from "../types.js";
|
|
2
|
-
|
|
2
|
+
type NativeEventConfig = {
|
|
3
|
+
preload?: boolean;
|
|
4
|
+
explicitLinks?: boolean;
|
|
5
|
+
actionBase?: string;
|
|
6
|
+
transformUrl?: (url: string) => string;
|
|
7
|
+
};
|
|
8
|
+
export declare function setupNativeEvents({ preload, explicitLinks, actionBase, transformUrl }?: NativeEventConfig): (router: RouterContext) => void;
|
|
9
|
+
export {};
|
package/dist/data/events.js
CHANGED
|
@@ -2,7 +2,7 @@ import { delegateEvents } from "solid-js/web";
|
|
|
2
2
|
import { onCleanup } from "solid-js";
|
|
3
3
|
import { actions } from "./action.js";
|
|
4
4
|
import { mockBase } from "../utils.js";
|
|
5
|
-
export function setupNativeEvents(preload = true, explicitLinks = false, actionBase = "/_server", transformUrl) {
|
|
5
|
+
export function setupNativeEvents({ preload = true, explicitLinks = false, actionBase = "/_server", transformUrl } = {}) {
|
|
6
6
|
return (router) => {
|
|
7
7
|
const basePath = router.base.path();
|
|
8
8
|
const navigateFromRoute = router.navigatorFactory(router.base);
|
|
@@ -65,7 +65,7 @@ export function setupNativeEvents(preload = true, explicitLinks = false, actionB
|
|
|
65
65
|
clearTimeout(preloadTimeout);
|
|
66
66
|
const res = handleAnchor(evt);
|
|
67
67
|
if (!res)
|
|
68
|
-
return lastElement = null;
|
|
68
|
+
return (lastElement = null);
|
|
69
69
|
const [a, url] = res;
|
|
70
70
|
if (lastElement === a)
|
|
71
71
|
return;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export * from "./routers/index.js";
|
|
2
2
|
export * from "./components.jsx";
|
|
3
3
|
export * from "./lifecycle.js";
|
|
4
|
-
export { useHref, useIsRouting, useLocation, useMatch, useCurrentMatches, useNavigate, useParams, useResolvedPath, useSearchParams, useBeforeLeave, usePreloadRoute } from "./routing.js";
|
|
4
|
+
export { useHref, useIsRouting, useLocation, useMatch, useCurrentMatches, useNavigate, useParams, useResolvedPath, useSearchParams, useBeforeLeave, usePreloadRoute, RouterContextObj as RouterContext } from "./routing.js";
|
|
5
5
|
export { mergeSearchString as _mergeSearchString } from "./utils.js";
|
|
6
6
|
export * from "./data/index.js";
|
|
7
7
|
export type { Location, LocationChange, SearchParams, MatchFilter, MatchFilters, NavigateOptions, Navigator, OutputMatch, Params, PathMatch, RouteSectionProps, RoutePreloadFunc, RoutePreloadFuncArgs, RouteDefinition, RouteDescription, RouteMatch, RouterIntegration, RouterUtils, SetParams, Submission, BeforeLeaveEventArgs, RouteLoadFunc, RouteLoadFuncArgs, RouterResponseInit, CustomResponse } from "./types.js";
|
package/dist/index.jsx
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export * from "./routers/index.js";
|
|
2
2
|
export * from "./components.jsx";
|
|
3
3
|
export * from "./lifecycle.js";
|
|
4
|
-
export { useHref, useIsRouting, useLocation, useMatch, useCurrentMatches, useNavigate, useParams, useResolvedPath, useSearchParams, useBeforeLeave, usePreloadRoute } from "./routing.js";
|
|
4
|
+
export { useHref, useIsRouting, useLocation, useMatch, useCurrentMatches, useNavigate, useParams, useResolvedPath, useSearchParams, useBeforeLeave, usePreloadRoute, RouterContextObj as RouterContext } from "./routing.js";
|
|
5
5
|
export { mergeSearchString as _mergeSearchString } from "./utils.js";
|
|
6
6
|
export * from "./data/index.js";
|
|
@@ -30,7 +30,7 @@ export function HashRouter(props) {
|
|
|
30
30
|
saveCurrentDepth();
|
|
31
31
|
},
|
|
32
32
|
init: notify => bindEvent(window, "hashchange", notifyIfNotBlocked(notify, delta => !beforeLeave.confirm(delta && delta < 0 ? delta : getSource()))),
|
|
33
|
-
create: setupNativeEvents(props.preload, props.explicitLinks, props.actionBase),
|
|
33
|
+
create: setupNativeEvents({ preload: props.preload, explicitLinks: props.explicitLinks, actionBase: props.actionBase }),
|
|
34
34
|
utils: {
|
|
35
35
|
go: delta => window.history.go(delta),
|
|
36
36
|
renderPath: path => `#${path}`,
|
|
@@ -49,7 +49,7 @@ export function MemoryRouter(props) {
|
|
|
49
49
|
get: memoryHistory.get,
|
|
50
50
|
set: memoryHistory.set,
|
|
51
51
|
init: memoryHistory.listen,
|
|
52
|
-
create: setupNativeEvents(props.preload, props.explicitLinks, props.actionBase),
|
|
52
|
+
create: setupNativeEvents({ preload: props.preload, explicitLinks: props.explicitLinks, actionBase: props.actionBase }),
|
|
53
53
|
utils: {
|
|
54
54
|
go: memoryHistory.go
|
|
55
55
|
}
|
package/dist/routers/Router.js
CHANGED
|
@@ -36,7 +36,7 @@ export function Router(props) {
|
|
|
36
36
|
return !beforeLeave.confirm(s.value, { state: s.state });
|
|
37
37
|
}
|
|
38
38
|
})),
|
|
39
|
-
create: setupNativeEvents(props.preload, props.explicitLinks, props.actionBase, props.transformUrl),
|
|
39
|
+
create: setupNativeEvents({ preload: props.preload, explicitLinks: props.explicitLinks, actionBase: props.actionBase, transformUrl: props.transformUrl }),
|
|
40
40
|
utils: {
|
|
41
41
|
go: delta => window.history.go(delta),
|
|
42
42
|
beforeLeave
|
package/dist/routing.d.ts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { JSX, Accessor } from "solid-js";
|
|
2
2
|
import type { BeforeLeaveEventArgs, Branch, Intent, Location, MatchFilters, NavigateOptions, Navigator, Params, RouteDescription, RouteContext, RouteDefinition, RouteMatch, RouterContext, RouterIntegration, SearchParams, SetSearchParams } from "./types.js";
|
|
3
|
+
/** Consider this API opaque and internal. It is likely to change in the future. */
|
|
3
4
|
export declare const RouterContextObj: import("solid-js").Context<RouterContext | undefined>;
|
|
4
5
|
export declare const RouteContextObj: import("solid-js").Context<RouteContext | undefined>;
|
|
5
6
|
export declare const useRouter: () => RouterContext;
|
|
6
7
|
export declare const useRoute: () => RouteContext;
|
|
7
8
|
export declare const useResolvedPath: (path: () => string) => Accessor<string | undefined>;
|
|
8
|
-
export declare const useHref: (to: () =>
|
|
9
|
+
export declare const useHref: <T extends string | undefined>(to: () => T) => () => string | T;
|
|
9
10
|
/**
|
|
10
11
|
* Retrieves method to do navigation. The method accepts a path to navigate to and an optional object with the following options:
|
|
11
12
|
*
|
package/dist/routing.js
CHANGED
|
@@ -4,6 +4,7 @@ import { isServer, getRequestEvent } from "solid-js/web";
|
|
|
4
4
|
import { createBeforeLeave } from "./lifecycle.js";
|
|
5
5
|
import { mockBase, createMemoObject, extractSearchParams, invariant, resolvePath, createMatcher, joinPaths, scoreRoute, mergeSearchString, expandOptionals } from "./utils.js";
|
|
6
6
|
const MAX_REDIRECTS = 100;
|
|
7
|
+
/** Consider this API opaque and internal. It is likely to change in the future. */
|
|
7
8
|
export const RouterContextObj = createContext();
|
|
8
9
|
export const RouteContextObj = createContext();
|
|
9
10
|
export const useRouter = () => invariant(useContext(RouterContextObj), "<A> and 'use' router primitives can be only used inside a Route.");
|
package/dist/types.d.ts
CHANGED
|
@@ -42,7 +42,7 @@ export interface NavigateOptions<S = unknown> {
|
|
|
42
42
|
state: S;
|
|
43
43
|
}
|
|
44
44
|
export interface Navigator {
|
|
45
|
-
(to: string, options?: Partial<NavigateOptions>): void;
|
|
45
|
+
(to: string | number, options?: Partial<NavigateOptions>): void;
|
|
46
46
|
(delta: number): void;
|
|
47
47
|
}
|
|
48
48
|
export type NavigatorFactory = (route?: RouteContext) => Navigator;
|
package/dist/utils.d.ts
CHANGED
|
@@ -10,3 +10,4 @@ export declare function scoreRoute(route: RouteDescription): number;
|
|
|
10
10
|
export declare function createMemoObject<T extends Record<string | symbol, unknown>>(fn: () => T): T;
|
|
11
11
|
export declare function mergeSearchString(search: string, params: SetSearchParams): string;
|
|
12
12
|
export declare function expandOptionals(pattern: string): string[];
|
|
13
|
+
export declare function setFunctionName<T>(obj: T, value: string): T;
|
package/dist/utils.js
CHANGED
|
@@ -175,3 +175,11 @@ export function expandOptionals(pattern) {
|
|
|
175
175
|
}
|
|
176
176
|
return expandOptionals(suffix).reduce((results, expansion) => [...results, ...prefixes.map(p => p + expansion)], []);
|
|
177
177
|
}
|
|
178
|
+
export function setFunctionName(obj, value) {
|
|
179
|
+
Object.defineProperty(obj, "name", {
|
|
180
|
+
value,
|
|
181
|
+
writable: false,
|
|
182
|
+
configurable: false
|
|
183
|
+
});
|
|
184
|
+
return obj;
|
|
185
|
+
}
|
package/package.json
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
"Ryan Turnquist"
|
|
7
7
|
],
|
|
8
8
|
"license": "MIT",
|
|
9
|
-
"version": "0.16.
|
|
9
|
+
"version": "0.16.1",
|
|
10
10
|
"homepage": "https://github.com/solidjs/solid-router#readme",
|
|
11
11
|
"repository": {
|
|
12
12
|
"type": "git",
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
"solid-js": "^1.8.6"
|
|
52
52
|
},
|
|
53
53
|
"scripts": {
|
|
54
|
-
"build": "tsc && rollup -c",
|
|
54
|
+
"build": "rm -rf dist && tsc && rollup -c",
|
|
55
55
|
"test": "vitest run && npm run test:types",
|
|
56
56
|
"test:watch": "vitest",
|
|
57
57
|
"test:types": "tsc --project tsconfig.test.json",
|
package/dist/src/components.d.ts
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import type { JSX } from "solid-js";
|
|
2
|
-
import type { Location, Navigator } from "./types.js";
|
|
3
|
-
declare module "solid-js" {
|
|
4
|
-
namespace JSX {
|
|
5
|
-
interface AnchorHTMLAttributes<T> {
|
|
6
|
-
state?: string;
|
|
7
|
-
noScroll?: boolean;
|
|
8
|
-
replace?: boolean;
|
|
9
|
-
preload?: boolean;
|
|
10
|
-
link?: boolean;
|
|
11
|
-
}
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
export interface AnchorProps extends Omit<JSX.AnchorHTMLAttributes<HTMLAnchorElement>, "state"> {
|
|
15
|
-
href: string;
|
|
16
|
-
replace?: boolean | undefined;
|
|
17
|
-
noScroll?: boolean | undefined;
|
|
18
|
-
state?: unknown | undefined;
|
|
19
|
-
inactiveClass?: string | undefined;
|
|
20
|
-
activeClass?: string | undefined;
|
|
21
|
-
end?: boolean | undefined;
|
|
22
|
-
}
|
|
23
|
-
export declare function A(props: AnchorProps): JSX.Element;
|
|
24
|
-
export interface NavigateProps {
|
|
25
|
-
href: ((args: {
|
|
26
|
-
navigate: Navigator;
|
|
27
|
-
location: Location;
|
|
28
|
-
}) => string) | string;
|
|
29
|
-
state?: unknown;
|
|
30
|
-
}
|
|
31
|
-
export declare function Navigate(props: NavigateProps): null;
|
package/dist/src/components.jsx
DELETED
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import { createMemo, mergeProps, splitProps } from "solid-js";
|
|
2
|
-
import { useHref, useLocation, useNavigate, useResolvedPath } from "./routing.js";
|
|
3
|
-
import { normalizePath } from "./utils.js";
|
|
4
|
-
export function A(props) {
|
|
5
|
-
props = mergeProps({ inactiveClass: "inactive", activeClass: "active" }, props);
|
|
6
|
-
const [, rest] = splitProps(props, [
|
|
7
|
-
"href",
|
|
8
|
-
"state",
|
|
9
|
-
"class",
|
|
10
|
-
"activeClass",
|
|
11
|
-
"inactiveClass",
|
|
12
|
-
"end"
|
|
13
|
-
]);
|
|
14
|
-
const to = useResolvedPath(() => props.href);
|
|
15
|
-
const href = useHref(to);
|
|
16
|
-
const location = useLocation();
|
|
17
|
-
const isActive = createMemo(() => {
|
|
18
|
-
const to_ = to();
|
|
19
|
-
if (to_ === undefined)
|
|
20
|
-
return [false, false];
|
|
21
|
-
const path = normalizePath(to_.split(/[?#]/, 1)[0]).toLowerCase();
|
|
22
|
-
const loc = decodeURI(normalizePath(location.pathname).toLowerCase());
|
|
23
|
-
return [props.end ? path === loc : loc.startsWith(path + "/") || loc === path, path === loc];
|
|
24
|
-
});
|
|
25
|
-
return (<a {...rest} href={href() || props.href} state={JSON.stringify(props.state)} classList={{
|
|
26
|
-
...(props.class && { [props.class]: true }),
|
|
27
|
-
[props.inactiveClass]: !isActive()[0],
|
|
28
|
-
[props.activeClass]: isActive()[0],
|
|
29
|
-
...rest.classList
|
|
30
|
-
}} link aria-current={isActive()[1] ? "page" : undefined}/>);
|
|
31
|
-
}
|
|
32
|
-
export function Navigate(props) {
|
|
33
|
-
const navigate = useNavigate();
|
|
34
|
-
const location = useLocation();
|
|
35
|
-
const { href, state } = props;
|
|
36
|
-
const path = typeof href === "function" ? href({ navigate, location }) : href;
|
|
37
|
-
navigate(path, { replace: true, state });
|
|
38
|
-
return null;
|
|
39
|
-
}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { JSX } from "solid-js";
|
|
2
|
-
import type { Submission, SubmissionStub, NarrowResponse } from "../types.js";
|
|
3
|
-
export type Action<T extends Array<any>, U, V = T> = (T extends [FormData | URLSearchParams] | [] ? JSX.SerializableAttributeValue : unknown) & ((...vars: T) => Promise<NarrowResponse<U>>) & {
|
|
4
|
-
url: string;
|
|
5
|
-
with<A extends any[], B extends any[]>(this: (this: any, ...args: [...A, ...B]) => Promise<NarrowResponse<U>>, ...args: A): Action<B, U, V>;
|
|
6
|
-
};
|
|
7
|
-
export declare const actions: Map<string, Action<any, any, any>>;
|
|
8
|
-
export declare function useSubmissions<T extends Array<any>, U, V>(fn: Action<T, U, V>, filter?: (input: V) => boolean): Submission<T, NarrowResponse<U>>[] & {
|
|
9
|
-
pending: boolean;
|
|
10
|
-
};
|
|
11
|
-
export declare function useSubmission<T extends Array<any>, U, V>(fn: Action<T, U, V>, filter?: (input: V) => boolean): Submission<T, NarrowResponse<U>> | SubmissionStub;
|
|
12
|
-
export declare function useAction<T extends Array<any>, U, V>(action: Action<T, U, V>): (...args: Parameters<Action<T, U, V>>) => Promise<NarrowResponse<U>>;
|
|
13
|
-
export declare function action<T extends Array<any>, U = void>(fn: (...args: T) => Promise<U>, name?: string): Action<T, U>;
|
|
14
|
-
export declare function action<T extends Array<any>, U = void>(fn: (...args: T) => Promise<U>, options?: {
|
|
15
|
-
name?: string;
|
|
16
|
-
onComplete?: (s: Submission<T, U>) => void;
|
|
17
|
-
}): Action<T, U>;
|
package/dist/src/data/action.js
DELETED
|
@@ -1,163 +0,0 @@
|
|
|
1
|
-
import { $TRACK, createMemo, createSignal, onCleanup, getOwner } from "solid-js";
|
|
2
|
-
import { isServer } from "solid-js/web";
|
|
3
|
-
import { useRouter } from "../routing.js";
|
|
4
|
-
import { mockBase, setFunctionName } from "../utils.js";
|
|
5
|
-
import { cacheKeyOp, hashKey, revalidate, query } from "./query.js";
|
|
6
|
-
export const actions = /* #__PURE__ */ new Map();
|
|
7
|
-
export function useSubmissions(fn, filter) {
|
|
8
|
-
const router = useRouter();
|
|
9
|
-
const subs = createMemo(() => router.submissions[0]().filter(s => s.url === fn.base && (!filter || filter(s.input))));
|
|
10
|
-
return new Proxy([], {
|
|
11
|
-
get(_, property) {
|
|
12
|
-
if (property === $TRACK)
|
|
13
|
-
return subs();
|
|
14
|
-
if (property === "pending")
|
|
15
|
-
return subs().some(sub => !sub.result);
|
|
16
|
-
return subs()[property];
|
|
17
|
-
},
|
|
18
|
-
has(_, property) {
|
|
19
|
-
return property in subs();
|
|
20
|
-
}
|
|
21
|
-
});
|
|
22
|
-
}
|
|
23
|
-
export function useSubmission(fn, filter) {
|
|
24
|
-
const submissions = useSubmissions(fn, filter);
|
|
25
|
-
return new Proxy({}, {
|
|
26
|
-
get(_, property) {
|
|
27
|
-
if ((submissions.length === 0 && property === "clear") || property === "retry")
|
|
28
|
-
return () => { };
|
|
29
|
-
return submissions[submissions.length - 1]?.[property];
|
|
30
|
-
}
|
|
31
|
-
});
|
|
32
|
-
}
|
|
33
|
-
export function useAction(action) {
|
|
34
|
-
const r = useRouter();
|
|
35
|
-
return (...args) => action.apply({ r }, args);
|
|
36
|
-
}
|
|
37
|
-
export function action(fn, options = {}) {
|
|
38
|
-
function mutate(...variables) {
|
|
39
|
-
const router = this.r;
|
|
40
|
-
const form = this.f;
|
|
41
|
-
const p = (router.singleFlight && fn.withOptions
|
|
42
|
-
? fn.withOptions({ headers: { "X-Single-Flight": "true" } })
|
|
43
|
-
: fn)(...variables);
|
|
44
|
-
const [result, setResult] = createSignal();
|
|
45
|
-
let submission;
|
|
46
|
-
function handler(error) {
|
|
47
|
-
return async (res) => {
|
|
48
|
-
const result = await handleResponse(res, error, router.navigatorFactory());
|
|
49
|
-
let retry = null;
|
|
50
|
-
o.onComplete?.({
|
|
51
|
-
...submission,
|
|
52
|
-
result: result?.data,
|
|
53
|
-
error: result?.error,
|
|
54
|
-
pending: false,
|
|
55
|
-
retry() {
|
|
56
|
-
return (retry = submission.retry());
|
|
57
|
-
}
|
|
58
|
-
});
|
|
59
|
-
if (retry)
|
|
60
|
-
return retry;
|
|
61
|
-
if (!result)
|
|
62
|
-
return submission.clear();
|
|
63
|
-
setResult(result);
|
|
64
|
-
if (result.error && !form)
|
|
65
|
-
throw result.error;
|
|
66
|
-
return result.data;
|
|
67
|
-
};
|
|
68
|
-
}
|
|
69
|
-
router.submissions[1](s => [
|
|
70
|
-
...s,
|
|
71
|
-
(submission = {
|
|
72
|
-
input: variables,
|
|
73
|
-
url,
|
|
74
|
-
get result() {
|
|
75
|
-
return result()?.data;
|
|
76
|
-
},
|
|
77
|
-
get error() {
|
|
78
|
-
return result()?.error;
|
|
79
|
-
},
|
|
80
|
-
get pending() {
|
|
81
|
-
return !result();
|
|
82
|
-
},
|
|
83
|
-
clear() {
|
|
84
|
-
router.submissions[1](v => v.filter(i => i !== submission));
|
|
85
|
-
},
|
|
86
|
-
retry() {
|
|
87
|
-
setResult(undefined);
|
|
88
|
-
const p = fn(...variables);
|
|
89
|
-
return p.then(handler(), handler(true));
|
|
90
|
-
}
|
|
91
|
-
})
|
|
92
|
-
]);
|
|
93
|
-
return p.then(handler(), handler(true));
|
|
94
|
-
}
|
|
95
|
-
const o = typeof options === "string" ? { name: options } : options;
|
|
96
|
-
const name = o.name || (!isServer ? String(hashString(fn.toString())) : undefined);
|
|
97
|
-
const url = fn.url || (name && `https://action/${name}`) || "";
|
|
98
|
-
mutate.base = url;
|
|
99
|
-
if (name)
|
|
100
|
-
setFunctionName(mutate, name);
|
|
101
|
-
return toAction(mutate, url);
|
|
102
|
-
}
|
|
103
|
-
function toAction(fn, url) {
|
|
104
|
-
fn.toString = () => {
|
|
105
|
-
if (!url)
|
|
106
|
-
throw new Error("Client Actions need explicit names if server rendered");
|
|
107
|
-
return url;
|
|
108
|
-
};
|
|
109
|
-
fn.with = function (...args) {
|
|
110
|
-
const newFn = function (...passedArgs) {
|
|
111
|
-
return fn.call(this, ...args, ...passedArgs);
|
|
112
|
-
};
|
|
113
|
-
newFn.base = fn.base;
|
|
114
|
-
const uri = new URL(url, mockBase);
|
|
115
|
-
uri.searchParams.set("args", hashKey(args));
|
|
116
|
-
return toAction(newFn, (uri.origin === "https://action" ? uri.origin : "") + uri.pathname + uri.search);
|
|
117
|
-
};
|
|
118
|
-
fn.url = url;
|
|
119
|
-
if (!isServer) {
|
|
120
|
-
actions.set(url, fn);
|
|
121
|
-
getOwner() && onCleanup(() => actions.delete(url));
|
|
122
|
-
}
|
|
123
|
-
return fn;
|
|
124
|
-
}
|
|
125
|
-
const hashString = (s) => s.split("").reduce((a, b) => ((a << 5) - a + b.charCodeAt(0)) | 0, 0);
|
|
126
|
-
async function handleResponse(response, error, navigate) {
|
|
127
|
-
let data;
|
|
128
|
-
let custom;
|
|
129
|
-
let keys;
|
|
130
|
-
let flightKeys;
|
|
131
|
-
if (response instanceof Response) {
|
|
132
|
-
if (response.headers.has("X-Revalidate"))
|
|
133
|
-
keys = response.headers.get("X-Revalidate").split(",");
|
|
134
|
-
if (response.customBody) {
|
|
135
|
-
data = custom = await response.customBody();
|
|
136
|
-
if (response.headers.has("X-Single-Flight")) {
|
|
137
|
-
data = data._$value;
|
|
138
|
-
delete custom._$value;
|
|
139
|
-
flightKeys = Object.keys(custom);
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
if (response.headers.has("Location")) {
|
|
143
|
-
const locationUrl = response.headers.get("Location") || "/";
|
|
144
|
-
if (locationUrl.startsWith("http")) {
|
|
145
|
-
window.location.href = locationUrl;
|
|
146
|
-
}
|
|
147
|
-
else {
|
|
148
|
-
navigate(locationUrl);
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
else if (error)
|
|
153
|
-
return { error: response };
|
|
154
|
-
else
|
|
155
|
-
data = response;
|
|
156
|
-
// invalidate
|
|
157
|
-
cacheKeyOp(keys, entry => (entry[0] = 0));
|
|
158
|
-
// set cache
|
|
159
|
-
flightKeys && flightKeys.forEach(k => query.set(k, custom[k]));
|
|
160
|
-
// trigger revalidation
|
|
161
|
-
await revalidate(keys, false);
|
|
162
|
-
return data != null ? { data } : undefined;
|
|
163
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|