@viewfly/router 0.3.0 → 0.3.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.
@@ -40,10 +40,11 @@ class Navigator {
40
40
  this.baseUrl = baseUrl;
41
41
  }
42
42
  }
43
- function formatUrl(pathname, query) {
43
+ function formatUrl(pathname, urlFormatParams) {
44
44
  pathname = pathname.replace(/\/+/g, '/');
45
- if (query) {
46
- return pathname + '?' + formatQueryParams(query);
45
+ if (urlFormatParams) {
46
+ const { queryParams, fragment } = urlFormatParams;
47
+ return pathname + (queryParams ? '?' + formatQueryParams(queryParams) : '') + (fragment ? '#' + fragment : '');
47
48
  }
48
49
  return pathname;
49
50
  }
@@ -78,8 +79,8 @@ let BrowserNavigator = class BrowserNavigator extends Navigator {
78
79
  history.replaceState(null, '', this.baseUrl);
79
80
  }
80
81
  }
81
- to(pathName, relative, queryParams) {
82
- const url = this.join(pathName, relative, queryParams);
82
+ to(pathName, relative, queryParams, fragment) {
83
+ const url = this.join(pathName, relative, queryParams, fragment);
83
84
  if (location.origin + url === location.href) {
84
85
  return true;
85
86
  }
@@ -87,8 +88,8 @@ let BrowserNavigator = class BrowserNavigator extends Navigator {
87
88
  this.urlChangeEvent.next();
88
89
  return true;
89
90
  }
90
- replace(pathName, relative, queryParams) {
91
- const url = this.join(pathName, relative, queryParams);
91
+ replace(pathName, relative, queryParams, fragment) {
92
+ const url = this.join(pathName, relative, queryParams, fragment);
92
93
  if (location.origin + url === location.href) {
93
94
  return true;
94
95
  }
@@ -96,9 +97,9 @@ let BrowserNavigator = class BrowserNavigator extends Navigator {
96
97
  this.urlChangeEvent.next();
97
98
  return true;
98
99
  }
99
- join(pathname, relative, queryParams) {
100
+ join(pathname, relative, queryParams, fragment) {
100
101
  if (pathname.startsWith('/')) {
101
- return formatUrl(this.baseUrl + pathname, queryParams);
102
+ return formatUrl(this.baseUrl + pathname, { queryParams, fragment });
102
103
  }
103
104
  let beforePath = relative.beforePath;
104
105
  while (true) {
@@ -122,7 +123,7 @@ let BrowserNavigator = class BrowserNavigator extends Navigator {
122
123
  }
123
124
  break;
124
125
  }
125
- return formatUrl(this.baseUrl + '/' + beforePath + '/' + pathname, queryParams);
126
+ return formatUrl(this.baseUrl + '/' + beforePath + '/' + pathname, { queryParams, fragment });
126
127
  }
127
128
  back() {
128
129
  history.back();
@@ -165,8 +166,8 @@ class Router {
165
166
  this.refreshEvent = new Subject();
166
167
  this.onRefresh = this.refreshEvent.asObservable();
167
168
  }
168
- navigateTo(path, params) {
169
- this.navigator.to(path, this, params);
169
+ navigateTo(path, params, fragment) {
170
+ this.navigator.to(path, this, params, fragment);
170
171
  }
171
172
  replaceTo(path, params) {
172
173
  this.navigator.replace(path, this, params);
@@ -181,14 +182,14 @@ class Router {
181
182
  return null;
182
183
  }
183
184
  let remainingPath = '';
184
- if (routeConfig.name === '') {
185
+ if (routeConfig.path === '') {
185
186
  remainingPath = this.path;
186
187
  }
187
- else if (routeConfig.name === '*') {
188
+ else if (routeConfig.path === '*') {
188
189
  remainingPath = '';
189
190
  }
190
191
  else {
191
- remainingPath = this.path.substring(routeConfig.name.length + 1);
192
+ remainingPath = this.path.substring(routeConfig.path.length + 1);
192
193
  }
193
194
  return {
194
195
  remainingPath,
@@ -211,16 +212,16 @@ class Router {
211
212
  let fallbackConfig = null;
212
213
  const pathname = ((_a = (this.path || '').match(/[^\/?#]+/)) === null || _a === void 0 ? void 0 : _a[0]) || '';
213
214
  for (const item of configs) {
214
- if (item.name === pathname) {
215
+ if (item.path === pathname) {
215
216
  matchedConfig = item;
216
217
  break;
217
218
  }
218
- else if (item.name === '*') {
219
+ else if (item.path === '*') {
219
220
  if (!fallbackConfig) {
220
221
  fallbackConfig = item;
221
222
  }
222
223
  }
223
- else if (item.name === '') {
224
+ else if (item.path === '') {
224
225
  if (!defaultConfig) {
225
226
  defaultConfig = item;
226
227
  }
@@ -251,13 +252,13 @@ function Link(props) {
251
252
  return;
252
253
  }
253
254
  ev.preventDefault();
254
- router.navigateTo(props.to, props.queryParams);
255
+ router.navigateTo(props.to, props.queryParams, props.fragment);
255
256
  }
256
257
  return () => {
257
258
  const Tag = props.tag || 'a';
258
259
  const attrs = Object.assign({}, props, Object.assign({ onClick: navigate }, props));
259
260
  if (Tag === 'a') {
260
- attrs.href = navigator.join(props.to, router, props.queryParams);
261
+ attrs.href = navigator.join(props.to, router, props.queryParams, props.fragment);
261
262
  }
262
263
  if (isActive() && props.active) {
263
264
  attrs.class = [attrs.class, props.active];
@@ -266,36 +267,6 @@ function Link(props) {
266
267
  };
267
268
  }
268
269
 
269
- function RootRouter(props) {
270
- const basePath = props.basePath || '';
271
- const navigator = new BrowserNavigator(basePath);
272
- function getPath() {
273
- const pathname = navigator.pathname;
274
- return pathname.startsWith(basePath) ? pathname.substring(basePath.length) : pathname;
275
- }
276
- const router = new Router(navigator, null, getPath());
277
- provide([
278
- {
279
- provide: Navigator,
280
- useValue: navigator
281
- },
282
- {
283
- provide: Router,
284
- useValue: router
285
- }
286
- ]);
287
- const subscription = navigator.onUrlChanged.subscribe(() => {
288
- router.refresh(getPath());
289
- });
290
- onUnmounted(() => {
291
- subscription.unsubscribe();
292
- navigator.destroy();
293
- });
294
- return () => {
295
- return jsx(Fragment, { children: props.children });
296
- };
297
- }
298
-
299
270
  function RouterOutlet(props) {
300
271
  const children = useSignal(null);
301
272
  const router = inject(Router);
@@ -341,4 +312,38 @@ function RouterOutlet(props) {
341
312
  };
342
313
  }
343
314
 
344
- export { BrowserNavigator, Link, Navigator, RootRouter, Router, RouterOutlet, formatQueryParams, formatUrl };
315
+ class RouterModule {
316
+ constructor(baseUrl = '') {
317
+ this.baseUrl = baseUrl;
318
+ this.subscription = new Subscription();
319
+ this.navigator = new BrowserNavigator(this.baseUrl);
320
+ }
321
+ setup(app) {
322
+ const baseUrl = this.baseUrl;
323
+ const navigator = this.navigator;
324
+ function getPath() {
325
+ const pathname = navigator.pathname;
326
+ return pathname.startsWith(baseUrl) ? pathname.substring(baseUrl.length) : pathname;
327
+ }
328
+ const router = new Router(navigator, null, getPath());
329
+ this.subscription.add(navigator.onUrlChanged.subscribe(() => {
330
+ router.refresh(getPath());
331
+ }));
332
+ app.provide([
333
+ {
334
+ provide: Navigator,
335
+ useValue: navigator
336
+ },
337
+ {
338
+ provide: Router,
339
+ useValue: router
340
+ }
341
+ ]);
342
+ }
343
+ onDestroy() {
344
+ this.subscription.unsubscribe();
345
+ this.navigator.destroy();
346
+ }
347
+ }
348
+
349
+ export { BrowserNavigator, Link, Navigator, Router, RouterModule, RouterOutlet, formatQueryParams, formatUrl };
package/bundles/index.js CHANGED
@@ -42,10 +42,11 @@ class Navigator {
42
42
  this.baseUrl = baseUrl;
43
43
  }
44
44
  }
45
- function formatUrl(pathname, query) {
45
+ function formatUrl(pathname, urlFormatParams) {
46
46
  pathname = pathname.replace(/\/+/g, '/');
47
- if (query) {
48
- return pathname + '?' + formatQueryParams(query);
47
+ if (urlFormatParams) {
48
+ const { queryParams, fragment } = urlFormatParams;
49
+ return pathname + (queryParams ? '?' + formatQueryParams(queryParams) : '') + (fragment ? '#' + fragment : '');
49
50
  }
50
51
  return pathname;
51
52
  }
@@ -80,8 +81,8 @@ exports.BrowserNavigator = class BrowserNavigator extends Navigator {
80
81
  history.replaceState(null, '', this.baseUrl);
81
82
  }
82
83
  }
83
- to(pathName, relative, queryParams) {
84
- const url = this.join(pathName, relative, queryParams);
84
+ to(pathName, relative, queryParams, fragment) {
85
+ const url = this.join(pathName, relative, queryParams, fragment);
85
86
  if (location.origin + url === location.href) {
86
87
  return true;
87
88
  }
@@ -89,8 +90,8 @@ exports.BrowserNavigator = class BrowserNavigator extends Navigator {
89
90
  this.urlChangeEvent.next();
90
91
  return true;
91
92
  }
92
- replace(pathName, relative, queryParams) {
93
- const url = this.join(pathName, relative, queryParams);
93
+ replace(pathName, relative, queryParams, fragment) {
94
+ const url = this.join(pathName, relative, queryParams, fragment);
94
95
  if (location.origin + url === location.href) {
95
96
  return true;
96
97
  }
@@ -98,9 +99,9 @@ exports.BrowserNavigator = class BrowserNavigator extends Navigator {
98
99
  this.urlChangeEvent.next();
99
100
  return true;
100
101
  }
101
- join(pathname, relative, queryParams) {
102
+ join(pathname, relative, queryParams, fragment) {
102
103
  if (pathname.startsWith('/')) {
103
- return formatUrl(this.baseUrl + pathname, queryParams);
104
+ return formatUrl(this.baseUrl + pathname, { queryParams, fragment });
104
105
  }
105
106
  let beforePath = relative.beforePath;
106
107
  while (true) {
@@ -124,7 +125,7 @@ exports.BrowserNavigator = class BrowserNavigator extends Navigator {
124
125
  }
125
126
  break;
126
127
  }
127
- return formatUrl(this.baseUrl + '/' + beforePath + '/' + pathname, queryParams);
128
+ return formatUrl(this.baseUrl + '/' + beforePath + '/' + pathname, { queryParams, fragment });
128
129
  }
129
130
  back() {
130
131
  history.back();
@@ -167,8 +168,8 @@ class Router {
167
168
  this.refreshEvent = new stream.Subject();
168
169
  this.onRefresh = this.refreshEvent.asObservable();
169
170
  }
170
- navigateTo(path, params) {
171
- this.navigator.to(path, this, params);
171
+ navigateTo(path, params, fragment) {
172
+ this.navigator.to(path, this, params, fragment);
172
173
  }
173
174
  replaceTo(path, params) {
174
175
  this.navigator.replace(path, this, params);
@@ -183,14 +184,14 @@ class Router {
183
184
  return null;
184
185
  }
185
186
  let remainingPath = '';
186
- if (routeConfig.name === '') {
187
+ if (routeConfig.path === '') {
187
188
  remainingPath = this.path;
188
189
  }
189
- else if (routeConfig.name === '*') {
190
+ else if (routeConfig.path === '*') {
190
191
  remainingPath = '';
191
192
  }
192
193
  else {
193
- remainingPath = this.path.substring(routeConfig.name.length + 1);
194
+ remainingPath = this.path.substring(routeConfig.path.length + 1);
194
195
  }
195
196
  return {
196
197
  remainingPath,
@@ -213,16 +214,16 @@ class Router {
213
214
  let fallbackConfig = null;
214
215
  const pathname = ((_a = (this.path || '').match(/[^\/?#]+/)) === null || _a === void 0 ? void 0 : _a[0]) || '';
215
216
  for (const item of configs) {
216
- if (item.name === pathname) {
217
+ if (item.path === pathname) {
217
218
  matchedConfig = item;
218
219
  break;
219
220
  }
220
- else if (item.name === '*') {
221
+ else if (item.path === '*') {
221
222
  if (!fallbackConfig) {
222
223
  fallbackConfig = item;
223
224
  }
224
225
  }
225
- else if (item.name === '') {
226
+ else if (item.path === '') {
226
227
  if (!defaultConfig) {
227
228
  defaultConfig = item;
228
229
  }
@@ -253,13 +254,13 @@ function Link(props) {
253
254
  return;
254
255
  }
255
256
  ev.preventDefault();
256
- router.navigateTo(props.to, props.queryParams);
257
+ router.navigateTo(props.to, props.queryParams, props.fragment);
257
258
  }
258
259
  return () => {
259
260
  const Tag = props.tag || 'a';
260
261
  const attrs = Object.assign({}, props, Object.assign({ onClick: navigate }, props));
261
262
  if (Tag === 'a') {
262
- attrs.href = navigator.join(props.to, router, props.queryParams);
263
+ attrs.href = navigator.join(props.to, router, props.queryParams, props.fragment);
263
264
  }
264
265
  if (isActive() && props.active) {
265
266
  attrs.class = [attrs.class, props.active];
@@ -268,36 +269,6 @@ function Link(props) {
268
269
  };
269
270
  }
270
271
 
271
- function RootRouter(props) {
272
- const basePath = props.basePath || '';
273
- const navigator = new exports.BrowserNavigator(basePath);
274
- function getPath() {
275
- const pathname = navigator.pathname;
276
- return pathname.startsWith(basePath) ? pathname.substring(basePath.length) : pathname;
277
- }
278
- const router = new Router(navigator, null, getPath());
279
- core.provide([
280
- {
281
- provide: Navigator,
282
- useValue: navigator
283
- },
284
- {
285
- provide: Router,
286
- useValue: router
287
- }
288
- ]);
289
- const subscription = navigator.onUrlChanged.subscribe(() => {
290
- router.refresh(getPath());
291
- });
292
- core.onUnmounted(() => {
293
- subscription.unsubscribe();
294
- navigator.destroy();
295
- });
296
- return () => {
297
- return jsxRuntime.jsx(jsxRuntime.Fragment, { children: props.children });
298
- };
299
- }
300
-
301
272
  function RouterOutlet(props) {
302
273
  const children = core.useSignal(null);
303
274
  const router = core.inject(Router);
@@ -343,10 +314,44 @@ function RouterOutlet(props) {
343
314
  };
344
315
  }
345
316
 
317
+ class RouterModule {
318
+ constructor(baseUrl = '') {
319
+ this.baseUrl = baseUrl;
320
+ this.subscription = new stream.Subscription();
321
+ this.navigator = new exports.BrowserNavigator(this.baseUrl);
322
+ }
323
+ setup(app) {
324
+ const baseUrl = this.baseUrl;
325
+ const navigator = this.navigator;
326
+ function getPath() {
327
+ const pathname = navigator.pathname;
328
+ return pathname.startsWith(baseUrl) ? pathname.substring(baseUrl.length) : pathname;
329
+ }
330
+ const router = new Router(navigator, null, getPath());
331
+ this.subscription.add(navigator.onUrlChanged.subscribe(() => {
332
+ router.refresh(getPath());
333
+ }));
334
+ app.provide([
335
+ {
336
+ provide: Navigator,
337
+ useValue: navigator
338
+ },
339
+ {
340
+ provide: Router,
341
+ useValue: router
342
+ }
343
+ ]);
344
+ }
345
+ onDestroy() {
346
+ this.subscription.unsubscribe();
347
+ this.navigator.destroy();
348
+ }
349
+ }
350
+
346
351
  exports.Link = Link;
347
352
  exports.Navigator = Navigator;
348
- exports.RootRouter = RootRouter;
349
353
  exports.Router = Router;
354
+ exports.RouterModule = RouterModule;
350
355
  exports.RouterOutlet = RouterOutlet;
351
356
  exports.formatQueryParams = formatQueryParams;
352
357
  exports.formatUrl = formatUrl;
package/bundles/link.d.ts CHANGED
@@ -5,6 +5,7 @@ export interface LinkProps extends Props {
5
5
  active?: string;
6
6
  exact?: boolean;
7
7
  queryParams?: QueryParams;
8
+ fragment?: string;
8
9
  tag?: string;
9
10
  }
10
11
  export declare function Link(props: LinkProps): () => any;
@@ -8,15 +8,19 @@ export declare abstract class Navigator {
8
8
  protected constructor(baseUrl: string);
9
9
  abstract onUrlChanged: Observable<void>;
10
10
  abstract get pathname(): string;
11
- abstract to(pathName: string, relative: Router, queryParams?: QueryParams): boolean;
12
- abstract replace(pathName: string, relative: Router, queryParams?: QueryParams): boolean;
13
- abstract join(pathName: string, relative: Router, queryParams?: QueryParams): string;
11
+ abstract to(pathName: string, relative: Router, queryParams?: QueryParams, fragment?: string): boolean;
12
+ abstract replace(pathName: string, relative: Router, queryParams?: QueryParams, fragment?: string): boolean;
13
+ abstract join(pathName: string, relative: Router, queryParams?: QueryParams, fragment?: string): string;
14
14
  abstract back(): void;
15
15
  abstract forward(): void;
16
16
  abstract go(offset: number): void;
17
17
  abstract destroy(): void;
18
18
  }
19
- export declare function formatUrl(pathname: string, query?: QueryParams): string;
19
+ export interface UrlFormatParams {
20
+ queryParams?: QueryParams;
21
+ fragment?: string;
22
+ }
23
+ export declare function formatUrl(pathname: string, urlFormatParams?: UrlFormatParams): string;
20
24
  export declare function formatQueryParams(queryParams: QueryParams): string;
21
25
  export declare class BrowserNavigator extends Navigator {
22
26
  onUrlChanged: Observable<void>;
@@ -24,9 +28,9 @@ export declare class BrowserNavigator extends Navigator {
24
28
  private urlChangeEvent;
25
29
  private subscription;
26
30
  constructor(baseUrl: string);
27
- to(pathName: string, relative: Router, queryParams?: QueryParams): boolean;
28
- replace(pathName: string, relative: Router, queryParams?: QueryParams): boolean;
29
- join(pathname: string, relative: Router, queryParams?: QueryParams): string;
31
+ to(pathName: string, relative: Router, queryParams?: QueryParams, fragment?: string): boolean;
32
+ replace(pathName: string, relative: Router, queryParams?: QueryParams, fragment?: string): boolean;
33
+ join(pathname: string, relative: Router, queryParams?: QueryParams, fragment?: string): string;
30
34
  back(): void;
31
35
  forward(): void;
32
36
  go(offset: number): void;
@@ -2,7 +2,7 @@ import { JSXInternal } from '@viewfly/core';
2
2
  import { Observable } from '@tanbo/stream';
3
3
  import { Navigator, QueryParams } from './navigator';
4
4
  export interface RouteConfig {
5
- name: string;
5
+ path: string;
6
6
  component?: JSXInternal.ComponentSetup;
7
7
  asyncComponent?: () => Promise<JSXInternal.ComponentSetup>;
8
8
  beforeEach?(): boolean | Promise<boolean>;
@@ -16,7 +16,7 @@ export declare class Router {
16
16
  get beforePath(): string;
17
17
  private refreshEvent;
18
18
  constructor(navigator: Navigator, parent: Router | null, path: string);
19
- navigateTo(path: string, params?: QueryParams): void;
19
+ navigateTo(path: string, params?: QueryParams, fragment?: string): void;
20
20
  replaceTo(path: string, params?: QueryParams): void;
21
21
  refresh(path: string): void;
22
22
  consumeConfig(routes: RouteConfig[]): {
@@ -1,4 +1,4 @@
1
1
  export * from './link';
2
- export * from './root-router';
3
2
  export * from './router-outlet';
3
+ export * from './router-module';
4
4
  export * from './providers/_api';
@@ -0,0 +1,9 @@
1
+ import { Application, Module } from '@viewfly/core';
2
+ export declare class RouterModule implements Module {
3
+ baseUrl: string;
4
+ private subscription;
5
+ private navigator;
6
+ constructor(baseUrl?: string);
7
+ setup(app: Application): void;
8
+ onDestroy(): void;
9
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@viewfly/router",
3
- "version": "0.3.0",
3
+ "version": "0.3.2",
4
4
  "description": "A routing library based on the Viewfly framework that can be run in the browser or Nodejs background.",
5
5
  "main": "./bundles/index.js",
6
6
  "module": "./bundles/index.esm.js",
@@ -13,7 +13,7 @@
13
13
  "keywords": [],
14
14
  "dependencies": {
15
15
  "@tanbo/stream": "^1.2.3",
16
- "@viewfly/core": "^0.3.0",
16
+ "@viewfly/core": "^0.3.1",
17
17
  "url": "^0.11.1"
18
18
  },
19
19
  "devDependencies": {
@@ -1,6 +0,0 @@
1
- import { Props, JSXInternal } from '@viewfly/core';
2
- export interface RootRouterProps extends Props {
3
- basePath?: string;
4
- children?: JSXInternal.JSXNode;
5
- }
6
- export declare function RootRouter(props: RootRouterProps): () => any;