@solidjs/router 0.10.0-beta.3 → 0.10.0-beta.4

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.
@@ -12,6 +12,7 @@ declare module "solid-js" {
12
12
  }
13
13
  export type RouterProps = {
14
14
  base?: string;
15
+ actionBase?: string;
15
16
  root?: Component<RouteSectionProps>;
16
17
  children: JSX.Element;
17
18
  } & ({
@@ -6,14 +6,16 @@ import { createBranches, createRouteContext, createRouterContext, getRouteMatche
6
6
  import { normalizePath, createMemoObject } from "./utils";
7
7
  export const Router = (props) => {
8
8
  let e;
9
- const { source, url, base } = props;
9
+ const { source, url, base, actionBase } = props;
10
10
  const integration = source ||
11
11
  (isServer
12
- ? staticIntegration({ value: url || ((e = getRequestEvent()) && getPath(e.request.url)) || "" })
12
+ ? staticIntegration({
13
+ value: url || ((e = getRequestEvent()) && getPath(e.request.url)) || ""
14
+ })
13
15
  : pathIntegration());
14
16
  const routeDefs = children(() => props.children);
15
17
  const branches = createMemo(() => createBranches(props.root ? { component: props.root, children: routeDefs() } : routeDefs(), props.base || ""));
16
- const routerState = createRouterContext(integration, branches, base);
18
+ const routerState = createRouterContext(integration, branches, { base, actionBase });
17
19
  return (<RouterContextObj.Provider value={routerState}>
18
20
  <Routes routerState={routerState} branches={branches()}/>
19
21
  </RouterContextObj.Provider>);
@@ -20,22 +20,22 @@ export function useSubmission(fn, filter) {
20
20
  const submissions = useSubmissions(fn, filter);
21
21
  return {
22
22
  get clear() {
23
- return submissions[0]?.clear;
23
+ return submissions[submissions.length - 1]?.clear;
24
24
  },
25
25
  get retry() {
26
- return submissions[0]?.retry;
26
+ return submissions[submissions.length - 1]?.retry;
27
27
  },
28
28
  get url() {
29
- return submissions[0]?.url;
29
+ return submissions[submissions.length - 1]?.url;
30
30
  },
31
31
  get input() {
32
- return submissions[0]?.input;
32
+ return submissions[submissions.length - 1]?.input;
33
33
  },
34
34
  get result() {
35
- return submissions[0]?.result;
35
+ return submissions[submissions.length - 1]?.result;
36
36
  },
37
37
  get pending() {
38
- return submissions[0]?.pending;
38
+ return submissions[submissions.length - 1]?.pending;
39
39
  }
40
40
  };
41
41
  }
@@ -51,13 +51,14 @@ export function cache(fn, name, options) {
51
51
  if (cached[2] === "preload" && intent !== "preload") {
52
52
  cached[0] = now;
53
53
  }
54
+ let res = cached[1];
54
55
  if (!isServer && intent === "navigate") {
55
- "then" in cached[1]
56
+ res = "then" in cached[1]
56
57
  ? cached[1].then(handleResponse(false), handleResponse(true))
57
58
  : handleResponse(false)(cached[1]);
58
59
  startTransition(() => revalidateSignals(cached[3], cached[0])); // update version
59
60
  }
60
- return cached[1];
61
+ return res;
61
62
  }
62
63
  let res = !isServer && sharedConfig.context && sharedConfig.load
63
64
  ? sharedConfig.load(key) // hydrating
@@ -66,11 +67,6 @@ export function cache(fn, name, options) {
66
67
  if (isServer && sharedConfig.context && !sharedConfig.context.noHydrate) {
67
68
  sharedConfig.context && sharedConfig.context.serialize(key, res);
68
69
  }
69
- if (intent !== "preload") {
70
- "then" in res
71
- ? res.then(handleResponse(false), handleResponse(true))
72
- : handleResponse(false)(res);
73
- }
74
70
  if (cached) {
75
71
  cached[0] = now;
76
72
  cached[1] = res;
@@ -82,6 +78,11 @@ export function cache(fn, name, options) {
82
78
  }
83
79
  else
84
80
  cache.set(key, (cached = [now, res, intent, new Set(version ? [version] : [])]));
81
+ if (intent !== "preload") {
82
+ res = "then" in res
83
+ ? res.then(handleResponse(false), handleResponse(true))
84
+ : handleResponse(false)(res);
85
+ }
85
86
  return res;
86
87
  function handleResponse(error) {
87
88
  return (v) => {
package/dist/index.js CHANGED
@@ -529,7 +529,7 @@ let intent;
529
529
  function getIntent() {
530
530
  return intent;
531
531
  }
532
- function createRouterContext(integration, getBranches, base = "") {
532
+ function createRouterContext(integration, getBranches, options = {}) {
533
533
  const {
534
534
  signal: [source, setSource],
535
535
  utils = {}
@@ -537,8 +537,8 @@ function createRouterContext(integration, getBranches, base = "") {
537
537
  const parsePath = utils.parsePath || (p => p);
538
538
  const renderPath = utils.renderPath || (p => p);
539
539
  const beforeLeave = utils.beforeLeave || createBeforeLeave();
540
- let submissions = [];
541
- const basePath = resolvePath("", base);
540
+ const basePath = resolvePath("", options.base || "");
541
+ const actionBase = options.actionBase || "/_server";
542
542
  if (basePath === undefined) {
543
543
  throw new Error(`${basePath} is not a valid base path`);
544
544
  } else if (basePath && !source().value) {
@@ -578,7 +578,7 @@ function createRouterContext(integration, getBranches, base = "") {
578
578
  parsePath,
579
579
  navigatorFactory,
580
580
  beforeLeave,
581
- submissions: createSignal(submissions)
581
+ submissions: createSignal(initFromFlash(location.query))
582
582
  };
583
583
  function navigateFromRoute(route, to, options) {
584
584
  // Untrack in case someone navigates in an effect - don't want to track `reference` or route paths
@@ -667,6 +667,16 @@ function createRouterContext(integration, getBranches, base = "") {
667
667
  referrers.length = 0;
668
668
  }
669
669
  }
670
+ function initFromFlash(params) {
671
+ let param = params.form ? JSON.parse(params.form) : null;
672
+ if (!param || !param.result) return [];
673
+ const input = new Map(param.entries);
674
+ return [{
675
+ url: param.url,
676
+ result: param.error ? new Error(param.result.message) : param.result,
677
+ input: input
678
+ }];
679
+ }
670
680
  createRenderEffect(() => {
671
681
  const {
672
682
  value,
@@ -771,10 +781,17 @@ function createRouterContext(integration, getBranches, base = "") {
771
781
  }
772
782
  function handleFormSubmit(evt) {
773
783
  let actionRef = evt.submitter && evt.submitter.getAttribute("formaction") || evt.target.action;
774
- if (actionRef && actionRef.startsWith("action:")) {
775
- const data = new FormData(evt.target);
776
- actions.get(actionRef).call(router, data);
784
+ if (!actionRef) return;
785
+ if (!actionRef.startsWith("action:")) {
786
+ const url = new URL(actionRef);
787
+ actionRef = parsePath(url.pathname + url.search);
788
+ if (!actionRef.startsWith(actionBase)) return;
789
+ }
790
+ const handler = actions.get(actionRef);
791
+ if (handler) {
777
792
  evt.preventDefault();
793
+ const data = new FormData(evt.target);
794
+ handler.call(router, data);
778
795
  }
779
796
  }
780
797
 
@@ -794,20 +811,6 @@ function createRouterContext(integration, getBranches, base = "") {
794
811
  document.removeEventListener("touchstart", handleAnchorPreload);
795
812
  document.removeEventListener("submit", handleFormSubmit);
796
813
  });
797
- } else {
798
- function initFromFlash(params) {
799
- let param = params.form ? JSON.parse(params.form) : null;
800
- if (!param || !param.result) {
801
- return [];
802
- }
803
- const input = new Map(param.entries);
804
- return [{
805
- url: param.url,
806
- result: param.error ? new Error(param.result.message) : param.result,
807
- input: input
808
- }];
809
- }
810
- submissions = initFromFlash(location.query);
811
814
  }
812
815
  return router;
813
816
  }
@@ -853,7 +856,8 @@ const Router = props => {
853
856
  const {
854
857
  source,
855
858
  url,
856
- base
859
+ base,
860
+ actionBase
857
861
  } = props;
858
862
  const integration = source || (isServer ? staticIntegration({
859
863
  value: url || (e = getRequestEvent()) && getPath(e.request.url) || ""
@@ -863,7 +867,10 @@ const Router = props => {
863
867
  component: props.root,
864
868
  children: routeDefs()
865
869
  } : routeDefs(), props.base || ""));
866
- const routerState = createRouterContext(integration, branches, base);
870
+ const routerState = createRouterContext(integration, branches, {
871
+ base,
872
+ actionBase
873
+ });
867
874
  return createComponent$1(RouterContextObj.Provider, {
868
875
  value: routerState,
869
876
  get children() {
@@ -1113,12 +1120,13 @@ function cache(fn, name, options) {
1113
1120
  if (cached[2] === "preload" && intent !== "preload") {
1114
1121
  cached[0] = now;
1115
1122
  }
1123
+ let res = cached[1];
1116
1124
  if (!isServer && intent === "navigate") {
1117
- "then" in cached[1] ? cached[1].then(handleResponse(false), handleResponse(true)) : handleResponse(false)(cached[1]);
1125
+ res = "then" in cached[1] ? cached[1].then(handleResponse(false), handleResponse(true)) : handleResponse(false)(cached[1]);
1118
1126
  startTransition(() => revalidateSignals(cached[3], cached[0])); // update version
1119
1127
  }
1120
1128
 
1121
- return cached[1];
1129
+ return res;
1122
1130
  }
1123
1131
  let res = !isServer && sharedConfig.context && sharedConfig.load ? sharedConfig.load(key) // hydrating
1124
1132
  : fn(...args);
@@ -1127,9 +1135,6 @@ function cache(fn, name, options) {
1127
1135
  if (isServer && sharedConfig.context && !sharedConfig.context.noHydrate) {
1128
1136
  sharedConfig.context && sharedConfig.context.serialize(key, res);
1129
1137
  }
1130
- if (intent !== "preload") {
1131
- "then" in res ? res.then(handleResponse(false), handleResponse(true)) : handleResponse(false)(res);
1132
- }
1133
1138
  if (cached) {
1134
1139
  cached[0] = now;
1135
1140
  cached[1] = res;
@@ -1139,6 +1144,9 @@ function cache(fn, name, options) {
1139
1144
  startTransition(() => revalidateSignals(cached[3], cached[0])); // update version
1140
1145
  }
1141
1146
  } else cache.set(key, cached = [now, res, intent, new Set(version ? [version] : [])]);
1147
+ if (intent !== "preload") {
1148
+ res = "then" in res ? res.then(handleResponse(false), handleResponse(true)) : handleResponse(false)(res);
1149
+ }
1142
1150
  return res;
1143
1151
  function handleResponse(error) {
1144
1152
  return v => {
@@ -1181,22 +1189,22 @@ function useSubmission(fn, filter) {
1181
1189
  const submissions = useSubmissions(fn, filter);
1182
1190
  return {
1183
1191
  get clear() {
1184
- return submissions[0]?.clear;
1192
+ return submissions[submissions.length - 1]?.clear;
1185
1193
  },
1186
1194
  get retry() {
1187
- return submissions[0]?.retry;
1195
+ return submissions[submissions.length - 1]?.retry;
1188
1196
  },
1189
1197
  get url() {
1190
- return submissions[0]?.url;
1198
+ return submissions[submissions.length - 1]?.url;
1191
1199
  },
1192
1200
  get input() {
1193
- return submissions[0]?.input;
1201
+ return submissions[submissions.length - 1]?.input;
1194
1202
  },
1195
1203
  get result() {
1196
- return submissions[0]?.result;
1204
+ return submissions[submissions.length - 1]?.result;
1197
1205
  },
1198
1206
  get pending() {
1199
- return submissions[0]?.pending;
1207
+ return submissions[submissions.length - 1]?.pending;
1200
1208
  }
1201
1209
  };
1202
1210
  }
package/dist/routing.d.ts CHANGED
@@ -20,5 +20,8 @@ export declare function getRouteMatches(branches: Branch[], location: string): R
20
20
  export declare function createLocation(path: Accessor<string>, state: Accessor<any>): Location;
21
21
  export declare function registerAction(url: string, fn: Function): void;
22
22
  export declare function getIntent(): Intent | undefined;
23
- export declare function createRouterContext(integration?: RouterIntegration | LocationChangeSignal, getBranches?: () => Branch[], base?: string): RouterContext;
23
+ export declare function createRouterContext(integration?: RouterIntegration | LocationChangeSignal, getBranches?: () => Branch[], options?: {
24
+ base?: string;
25
+ actionBase?: string;
26
+ }): RouterContext;
24
27
  export declare function createRouteContext(router: RouterContext, parent: RouteContext, outlet: () => JSX.Element, match: () => RouteMatch, params: Params): RouteContext;
package/dist/routing.js CHANGED
@@ -181,13 +181,13 @@ let intent;
181
181
  export function getIntent() {
182
182
  return intent;
183
183
  }
184
- export function createRouterContext(integration, getBranches, base = "") {
184
+ export function createRouterContext(integration, getBranches, options = {}) {
185
185
  const { signal: [source, setSource], utils = {} } = normalizeIntegration(integration);
186
186
  const parsePath = utils.parsePath || (p => p);
187
187
  const renderPath = utils.renderPath || (p => p);
188
188
  const beforeLeave = utils.beforeLeave || createBeforeLeave();
189
- let submissions = [];
190
- const basePath = resolvePath("", base);
189
+ const basePath = resolvePath("", options.base || "");
190
+ const actionBase = options.actionBase || "/_server";
191
191
  if (basePath === undefined) {
192
192
  throw new Error(`${basePath} is not a valid base path`);
193
193
  }
@@ -225,7 +225,7 @@ export function createRouterContext(integration, getBranches, base = "") {
225
225
  parsePath,
226
226
  navigatorFactory,
227
227
  beforeLeave,
228
- submissions: createSignal(submissions)
228
+ submissions: createSignal(initFromFlash(location.query))
229
229
  };
230
230
  function navigateFromRoute(route, to, options) {
231
231
  // Untrack in case someone navigates in an effect - don't want to track `reference` or route paths
@@ -301,6 +301,19 @@ export function createRouterContext(integration, getBranches, base = "") {
301
301
  referrers.length = 0;
302
302
  }
303
303
  }
304
+ function initFromFlash(params) {
305
+ let param = params.form ? JSON.parse(params.form) : null;
306
+ if (!param || !param.result)
307
+ return [];
308
+ const input = new Map(param.entries);
309
+ return [
310
+ {
311
+ url: param.url,
312
+ result: param.error ? new Error(param.result.message) : param.result,
313
+ input: input
314
+ }
315
+ ];
316
+ }
304
317
  createRenderEffect(() => {
305
318
  const { value, state } = source();
306
319
  // Untrack this whole block so `start` doesn't cause Solid's Listener to be preserved
@@ -422,10 +435,19 @@ export function createRouterContext(integration, getBranches, base = "") {
422
435
  }
423
436
  function handleFormSubmit(evt) {
424
437
  let actionRef = (evt.submitter && evt.submitter.getAttribute("formaction")) || evt.target.action;
425
- if (actionRef && actionRef.startsWith("action:")) {
426
- const data = new FormData(evt.target);
427
- actions.get(actionRef).call(router, data);
438
+ if (!actionRef)
439
+ return;
440
+ if (!actionRef.startsWith("action:")) {
441
+ const url = new URL(actionRef);
442
+ actionRef = parsePath(url.pathname + url.search);
443
+ if (!actionRef.startsWith(actionBase))
444
+ return;
445
+ }
446
+ const handler = actions.get(actionRef);
447
+ if (handler) {
428
448
  evt.preventDefault();
449
+ const data = new FormData(evt.target);
450
+ handler.call(router, data);
429
451
  }
430
452
  }
431
453
  // ensure delegated event run first
@@ -445,23 +467,6 @@ export function createRouterContext(integration, getBranches, base = "") {
445
467
  document.removeEventListener("submit", handleFormSubmit);
446
468
  });
447
469
  }
448
- else {
449
- function initFromFlash(params) {
450
- let param = params.form ? JSON.parse(params.form) : null;
451
- if (!param || !param.result) {
452
- return [];
453
- }
454
- const input = new Map(param.entries);
455
- return [
456
- {
457
- url: param.url,
458
- result: param.error ? new Error(param.result.message) : param.result,
459
- input: input
460
- }
461
- ];
462
- }
463
- submissions = initFromFlash(location.query);
464
- }
465
470
  return router;
466
471
  }
467
472
  export function createRouteContext(router, parent, outlet, match, params) {
package/package.json CHANGED
@@ -6,7 +6,7 @@
6
6
  "Ryan Turnquist"
7
7
  ],
8
8
  "license": "MIT",
9
- "version": "0.10.0-beta.3",
9
+ "version": "0.10.0-beta.4",
10
10
  "homepage": "https://github.com/solidjs/solid-router#readme",
11
11
  "repository": {
12
12
  "type": "git",