@next-box/link-extra 0.1.0 → 0.1.2
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 +138 -2
- package/dist/cjs/Link.cjs +3 -0
- package/dist/cjs/Link.cjs.map +1 -0
- package/dist/cjs/LinkProvider.cjs +3 -0
- package/dist/cjs/LinkProvider.cjs.map +1 -0
- package/dist/cjs/helpers.cjs +2 -0
- package/dist/cjs/helpers.cjs.map +1 -0
- package/dist/cjs/index.cjs +1 -1
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/useLinkExtra.cjs +2 -0
- package/dist/cjs/useLinkExtra.cjs.map +1 -0
- package/dist/esm/Link.mjs +3 -0
- package/dist/esm/Link.mjs.map +1 -0
- package/dist/esm/LinkProvider.mjs +3 -0
- package/dist/esm/LinkProvider.mjs.map +1 -0
- package/dist/esm/helpers.mjs +2 -0
- package/dist/esm/helpers.mjs.map +1 -0
- package/dist/esm/index.mjs +1 -1
- package/dist/esm/index.mjs.map +1 -1
- package/dist/esm/useLinkExtra.mjs +2 -0
- package/dist/esm/useLinkExtra.mjs.map +1 -0
- package/dist/production.analysis.txt +26 -26
- package/dist/types/cjs/Link.d.cts.map +1 -1
- package/dist/types/cjs/LinkProvider.d.cts +2 -3
- package/dist/types/cjs/LinkProvider.d.cts.map +1 -1
- package/dist/types/cjs/helpers.d.cts.map +1 -1
- package/dist/types/esm/Link.d.ts.map +1 -1
- package/dist/types/esm/LinkProvider.d.ts +2 -3
- package/dist/types/esm/LinkProvider.d.ts.map +1 -1
- package/dist/types/esm/helpers.d.ts.map +1 -1
- package/dist/types/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +13 -13
- package/src/Link.tsx +2 -0
- package/src/LinkProvider.tsx +24 -6
- package/src/helpers.ts +18 -19
- package/src/main.test.tsx +159 -0
package/README.md
CHANGED
|
@@ -1,8 +1,144 @@
|
|
|
1
1
|
# @next-box/link-extra
|
|
2
2
|
|
|
3
|
-
A
|
|
3
|
+
A configurable link component for React applications, primarily designed for Next.js.
|
|
4
4
|
|
|
5
5
|
[](https://badge.fury.io/js/%40next-box%2Flink-extra)
|
|
6
6
|
[](LICENSE)
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
Next.js is a powerful framework for building modern React applications, particularly with its support for React Server Components and server-side rendering. However, these features can introduce some differences in navigation behaviour compared with traditional client-side applications.
|
|
9
|
+
|
|
10
|
+
Client-side navigation can sometimes feel unresponsive when the destination requires server-side work, with the browser waiting for the new route to begin rendering before the UI changes. This has been discussed in the Next.js community, including [Slow route navigation](https://github.com/vercel/next.js/discussions/65150) and [How to indicate loading during pagination](https://github.com/vercel/next.js/discussions/55481).
|
|
11
|
+
|
|
12
|
+
Next.js also maintains a client-side Router Cache to improve navigation performance. While this is useful for many applications, there are cases where an application needs to ensure that navigation retrieves the latest version of a route. The ability to opt out of this client-side caching has been discussed in [Opt-out of client cache](https://github.com/vercel/next.js/discussions/54162), and the distinction between the Router Cache and server-side caching is discussed in [Deep Dive: Caching and Revalidating](https://github.com/vercel/next.js/discussions/54075).
|
|
13
|
+
|
|
14
|
+
Finally, applications often have their own link components and design systems. Integrating these with Next.js `Link` can be awkward, particularly when an application needs the `href` applied to its own anchor element rather than having Next.js render the anchor itself. This has been discussed in the Next.js community, including [Add back `passHref` to the new next/link component](https://github.com/vercel/next.js/discussions/49508) and [Remove `legacyBehavior` from Link component on Next.js 15](https://github.com/vercel/next.js/discussions/67987).
|
|
15
|
+
|
|
16
|
+
`@next-box/link-extra` provides a wrapper around the Next.js `Link` component that addresses these concerns while retaining Next.js client-side navigation.
|
|
17
|
+
|
|
18
|
+
## What it provides
|
|
19
|
+
|
|
20
|
+
### Loading feedback
|
|
21
|
+
|
|
22
|
+
A navigation can take some time to begin rendering, particularly when the destination requires server-side work. `@next-box/link-extra` can display a custom loading component if navigation has not completed within a configurable timeout.
|
|
23
|
+
|
|
24
|
+
If the route transition completes before the timeout, no loading indicator is displayed. If it takes longer, the loading component is rendered automatically.
|
|
25
|
+
|
|
26
|
+
### Router cache control
|
|
27
|
+
|
|
28
|
+
`@next-box/link-extra` provides the `disableRouterCache` prop for cases where an application needs to bypass the Next.js client-side Router Cache.
|
|
29
|
+
|
|
30
|
+
When enabled, the link adds a cache-busting query parameter to the destination URL. This is enabled by default.
|
|
31
|
+
|
|
32
|
+
### Custom link components
|
|
33
|
+
|
|
34
|
+
The library separates the Next.js navigation link from the component used to render the actual link.
|
|
35
|
+
|
|
36
|
+
This allows applications to provide their own link component for styling and design-system requirements while retaining Next.js navigation behaviour.
|
|
37
|
+
|
|
38
|
+
## Installation
|
|
39
|
+
|
|
40
|
+
```shell
|
|
41
|
+
npm add @next-box/link-extra
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Usage
|
|
45
|
+
|
|
46
|
+
### Create a link provider
|
|
47
|
+
|
|
48
|
+
`LinkProvider` supplies the Next.js link, your own link component, and the loading component used by `Link`.
|
|
49
|
+
|
|
50
|
+
It also receives the current pathname so that it can detect when a navigation has completed.
|
|
51
|
+
|
|
52
|
+
```tsx
|
|
53
|
+
'use client';
|
|
54
|
+
|
|
55
|
+
import Link from 'next/link';
|
|
56
|
+
import { usePathname } from 'next/navigation';
|
|
57
|
+
import {
|
|
58
|
+
LinkProvider,
|
|
59
|
+
} from '@next-box/link-extra';
|
|
60
|
+
|
|
61
|
+
const LinkProviderWrapper = ({
|
|
62
|
+
children,
|
|
63
|
+
}: {
|
|
64
|
+
children: ReactNode;
|
|
65
|
+
}) => {
|
|
66
|
+
const pathname = usePathname();
|
|
67
|
+
|
|
68
|
+
return (
|
|
69
|
+
<LinkProvider
|
|
70
|
+
LoadingComponent={Loading}
|
|
71
|
+
NextLink={Link}
|
|
72
|
+
OwnLink={YourLink}
|
|
73
|
+
pathname={pathname}
|
|
74
|
+
>
|
|
75
|
+
{children}
|
|
76
|
+
</LinkProvider>
|
|
77
|
+
);
|
|
78
|
+
};
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
`LinkProvider` is a Client Component. The wrapper above supplies the current pathname and the link component implementations from client code; these component functions cannot be passed as props from a Server Component.
|
|
82
|
+
|
|
83
|
+
### Render a link
|
|
84
|
+
|
|
85
|
+
Once the provider has been configured, use the `Link` component in place of your normal Next.js link.
|
|
86
|
+
|
|
87
|
+
```tsx
|
|
88
|
+
import { Link } from '@next-box/link-extra';
|
|
89
|
+
|
|
90
|
+
const Component = () => {
|
|
91
|
+
return (
|
|
92
|
+
<Link href="/dashboard">
|
|
93
|
+
Dashboard
|
|
94
|
+
</Link>
|
|
95
|
+
);
|
|
96
|
+
};
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### Disable Router Cache
|
|
100
|
+
|
|
101
|
+
Router cache busting is enabled by default.
|
|
102
|
+
|
|
103
|
+
To allow Next.js to use its normal Router Cache behaviour for an individual link, set `disableRouterCache` to `false`:
|
|
104
|
+
|
|
105
|
+
```tsx
|
|
106
|
+
<Link
|
|
107
|
+
href="/dashboard"
|
|
108
|
+
disableRouterCache={false}
|
|
109
|
+
>
|
|
110
|
+
Dashboard
|
|
111
|
+
</Link>
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### Configure loading behaviour
|
|
115
|
+
|
|
116
|
+
The loading timeout defaults to `500ms`. This can be changed through `LinkProvider`:
|
|
117
|
+
|
|
118
|
+
```tsx
|
|
119
|
+
<LinkProvider
|
|
120
|
+
LoadingComponent={Loading}
|
|
121
|
+
NextLink={Link}
|
|
122
|
+
OwnLink={YourLink}
|
|
123
|
+
pathname={pathname}
|
|
124
|
+
loadingTimeout={1000}
|
|
125
|
+
>
|
|
126
|
+
{children}
|
|
127
|
+
</LinkProvider>
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
The loading component is only rendered when a link navigation remains in progress beyond the configured timeout.
|
|
131
|
+
|
|
132
|
+
### Prevent loading for a link
|
|
133
|
+
|
|
134
|
+
The loading state is only triggered when the link represents navigation to a different URL and the click has not been prevented.
|
|
135
|
+
|
|
136
|
+
This means links that point to the current location, or clicks where `event.preventDefault()` has been called, do not trigger the loading indicator.
|
|
137
|
+
|
|
138
|
+
## Changelog
|
|
139
|
+
|
|
140
|
+
See the [changelog](../../CHANGELOG.md) for features, fixes, and other changes included in each major, minor, and patch release.
|
|
141
|
+
|
|
142
|
+
## License
|
|
143
|
+
|
|
144
|
+
`@next-box/link-extra` is [MIT Licensed](LICENSE).
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
"use strict";var e=require("react/jsx-runtime"),r=require("./helpers.cjs"),c=require("./useLinkExtra.cjs");exports.Link=({children:i,disableRouterCache:n=!0,href:s="#",onClick:t,prefetch:a=!1,scroll:l=!1,...h})=>{const{NextLink:u,OwnLink:o,onLinkClicked:d}=c.useLinkExtra();return n&&(s=r.addCacheBusterQueryParam(s)),e.jsx(u,{href:s,legacyBehavior:!0,passHref:!0,prefetch:a,scroll:l,children:e.jsx(o,{onClick:e=>{t&&t(e),r.shouldUrlAndLocationMatch(s)||e.defaultPrevented||d()},...h,children:i})})};
|
|
3
|
+
//# sourceMappingURL=Link.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Link.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":";"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
"use strict";var e=require("react/jsx-runtime"),r=require("react");const n=r.createContext({});exports.LinkContext=n,exports.LinkProvider=({LoadingComponent:t,NextLink:u,OwnLink:l,children:c,loadingTimeout:i=500,pathname:o})=>{const s=r.useRef(null),[a,x]=r.useState(!1),k=r.useCallback(()=>{null!==s.current&&clearTimeout(s.current),s.current=setTimeout(()=>{s.current=null,x(!0)},i)},[i]);return r.useEffect(()=>(null!==s.current&&(clearTimeout(s.current),s.current=null),x(!1),scroll(0,0),()=>{null!==s.current&&(clearTimeout(s.current),s.current=null)}),[o]),e.jsx(n,{value:{NextLink:u,OwnLink:l,onLinkClicked:()=>{k()}},children:e.jsxs(e.Fragment,{children:[c,a?e.jsx(t,{}):void 0]})})};
|
|
3
|
+
//# sourceMappingURL=LinkProvider.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LinkProvider.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":";"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";var a=require("nanoid");const r=(a,r=!1)=>{const e=new URLSearchParams(a).entries().filter(([a])=>!r||"y"!==a).toArray().toSorted(([a,r],[e,o])=>a.localeCompare(e)||r.localeCompare(o));return new URLSearchParams(e).toString()};exports.addCacheBusterQueryParam=e=>{if(!globalThis.location)return e;const o=URL.parse(e,location.origin);if(!o)return e;const t=new URLSearchParams(location.search).get("y"),{pathname:n,search:c}=o,i=new URLSearchParams(c);return n===location.pathname&&r(c,!0)===r(location.search,!0)?i.set("y",t??a.nanoid()):i.set("y",a.nanoid()),`${n}?${i.toString()}`},exports.shouldUrlAndLocationMatch=a=>{if(!globalThis.location)return!1;const e=URL.parse(a,location.origin);return!!e&&(e.pathname===location.pathname&&r(e.search,!0)===r(location.search,!0))};
|
|
2
|
+
//# sourceMappingURL=helpers.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"helpers.cjs","sources":["../../src/helpers.ts"],"sourcesContent":["import { nanoid } from 'nanoid';\n\nconst normalizeSearchParams = (search: string, toOmitCacheBuster = false): string => {\n const entries = new URLSearchParams(search)\n .entries()\n .filter(([key]) => !toOmitCacheBuster || key !== 'y')\n .toArray()\n .toSorted(([keyA, valueA], [keyB, valueB]) => keyA.localeCompare(keyB) || valueA.localeCompare(valueB));\n\n return new URLSearchParams(entries).toString();\n};\n\nexport const shouldUrlAndLocationMatch = (url: string): boolean => {\n // It is possible for this to be undefined\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n if (!globalThis.location) {\n return false;\n }\n\n const parsedUrl = URL.parse(url, location.origin);\n\n if (!parsedUrl) {\n return false;\n }\n\n return (\n parsedUrl.pathname === location.pathname &&\n normalizeSearchParams(parsedUrl.search, true) === normalizeSearchParams(location.search, true)\n );\n};\n\nexport const addCacheBusterQueryParam = (url: string): string => {\n // It is possible for this to be undefined\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n if (!globalThis.location) {\n return url;\n }\n\n const parsedUrl = URL.parse(url, location.origin);\n\n if (!parsedUrl) {\n return url;\n }\n\n const locationSearchParams = new URLSearchParams(location.search);\n const locationCacheBusterSearchParam = locationSearchParams.get('y');\n\n const { pathname, search } = parsedUrl;\n const searchParams = new URLSearchParams(search);\n\n if (\n pathname === location.pathname &&\n normalizeSearchParams(search, true) === normalizeSearchParams(location.search, true)\n ) {\n searchParams.set('y', locationCacheBusterSearchParam ?? nanoid());\n } else {\n searchParams.set('y', nanoid());\n }\n\n return `${pathname}?${searchParams.toString()}`;\n};\n"],"names":["normalizeSearchParams","search","toOmitCacheBuster","entries","URLSearchParams","filter","key","toArray","toSorted","keyA","valueA","keyB","valueB","localeCompare","toString","url","globalThis","location","parsedUrl","URL","parse","origin","locationCacheBusterSearchParam","get","pathname","searchParams","set","nanoid"],"mappings":"qCAEA,MAAMA,EAAwB,CAACC,EAAgBC,GAAoB,KACjE,MAAMC,EAAU,IAAIC,gBAAgBH,GACjCE,UACAE,OAAO,EAAEC,MAAUJ,GAA6B,MAARI,GACxCC,UACAC,SAAS,EAAEC,EAAMC,IAAUC,EAAMC,KAAYH,EAAKI,cAAcF,IAASD,EAAOG,cAAcD,IAEjG,OAAO,IAAIR,gBAAgBD,GAASW,6CAsBGC,IAGvC,IAAKC,WAAWC,SACd,OAAOF,EAGT,MAAMG,EAAYC,IAAIC,MAAML,EAAKE,SAASI,QAE1C,IAAKH,EACH,OAAOH,EAGT,MACMO,EADuB,IAAIlB,gBAAgBa,SAAShB,QACEsB,IAAI,MAE1DC,SAAEA,EAAQvB,OAAEA,GAAWiB,EACvBO,EAAe,IAAIrB,gBAAgBH,GAWzC,OAREuB,IAAaP,SAASO,UACtBxB,EAAsBC,GAAQ,KAAUD,EAAsBiB,SAAShB,QAAQ,GAE/EwB,EAAaC,IAAI,IAAKJ,GAAkCK,EAAAA,UAExDF,EAAaC,IAAI,IAAKC,EAAAA,UAGjB,GAAGH,KAAYC,EAAaX,gDA/CKC,IAGxC,IAAKC,WAAWC,SACd,OAAO,EAGT,MAAMC,EAAYC,IAAIC,MAAML,EAAKE,SAASI,QAE1C,QAAKH,IAKHA,EAAUM,WAAaP,SAASO,UAChCxB,EAAsBkB,EAAUjB,QAAQ,KAAUD,EAAsBiB,SAAShB,QAAQ"}
|
package/dist/cjs/index.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var r=require("./LinkProvider.cjs"),e=require("./Link.cjs"),i=require("./helpers.cjs"),t=require("./useLinkExtra.cjs");exports.LinkContext=r.LinkContext,exports.LinkProvider=r.LinkProvider,exports.Link=e.Link,exports.addCacheBusterQueryParam=i.addCacheBusterQueryParam,exports.shouldUrlAndLocationMatch=i.shouldUrlAndLocationMatch,exports.useLinkExtra=t.useLinkExtra;
|
|
2
2
|
//# sourceMappingURL=index.cjs.map
|
package/dist/cjs/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","sources":[
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useLinkExtra.cjs","sources":["../../src/useLinkExtra.ts"],"sourcesContent":["import { use } from 'react';\nimport { type LinkContextData } from '#types.ts';\nimport { LinkContext } from './LinkProvider.tsx';\n\nexport const useLinkExtra = (): LinkContextData => {\n return use(LinkContext);\n};\n"],"names":["use","LinkContext"],"mappings":"yFAI4B,IACnBA,EAAAA,IAAIC,EAAAA"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import{jsx as e}from"react/jsx-runtime";import{addCacheBusterQueryParam as r,shouldUrlAndLocationMatch as i}from"./helpers.mjs";import{useLinkExtra as n}from"./useLinkExtra.mjs";const o=({children:o,disableRouterCache:t=!0,href:c="#",onClick:l,prefetch:s=!1,scroll:h=!1,...f})=>{const{NextLink:m,OwnLink:a,onLinkClicked:p}=n();return t&&(c=r(c)),e(m,{href:c,legacyBehavior:!0,passHref:!0,prefetch:s,scroll:h,children:e(a,{onClick:e=>{l&&l(e),i(c)||e.defaultPrevented||p()},...f,children:o})})};export{o as Link};
|
|
3
|
+
//# sourceMappingURL=Link.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Link.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import{jsx as n,jsxs as r,Fragment as e}from"react/jsx-runtime";import{createContext as t,useRef as l,useState as u,useCallback as c,useEffect as i}from"react";const o=t({}),m=({LoadingComponent:t,NextLink:m,OwnLink:a,children:d,loadingTimeout:k=500,pathname:L})=>{const p=l(null),[s,T]=u(!1),h=c(()=>{null!==p.current&&clearTimeout(p.current),p.current=setTimeout(()=>{p.current=null,T(!0)},k)},[k]);return i(()=>(null!==p.current&&(clearTimeout(p.current),p.current=null),T(!1),scroll(0,0),()=>{null!==p.current&&(clearTimeout(p.current),p.current=null)}),[L]),n(o,{value:{NextLink:m,OwnLink:a,onLinkClicked:()=>{h()}},children:r(e,{children:[d,s?n(t,{}):void 0]})})};export{o as LinkContext,m as LinkProvider};
|
|
3
|
+
//# sourceMappingURL=LinkProvider.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LinkProvider.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{nanoid as a}from"nanoid";const r=(a,r=!1)=>{const o=new URLSearchParams(a).entries().filter(([a])=>!r||"y"!==a).toArray().toSorted(([a,r],[o,t])=>a.localeCompare(o)||r.localeCompare(t));return new URLSearchParams(o).toString()},o=a=>{if(!globalThis.location)return!1;const o=URL.parse(a,location.origin);return!!o&&(o.pathname===location.pathname&&r(o.search,!0)===r(location.search,!0))},t=o=>{if(!globalThis.location)return o;const t=URL.parse(o,location.origin);if(!t)return o;const e=new URLSearchParams(location.search).get("y"),{pathname:n,search:c}=t,i=new URLSearchParams(c);return n===location.pathname&&r(c,!0)===r(location.search,!0)?i.set("y",e??a()):i.set("y",a()),`${n}?${i.toString()}`};export{t as addCacheBusterQueryParam,o as shouldUrlAndLocationMatch};
|
|
2
|
+
//# sourceMappingURL=helpers.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"helpers.mjs","sources":["../../src/helpers.ts"],"sourcesContent":["import { nanoid } from 'nanoid';\n\nconst normalizeSearchParams = (search: string, toOmitCacheBuster = false): string => {\n const entries = new URLSearchParams(search)\n .entries()\n .filter(([key]) => !toOmitCacheBuster || key !== 'y')\n .toArray()\n .toSorted(([keyA, valueA], [keyB, valueB]) => keyA.localeCompare(keyB) || valueA.localeCompare(valueB));\n\n return new URLSearchParams(entries).toString();\n};\n\nexport const shouldUrlAndLocationMatch = (url: string): boolean => {\n // It is possible for this to be undefined\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n if (!globalThis.location) {\n return false;\n }\n\n const parsedUrl = URL.parse(url, location.origin);\n\n if (!parsedUrl) {\n return false;\n }\n\n return (\n parsedUrl.pathname === location.pathname &&\n normalizeSearchParams(parsedUrl.search, true) === normalizeSearchParams(location.search, true)\n );\n};\n\nexport const addCacheBusterQueryParam = (url: string): string => {\n // It is possible for this to be undefined\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n if (!globalThis.location) {\n return url;\n }\n\n const parsedUrl = URL.parse(url, location.origin);\n\n if (!parsedUrl) {\n return url;\n }\n\n const locationSearchParams = new URLSearchParams(location.search);\n const locationCacheBusterSearchParam = locationSearchParams.get('y');\n\n const { pathname, search } = parsedUrl;\n const searchParams = new URLSearchParams(search);\n\n if (\n pathname === location.pathname &&\n normalizeSearchParams(search, true) === normalizeSearchParams(location.search, true)\n ) {\n searchParams.set('y', locationCacheBusterSearchParam ?? nanoid());\n } else {\n searchParams.set('y', nanoid());\n }\n\n return `${pathname}?${searchParams.toString()}`;\n};\n"],"names":["normalizeSearchParams","search","toOmitCacheBuster","entries","URLSearchParams","filter","key","toArray","toSorted","keyA","valueA","keyB","valueB","localeCompare","toString","shouldUrlAndLocationMatch","url","globalThis","location","parsedUrl","URL","parse","origin","pathname","addCacheBusterQueryParam","locationCacheBusterSearchParam","get","searchParams","set","nanoid"],"mappings":"gCAEA,MAAMA,EAAwB,CAACC,EAAgBC,GAAoB,KACjE,MAAMC,EAAU,IAAIC,gBAAgBH,GACjCE,UACAE,OAAO,EAAEC,MAAUJ,GAA6B,MAARI,GACxCC,UACAC,SAAS,EAAEC,EAAMC,IAAUC,EAAMC,KAAYH,EAAKI,cAAcF,IAASD,EAAOG,cAAcD,IAEjG,OAAO,IAAIR,gBAAgBD,GAASW,YAGzBC,EAA6BC,IAGxC,IAAKC,WAAWC,SACd,OAAO,EAGT,MAAMC,EAAYC,IAAIC,MAAML,EAAKE,SAASI,QAE1C,QAAKH,IAKHA,EAAUI,WAAaL,SAASK,UAChCvB,EAAsBmB,EAAUlB,QAAQ,KAAUD,EAAsBkB,SAASjB,QAAQ,KAIhFuB,EAA4BR,IAGvC,IAAKC,WAAWC,SACd,OAAOF,EAGT,MAAMG,EAAYC,IAAIC,MAAML,EAAKE,SAASI,QAE1C,IAAKH,EACH,OAAOH,EAGT,MACMS,EADuB,IAAIrB,gBAAgBc,SAASjB,QACEyB,IAAI,MAE1DH,SAAEA,EAAQtB,OAAEA,GAAWkB,EACvBQ,EAAe,IAAIvB,gBAAgBH,GAWzC,OAREsB,IAAaL,SAASK,UACtBvB,EAAsBC,GAAQ,KAAUD,EAAsBkB,SAASjB,QAAQ,GAE/E0B,EAAaC,IAAI,IAAKH,GAAkCI,KAExDF,EAAaC,IAAI,IAAKC,KAGjB,GAAGN,KAAYI,EAAab"}
|
package/dist/esm/index.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
|
|
1
|
+
export{LinkContext,LinkProvider}from"./LinkProvider.mjs";export{Link}from"./Link.mjs";export{addCacheBusterQueryParam,shouldUrlAndLocationMatch}from"./helpers.mjs";export{useLinkExtra}from"./useLinkExtra.mjs";
|
|
2
2
|
//# sourceMappingURL=index.mjs.map
|
package/dist/esm/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","sources":[
|
|
1
|
+
{"version":3,"file":"index.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useLinkExtra.mjs","sources":["../../src/useLinkExtra.ts"],"sourcesContent":["import { use } from 'react';\nimport { type LinkContextData } from '#types.ts';\nimport { LinkContext } from './LinkProvider.tsx';\n\nexport const useLinkExtra = (): LinkContextData => {\n return use(LinkContext);\n};\n"],"names":["useLinkExtra","use","LinkContext"],"mappings":"mFAIaA,EAAe,IACnBC,EAAIC"}
|
|
@@ -1,49 +1,49 @@
|
|
|
1
1
|
-----------------------------
|
|
2
2
|
Rollup File Analysis
|
|
3
3
|
-----------------------------
|
|
4
|
-
bundle size:
|
|
5
|
-
original size:
|
|
6
|
-
code reduction:
|
|
4
|
+
bundle size: 5.257 KB
|
|
5
|
+
original size: 6.157 KB
|
|
6
|
+
code reduction: 14.62 %
|
|
7
7
|
module count: 5
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
file: /src/
|
|
11
|
-
bundle space:
|
|
12
|
-
rendered size:
|
|
13
|
-
original size:
|
|
14
|
-
code reduction:
|
|
9
|
+
████████████████████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
|
|
10
|
+
file: /src/LinkProvider.tsx
|
|
11
|
+
bundle space: 41.54 %
|
|
12
|
+
rendered size: 2.184 KB
|
|
13
|
+
original size: 2.417 KB
|
|
14
|
+
code reduction: 9.64 %
|
|
15
15
|
dependents: 2
|
|
16
|
-
- /src/Link.tsx
|
|
17
16
|
- /src/index.ts
|
|
17
|
+
- /src/useLinkExtra.ts
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
file: /src/
|
|
21
|
-
bundle space:
|
|
22
|
-
rendered size: 1.
|
|
23
|
-
original size:
|
|
24
|
-
code reduction:
|
|
19
|
+
████████████████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
|
|
20
|
+
file: /src/helpers.ts
|
|
21
|
+
bundle space: 32.97 %
|
|
22
|
+
rendered size: 1.733 KB
|
|
23
|
+
original size: 1.811 KB
|
|
24
|
+
code reduction: 4.31 %
|
|
25
25
|
dependents: 2
|
|
26
|
-
- /src/useLinkExtra.ts
|
|
27
26
|
- /src/index.ts
|
|
27
|
+
- /src/Link.tsx
|
|
28
28
|
|
|
29
|
-
|
|
29
|
+
████████████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
|
|
30
30
|
file: /src/Link.tsx
|
|
31
|
-
bundle space:
|
|
32
|
-
rendered size: 1.
|
|
33
|
-
original size: 1.
|
|
34
|
-
code reduction:
|
|
31
|
+
bundle space: 24.03 %
|
|
32
|
+
rendered size: 1.263 KB
|
|
33
|
+
original size: 1.559 KB
|
|
34
|
+
code reduction: 18.99 %
|
|
35
35
|
dependents: 1
|
|
36
36
|
- /src/index.ts
|
|
37
37
|
|
|
38
38
|
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
|
|
39
39
|
file: /src/useLinkExtra.ts
|
|
40
|
-
bundle space: 1.
|
|
41
|
-
rendered size:
|
|
40
|
+
bundle space: 1.46 %
|
|
41
|
+
rendered size: 77 Bytes
|
|
42
42
|
original size: 213 Bytes
|
|
43
|
-
code reduction:
|
|
43
|
+
code reduction: 63.85 %
|
|
44
44
|
dependents: 2
|
|
45
|
-
- /src/Link.tsx
|
|
46
45
|
- /src/index.ts
|
|
46
|
+
- /src/Link.tsx
|
|
47
47
|
|
|
48
48
|
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
|
|
49
49
|
file: /src/index.ts
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Link.d.cts","sourceRoot":"","sources":["../../../src/Link.ctsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"Link.d.cts","sourceRoot":"","sources":["../../../src/Link.ctsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,oBAAoB,EAAE,KAAK,GAAG,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAI5E,MAAM,MAAM,SAAS,CAAC,CAAC,SAAS,MAAM,IAAI;IACxC,QAAQ,EAAE,SAAS,CAAC;IACpB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB,GAAG,oBAAoB,CAAC,iBAAiB,CAAC,GACzC,CAAC,CAAC;AAEJ,eAAO,MAAM,IAAI,GAAI,CAAC,SAAS,MAAM,EAAE,kFAQpC,SAAS,CAAC,CAAC,CAAC,KAAG,GAAG,CAAC,OA6BrB,CAAC"}
|
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
import type Link from 'next/link.js';
|
|
2
1
|
import { type ComponentType, type FC, type ReactNode } from 'react';
|
|
3
|
-
import { type LinkContextData, type OwnLinkProps } from '#types.js';
|
|
2
|
+
import { type LinkContextData, type NextLinkComponent, type OwnLinkProps } from '#types.js';
|
|
4
3
|
export declare const LinkContext: import("react").Context<LinkContextData>;
|
|
5
4
|
export type LinkProviderProps = {
|
|
6
5
|
LoadingComponent: ComponentType;
|
|
7
|
-
NextLink:
|
|
6
|
+
NextLink: NextLinkComponent;
|
|
8
7
|
OwnLink: ComponentType<OwnLinkProps>;
|
|
9
8
|
children: ReactNode | ReactNode[];
|
|
10
9
|
loadingTimeout?: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LinkProvider.d.cts","sourceRoot":"","sources":["../../../src/LinkProvider.ctsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"LinkProvider.d.cts","sourceRoot":"","sources":["../../../src/LinkProvider.ctsx"],"names":[],"mappings":"AAEA,OAAO,EACL,KAAK,aAAa,EAClB,KAAK,EAAE,EACP,KAAK,SAAS,EAMf,MAAM,OAAO,CAAC;AACf,OAAO,EAAE,KAAK,eAAe,EAAE,KAAK,iBAAiB,EAAE,KAAK,YAAY,EAAE,MAAM,WAAW,CAAC;AAI5F,eAAO,MAAM,WAAW,0CAAwD,CAAC;AAEjF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,gBAAgB,EAAE,aAAa,CAAC;IAChC,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,OAAO,EAAE,aAAa,CAAC,YAAY,CAAC,CAAC;IACrC,QAAQ,EAAE,SAAS,GAAG,SAAS,EAAE,CAAC;IAClC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,EAAE,CAAC,iBAAiB,CAmE9C,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helpers.d.cts","sourceRoot":"","sources":["../../../src/helpers.cts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"helpers.d.cts","sourceRoot":"","sources":["../../../src/helpers.cts"],"names":[],"mappings":"AAYA,eAAO,MAAM,yBAAyB,GAAI,KAAK,MAAM,KAAG,OAiBvD,CAAC;AAEF,eAAO,MAAM,wBAAwB,GAAI,KAAK,MAAM,KAAG,MA6BtD,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Link.d.ts","sourceRoot":"","sources":["../../../src/Link.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"Link.d.ts","sourceRoot":"","sources":["../../../src/Link.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,oBAAoB,EAAE,KAAK,GAAG,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAI5E,MAAM,MAAM,SAAS,CAAC,CAAC,SAAS,MAAM,IAAI;IACxC,QAAQ,EAAE,SAAS,CAAC;IACpB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB,GAAG,oBAAoB,CAAC,iBAAiB,CAAC,GACzC,CAAC,CAAC;AAEJ,eAAO,MAAM,IAAI,GAAI,CAAC,SAAS,MAAM,EAAE,kFAQpC,SAAS,CAAC,CAAC,CAAC,KAAG,GAAG,CAAC,OA6BrB,CAAC"}
|
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
import type Link from 'next/link.js';
|
|
2
1
|
import { type ComponentType, type FC, type ReactNode } from 'react';
|
|
3
|
-
import { type LinkContextData, type OwnLinkProps } from '#types.js';
|
|
2
|
+
import { type LinkContextData, type NextLinkComponent, type OwnLinkProps } from '#types.js';
|
|
4
3
|
export declare const LinkContext: import("react").Context<LinkContextData>;
|
|
5
4
|
export type LinkProviderProps = {
|
|
6
5
|
LoadingComponent: ComponentType;
|
|
7
|
-
NextLink:
|
|
6
|
+
NextLink: NextLinkComponent;
|
|
8
7
|
OwnLink: ComponentType<OwnLinkProps>;
|
|
9
8
|
children: ReactNode | ReactNode[];
|
|
10
9
|
loadingTimeout?: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LinkProvider.d.ts","sourceRoot":"","sources":["../../../src/LinkProvider.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"LinkProvider.d.ts","sourceRoot":"","sources":["../../../src/LinkProvider.tsx"],"names":[],"mappings":"AAEA,OAAO,EACL,KAAK,aAAa,EAClB,KAAK,EAAE,EACP,KAAK,SAAS,EAMf,MAAM,OAAO,CAAC;AACf,OAAO,EAAE,KAAK,eAAe,EAAE,KAAK,iBAAiB,EAAE,KAAK,YAAY,EAAE,MAAM,WAAW,CAAC;AAI5F,eAAO,MAAM,WAAW,0CAAwD,CAAC;AAEjF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,gBAAgB,EAAE,aAAa,CAAC;IAChC,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,OAAO,EAAE,aAAa,CAAC,YAAY,CAAC,CAAC;IACrC,QAAQ,EAAE,SAAS,GAAG,SAAS,EAAE,CAAC;IAClC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,EAAE,CAAC,iBAAiB,CAmE9C,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../../src/helpers.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../../src/helpers.ts"],"names":[],"mappings":"AAYA,eAAO,MAAM,yBAAyB,GAAI,KAAK,MAAM,KAAG,OAiBvD,CAAC;AAEF,eAAO,MAAM,wBAAwB,GAAI,KAAK,MAAM,KAAG,MA6BtD,CAAC"}
|