@solidjs/router 0.16.1 → 0.17.0-next.0
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/README.md +85 -79
- package/dist/components.jsx +22 -16
- package/dist/data/action.d.ts +12 -10
- package/dist/data/action.js +94 -75
- package/dist/data/events.js +1 -1
- package/dist/data/index.d.ts +2 -3
- package/dist/data/index.js +2 -3
- package/dist/data/query.d.ts +1 -3
- package/dist/data/query.js +10 -16
- package/dist/index.d.ts +1 -1
- package/dist/index.js +212 -261
- package/dist/lifecycle.js +1 -1
- package/dist/routers/Router.js +1 -1
- package/dist/routers/StaticRouter.js +1 -1
- package/dist/routers/components.d.ts +0 -4
- package/dist/routers/components.jsx +30 -19
- package/dist/routing.d.ts +2 -2
- package/dist/routing.js +70 -49
- package/dist/types.d.ts +2 -17
- package/package.json +7 -5
- package/dist/data/createAsync.d.ts +0 -32
- package/dist/data/createAsync.js +0 -96
package/dist/lifecycle.js
CHANGED
package/dist/routers/Router.js
CHANGED
|
@@ -10,8 +10,6 @@ export type BaseRouterProps = {
|
|
|
10
10
|
singleFlight?: boolean;
|
|
11
11
|
children?: JSX.Element | RouteDefinition | RouteDefinition[];
|
|
12
12
|
transformUrl?: (url: string) => string;
|
|
13
|
-
/** @deprecated use rootPreload */
|
|
14
|
-
rootLoad?: RoutePreloadFunc;
|
|
15
13
|
};
|
|
16
14
|
export declare const createRouterComponent: (router: RouterIntegration) => (props: BaseRouterProps) => JSX.Element;
|
|
17
15
|
export type RouteProps<S extends string, T = unknown> = {
|
|
@@ -21,7 +19,5 @@ export type RouteProps<S extends string, T = unknown> = {
|
|
|
21
19
|
matchFilters?: MatchFilters<S>;
|
|
22
20
|
component?: Component<RouteSectionProps<T>>;
|
|
23
21
|
info?: Record<string, any>;
|
|
24
|
-
/** @deprecated use preload */
|
|
25
|
-
load?: RoutePreloadFunc<T>;
|
|
26
22
|
};
|
|
27
23
|
export declare const Route: <S extends string, T = unknown>(props: RouteProps<S, T>) => JSX.Element;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/*@refresh skip*/
|
|
2
|
-
import { children, createMemo, createRoot, getOwner,
|
|
3
|
-
import { getRequestEvent, isServer } from "
|
|
2
|
+
import { children, createMemo, createRoot, getOwner, merge, untrack } from "solid-js";
|
|
3
|
+
import { getRequestEvent, isServer } from "@solidjs/web";
|
|
4
4
|
import { createBranches, createRouteContext, createRouterContext, getIntent, getRouteMatches, RouteContextObj, RouterContextObj, setInPreloadFn } from "../routing.js";
|
|
5
5
|
export const createRouterComponent = (router) => (props) => {
|
|
6
6
|
const { base } = props;
|
|
@@ -13,12 +13,12 @@ export const createRouterComponent = (router) => (props) => {
|
|
|
13
13
|
transformUrl: props.transformUrl,
|
|
14
14
|
});
|
|
15
15
|
router.create && router.create(routerState);
|
|
16
|
-
return (<RouterContextObj
|
|
17
|
-
<Root routerState={routerState} root={props.root} preload={props.rootPreload
|
|
16
|
+
return (<RouterContextObj value={routerState}>
|
|
17
|
+
<Root routerState={routerState} root={props.root} preload={props.rootPreload}>
|
|
18
18
|
{(context = getOwner()) && null}
|
|
19
19
|
<Routes routerState={routerState} branches={branches()}/>
|
|
20
20
|
</Root>
|
|
21
|
-
</RouterContextObj
|
|
21
|
+
</RouterContextObj>);
|
|
22
22
|
};
|
|
23
23
|
function Root(props) {
|
|
24
24
|
const location = props.routerState.location;
|
|
@@ -29,11 +29,13 @@ function Root(props) {
|
|
|
29
29
|
props.preload({ params, location, intent: getIntent() || "initial" });
|
|
30
30
|
setInPreloadFn(false);
|
|
31
31
|
}));
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
32
|
+
const RootComp = props.root;
|
|
33
|
+
if (RootComp) {
|
|
34
|
+
return (<RootComp params={params} location={location} data={data()}>
|
|
35
|
+
{props.children}
|
|
36
|
+
</RootComp>);
|
|
37
|
+
}
|
|
38
|
+
return props.children;
|
|
37
39
|
}
|
|
38
40
|
function Routes(props) {
|
|
39
41
|
if (isServer) {
|
|
@@ -54,11 +56,14 @@ function Routes(props) {
|
|
|
54
56
|
}
|
|
55
57
|
const disposers = [];
|
|
56
58
|
let root;
|
|
57
|
-
|
|
58
|
-
|
|
59
|
+
let prevMatches;
|
|
60
|
+
const routeStates = createMemo((prev) => {
|
|
61
|
+
const nextMatches = props.routerState.matches();
|
|
62
|
+
const previousMatches = prevMatches;
|
|
63
|
+
let equal = previousMatches && nextMatches.length === previousMatches.length;
|
|
59
64
|
const next = [];
|
|
60
65
|
for (let i = 0, len = nextMatches.length; i < len; i++) {
|
|
61
|
-
const prevMatch =
|
|
66
|
+
const prevMatch = previousMatches && previousMatches[i];
|
|
62
67
|
const nextMatch = nextMatches[i];
|
|
63
68
|
if (prev && prevMatch && nextMatch.route.key === prevMatch.route.key) {
|
|
64
69
|
next[i] = prev[i];
|
|
@@ -70,7 +75,7 @@ function Routes(props) {
|
|
|
70
75
|
}
|
|
71
76
|
createRoot(dispose => {
|
|
72
77
|
disposers[i] = dispose;
|
|
73
|
-
next[i] = createRouteContext(props.routerState, next[i - 1] || props.routerState.base, createOutlet(() => routeStates()[i + 1]), () => {
|
|
78
|
+
next[i] = createRouteContext(props.routerState, next[i - 1] || props.routerState.base, createOutlet(() => routeStates()?.[i + 1]), () => {
|
|
74
79
|
const routeMatches = props.routerState.matches();
|
|
75
80
|
return routeMatches[i] ?? routeMatches[0];
|
|
76
81
|
});
|
|
@@ -79,21 +84,27 @@ function Routes(props) {
|
|
|
79
84
|
}
|
|
80
85
|
disposers.splice(nextMatches.length).forEach(dispose => dispose());
|
|
81
86
|
if (prev && equal) {
|
|
87
|
+
prevMatches = nextMatches;
|
|
82
88
|
return prev;
|
|
83
89
|
}
|
|
84
90
|
root = next[0];
|
|
91
|
+
prevMatches = nextMatches;
|
|
85
92
|
return next;
|
|
86
|
-
})
|
|
93
|
+
}, undefined);
|
|
87
94
|
return createOutlet(() => routeStates() && root)();
|
|
88
95
|
}
|
|
89
96
|
const createOutlet = (child) => {
|
|
90
|
-
return () =>
|
|
91
|
-
|
|
92
|
-
|
|
97
|
+
return () => {
|
|
98
|
+
const c = child();
|
|
99
|
+
if (c) {
|
|
100
|
+
return <RouteContextObj value={c}>{c.outlet()}</RouteContextObj>;
|
|
101
|
+
}
|
|
102
|
+
return undefined;
|
|
103
|
+
};
|
|
93
104
|
};
|
|
94
105
|
export const Route = (props) => {
|
|
95
106
|
const childRoutes = children(() => props.children);
|
|
96
|
-
return
|
|
107
|
+
return merge(props, {
|
|
97
108
|
get children() {
|
|
98
109
|
return childRoutes();
|
|
99
110
|
}
|
package/dist/routing.d.ts
CHANGED
|
@@ -39,8 +39,8 @@ export declare const useNavigate: () => Navigator;
|
|
|
39
39
|
*/
|
|
40
40
|
export declare const useLocation: <S = unknown>() => Location<S>;
|
|
41
41
|
/**
|
|
42
|
-
* Retrieves signal that indicates whether the
|
|
43
|
-
* Useful for showing
|
|
42
|
+
* Retrieves a signal that indicates whether the router is currently processing a navigation.
|
|
43
|
+
* Useful for showing pending navigation state while the next route and its data settle.
|
|
44
44
|
*
|
|
45
45
|
* @example
|
|
46
46
|
* ```js
|
package/dist/routing.js
CHANGED
|
@@ -1,15 +1,23 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { createComponent, createContext, createMemo,
|
|
3
|
-
import { isServer, getRequestEvent } from "
|
|
1
|
+
import { flush, runWithOwner } from "solid-js";
|
|
2
|
+
import { createComponent, createContext, createMemo, createSignal, onCleanup, untrack, useContext } from "solid-js";
|
|
3
|
+
import { isServer, getRequestEvent } from "@solidjs/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
7
|
/** Consider this API opaque and internal. It is likely to change in the future. */
|
|
8
8
|
export const RouterContextObj = createContext();
|
|
9
9
|
export const RouteContextObj = createContext();
|
|
10
|
+
function useOptionalContext(context) {
|
|
11
|
+
try {
|
|
12
|
+
return useContext(context);
|
|
13
|
+
}
|
|
14
|
+
catch {
|
|
15
|
+
return undefined;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
10
18
|
export const useRouter = () => invariant(useContext(RouterContextObj), "<A> and 'use' router primitives can be only used inside a Route.");
|
|
11
19
|
let TempRoute;
|
|
12
|
-
export const useRoute = () => TempRoute ||
|
|
20
|
+
export const useRoute = () => TempRoute || useOptionalContext(RouteContextObj) || useRouter().base;
|
|
13
21
|
export const useResolvedPath = (path) => {
|
|
14
22
|
const route = useRoute();
|
|
15
23
|
return createMemo(() => route.resolvePath(path()));
|
|
@@ -53,8 +61,8 @@ export const useNavigate = () => useRouter().navigatorFactory();
|
|
|
53
61
|
*/
|
|
54
62
|
export const useLocation = () => useRouter().location;
|
|
55
63
|
/**
|
|
56
|
-
* Retrieves signal that indicates whether the
|
|
57
|
-
* Useful for showing
|
|
64
|
+
* Retrieves a signal that indicates whether the router is currently processing a navigation.
|
|
65
|
+
* Useful for showing pending navigation state while the next route and its data settle.
|
|
58
66
|
*
|
|
59
67
|
* @example
|
|
60
68
|
* ```js
|
|
@@ -205,12 +213,12 @@ export const useBeforeLeave = (listener) => {
|
|
|
205
213
|
onCleanup(s);
|
|
206
214
|
};
|
|
207
215
|
export function createRoutes(routeDef, base = "") {
|
|
208
|
-
const { component, preload,
|
|
216
|
+
const { component, preload, children, info } = routeDef;
|
|
209
217
|
const isLeaf = !children || (Array.isArray(children) && !children.length);
|
|
210
218
|
const shared = {
|
|
211
219
|
key: routeDef,
|
|
212
220
|
component,
|
|
213
|
-
preload
|
|
221
|
+
preload,
|
|
214
222
|
info
|
|
215
223
|
};
|
|
216
224
|
return asArray(routeDef.path).reduce((acc, originalPath) => {
|
|
@@ -309,7 +317,7 @@ function createLocation(path, state, queryWrapper) {
|
|
|
309
317
|
const search = createMemo(() => url().search, true);
|
|
310
318
|
const hash = createMemo(() => url().hash);
|
|
311
319
|
const key = () => "";
|
|
312
|
-
const queryFn =
|
|
320
|
+
const queryFn = createMemo(() => extractSearchParams(url()));
|
|
313
321
|
return {
|
|
314
322
|
get pathname() {
|
|
315
323
|
return pathname();
|
|
@@ -352,43 +360,32 @@ export function createRouterContext(integration, branches, getContext, options =
|
|
|
352
360
|
else if (basePath && !source().value) {
|
|
353
361
|
setSource({ value: basePath, replace: true, scroll: false });
|
|
354
362
|
}
|
|
355
|
-
const [isRouting, setIsRouting] = createSignal(false);
|
|
356
|
-
//
|
|
363
|
+
const [isRouting, setIsRouting] = createSignal(false, { pureWrite: true });
|
|
364
|
+
// Navigate override written from event handlers.
|
|
365
|
+
const [navigateTarget, setNavigateTarget] = createSignal(undefined, {
|
|
366
|
+
pureWrite: true
|
|
367
|
+
});
|
|
368
|
+
// Keep track of last target, so that last call to navigate wins
|
|
357
369
|
let lastTransitionTarget;
|
|
358
|
-
//
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
if (
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
if (!isServer)
|
|
373
|
-
submissions[1](subs => subs.filter(s => s.pending));
|
|
374
|
-
}).finally(() => {
|
|
375
|
-
if (lastTransitionTarget !== newTarget)
|
|
376
|
-
return;
|
|
377
|
-
// Batch, in order for isRouting and final source update to happen together
|
|
378
|
-
batch(() => {
|
|
379
|
-
intent = undefined;
|
|
380
|
-
if (newIntent === "navigate")
|
|
381
|
-
navigateEnd(lastTransitionTarget);
|
|
382
|
-
setIsRouting(false);
|
|
383
|
-
lastTransitionTarget = undefined;
|
|
384
|
-
});
|
|
385
|
-
});
|
|
386
|
-
};
|
|
387
|
-
const [reference, setReference] = createSignal(source().value);
|
|
388
|
-
const [state, setState] = createSignal(source().state);
|
|
370
|
+
// source() remains canonical for native history changes; navigateTarget()
|
|
371
|
+
// temporarily overrides it for in-flight programmatic navigation.
|
|
372
|
+
const reference = createMemo(() => {
|
|
373
|
+
const nav = navigateTarget();
|
|
374
|
+
if (nav !== undefined)
|
|
375
|
+
return nav.value;
|
|
376
|
+
return source().value;
|
|
377
|
+
});
|
|
378
|
+
const state = createMemo(() => {
|
|
379
|
+
const nav = navigateTarget();
|
|
380
|
+
if (nav !== undefined)
|
|
381
|
+
return nav.state;
|
|
382
|
+
return source().state;
|
|
383
|
+
});
|
|
389
384
|
const location = createLocation(reference, state, utils.queryWrapper);
|
|
390
385
|
const referrers = [];
|
|
391
|
-
const submissions = createSignal(isServer ? initFromFlash() : []
|
|
386
|
+
const submissions = createSignal(isServer ? initFromFlash() : [], {
|
|
387
|
+
pureWrite: true
|
|
388
|
+
});
|
|
392
389
|
const matches = createMemo(() => {
|
|
393
390
|
if (typeof options.transformUrl === "function") {
|
|
394
391
|
return getRouteMatches(branches(), options.transformUrl(location.pathname));
|
|
@@ -414,8 +411,6 @@ export function createRouterContext(integration, branches, getContext, options =
|
|
|
414
411
|
return resolvePath(basePath, to);
|
|
415
412
|
}
|
|
416
413
|
};
|
|
417
|
-
// Create a native transition, when source updates
|
|
418
|
-
createRenderEffect(on(source, source => transition("native", source), { defer: true }));
|
|
419
414
|
return {
|
|
420
415
|
base: baseRoute,
|
|
421
416
|
location,
|
|
@@ -470,17 +465,35 @@ export function createRouterContext(integration, branches, getContext, options =
|
|
|
470
465
|
}
|
|
471
466
|
else if (beforeLeave.confirm(resolvedTo, options)) {
|
|
472
467
|
referrers.push({ value: current, replace, scroll, state: state() });
|
|
473
|
-
|
|
468
|
+
const newTarget = {
|
|
474
469
|
value: resolvedTo,
|
|
475
470
|
state: nextState
|
|
476
|
-
}
|
|
471
|
+
};
|
|
472
|
+
if (lastTransitionTarget === undefined) {
|
|
473
|
+
setIsRouting(true);
|
|
474
|
+
flush();
|
|
475
|
+
}
|
|
476
|
+
intent = "navigate";
|
|
477
|
+
lastTransitionTarget = newTarget;
|
|
478
|
+
if (lastTransitionTarget === newTarget) {
|
|
479
|
+
setNavigateTarget({ ...lastTransitionTarget });
|
|
480
|
+
queueMicrotask(() => {
|
|
481
|
+
if (lastTransitionTarget !== newTarget)
|
|
482
|
+
return;
|
|
483
|
+
intent = undefined;
|
|
484
|
+
navigateEnd(lastTransitionTarget);
|
|
485
|
+
setNavigateTarget(undefined);
|
|
486
|
+
setIsRouting(false);
|
|
487
|
+
lastTransitionTarget = undefined;
|
|
488
|
+
});
|
|
489
|
+
}
|
|
477
490
|
}
|
|
478
491
|
}
|
|
479
492
|
});
|
|
480
493
|
}
|
|
481
494
|
function navigatorFactory(route) {
|
|
482
495
|
// Workaround for vite issue (https://github.com/vitejs/vite/issues/3803)
|
|
483
|
-
route = route ||
|
|
496
|
+
route = route || useOptionalContext(RouteContextObj) || baseRoute;
|
|
484
497
|
return (to, options) => navigateFromRoute(route, to, options);
|
|
485
498
|
}
|
|
486
499
|
function navigateEnd(next) {
|
|
@@ -525,7 +538,15 @@ export function createRouterContext(integration, branches, getContext, options =
|
|
|
525
538
|
}
|
|
526
539
|
function initFromFlash() {
|
|
527
540
|
const e = getRequestEvent();
|
|
528
|
-
|
|
541
|
+
if (!(e && e.router && e.router.submission))
|
|
542
|
+
return [];
|
|
543
|
+
return [
|
|
544
|
+
{
|
|
545
|
+
...e.router.submission,
|
|
546
|
+
clear() { },
|
|
547
|
+
retry() { }
|
|
548
|
+
}
|
|
549
|
+
];
|
|
529
550
|
}
|
|
530
551
|
}
|
|
531
552
|
export function createRouteContext(router, parent, outlet, match) {
|
package/dist/types.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Component, JSX, Signal } from "solid-js";
|
|
2
|
-
declare module "
|
|
2
|
+
declare module "@solidjs/web" {
|
|
3
3
|
interface RequestEvent {
|
|
4
4
|
response: {
|
|
5
5
|
status?: number;
|
|
@@ -12,6 +12,7 @@ declare module "solid-js/web" {
|
|
|
12
12
|
submission?: {
|
|
13
13
|
input: any;
|
|
14
14
|
result: any;
|
|
15
|
+
error?: any;
|
|
15
16
|
url: string;
|
|
16
17
|
};
|
|
17
18
|
dataOnly?: boolean | string[];
|
|
@@ -78,8 +79,6 @@ export type RouteDefinition<S extends string | string[] = any, T = unknown> = {
|
|
|
78
79
|
children?: RouteDefinition | RouteDefinition[];
|
|
79
80
|
component?: Component<RouteSectionProps<T>>;
|
|
80
81
|
info?: Record<string, any>;
|
|
81
|
-
/** @deprecated use preload */
|
|
82
|
-
load?: RoutePreloadFunc;
|
|
83
82
|
};
|
|
84
83
|
export type MatchFilter = readonly string[] | RegExp | ((s: string) => boolean);
|
|
85
84
|
export type PathParams<P extends string | readonly string[]> = P extends `${infer Head}/${infer Tail}` ? [...PathParams<Head>, ...PathParams<Tail>] : P extends `:${infer S}?` ? [S] : P extends `:${infer S}` ? [S] : P extends `*${infer S}` ? [S] : [];
|
|
@@ -166,20 +165,10 @@ export type Submission<T, U> = {
|
|
|
166
165
|
readonly input: T;
|
|
167
166
|
readonly result?: U;
|
|
168
167
|
readonly error: any;
|
|
169
|
-
readonly pending: boolean;
|
|
170
168
|
readonly url: string;
|
|
171
169
|
clear: () => void;
|
|
172
170
|
retry: () => void;
|
|
173
171
|
};
|
|
174
|
-
export type SubmissionStub = {
|
|
175
|
-
readonly input: undefined;
|
|
176
|
-
readonly result: undefined;
|
|
177
|
-
readonly error: undefined;
|
|
178
|
-
readonly pending: undefined;
|
|
179
|
-
readonly url: undefined;
|
|
180
|
-
clear: () => void;
|
|
181
|
-
retry: () => void;
|
|
182
|
-
};
|
|
183
172
|
export interface MaybePreloadableComponent extends Component {
|
|
184
173
|
preload?: () => void;
|
|
185
174
|
}
|
|
@@ -194,7 +183,3 @@ export type CustomResponse<T> = Omit<Response, "clone"> & {
|
|
|
194
183
|
customBody: () => T;
|
|
195
184
|
clone(...args: readonly unknown[]): CustomResponse<T>;
|
|
196
185
|
};
|
|
197
|
-
/** @deprecated */
|
|
198
|
-
export type RouteLoadFunc = RoutePreloadFunc;
|
|
199
|
-
/** @deprecated */
|
|
200
|
-
export type RouteLoadFuncArgs = RoutePreloadFuncArgs;
|
package/package.json
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
"Ryan Turnquist"
|
|
7
7
|
],
|
|
8
8
|
"license": "MIT",
|
|
9
|
-
"version": "0.
|
|
9
|
+
"version": "0.17.0-next.0",
|
|
10
10
|
"homepage": "https://github.com/solidjs/solid-router#readme",
|
|
11
11
|
"repository": {
|
|
12
12
|
"type": "git",
|
|
@@ -29,6 +29,7 @@
|
|
|
29
29
|
],
|
|
30
30
|
"sideEffects": false,
|
|
31
31
|
"devDependencies": {
|
|
32
|
+
"@solidjs/web": "2.0.0-beta.3",
|
|
32
33
|
"@babel/core": "^7.26.0",
|
|
33
34
|
"@babel/preset-typescript": "^7.26.0",
|
|
34
35
|
"@changesets/cli": "^2.27.10",
|
|
@@ -37,18 +38,19 @@
|
|
|
37
38
|
"@rollup/plugin-terser": "0.4.4",
|
|
38
39
|
"@types/jest": "^29.5.14",
|
|
39
40
|
"@types/node": "^22.10.0",
|
|
40
|
-
"babel-preset-solid": "
|
|
41
|
+
"babel-preset-solid": "2.0.0-beta.3",
|
|
41
42
|
"jsdom": "^25.0.1",
|
|
42
43
|
"prettier": "^3.4.1",
|
|
43
44
|
"rollup": "^4.27.4",
|
|
44
|
-
"solid-js": "
|
|
45
|
+
"solid-js": "2.0.0-beta.3",
|
|
45
46
|
"typescript": "^5.7.2",
|
|
46
47
|
"vite": "^6.0.0",
|
|
47
|
-
"vite-plugin-solid": "
|
|
48
|
+
"vite-plugin-solid": "3.0.0-next.2",
|
|
48
49
|
"vitest": "^2.1.6"
|
|
49
50
|
},
|
|
50
51
|
"peerDependencies": {
|
|
51
|
-
"
|
|
52
|
+
"@solidjs/web": "^2.0.0-beta.3",
|
|
53
|
+
"solid-js": "^2.0.0-beta.3"
|
|
52
54
|
},
|
|
53
55
|
"scripts": {
|
|
54
56
|
"build": "rm -rf dist && tsc && rollup -c",
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import { type ReconcileOptions } from "solid-js/store";
|
|
2
|
-
/**
|
|
3
|
-
* As `createAsync` and `createAsyncStore` are wrappers for `createResource`,
|
|
4
|
-
* this type allows to support `latest` field for these primitives.
|
|
5
|
-
* It will be removed in the future.
|
|
6
|
-
*/
|
|
7
|
-
export type AccessorWithLatest<T> = {
|
|
8
|
-
(): T;
|
|
9
|
-
latest: T;
|
|
10
|
-
};
|
|
11
|
-
export declare function createAsync<T>(fn: (prev: T) => Promise<T>, options: {
|
|
12
|
-
name?: string;
|
|
13
|
-
initialValue: T;
|
|
14
|
-
deferStream?: boolean;
|
|
15
|
-
}): AccessorWithLatest<T>;
|
|
16
|
-
export declare function createAsync<T>(fn: (prev: T | undefined) => Promise<T>, options?: {
|
|
17
|
-
name?: string;
|
|
18
|
-
initialValue?: T;
|
|
19
|
-
deferStream?: boolean;
|
|
20
|
-
}): AccessorWithLatest<T | undefined>;
|
|
21
|
-
export declare function createAsyncStore<T>(fn: (prev: T) => Promise<T>, options: {
|
|
22
|
-
name?: string;
|
|
23
|
-
initialValue: T;
|
|
24
|
-
deferStream?: boolean;
|
|
25
|
-
reconcile?: ReconcileOptions;
|
|
26
|
-
}): AccessorWithLatest<T>;
|
|
27
|
-
export declare function createAsyncStore<T>(fn: (prev: T | undefined) => Promise<T>, options?: {
|
|
28
|
-
name?: string;
|
|
29
|
-
initialValue?: T;
|
|
30
|
-
deferStream?: boolean;
|
|
31
|
-
reconcile?: ReconcileOptions;
|
|
32
|
-
}): AccessorWithLatest<T | undefined>;
|
package/dist/data/createAsync.js
DELETED
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* This is mock of the eventual Solid 2.0 primitive. It is not fully featured.
|
|
3
|
-
*/
|
|
4
|
-
import { createResource, sharedConfig, untrack, catchError } from "solid-js";
|
|
5
|
-
import { createStore, reconcile, unwrap } from "solid-js/store";
|
|
6
|
-
import { isServer } from "solid-js/web";
|
|
7
|
-
import { setFunctionName } from "../utils.js";
|
|
8
|
-
export function createAsync(fn, options) {
|
|
9
|
-
let resource;
|
|
10
|
-
let prev = () => !resource || resource.state === "unresolved" ? undefined : resource.latest;
|
|
11
|
-
[resource] = createResource(() => subFetch(fn, catchError(() => untrack(prev), () => undefined)), v => v, options);
|
|
12
|
-
const resultAccessor = (() => resource());
|
|
13
|
-
if (options?.name)
|
|
14
|
-
setFunctionName(resultAccessor, options.name);
|
|
15
|
-
Object.defineProperty(resultAccessor, "latest", {
|
|
16
|
-
get() {
|
|
17
|
-
return resource.latest;
|
|
18
|
-
}
|
|
19
|
-
});
|
|
20
|
-
return resultAccessor;
|
|
21
|
-
}
|
|
22
|
-
export function createAsyncStore(fn, options = {}) {
|
|
23
|
-
let resource;
|
|
24
|
-
let prev = () => !resource || resource.state === "unresolved"
|
|
25
|
-
? undefined
|
|
26
|
-
: unwrap(resource.latest);
|
|
27
|
-
[resource] = createResource(() => subFetch(fn, catchError(() => untrack(prev), () => undefined)), v => v, {
|
|
28
|
-
...options,
|
|
29
|
-
storage: (init) => createDeepSignal(init, options.reconcile)
|
|
30
|
-
});
|
|
31
|
-
const resultAccessor = (() => resource());
|
|
32
|
-
Object.defineProperty(resultAccessor, "latest", {
|
|
33
|
-
get() {
|
|
34
|
-
return resource.latest;
|
|
35
|
-
}
|
|
36
|
-
});
|
|
37
|
-
return resultAccessor;
|
|
38
|
-
}
|
|
39
|
-
function createDeepSignal(value, options) {
|
|
40
|
-
const [store, setStore] = createStore({
|
|
41
|
-
value: structuredClone(value)
|
|
42
|
-
});
|
|
43
|
-
return [
|
|
44
|
-
() => store.value,
|
|
45
|
-
(v) => {
|
|
46
|
-
typeof v === "function" && (v = v());
|
|
47
|
-
setStore("value", reconcile(structuredClone(v), options));
|
|
48
|
-
return store.value;
|
|
49
|
-
}
|
|
50
|
-
];
|
|
51
|
-
}
|
|
52
|
-
// mock promise while hydrating to prevent fetching
|
|
53
|
-
class MockPromise {
|
|
54
|
-
static all() {
|
|
55
|
-
return new MockPromise();
|
|
56
|
-
}
|
|
57
|
-
static allSettled() {
|
|
58
|
-
return new MockPromise();
|
|
59
|
-
}
|
|
60
|
-
static any() {
|
|
61
|
-
return new MockPromise();
|
|
62
|
-
}
|
|
63
|
-
static race() {
|
|
64
|
-
return new MockPromise();
|
|
65
|
-
}
|
|
66
|
-
static reject() {
|
|
67
|
-
return new MockPromise();
|
|
68
|
-
}
|
|
69
|
-
static resolve() {
|
|
70
|
-
return new MockPromise();
|
|
71
|
-
}
|
|
72
|
-
catch() {
|
|
73
|
-
return new MockPromise();
|
|
74
|
-
}
|
|
75
|
-
then() {
|
|
76
|
-
return new MockPromise();
|
|
77
|
-
}
|
|
78
|
-
finally() {
|
|
79
|
-
return new MockPromise();
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
function subFetch(fn, prev) {
|
|
83
|
-
if (isServer || !sharedConfig.context)
|
|
84
|
-
return fn(prev);
|
|
85
|
-
const ogFetch = fetch;
|
|
86
|
-
const ogPromise = Promise;
|
|
87
|
-
try {
|
|
88
|
-
window.fetch = () => new MockPromise();
|
|
89
|
-
Promise = MockPromise;
|
|
90
|
-
return fn(prev);
|
|
91
|
-
}
|
|
92
|
-
finally {
|
|
93
|
-
window.fetch = ogFetch;
|
|
94
|
-
Promise = ogPromise;
|
|
95
|
-
}
|
|
96
|
-
}
|