vike 0.4.203 → 0.4.204

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.
Files changed (38) hide show
  1. package/dist/cjs/client/server-routing-runtime/utils.js +0 -1
  2. package/dist/cjs/shared/page-configs/assertPlusFileExport.js +1 -3
  3. package/dist/cjs/shared/page-configs/serialize/parsePageConfigs.js +2 -1
  4. package/dist/cjs/utils/PROJECT_VERSION.js +1 -1
  5. package/dist/cjs/utils/parseUrl.js +4 -4
  6. package/dist/esm/client/client-routing-runtime/entry.js +1 -1
  7. package/dist/esm/client/client-routing-runtime/history.d.ts +4 -0
  8. package/dist/esm/client/client-routing-runtime/history.js +8 -6
  9. package/dist/esm/client/client-routing-runtime/initClientRouter.js +3 -0
  10. package/dist/esm/client/client-routing-runtime/initOnLinkClick.js +15 -6
  11. package/dist/esm/client/client-routing-runtime/navigate.js +2 -1
  12. package/dist/esm/client/client-routing-runtime/normalizeUrlArgument.js +1 -0
  13. package/dist/esm/client/client-routing-runtime/renderPageClientSide.js +2 -1
  14. package/dist/esm/client/client-routing-runtime/setScrollPosition.d.ts +2 -0
  15. package/dist/esm/client/client-routing-runtime/setScrollPosition.js +25 -7
  16. package/dist/esm/client/client-routing-runtime/skipLink.d.ts +2 -0
  17. package/dist/esm/client/client-routing-runtime/skipLink.js +19 -15
  18. package/dist/esm/client/client-routing-runtime/utils.d.ts +0 -2
  19. package/dist/esm/client/client-routing-runtime/utils.js +0 -4
  20. package/dist/esm/client/server-routing-runtime/getPageContext.js +2 -1
  21. package/dist/esm/client/server-routing-runtime/utils.d.ts +0 -1
  22. package/dist/esm/client/server-routing-runtime/utils.js +0 -1
  23. package/dist/esm/client/shared/getCurrentUrl.js +5 -0
  24. package/dist/esm/client/shared/normalizeClientSideUrl.d.ts +5 -0
  25. package/dist/esm/client/shared/normalizeClientSideUrl.js +11 -0
  26. package/dist/esm/client/shared/utils.d.ts +1 -0
  27. package/dist/esm/client/shared/utils.js +1 -0
  28. package/dist/esm/shared/page-configs/assertPlusFileExport.js +1 -3
  29. package/dist/esm/shared/page-configs/serialize/parsePageConfigs.js +2 -1
  30. package/dist/esm/utils/PROJECT_VERSION.d.ts +1 -1
  31. package/dist/esm/utils/PROJECT_VERSION.js +1 -1
  32. package/dist/esm/utils/parseUrl.d.ts +2 -2
  33. package/dist/esm/utils/parseUrl.js +4 -4
  34. package/dist/esm/utils/projectInfo.d.ts +1 -1
  35. package/package.json +1 -1
  36. package/dist/cjs/utils/getCurrentUrl.js +0 -18
  37. package/dist/esm/utils/getCurrentUrl.js +0 -16
  38. /package/dist/esm/{utils → client/shared}/getCurrentUrl.d.ts +0 -0
@@ -22,7 +22,6 @@ __exportStar(require("../../utils/assert.js"), exports);
22
22
  __exportStar(require("../../utils/assertSingleInstance.js"), exports);
23
23
  __exportStar(require("../../shared/hooks/executeHook.js"), exports);
24
24
  __exportStar(require("../../utils/checkType.js"), exports); // Only used by Server Routing (not needed for Client Routing)
25
- __exportStar(require("../../utils/getCurrentUrl.js"), exports);
26
25
  __exportStar(require("../../utils/getGlobalObject.js"), exports);
27
26
  __exportStar(require("../../utils/hasProp.js"), exports);
28
27
  __exportStar(require("../../utils/isCallable.js"), exports);
@@ -29,9 +29,7 @@ function assertPlusFileExport(fileExports, filePathToShowToUser, configName) {
29
29
  (0, utils_js_1.assertUsage)(false, `${filePathToShowToUser} should have ${exportNamed} or ${exportDefault}`);
30
30
  }
31
31
  if (exportNamesValid.length === 2) {
32
- (0, utils_js_1.assertWarning)(false, `${filePathToShowToUser} is ambiguous: remove ${exportDefault} or ${exportNamed}`, {
33
- onlyOnce: true
34
- });
32
+ (0, utils_js_1.assertUsage)(false, `${filePathToShowToUser} is ambiguous: remove ${exportDefault} or ${exportNamed}`);
35
33
  }
36
34
  if (!TOLERATE_SIDE_EXPORTS.some((ext) => filePathToShowToUser.endsWith(ext))) {
37
35
  exportNamesInvalid.forEach((exportInvalid) => {
@@ -114,6 +114,7 @@ function parseValueSerialized(valueSerialized, configName, getDefinedAtFile) {
114
114
  const isSideExport = exportName !== 'default' && exportName !== configName;
115
115
  if (!isSideExport) {
116
116
  value = exportValue;
117
+ // Already asserted by assertPlusFileExport() call above.
117
118
  (0, utils_js_1.assert)(!valueWasFound);
118
119
  valueWasFound = true;
119
120
  }
@@ -131,7 +132,7 @@ function parseValueSerialized(valueSerialized, configName, getDefinedAtFile) {
131
132
  });
132
133
  }
133
134
  });
134
- // Already validated by assertPlusFileExport() call above.
135
+ // Already asserted by assertPlusFileExport() call above.
135
136
  (0, utils_js_1.assert)(valueWasFound);
136
137
  return { value, sideExports };
137
138
  }
@@ -2,4 +2,4 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.PROJECT_VERSION = void 0;
4
4
  // Automatically updated by @brillout/release-me
5
- exports.PROJECT_VERSION = '0.4.203';
5
+ exports.PROJECT_VERSION = '0.4.204';
@@ -24,9 +24,9 @@ function parseUrl(url, baseServer) {
24
24
  (0, assert_js_1.assert)(isUrl(url), url);
25
25
  (0, assert_js_1.assert)(baseServer.startsWith('/'));
26
26
  // Hash
27
- const [urlWithoutHash, ...hashList] = url.split('#');
27
+ const [urlWithoutHash, ...h] = url.split('#');
28
28
  (0, assert_js_1.assert)(urlWithoutHash !== undefined);
29
- const hashOriginal = ['', ...hashList].join('#') || null;
29
+ const hashOriginal = ['', ...h].join('#') || null;
30
30
  (0, assert_js_1.assert)(hashOriginal === null || hashOriginal.startsWith('#'));
31
31
  const hash = hashOriginal === null ? '' : decodeSafe(hashOriginal.slice(1));
32
32
  // Search
@@ -111,14 +111,14 @@ function getPathnameAbsoluteWithBase(url, baseServer) {
111
111
  const baseURI = typeof window !== 'undefined' ? window?.document?.baseURI : undefined;
112
112
  let base;
113
113
  if (baseURI) {
114
- const baseURIPathaname = parseOrigin(baseURI.split('?')[0]).pathname;
114
+ const baseURIPathaname = parseOrigin(baseURI.split('?')[0].split('#')[0]).pathname;
115
115
  base = baseURIPathaname;
116
116
  }
117
117
  else {
118
118
  base = baseServer;
119
119
  }
120
120
  const pathnameAbsoluteWithBase = resolveUrlPathnameRelative(url, base);
121
- return { protocol: null, origin: null, pathnameAbsoluteWithBase: pathnameAbsoluteWithBase };
121
+ return { protocol: null, origin: null, pathnameAbsoluteWithBase };
122
122
  }
123
123
  }
124
124
  function parseOrigin(url) {
@@ -7,6 +7,6 @@ import { removeFoucBuster } from '../shared/removeFoucBuster.js';
7
7
  // @ts-ignore Since dist/cjs/client/ is never used, we can ignore this error.
8
8
  const isProd = import.meta.env.PROD;
9
9
  assertSingleInstance_onClientEntryClientRouting(isProd);
10
+ initClientRouter();
10
11
  if (import.meta.env.DEV)
11
12
  removeFoucBuster();
12
- initClientRouter();
@@ -1,6 +1,8 @@
1
1
  export { pushHistoryState };
2
2
  export { onPopStateBegin };
3
3
  export { saveScrollPosition };
4
+ export { initHistoryState };
5
+ export { monkeyPatchHistoryAPI };
4
6
  export type { HistoryInfo };
5
7
  export type { ScrollPosition };
6
8
  type StateEnhanced = {
@@ -15,6 +17,7 @@ type ScrollPosition = {
15
17
  };
16
18
  declare function saveScrollPosition(): void;
17
19
  declare function pushHistoryState(url: string, overwriteLastHistoryEntry: boolean): void;
20
+ declare function monkeyPatchHistoryAPI(): void;
18
21
  type HistoryInfo = {
19
22
  url: `/${string}`;
20
23
  state: StateEnhanced;
@@ -24,3 +27,4 @@ declare function onPopStateBegin(): {
24
27
  previous: HistoryInfo;
25
28
  current: HistoryInfo;
26
29
  };
30
+ declare function initHistoryState(): void;
@@ -1,8 +1,11 @@
1
1
  export { pushHistoryState };
2
2
  export { onPopStateBegin };
3
3
  export { saveScrollPosition };
4
- import { assert, assertUsage, getCurrentUrl, getGlobalObject, hasProp, isObject } from './utils.js';
5
- init();
4
+ export { initHistoryState };
5
+ export { monkeyPatchHistoryAPI };
6
+ import { getCurrentUrl } from '../shared/getCurrentUrl.js';
7
+ import { assert, assertUsage, getGlobalObject, hasProp, isObject } from './utils.js';
8
+ initHistoryState(); // we redundantly call initHistoryState() to ensure it's called early
6
9
  const globalObject = getGlobalObject('history.ts', { previous: getHistoryInfo() });
7
10
  // `window.history.state === null` when:
8
11
  // - The very first render
@@ -129,10 +132,6 @@ function assertStateVikeEnhanced(state) {
129
132
  assert(hasProp(state.scrollPosition, 'x', 'number') && hasProp(state.scrollPosition, 'y', 'number'));
130
133
  }
131
134
  }
132
- function init() {
133
- enhanceHistoryState();
134
- monkeyPatchHistoryAPI();
135
- }
136
135
  function getHistoryInfo() {
137
136
  return {
138
137
  url: getCurrentUrl(),
@@ -148,3 +147,6 @@ function onPopStateBegin() {
148
147
  globalObject.previous = current;
149
148
  return { isNewState, previous, current };
150
149
  }
150
+ function initHistoryState() {
151
+ enhanceHistoryState();
152
+ }
@@ -6,6 +6,7 @@ import { initOnLinkClick } from './initOnLinkClick.js';
6
6
  import { setupNativeScrollRestoration } from './scrollRestoration.js';
7
7
  import { autoSaveScrollPosition } from './setScrollPosition.js';
8
8
  import { initLinkPrefetchHandlers } from './prefetch.js';
9
+ import { initHistoryState, monkeyPatchHistoryAPI } from './history.js';
9
10
  async function initClientRouter() {
10
11
  // Init navigation history and scroll restoration
11
12
  initHistoryAndScroll();
@@ -27,6 +28,8 @@ async function renderFirstPage() {
27
28
  });
28
29
  }
29
30
  function initHistoryAndScroll() {
31
+ monkeyPatchHistoryAPI();
32
+ initHistoryState(); // we redundantly call initHistoryState() to ensure it's called early
30
33
  setupNativeScrollRestoration();
31
34
  autoSaveScrollPosition();
32
35
  // Handle back-/forward navigation
@@ -1,21 +1,30 @@
1
1
  // Code adapted from https://github.com/HenrikJoreteg/internal-nav-helper/blob/5199ec5448d0b0db7ec63cf76d88fa6cad878b7d/src/index.js#L11-L29
2
2
  export { initOnLinkClick };
3
3
  import { assert } from './utils.js';
4
- import { skipLink } from './skipLink.js';
4
+ import { isSameAsCurrentUrl, skipLink } from './skipLink.js';
5
5
  import { renderPageClientSide } from './renderPageClientSide.js';
6
+ import { scrollToHashOrTop } from './setScrollPosition.js';
6
7
  function initOnLinkClick() {
7
- document.addEventListener('click', handler);
8
+ document.addEventListener('click', onClick);
8
9
  }
9
- async function handler(ev) {
10
+ async function onClick(ev) {
10
11
  if (!isNormalLeftClick(ev))
11
12
  return;
12
13
  const linkTag = findLinkTag(ev.target);
13
14
  if (!linkTag)
14
15
  return;
15
- const url = linkTag.getAttribute('href');
16
+ const href = linkTag.getAttribute('href');
17
+ // Workaround for Firefox bug: clicking on a hash link that doesn't change the current URL causes Firefox to erroneously set `window.history.state = null` without firing any signal that we can detect.
18
+ // - https://github.com/vikejs/vike/issues/1962
19
+ // - https://github.com/sveltejs/kit/issues/8725
20
+ if (href?.includes('#') && isSameAsCurrentUrl(href)) {
21
+ ev.preventDefault();
22
+ scrollToHashOrTop(href.split('#')[1]);
23
+ return;
24
+ }
16
25
  if (skipLink(linkTag))
17
26
  return;
18
- assert(url);
27
+ assert(href);
19
28
  ev.preventDefault();
20
29
  let scrollTarget;
21
30
  {
@@ -25,7 +34,7 @@ async function handler(ev) {
25
34
  }
26
35
  await renderPageClientSide({
27
36
  scrollTarget,
28
- urlOriginal: url,
37
+ urlOriginal: href,
29
38
  isBackwardNavigation: false
30
39
  });
31
40
  }
@@ -1,8 +1,9 @@
1
1
  export { navigate };
2
2
  export { reload };
3
+ import { getCurrentUrl } from '../shared/getCurrentUrl.js';
3
4
  import { normalizeUrlArgument } from './normalizeUrlArgument.js';
4
5
  import { firstRenderStartPromise, renderPageClientSide } from './renderPageClientSide.js';
5
- import { assertClientRouting, getCurrentUrl } from './utils.js';
6
+ import { assertClientRouting } from './utils.js';
6
7
  assertClientRouting();
7
8
  /** Programmatically navigate to a new page.
8
9
  *
@@ -5,6 +5,7 @@ function normalizeUrlArgument(url, fnName) {
5
5
  const errMsg = `[${fnName}(url)] Invalid URL ${url}`;
6
6
  assertUsage(isUrl(url), errMsg);
7
7
  if (url.startsWith(location.origin)) {
8
+ // Use normalizeClientSideUrl() instead?
8
9
  url = url.slice(location.origin.length);
9
10
  }
10
11
  assertUsage(url.startsWith('/') || isUrlPathnameRelative(url),
@@ -2,7 +2,7 @@ export { renderPageClientSide };
2
2
  export { getRenderCount };
3
3
  export { disableClientRouting };
4
4
  export { firstRenderStartPromise };
5
- import { assert, getCurrentUrl, isSameErrorMessage, objectAssign, redirectHard, getGlobalObject, executeHook, hasProp, augmentType, genPromise, isCallable } from './utils.js';
5
+ import { assert, isSameErrorMessage, objectAssign, redirectHard, getGlobalObject, executeHook, hasProp, augmentType, genPromise, isCallable } from './utils.js';
6
6
  import { getPageContextFromClientHooks, getPageContextFromServerHooks, getPageContextFromHooks_isHydration, getPageContextFromHooks_serialized, setPageContextInitIsPassedToClient } from './getPageContextFromHooks.js';
7
7
  import { createPageContext } from './createPageContext.js';
8
8
  import { addLinkPrefetchHandlers, addLinkPrefetchHandlers_unwatch, addLinkPrefetchHandlers_watch, getPageContextPrefetched, populatePageContextPrefetchCache } from './prefetch.js';
@@ -19,6 +19,7 @@ import { browserNativeScrollRestoration_disable, setInitialRenderIsDone } from '
19
19
  import { getErrorPageId } from '../../shared/error-page.js';
20
20
  import { setPageContextCurrent } from './getPageContextCurrent.js';
21
21
  import { getRouteStringParameterList } from '../../shared/route/resolveRouteString.js';
22
+ import { getCurrentUrl } from '../shared/getCurrentUrl.js';
22
23
  const globalObject = getGlobalObject('renderPageClientSide.ts', (() => {
23
24
  const { promise: firstRenderStartPromise, resolve: firstRenderStartPromiseResolve } = genPromise();
24
25
  return {
@@ -1,9 +1,11 @@
1
1
  export { setScrollPosition };
2
2
  export { autoSaveScrollPosition };
3
+ export { scrollToHashOrTop };
3
4
  export type { ScrollTarget };
4
5
  import { type ScrollPosition } from './history.js';
5
6
  type ScrollTarget = undefined | {
6
7
  preserveScroll: boolean;
7
8
  } | ScrollPosition;
8
9
  declare function setScrollPosition(scrollTarget: ScrollTarget): void;
10
+ declare function scrollToHashOrTop(hash: null | string): void;
9
11
  declare function autoSaveScrollPosition(): void;
@@ -1,5 +1,6 @@
1
1
  export { setScrollPosition };
2
2
  export { autoSaveScrollPosition };
3
+ export { scrollToHashOrTop };
3
4
  import { assert, onPageHide, sleep, throttle } from './utils.js';
4
5
  import { saveScrollPosition } from './history.js';
5
6
  function setScrollPosition(scrollTarget) {
@@ -10,22 +11,39 @@ function setScrollPosition(scrollTarget) {
10
11
  if (scrollTarget?.preserveScroll) {
11
12
  return;
12
13
  }
13
- scrollToTopOrHash();
14
+ const hash = getUrlHash();
15
+ scrollToHashOrTop(hash);
14
16
  }
15
17
  // Replicates the browser's native behavior
16
- function scrollToTopOrHash() {
17
- const hash = getUrlHash();
18
- if (!hash || hash === 'top') {
19
- setScroll({ x: 0, y: 0 });
18
+ function scrollToHashOrTop(hash) {
19
+ if (!hash) {
20
+ scrollToTop();
20
21
  }
21
22
  else {
22
- const hashTarget = document.getElementById(hash) || document.getElementsByName(hash)[0];
23
+ const id = decodeURIComponent(hash);
24
+ const hashTarget = document.getElementById(id) || document.getElementsByName(id)[0];
23
25
  if (hashTarget) {
24
26
  hashTarget.scrollIntoView();
27
+ // Is this standard? We just copied SvelteKit: https://github.com/sveltejs/kit/blob/94c45b9372a9ed2b80e21cdca3f235c45edaa5b0/packages/kit/src/runtime/client/client.js#L2132
28
+ hashTarget.focus();
29
+ }
30
+ else if (hash === 'top') {
31
+ scrollToTop();
25
32
  }
26
33
  }
27
34
  }
28
- /** Change the browser's scoll position, in a way that works during a repaint. */
35
+ function scrollToTop() {
36
+ setScroll({ x: 0, y: 0 });
37
+ }
38
+ /**
39
+ * Change the browser's scroll position, in a way that works during a repaint.
40
+ *
41
+ * I don't remember exactly why I implemented this and what I meant with "repaint"
42
+ * - https://github.com/vikejs/vike/commit/fd70fadb0bcea8d922f961f1c88713994e0aaf34
43
+ * - I guess scrolling doesn't work during a page rendering? So we have to re-scroll until the scroll position is correct?
44
+ * - Do other frameworks implement this? SvelteKit doesn't seem to.
45
+ * - Let's remove it and see if users complain?
46
+ */
29
47
  function setScroll(scrollPosition) {
30
48
  const scroll = () => window.scrollTo(scrollPosition.x, scrollPosition.y);
31
49
  const done = () => window.scrollX === scrollPosition.x && window.scrollY === scrollPosition.y;
@@ -1,2 +1,4 @@
1
1
  export { skipLink };
2
+ export { isSameAsCurrentUrl };
2
3
  declare function skipLink(linkTag: HTMLElement): boolean;
4
+ declare function isSameAsCurrentUrl(href: string): boolean;
@@ -1,15 +1,17 @@
1
1
  export { skipLink };
2
+ export { isSameAsCurrentUrl };
3
+ import { normalizeClientSideUrl } from '../shared/normalizeClientSideUrl.js';
2
4
  import { getBaseServer } from './getBaseServer.js';
3
5
  import { assert, parseUrl, isBaseServer, isUrl, isUrlExternal } from './utils.js';
4
6
  function skipLink(linkTag) {
5
- const url = linkTag.getAttribute('href');
6
- return (url === null ||
7
- !isUrl(url) ||
8
- url === '' ||
9
- isUrlExternal(url) ||
10
- isHashUrl(url) ||
7
+ const href = linkTag.getAttribute('href');
8
+ return (href === null ||
9
+ !isUrl(href) ||
10
+ href === '' ||
11
+ isUrlExternal(href) ||
12
+ isSamePageHashLink(href) ||
11
13
  isNewTabLink(linkTag) ||
12
- !hasBaseServer(url) ||
14
+ !hasBaseServer(href) ||
13
15
  // Purposely last because disableAutomaticLinkInterception will be removed in the next major release
14
16
  !isVikeLink(linkTag));
15
17
  }
@@ -29,20 +31,22 @@ function isNewTabLink(linkTag) {
29
31
  const rel = linkTag.getAttribute('rel');
30
32
  return target === '_blank' || target === '_external' || rel === 'external' || linkTag.hasAttribute('download');
31
33
  }
32
- function isHashUrl(url) {
33
- if (url.startsWith('#')) {
34
- return true;
35
- }
36
- const removeHash = (url) => url.split('#')[0];
37
- if (url.includes('#') && removeHash(url) === removeHash(window.location.pathname)) {
34
+ function isSamePageHashLink(href) {
35
+ if (href.includes('#') &&
36
+ normalizeClientSideUrl(href, { withoutHash: true }) ===
37
+ normalizeClientSideUrl(window.location.href, { withoutHash: true })) {
38
38
  return true;
39
39
  }
40
+ assert(!href.startsWith('#'));
40
41
  return false;
41
42
  }
42
- function hasBaseServer(url) {
43
+ function isSameAsCurrentUrl(href) {
44
+ return normalizeClientSideUrl(href) === normalizeClientSideUrl(window.location.href);
45
+ }
46
+ function hasBaseServer(href) {
43
47
  const baseServer = getBaseServer();
44
48
  assert(isBaseServer(baseServer));
45
- const { hasBaseServer } = parseUrl(url, baseServer);
49
+ const { hasBaseServer } = parseUrl(href, baseServer);
46
50
  return hasBaseServer;
47
51
  }
48
52
  function isDisableAutomaticLinkInterception() {
@@ -1,8 +1,6 @@
1
- export * from '../server-routing-runtime/utils.js';
2
1
  export * from '../../utils/assert.js';
3
2
  export * from '../../utils/assertSingleInstance.js';
4
3
  export * from '../../shared/hooks/executeHook.js';
5
- export * from '../../utils/getCurrentUrl.js';
6
4
  export * from '../../utils/getGlobalObject.js';
7
5
  export * from '../../utils/hasProp.js';
8
6
  export * from '../../utils/isBrowser.js';
@@ -2,13 +2,9 @@
2
2
  // We assume all runtime entries will load this utils.ts file
3
3
  import { onLoad } from './onLoad.js';
4
4
  onLoad();
5
- // We load the Server Routing utils: we tolerate the tiny amount of code that is only needed by Server Routing (only 1-2 lines).
6
- // We re-export some of the utils down below only to list the utils needed by Client Routing.
7
- export * from '../server-routing-runtime/utils.js';
8
5
  export * from '../../utils/assert.js';
9
6
  export * from '../../utils/assertSingleInstance.js';
10
7
  export * from '../../shared/hooks/executeHook.js';
11
- export * from '../../utils/getCurrentUrl.js';
12
8
  export * from '../../utils/getGlobalObject.js';
13
9
  export * from '../../utils/hasProp.js';
14
10
  export * from '../../utils/isBrowser.js';
@@ -1,7 +1,8 @@
1
- import { assertUsage, assertWarning, getCurrentUrl, objectAssign } from './utils.js';
1
+ import { assertUsage, assertWarning, objectAssign } from './utils.js';
2
2
  import { getPageContextSerializedInHtml } from '../shared/getPageContextSerializedInHtml.js';
3
3
  import { getPageFilesAll } from '../../shared/getPageFiles.js';
4
4
  import { loadUserFilesClientSide } from '../shared/loadUserFilesClientSide.js';
5
+ import { getCurrentUrl } from '../shared/getCurrentUrl.js';
5
6
  export { getPageContext };
6
7
  const urlFirst = getCurrentUrl({ withoutHash: true });
7
8
  async function getPageContext() {
@@ -2,7 +2,6 @@ export * from '../../utils/assert.js';
2
2
  export * from '../../utils/assertSingleInstance.js';
3
3
  export * from '../../shared/hooks/executeHook.js';
4
4
  export * from '../../utils/checkType.js';
5
- export * from '../../utils/getCurrentUrl.js';
6
5
  export * from '../../utils/getGlobalObject.js';
7
6
  export * from '../../utils/hasProp.js';
8
7
  export * from '../../utils/isCallable.js';
@@ -6,7 +6,6 @@ export * from '../../utils/assert.js';
6
6
  export * from '../../utils/assertSingleInstance.js';
7
7
  export * from '../../shared/hooks/executeHook.js';
8
8
  export * from '../../utils/checkType.js'; // Only used by Server Routing (not needed for Client Routing)
9
- export * from '../../utils/getCurrentUrl.js';
10
9
  export * from '../../utils/getGlobalObject.js';
11
10
  export * from '../../utils/hasProp.js';
12
11
  export * from '../../utils/isCallable.js';
@@ -0,0 +1,5 @@
1
+ export { getCurrentUrl };
2
+ import { normalizeClientSideUrl } from './normalizeClientSideUrl.js';
3
+ function getCurrentUrl(options) {
4
+ return normalizeClientSideUrl(window.location.href, options);
5
+ }
@@ -0,0 +1,5 @@
1
+ export { normalizeClientSideUrl };
2
+ /** Resolves relative URLs */
3
+ declare function normalizeClientSideUrl(url: string, options?: {
4
+ withoutHash: true;
5
+ }): `/${string}`;
@@ -0,0 +1,11 @@
1
+ export { normalizeClientSideUrl };
2
+ import { assert, parseUrl } from './utils.js';
3
+ /** Resolves relative URLs */
4
+ function normalizeClientSideUrl(url, options) {
5
+ const { searchOriginal, hashOriginal, pathname } = parseUrl(url, '/');
6
+ let urlCurrent = `${pathname}${searchOriginal || ''}`;
7
+ if (!options?.withoutHash)
8
+ urlCurrent += hashOriginal || '';
9
+ assert(urlCurrent.startsWith('/'));
10
+ return urlCurrent;
11
+ }
@@ -1 +1,2 @@
1
1
  export * from '../../utils/assert.js';
2
+ export * from '../../utils/parseUrl.js';
@@ -1 +1,2 @@
1
1
  export * from '../../utils/assert.js';
2
+ export * from '../../utils/parseUrl.js';
@@ -24,9 +24,7 @@ function assertPlusFileExport(fileExports, filePathToShowToUser, configName) {
24
24
  assertUsage(false, `${filePathToShowToUser} should have ${exportNamed} or ${exportDefault}`);
25
25
  }
26
26
  if (exportNamesValid.length === 2) {
27
- assertWarning(false, `${filePathToShowToUser} is ambiguous: remove ${exportDefault} or ${exportNamed}`, {
28
- onlyOnce: true
29
- });
27
+ assertUsage(false, `${filePathToShowToUser} is ambiguous: remove ${exportDefault} or ${exportNamed}`);
30
28
  }
31
29
  if (!TOLERATE_SIDE_EXPORTS.some((ext) => filePathToShowToUser.endsWith(ext))) {
32
30
  exportNamesInvalid.forEach((exportInvalid) => {
@@ -112,6 +112,7 @@ function parseValueSerialized(valueSerialized, configName, getDefinedAtFile) {
112
112
  const isSideExport = exportName !== 'default' && exportName !== configName;
113
113
  if (!isSideExport) {
114
114
  value = exportValue;
115
+ // Already asserted by assertPlusFileExport() call above.
115
116
  assert(!valueWasFound);
116
117
  valueWasFound = true;
117
118
  }
@@ -129,7 +130,7 @@ function parseValueSerialized(valueSerialized, configName, getDefinedAtFile) {
129
130
  });
130
131
  }
131
132
  });
132
- // Already validated by assertPlusFileExport() call above.
133
+ // Already asserted by assertPlusFileExport() call above.
133
134
  assert(valueWasFound);
134
135
  return { value, sideExports };
135
136
  }
@@ -1 +1 @@
1
- export declare const PROJECT_VERSION: "0.4.203";
1
+ export declare const PROJECT_VERSION: "0.4.204";
@@ -1,2 +1,2 @@
1
1
  // Automatically updated by @brillout/release-me
2
- export const PROJECT_VERSION = '0.4.203';
2
+ export const PROJECT_VERSION = '0.4.204';
@@ -31,11 +31,11 @@ type UrlPublic = {
31
31
  /** The URL search parameters array, e.g. `{ fruit: ['apple', 'orange'] }` for `https://example.com?fruit=apple&fruit=orange` **/
32
32
  searchAll: Record<string, string[]>;
33
33
  /** The URL search parameterer string, e.g. `?details=yes` in `https://example.com/product/42?details=yes#reviews` */
34
- searchOriginal: null | string;
34
+ searchOriginal: null | `?${string}`;
35
35
  /** The URL hash, e.g. `reviews` in `https://example.com/product/42?details=yes#reviews` */
36
36
  hash: string;
37
37
  /** The URL hash string, e.g. `#reviews` in `https://example.com/product/42?details=yes#reviews` */
38
- hashOriginal: null | string;
38
+ hashOriginal: null | `#${string}`;
39
39
  /** @deprecated */
40
40
  hashString: null | string;
41
41
  /** @deprecated */
@@ -20,9 +20,9 @@ function parseUrl(url, baseServer) {
20
20
  assert(isUrl(url), url);
21
21
  assert(baseServer.startsWith('/'));
22
22
  // Hash
23
- const [urlWithoutHash, ...hashList] = url.split('#');
23
+ const [urlWithoutHash, ...h] = url.split('#');
24
24
  assert(urlWithoutHash !== undefined);
25
- const hashOriginal = ['', ...hashList].join('#') || null;
25
+ const hashOriginal = ['', ...h].join('#') || null;
26
26
  assert(hashOriginal === null || hashOriginal.startsWith('#'));
27
27
  const hash = hashOriginal === null ? '' : decodeSafe(hashOriginal.slice(1));
28
28
  // Search
@@ -107,14 +107,14 @@ function getPathnameAbsoluteWithBase(url, baseServer) {
107
107
  const baseURI = typeof window !== 'undefined' ? window?.document?.baseURI : undefined;
108
108
  let base;
109
109
  if (baseURI) {
110
- const baseURIPathaname = parseOrigin(baseURI.split('?')[0]).pathname;
110
+ const baseURIPathaname = parseOrigin(baseURI.split('?')[0].split('#')[0]).pathname;
111
111
  base = baseURIPathaname;
112
112
  }
113
113
  else {
114
114
  base = baseServer;
115
115
  }
116
116
  const pathnameAbsoluteWithBase = resolveUrlPathnameRelative(url, base);
117
- return { protocol: null, origin: null, pathnameAbsoluteWithBase: pathnameAbsoluteWithBase };
117
+ return { protocol: null, origin: null, pathnameAbsoluteWithBase };
118
118
  }
119
119
  }
120
120
  function parseOrigin(url) {
@@ -1,4 +1,4 @@
1
1
  export declare const projectInfo: {
2
2
  projectName: "Vike";
3
- projectVersion: "0.4.203";
3
+ projectVersion: "0.4.204";
4
4
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vike",
3
- "version": "0.4.203",
3
+ "version": "0.4.204",
4
4
  "repository": "https://github.com/vikejs/vike",
5
5
  "exports": {
6
6
  "./server": {
@@ -1,18 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getCurrentUrl = getCurrentUrl;
4
- const parseUrl_js_1 = require("./parseUrl.js");
5
- const assert_js_1 = require("./assert.js");
6
- function getCurrentUrl(options) {
7
- const url = window.location.href;
8
- const { searchOriginal, hashOriginal, pathname } = (0, parseUrl_js_1.parseUrl)(url, '/');
9
- let urlCurrent;
10
- if (options?.withoutHash) {
11
- urlCurrent = `${pathname}${searchOriginal || ''}`;
12
- }
13
- else {
14
- urlCurrent = `${pathname}${searchOriginal || ''}${hashOriginal || ''}`;
15
- }
16
- (0, assert_js_1.assert)(urlCurrent.startsWith('/'));
17
- return urlCurrent;
18
- }
@@ -1,16 +0,0 @@
1
- export { getCurrentUrl };
2
- import { parseUrl } from './parseUrl.js';
3
- import { assert } from './assert.js';
4
- function getCurrentUrl(options) {
5
- const url = window.location.href;
6
- const { searchOriginal, hashOriginal, pathname } = parseUrl(url, '/');
7
- let urlCurrent;
8
- if (options?.withoutHash) {
9
- urlCurrent = `${pathname}${searchOriginal || ''}`;
10
- }
11
- else {
12
- urlCurrent = `${pathname}${searchOriginal || ''}${hashOriginal || ''}`;
13
- }
14
- assert(urlCurrent.startsWith('/'));
15
- return urlCurrent;
16
- }