@native-router/core 1.0.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 ADDED
@@ -0,0 +1,79 @@
1
+ [![npm](https://img.shields.io/npm/v/@native-router/core.svg)](https://www.npmjs.com/package/@native-router/core)
2
+ [![Build Status](https://github.com/wmzy/@native-router/core/actions/workflows/ci.yml/badge.svg)](https://github.com/wmzy/@native-router/core/actions)
3
+ [![Coverage](https://img.shields.io/codecov/c/github/wmzy/@native-router/core.svg)](https://codecov.io/gh/wmzy/@native-router/core)
4
+ [![install size](https://packagephobia.now.sh/badge?p=@native-router/core)](https://packagephobia.now.sh/result?p=@native-router/core)
5
+
6
+ # Native Router React
7
+
8
+ > A route close to the native experience for react.
9
+
10
+ English | [简体中文](./README-zh_CN.md)
11
+
12
+ ## Features
13
+
14
+ - Asynchronous navigation
15
+ - Cancelable
16
+ - Page data concurrent fetch
17
+ - Link prefetch and preview
18
+ - Most unused features can be tree-shaking
19
+ - SSR support
20
+
21
+ ## Install
22
+
23
+ ```bash
24
+ npm i @native-router/core
25
+ ```
26
+
27
+ ## Usage
28
+
29
+ ```tsx
30
+ import {View, HistoryRouter as Router} from '@native-router/core';
31
+ import Loading from '@/components/Loading';
32
+ import RouterError from '@/components/RouterError';
33
+ import * as userService from '@/services/user';
34
+
35
+ export default function App() {
36
+ return (
37
+ <Router
38
+ routes={{
39
+ component: () => import('./Layout'),
40
+ children: [
41
+ {
42
+ path: '/',
43
+ component: () => import('./Home')
44
+ },
45
+ {
46
+ path: '/users',
47
+ component: () => import('./UserList'),
48
+ data: userService.fetchList
49
+ },
50
+ {
51
+ path: '/users/:id',
52
+ component: () => import('./UserProfile'),
53
+ data: ({id}) => userService.fetchById(+id)
54
+ },
55
+ {
56
+ path: '/help',
57
+ component: () => import('./Help')
58
+ },
59
+ {
60
+ path: '/about',
61
+ component: () => import('./About')
62
+ }
63
+ ]
64
+ }}
65
+ baseUrl="/demos"
66
+ errorHandler={(e) => <RouterError error={e} />}
67
+ >
68
+ <View />
69
+ <Loading />
70
+ </Router>
71
+ );
72
+ }
73
+
74
+ ```
75
+ See [demos](/demos/) for a complete example.
76
+
77
+ ## Documentation
78
+
79
+ [API](https://wmzy.github.io/@native-router/core/modules.html)
package/dist/index.mjs ADDED
@@ -0,0 +1,393 @@
1
+ import { parsePath, createPath } from 'history';
2
+ import { match as match$1 } from 'path-to-regexp';
3
+
4
+ let i = 1;
5
+ function uniqId() {
6
+ return i++;
7
+ }
8
+ function noop() {}
9
+ const reject = /* @__PURE__ */Promise.reject.bind(Promise);
10
+ function cancelPromise() {
11
+ return new Promise(noop);
12
+ }
13
+ function createCurrentGuard() {
14
+ let current;
15
+ return [function currentGuard(promise) {
16
+ const cur = uniqId();
17
+ current = cur;
18
+ return promise.then(result => current === cur ? result : cancelPromise()).catch(err => current === cur ? Promise.reject(err) : cancelPromise());
19
+ }, function cancel() {
20
+ current = undefined;
21
+ }];
22
+ }
23
+
24
+ /* eslint-disable max-classes-per-file */
25
+
26
+ class NativeRouterError extends Error {}
27
+ class NotFoundError extends NativeRouterError {
28
+ constructor(pathname) {
29
+ super(`Can't find the path: ${pathname}`);
30
+ }
31
+ }
32
+
33
+ /**
34
+ * Create a router instance.
35
+ * @group Methods
36
+ * @category Router
37
+ * @param routes routes config
38
+ * @param history {@link https://www.npmjs.com/package/history history} instance
39
+ * @param resolveView a callback to resolve view. see {@link defaultResolveView}
40
+ * @param options options
41
+ * @returns a router instance
42
+ */
43
+ function create(routes, history, resolveView, options) {
44
+ const [currentGuard, cancelAll] = createCurrentGuard();
45
+ const {
46
+ index,
47
+ locationStack
48
+ } = getHistoryState({
49
+ history: history
50
+ });
51
+ const viewStack = new Array(locationStack.length).fill(null);
52
+ if (options?.currentView) {
53
+ viewStack[index] = options.currentView;
54
+ }
55
+ return {
56
+ routes: Array.isArray(routes) ? routes : [routes],
57
+ resolveView,
58
+ history: history,
59
+ locationStack,
60
+ viewStack,
61
+ currentGuard,
62
+ cancelAll,
63
+ errorHandler: reject,
64
+ ...options,
65
+ baseUrl: options?.baseUrl || ''
66
+ };
67
+ }
68
+ function setOptions(router, options) {
69
+ return Object.assign(router, options);
70
+ }
71
+ function getLocation({
72
+ history
73
+ }) {
74
+ const state = history.location.state || {};
75
+ return {
76
+ ...history.location,
77
+ state: state.state
78
+ };
79
+ }
80
+ function getHistoryState(router) {
81
+ const {
82
+ location
83
+ } = router.history;
84
+ const state = location.state || {};
85
+ return {
86
+ index: state.index || 0,
87
+ locationStack: state.locationStack || [getLocation(router)]
88
+ };
89
+ }
90
+ function getCurrentView(router) {
91
+ return router.viewStack[getHistoryState(router).index];
92
+ }
93
+
94
+ /**
95
+ * Match a path.
96
+ * @group Methods
97
+ * @category Router
98
+ * @param router router instance
99
+ * @param pathname the pathname
100
+ * @returns the matched result
101
+ */
102
+ function match(router, pathname) {
103
+ function matchRoutes(routes, baseUrl,
104
+ // eslint-disable-next-line @typescript-eslint/no-shadow
105
+ pathname) {
106
+ for (let i = 0; i < routes.length; i++) {
107
+ const route = routes[i];
108
+ const end = !route.children;
109
+ const matched = route.path ? match$1(route.path, {
110
+ strict: true,
111
+ sensitive: true,
112
+ decode: typeof decodeURIComponent === 'function' ? decodeURIComponent : undefined,
113
+ end
114
+ })(pathname) : {
115
+ path: '',
116
+ index: 0,
117
+ params: {}
118
+ };
119
+ if (matched) {
120
+ const result = {
121
+ route,
122
+ ...matched
123
+ };
124
+ if (end) return [result];
125
+ const children = matchRoutes(route.children, `${baseUrl}${route.path || ''}`, pathname.slice(matched.path.length));
126
+ if (children) return [result, ...children];
127
+ return undefined;
128
+ }
129
+ }
130
+ return undefined;
131
+ }
132
+ return matchRoutes(router.routes, router.baseUrl, pathname.slice(router.baseUrl.length));
133
+ }
134
+
135
+ /**
136
+ * Path to Location.
137
+ * @group Methods
138
+ * @category Router
139
+ * @param router router instance
140
+ * @param to path string
141
+ * @param state the state of location
142
+ * @returns location
143
+ */
144
+ function toLocation(router, to, state) {
145
+ const {
146
+ baseUrl
147
+ } = router;
148
+ return {
149
+ pathname: '',
150
+ search: '',
151
+ hash: '',
152
+ ...parsePath(baseUrl + to),
153
+ state
154
+ };
155
+ }
156
+
157
+ /**
158
+ * Resolve a location.
159
+ * @group Methods
160
+ * @category Router
161
+ * @param router router instance
162
+ * @param location history instance
163
+ * @returns resolve task(a promise)
164
+ */
165
+ function resolve(router, location) {
166
+ const matched = match(router, location.pathname);
167
+ const {
168
+ resolveView,
169
+ errorHandler
170
+ } = router;
171
+ return (matched ? resolveView(matched, {
172
+ router,
173
+ location
174
+ }) : Promise.reject(new NotFoundError(location.pathname))).catch(errorHandler);
175
+ }
176
+
177
+ /**
178
+ * Resolve a path.
179
+ * @group Methods
180
+ * @category Router
181
+ * @param router router instance
182
+ * @param to the path
183
+ * @param state state of the path location
184
+ * @returns resolve task(a promise)
185
+ */
186
+ function resolveTo(router, to, state) {
187
+ const location = toLocation(router, to, state);
188
+ return resolve(router, location);
189
+ }
190
+
191
+ /**
192
+ * Commit the resolve task and push history.
193
+ * @group Methods
194
+ * @category Router
195
+ * @param router router instance
196
+ * @param resolvePromise resolve task(a promise)
197
+ * @param location the location to resolved
198
+ */
199
+ function commit(router, resolvePromise, location) {
200
+ const {
201
+ history
202
+ } = router;
203
+ const nextIndex = getHistoryState(router).index + 1;
204
+ return commitBase(router, resolvePromise, location, resolvedView => {
205
+ router.locationStack = [...router.locationStack.slice(0, nextIndex), location];
206
+ router.viewStack = [...router.viewStack.slice(0, nextIndex), resolvedView];
207
+ history.push(location, {
208
+ index: nextIndex,
209
+ locationStack: router.locationStack,
210
+ state: location.state
211
+ });
212
+ });
213
+ }
214
+
215
+ /**
216
+ * Commit the resolve task and replace history.
217
+ * @group Methods
218
+ * @category Router
219
+ * @param router router instance
220
+ * @param resolvePromise resolve task(a promise)
221
+ * @param location the location to resolved
222
+ */
223
+ function commitReplace(router, resolvePromise, location) {
224
+ const {
225
+ history
226
+ } = router;
227
+ const {
228
+ index
229
+ } = getHistoryState(router);
230
+ return commitBase(router, resolvePromise, location, resolvedView => {
231
+ router.locationStack[index] = location;
232
+ router.viewStack[index] = resolvedView;
233
+ history.replace(location, {
234
+ index,
235
+ locationStack: router.locationStack,
236
+ state: location.state
237
+ });
238
+ });
239
+ }
240
+ function commitBase(router, resolvePromise, location, onResolved) {
241
+ const {
242
+ currentGuard,
243
+ onLoadingChange = noop
244
+ } = router;
245
+ if (router.resolving) {
246
+ // Cancel current resolve
247
+ onLoadingChange();
248
+ }
249
+ router.resolving = location;
250
+ onLoadingChange('pending');
251
+ return currentGuard(resolvePromise).then(onResolved)
252
+ // eslint-disable-next-line no-void
253
+ .then(() => void onLoadingChange('resolved')).catch(e => {
254
+ onLoadingChange('rejected');
255
+ throw e;
256
+ });
257
+ }
258
+
259
+ /**
260
+ * Navigate to a new path.
261
+ * @group Methods
262
+ * @category Router
263
+ * @param router router instance
264
+ * @param to path string
265
+ * @param state location state
266
+ */
267
+ function navigate(router, to, state) {
268
+ const location = toLocation(router, to, state);
269
+ const viewPromise = resolve(router, location);
270
+ return commit(router, viewPromise, location);
271
+ }
272
+
273
+ /**
274
+ * Refresh the page.
275
+ * @group Methods
276
+ * @category Router
277
+ * @param router router instance
278
+ */
279
+ function refresh(router) {
280
+ const location = getLocation(router);
281
+ const viewPromise = resolve(router, location);
282
+ return commitReplace(router, viewPromise, location);
283
+ }
284
+
285
+ /**
286
+ * Navigate in history stack.
287
+ * @group Methods
288
+ * @category Router
289
+ * @param router router instance
290
+ * @param delta history stack index
291
+ */
292
+ function go(router, delta) {
293
+ router.history.go(delta);
294
+ }
295
+
296
+ /**
297
+ * Forward in history stack.
298
+ * @group Methods
299
+ * @category Router
300
+ * @param router router instance
301
+ */
302
+ function forward(router) {
303
+ router.history.forward();
304
+ }
305
+
306
+ /**
307
+ * Back in history stack.
308
+ * @group Methods
309
+ * @category Router
310
+ * @param router router instance
311
+ */
312
+ function back(router) {
313
+ router.history.back();
314
+ }
315
+
316
+ /**
317
+ * Create href of a route path. For {@link Link Link Component} hover url preview.
318
+ * @group Methods
319
+ * @category Router
320
+ * @param router router instance
321
+ * @param to route path
322
+ * @returns href
323
+ */
324
+ function createHref({
325
+ baseUrl,
326
+ history
327
+ }, to) {
328
+ return baseUrl + history.createHref(to);
329
+ }
330
+
331
+ /**
332
+ * Cancel the current navigate.
333
+ * @group Methods
334
+ * @category Router
335
+ * @param router router instance
336
+ */
337
+ function cancel({
338
+ cancelAll,
339
+ onLoadingChange = noop
340
+ }) {
341
+ cancelAll();
342
+ onLoadingChange();
343
+ }
344
+ function initHistoryStack(router) {
345
+ const {
346
+ history
347
+ } = router;
348
+ const {
349
+ locationStack
350
+ } = getHistoryState(router);
351
+ return Promise.all(locationStack.map(l => resolve(router, l))).then(views => {
352
+ router.viewStack = views;
353
+ history.replace(createPath(history.location), history.location.state);
354
+ });
355
+ }
356
+
357
+ /**
358
+ * Listen the history change.
359
+ * @group Methods
360
+ * @category Router
361
+ * @param router router instance
362
+ * @param onViewChange a callback function will be call when view changed
363
+ * @returns unlisten - A function that may be used to stop listening
364
+ */
365
+ function listen(router, onViewChange) {
366
+ const {
367
+ history
368
+ } = router;
369
+ const rmListener = history.listen(({
370
+ action,
371
+ location
372
+ }) => {
373
+ cancel(router);
374
+ const state = location.state;
375
+ const index = state?.index || 0;
376
+ const view = router.viewStack[index];
377
+ onViewChange(view);
378
+ if (!view) refresh(router);
379
+ if (action === 'POP') {
380
+ history.replace(createPath(history.location), {
381
+ ...state,
382
+ locationStack: router.locationStack
383
+ });
384
+ }
385
+ });
386
+ history.replace(createPath(history.location), history.location.state);
387
+ return () => {
388
+ cancel(router);
389
+ rmListener();
390
+ };
391
+ }
392
+
393
+ export { NativeRouterError, NotFoundError, back, cancel, commit, commitReplace, create, createHref, forward, getCurrentView, getLocation, go, initHistoryStack, listen, match, navigate, refresh, resolve, resolveTo, setOptions, toLocation };
@@ -0,0 +1,5 @@
1
+ export declare class NativeRouterError extends Error {
2
+ }
3
+ export declare class NotFoundError extends NativeRouterError {
4
+ constructor(pathname: string);
5
+ }
@@ -0,0 +1,3 @@
1
+ export * from './router';
2
+ export * from './errors';
3
+ export type * from './types';
@@ -0,0 +1,154 @@
1
+ import { History } from 'history';
2
+ import type { Location, Matched, Options, BaseRoute, RouterInstance, ResolveView } from './types';
3
+ /**
4
+ * Create a router instance.
5
+ * @group Methods
6
+ * @category Router
7
+ * @param routes routes config
8
+ * @param history {@link https://www.npmjs.com/package/history history} instance
9
+ * @param resolveView a callback to resolve view. see {@link defaultResolveView}
10
+ * @param options options
11
+ * @returns a router instance
12
+ */
13
+ export declare function create<R extends BaseRoute = BaseRoute, V = any>(routes: R | R[], history: History, resolveView: ResolveView<R, V>, options?: Options<V>): RouterInstance<R, V>;
14
+ export declare function setOptions<R extends BaseRoute = BaseRoute, V = any>(router: RouterInstance<R, V>, options: Omit<Options<V>, 'currentView'>): {
15
+ routes: R[];
16
+ baseUrl: string;
17
+ history: History & {
18
+ location: import("./types").WrappedLocation;
19
+ };
20
+ viewStack: V[];
21
+ locationStack: Location<any>[];
22
+ resolveView: ResolveView<R, V>;
23
+ currentGuard<T>(promise: Promise<T>): Promise<T>;
24
+ cancelAll(): void;
25
+ resolving?: Location<any> | undefined;
26
+ } & Required<Pick<Options<V>, "baseUrl">> & Omit<Options<V>, "baseUrl"> & Omit<Options<V>, "currentView">;
27
+ export declare function getLocation({ history }: Pick<RouterInstance<any>, 'history'>): {
28
+ state: any;
29
+ key: string;
30
+ pathname: string;
31
+ search: string;
32
+ hash: string;
33
+ };
34
+ export declare function getCurrentView<R extends BaseRoute = BaseRoute>(router: RouterInstance<R>): any;
35
+ /**
36
+ * Match a path.
37
+ * @group Methods
38
+ * @category Router
39
+ * @param router router instance
40
+ * @param pathname the pathname
41
+ * @returns the matched result
42
+ */
43
+ export declare function match<R extends BaseRoute = BaseRoute>(router: RouterInstance<R>, pathname: string): Matched<R>[] | undefined;
44
+ /**
45
+ * Path to Location.
46
+ * @group Methods
47
+ * @category Router
48
+ * @param router router instance
49
+ * @param to path string
50
+ * @param state the state of location
51
+ * @returns location
52
+ */
53
+ export declare function toLocation<R extends BaseRoute = BaseRoute, V = any>(router: RouterInstance<R, V>, to: string, state?: any): Location;
54
+ /**
55
+ * Resolve a location.
56
+ * @group Methods
57
+ * @category Router
58
+ * @param router router instance
59
+ * @param location history instance
60
+ * @returns resolve task(a promise)
61
+ */
62
+ export declare function resolve<R extends BaseRoute = BaseRoute, V = any>(router: RouterInstance<R, V>, location: Location): Promise<V>;
63
+ /**
64
+ * Resolve a path.
65
+ * @group Methods
66
+ * @category Router
67
+ * @param router router instance
68
+ * @param to the path
69
+ * @param state state of the path location
70
+ * @returns resolve task(a promise)
71
+ */
72
+ export declare function resolveTo<R extends BaseRoute = BaseRoute, V = any>(router: RouterInstance<R, V>, to: string, state?: any): Promise<V>;
73
+ /**
74
+ * Commit the resolve task and push history.
75
+ * @group Methods
76
+ * @category Router
77
+ * @param router router instance
78
+ * @param resolvePromise resolve task(a promise)
79
+ * @param location the location to resolved
80
+ */
81
+ export declare function commit<R extends BaseRoute = BaseRoute, V = any>(router: RouterInstance<R, V>, resolvePromise: Promise<V>, location: Location): Promise<void>;
82
+ /**
83
+ * Commit the resolve task and replace history.
84
+ * @group Methods
85
+ * @category Router
86
+ * @param router router instance
87
+ * @param resolvePromise resolve task(a promise)
88
+ * @param location the location to resolved
89
+ */
90
+ export declare function commitReplace<R extends BaseRoute = BaseRoute, V = any>(router: RouterInstance<R, V>, resolvePromise: Promise<V>, location: Location): Promise<void>;
91
+ /**
92
+ * Navigate to a new path.
93
+ * @group Methods
94
+ * @category Router
95
+ * @param router router instance
96
+ * @param to path string
97
+ * @param state location state
98
+ */
99
+ export declare function navigate<R extends BaseRoute = BaseRoute, V = any>(router: RouterInstance<R, V>, to: string, state?: any): Promise<void>;
100
+ /**
101
+ * Refresh the page.
102
+ * @group Methods
103
+ * @category Router
104
+ * @param router router instance
105
+ */
106
+ export declare function refresh<R extends BaseRoute = BaseRoute, V = any>(router: RouterInstance<R, V>): Promise<void>;
107
+ /**
108
+ * Navigate in history stack.
109
+ * @group Methods
110
+ * @category Router
111
+ * @param router router instance
112
+ * @param delta history stack index
113
+ */
114
+ export declare function go<R extends BaseRoute = BaseRoute, V = any>(router: RouterInstance<R, V>, delta: number): void;
115
+ /**
116
+ * Forward in history stack.
117
+ * @group Methods
118
+ * @category Router
119
+ * @param router router instance
120
+ */
121
+ export declare function forward<R extends BaseRoute = BaseRoute, V = any>(router: RouterInstance<R, V>): void;
122
+ /**
123
+ * Back in history stack.
124
+ * @group Methods
125
+ * @category Router
126
+ * @param router router instance
127
+ */
128
+ export declare function back<R extends BaseRoute = BaseRoute, V = any>(router: RouterInstance<R, V>): void;
129
+ /**
130
+ * Create href of a route path. For {@link Link Link Component} hover url preview.
131
+ * @group Methods
132
+ * @category Router
133
+ * @param router router instance
134
+ * @param to route path
135
+ * @returns href
136
+ */
137
+ export declare function createHref<R extends BaseRoute = BaseRoute, V = any>({ baseUrl, history }: RouterInstance<R, V>, to: string): string;
138
+ /**
139
+ * Cancel the current navigate.
140
+ * @group Methods
141
+ * @category Router
142
+ * @param router router instance
143
+ */
144
+ export declare function cancel<R extends BaseRoute = BaseRoute, V = any>({ cancelAll, onLoadingChange }: RouterInstance<R, V>): void;
145
+ export declare function initHistoryStack<R extends BaseRoute = BaseRoute, V = any>(router: RouterInstance<R, V>): Promise<void>;
146
+ /**
147
+ * Listen the history change.
148
+ * @group Methods
149
+ * @category Router
150
+ * @param router router instance
151
+ * @param onViewChange a callback function will be call when view changed
152
+ * @returns unlisten - A function that may be used to stop listening
153
+ */
154
+ export declare function listen<R extends BaseRoute = BaseRoute, V = any>(router: RouterInstance<R, V>, onViewChange: (v: V) => void): () => void;
@@ -0,0 +1,74 @@
1
+ import type { Path, MatchResult } from 'path-to-regexp';
2
+ import type { History, Path as HPath } from 'history';
3
+ import type { AnchorHTMLAttributes, ComponentType, Context as ReactContext, DetailedHTMLProps, ReactNode } from 'react';
4
+ export type Location<T = any> = HPath & {
5
+ state?: T;
6
+ };
7
+ export type HistoryState = {
8
+ locationStack: Location[];
9
+ index: number;
10
+ state?: any;
11
+ };
12
+ export type WrappedLocation = Location<HistoryState>;
13
+ export type Awaitable<T> = T | Promise<T>;
14
+ export type BaseRoute<T = any> = {
15
+ path?: Path;
16
+ children?: BaseRoute<T>[];
17
+ } & Omit<T, 'path' | 'children'>;
18
+ export type Matched<R extends BaseRoute = BaseRoute> = {
19
+ route: R;
20
+ } & MatchResult<Record<string, string>>;
21
+ export type ResolveViewContext<R extends BaseRoute> = {
22
+ router: RouterInstance<R>;
23
+ location: Location;
24
+ };
25
+ export type ResolveView<R extends BaseRoute, V> = (matched: Matched<R>[], ctx: ResolveViewContext<R>) => Promise<V>;
26
+ export type Options<V> = {
27
+ baseUrl?: string;
28
+ currentView?: V;
29
+ errorHandler?(e: Error): V | Promise<V>;
30
+ onLoadingChange?(status?: 'pending' | 'resolved' | 'rejected'): void;
31
+ };
32
+ export type RequiredOf<T, K extends keyof T> = Required<Pick<T, K>> & Omit<T, K>;
33
+ export type RouterInstance<R extends BaseRoute, V = any> = {
34
+ routes: R[];
35
+ baseUrl: string;
36
+ history: History & {
37
+ location: WrappedLocation;
38
+ };
39
+ viewStack: V[];
40
+ locationStack: Location[];
41
+ resolveView: ResolveView<R, V>;
42
+ currentGuard<T>(promise: Promise<T>): Promise<T>;
43
+ cancelAll(): void;
44
+ resolving?: Location;
45
+ } & RequiredOf<Options<V>, 'baseUrl'>;
46
+ export type Context<T extends BaseRoute> = {
47
+ matched: Matched<T>[];
48
+ index: number;
49
+ router: RouterInstance<BaseRoute>;
50
+ location: Location;
51
+ params: Record<string, string>;
52
+ };
53
+ export type Route = BaseRoute<{
54
+ name?: string;
55
+ data?(ctx: Context<Route>): any | Promise<any>;
56
+ component?(ctx: Context<Route>): ComponentType | Promise<ComponentType | {
57
+ default: ComponentType;
58
+ }>;
59
+ }>;
60
+ export type StateContext<S> = {
61
+ SetterContext: ReactContext<((v: S) => void) | undefined>;
62
+ ValueContext: ReactContext<S | undefined>;
63
+ Provider: ComponentType<{
64
+ children: ReactNode;
65
+ }>;
66
+ };
67
+ export type LoadStatus = {
68
+ key: number;
69
+ status: 'pending' | 'resolved' | 'rejected';
70
+ };
71
+ export type LinkProps = {
72
+ to: string;
73
+ children?: ReactNode;
74
+ } & DetailedHTMLProps<AnchorHTMLAttributes<HTMLAnchorElement>, HTMLAnchorElement>;
@@ -0,0 +1,12 @@
1
+ export declare function uniqId(): number;
2
+ export declare function noop(): void;
3
+ export declare const resolve: {
4
+ (): Promise<void>;
5
+ <T>(value: T): Promise<Awaited<T>>;
6
+ <T_1>(value: T_1 | PromiseLike<T_1>): Promise<Awaited<T_1>>;
7
+ };
8
+ export declare const reject: <T = never>(reason?: any) => Promise<T>;
9
+ export declare function cancelPromise(): Promise<unknown>;
10
+ export declare function createCurrentGuard(): readonly [<T>(promise: Promise<T>) => Promise<T>, () => void];
11
+ export declare function splitProps<T extends object = object, K extends keyof T = keyof T>(obj: T, keys: K[]): [Pick<T, K>, Omit<T, K>];
12
+ export declare function isString(maybeString: unknown): maybeString is string;
package/package.json ADDED
@@ -0,0 +1,119 @@
1
+ {
2
+ "name": "@native-router/core",
3
+ "version": "1.0.0",
4
+ "exports": {
5
+ ".": {
6
+ "import": "./dist/index.mjs",
7
+ "types": "./dist/types/index.d.ts"
8
+ }
9
+ },
10
+ "types": "./dist/types/index.d.ts",
11
+ "keywords": [
12
+ "react",
13
+ "router",
14
+ "react router",
15
+ "react-router",
16
+ "async",
17
+ "tiny",
18
+ "data-fetching",
19
+ "prefetch",
20
+ "preview"
21
+ ],
22
+ "description": "A route close to the native experience for react.",
23
+ "files": [
24
+ "dist"
25
+ ],
26
+ "scripts": {
27
+ "start": "npm test -- --watch",
28
+ "build": "rm -rf dist && rollup -c && tsc -p tsconfig.production.json && tsc-alias -p tsconfig.production.json",
29
+ "commit": "lint-staged && git-cz -n",
30
+ "coverage": "nyc report --reporter=text-lcov > ./.nyc_output/coverage.txt",
31
+ "lint": "eslint --fix src test demos *.js --ext .js,.jsx,.ts,.tsx",
32
+ "doc:gen": "typedoc",
33
+ "deploy": "npm run doc:gen && npm run build:demo && gh-pages -d dist",
34
+ "test": "cross-env NODE_ENV=test nyc mocha",
35
+ "preversion": "npm run build",
36
+ "postversion": "npm publish",
37
+ "postpublish": "git push --follow-tags && npm run deploy"
38
+ },
39
+ "repository": {
40
+ "type": "git",
41
+ "url": "https://github.com/wmzy/@native-router/core"
42
+ },
43
+ "sideEffects": false,
44
+ "author": "wmzy",
45
+ "license": "MIT",
46
+ "bugs": {
47
+ "url": "https://github.com/wmzy/@native-router/core/issues"
48
+ },
49
+ "homepage": "https://github.com/wmzy/@native-router/core",
50
+ "engines": {
51
+ "node": ">=14"
52
+ },
53
+ "peerDependencies": {
54
+ "react": "^17.0.0 || ^18.0.0",
55
+ "react-dom": "^17.0.0 || ^18.0.0"
56
+ },
57
+ "dependencies": {
58
+ "history": "^5.3.0",
59
+ "path-to-regexp": "^6.2.1"
60
+ },
61
+ "devDependencies": {
62
+ "@babel/core": "^7.22.9",
63
+ "@babel/preset-env": "^7.22.9",
64
+ "@babel/preset-react": "^7.22.5",
65
+ "@babel/preset-typescript": "^7.22.5",
66
+ "@babel/register": "^7.22.5",
67
+ "@linaria/babel-preset": "^4.5.4",
68
+ "@linaria/core": "^4.5.4",
69
+ "@rollup/plugin-babel": "^6.0.3",
70
+ "@rollup/plugin-commonjs": "^25.0.4",
71
+ "@rollup/plugin-node-resolve": "^15.1.0",
72
+ "@rollup/plugin-replace": "^5.0.2",
73
+ "@types/mocha": "^10.0.1",
74
+ "@types/node": "^20.4.5",
75
+ "@types/react": "^18.2.16",
76
+ "@types/react-dom": "^18.2.7",
77
+ "@types/sinon": "^10.0.15",
78
+ "@typescript-eslint/eslint-plugin": "^6.2.0",
79
+ "@typescript-eslint/parser": "^6.2.0",
80
+ "@vitejs/plugin-react": "^4.0.3",
81
+ "babel-plugin-module-resolver": "^5.0.0",
82
+ "commitizen": "^4.3.0",
83
+ "core-js": "^3.31.1",
84
+ "coveralls": "^3.1.1",
85
+ "cross-env": "^7.0.3",
86
+ "eslint": "^8.45.0",
87
+ "eslint-config-airbnb": "^19.0.4",
88
+ "eslint-config-airbnb-typescript": "^17.1.0",
89
+ "eslint-config-prettier": "^8.8.0",
90
+ "eslint-import-resolver-typescript": "^3.5.5",
91
+ "eslint-plugin-compat": "^4.1.4",
92
+ "eslint-plugin-import": "^2.27.5",
93
+ "eslint-plugin-jsx-a11y": "^6.7.1",
94
+ "eslint-plugin-mocha": "^10.1.0",
95
+ "eslint-plugin-prettier": "^5.0.0",
96
+ "eslint-plugin-react": "^7.33.0",
97
+ "eslint-plugin-react-hooks": "^4.6.0",
98
+ "gh-pages": "^5.0.0",
99
+ "global-jsdom": "^9.0.1",
100
+ "husky": "^8.0.3",
101
+ "jsdom": "^22.1.0",
102
+ "lint-staged": "^13.2.3",
103
+ "mocha": "^10.2.0",
104
+ "nyc": "^15.1.0",
105
+ "prettier": "^3.0.0",
106
+ "react": "^18.2.0",
107
+ "react-dom": "^18.2.0",
108
+ "rollup": "^3.28.0",
109
+ "should": "^13.2.3",
110
+ "should-sinon": "0.0.6",
111
+ "sinon": "^15.2.0",
112
+ "terser": "^5.19.2",
113
+ "tsc-alias": "^1.8.7",
114
+ "typedoc": "^0.24.8",
115
+ "typedoc-plugin-mark-react-functional-components": "^0.2.2",
116
+ "typedoc-plugin-missing-exports": "^2.0.0",
117
+ "typescript": "^5.1.6"
118
+ }
119
+ }