@esportsplus/routing 0.0.12 → 0.0.14

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.
@@ -0,0 +1,4 @@
1
+ declare const PLACEHOLDER = 0;
2
+ declare const STATIC = 1;
3
+ declare const WILDCARD = 2;
4
+ export { PLACEHOLDER, STATIC, WILDCARD };
@@ -0,0 +1,4 @@
1
+ const PLACEHOLDER = 0;
2
+ const STATIC = 1;
3
+ const WILDCARD = 2;
4
+ export { PLACEHOLDER, STATIC, WILDCARD };
package/build/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
- import hash from './hash';
2
1
  import middleware from './middleware';
3
2
  import router from './router';
4
3
  import slugify from './slugify';
5
- export { hash, middleware, router, slugify };
4
+ import spa from './spa';
5
+ export { middleware, router, slugify, spa };
6
6
  export * from './types';
package/build/index.js CHANGED
@@ -1,6 +1,6 @@
1
- import hash from './hash';
2
1
  import middleware from './middleware';
3
2
  import router from './router';
4
3
  import slugify from './slugify';
5
- export { hash, middleware, router, slugify };
4
+ import spa from './spa';
5
+ export { middleware, router, slugify, spa };
6
6
  export * from './types';
@@ -1,5 +1,5 @@
1
- import { Router } from '../types';
2
- declare const _default: (request: {
1
+ import { Middleware, Request, Router } from '../types';
2
+ declare const _default: <R>(request: {
3
3
  data: ReturnType<Router['match']>;
4
- }) => unknown;
4
+ }) => Middleware<Request, R>;
5
5
  export default _default;
@@ -2,16 +2,16 @@ import factory from '@esportsplus/middleware';
2
2
  import dispatch from './dispatch';
3
3
  import match from './match';
4
4
  declare const _default: {
5
- dispatch: (request: {
5
+ dispatch: <R>(request: {
6
6
  data: {
7
7
  parameters?: Record<PropertyKey, unknown> | undefined;
8
8
  route?: import("../router/route").Route | undefined;
9
9
  };
10
- }) => unknown;
11
- factory: <I, R>(...middleware: import("@esportsplus/middleware/build/types").Middleware<I, R>[]) => import("@esportsplus/middleware/build/types").Next<I, R>;
12
- match: (router: import("../router").Router, { spa }?: {
10
+ }) => import("@esportsplus/middleware/build/types").Middleware<import("../types").Request, R>;
11
+ factory: <I, R_1>(...middleware: import("@esportsplus/middleware/build/types").Middleware<I, R_1>[]) => import("@esportsplus/middleware/build/types").Next<I, R_1>;
12
+ match: <R_2>(router: import("../router").Router, { spa }?: {
13
13
  spa?: boolean | undefined;
14
- }) => (request: import("../types").Request, next: import("@esportsplus/middleware/build/types").Next<import("../types").Request, unknown>) => unknown;
14
+ }) => import("@esportsplus/middleware/build/types").Middleware<import("../types").Request, R_2>;
15
15
  };
16
16
  export default _default;
17
17
  export { dispatch, factory, match };
@@ -1,5 +1,5 @@
1
- import { Next, Request, Router } from '../types';
2
- declare const _default: (router: Router, { spa }?: {
1
+ import { Middleware, Request, Router } from '../types';
2
+ declare const _default: <R>(router: Router, { spa }?: {
3
3
  spa?: boolean | undefined;
4
- }) => (request: Request, next: Next<Request, unknown>) => unknown;
4
+ }) => Middleware<Request, R>;
5
5
  export default _default;
@@ -16,7 +16,7 @@ declare class Router {
16
16
  routes: (fn: (router: Router) => void) => void;
17
17
  };
18
18
  match(method: string, path: string, subdomain?: string | null): ReturnType<Node['find']>;
19
- on(methods: string[], options: Options): void;
19
+ on(methods: string[], options: Options): this;
20
20
  post(options: Options): this;
21
21
  put(options: Options): this;
22
22
  uri(name: string, values?: unknown[]): string;
@@ -1,4 +1,4 @@
1
- import { STATIC } from "../symbols";
1
+ import { STATIC } from "../constants";
2
2
  import { Node } from './node';
3
3
  import { normalize, radixkey } from './path';
4
4
  import { Route } from './route';
@@ -31,13 +31,13 @@ class Router {
31
31
  this.root = new Node();
32
32
  }
33
33
  add(radixkey, route) {
34
- let node = this.root.add(radixkey, route);
35
- if (node.type === STATIC) {
34
+ if (radixkey.indexOf(':') === -1 || this.root.add(radixkey, route).type === STATIC) {
36
35
  if (this.static[radixkey]) {
37
36
  throw new Error(`Routing: static path '${radixkey}' is already in use`);
38
37
  }
39
38
  this.static[radixkey] = route;
40
39
  }
40
+ return this;
41
41
  }
42
42
  route({ middleware, name, path, responder, subdomain }) {
43
43
  let route = new Route(responder);
@@ -79,10 +79,8 @@ class Router {
79
79
  }
80
80
  match(method, path, subdomain) {
81
81
  let key = radixkey(path, { method, subdomain });
82
- if (this.static[key]) {
83
- return {
84
- route: this.static[key]
85
- };
82
+ if (key in this.static) {
83
+ return { route: this.static[key] };
86
84
  }
87
85
  return this.root.find(key);
88
86
  }
@@ -119,6 +117,7 @@ class Router {
119
117
  this.subdomains.push(route.subdomain);
120
118
  }
121
119
  }
120
+ return this;
122
121
  }
123
122
  post(options) {
124
123
  this.on(['POST'], options);
@@ -129,7 +128,7 @@ class Router {
129
128
  return this;
130
129
  }
131
130
  uri(name, values = []) {
132
- let path = this.routes?.[name]?.path;
131
+ let path = this.routes[name]?.path;
133
132
  if (!path) {
134
133
  throw new Error(`Routing: route name '${name}' does not exist or it does not provide a path`);
135
134
  }
@@ -1,4 +1,4 @@
1
- import { PLACEHOLDER, STATIC, WILDCARD } from "../symbols";
1
+ import { PLACEHOLDER, STATIC, WILDCARD } from "../constants";
2
2
  class Node {
3
3
  children = null;
4
4
  parent = null;
package/build/spa.d.ts ADDED
@@ -0,0 +1,16 @@
1
+ import { Router } from './types';
2
+ type Cache<T = Record<string, unknown>> = {
3
+ factory: () => T;
4
+ state: T;
5
+ };
6
+ declare const _default: (router: Router, fn?: Cache['factory']) => {
7
+ back: () => void;
8
+ forward: () => void;
9
+ redirect: (path: string, { state, values }: {
10
+ state?: Record<PropertyKey, unknown> | undefined;
11
+ values?: unknown[] | undefined;
12
+ }) => void;
13
+ request: Record<string, unknown>;
14
+ uri: (path: string, values?: unknown[]) => string;
15
+ };
16
+ export default _default;
package/build/spa.js ADDED
@@ -0,0 +1,56 @@
1
+ let cache = [];
2
+ function request(url = window?.location?.href || '') {
3
+ let { hash, hostname, href, origin, port, protocol } = new URL(url), path = hash?.replace('#/', '/')?.split('?') || ['/', ''];
4
+ return {
5
+ data: {},
6
+ href,
7
+ hostname,
8
+ method: 'GET',
9
+ origin,
10
+ path: path[0],
11
+ port,
12
+ protocol,
13
+ query: Object.fromEntries((new URLSearchParams(path[1])).entries())
14
+ };
15
+ }
16
+ function update() {
17
+ for (let i = 0, n = cache.length; i < n; i++) {
18
+ let { factory, state } = cache[i], values = factory();
19
+ for (let key in values) {
20
+ state[key] = values[key];
21
+ }
22
+ }
23
+ }
24
+ const back = () => window.history.back();
25
+ const forward = () => window.history.forward();
26
+ export default (router, fn = request) => {
27
+ let state = {};
28
+ cache.push({
29
+ factory: fn,
30
+ state
31
+ });
32
+ update();
33
+ window.addEventListener('popstate', update);
34
+ return {
35
+ back,
36
+ forward,
37
+ redirect: (path, { state, values }) => {
38
+ if (path.startsWith('http://') || path.startsWith('https://')) {
39
+ return window.location.replace(path);
40
+ }
41
+ let uri = router.uri(path, values || []);
42
+ if (uri[0] === '/') {
43
+ uri = '#' + uri;
44
+ }
45
+ window.history.pushState(state || {}, '', uri);
46
+ },
47
+ request: state,
48
+ uri: (path, values = []) => {
49
+ let uri = router.uri(path, values || []);
50
+ if (uri[0] === '/') {
51
+ uri = '#' + uri;
52
+ }
53
+ return uri;
54
+ }
55
+ };
56
+ };
package/build/types.d.ts CHANGED
@@ -8,11 +8,16 @@ type Options = {
8
8
  subdomain?: string;
9
9
  };
10
10
  type Request = {
11
- data: ReturnType<Router['match']>;
11
+ data: ReturnType<Router['match']> & Record<PropertyKey, unknown>;
12
+ href: string;
12
13
  hostname: string;
13
14
  method: string;
15
+ origin: string;
14
16
  path: string;
17
+ port: string;
18
+ protocol: string;
19
+ query: Record<string, unknown>;
15
20
  subdomain?: string;
16
21
  };
17
- type Responder = <T>(request: T) => Promise<unknown> | unknown;
22
+ type Responder = <T, U>(request: T) => Promise<U> | U;
18
23
  export { Middleware, Next, Options, Request, Responder, Route, Router };
package/package.json CHANGED
@@ -16,5 +16,5 @@
16
16
  "prepublishOnly": "npm run build"
17
17
  },
18
18
  "types": "./build/index.d.ts",
19
- "version": "0.0.12"
19
+ "version": "0.0.14"
20
20
  }
package/src/index.ts CHANGED
@@ -1,8 +1,8 @@
1
- import hash from './hash';
2
1
  import middleware from './middleware';
3
2
  import router from './router';
4
3
  import slugify from './slugify';
4
+ import spa from './spa';
5
5
 
6
6
 
7
- export { hash, middleware, router, slugify };
7
+ export { middleware, router, slugify, spa };
8
8
  export * from './types';
@@ -1,12 +1,12 @@
1
- import { Router } from '~/types';
1
+ import { Middleware, Request, Router } from '~/types';
2
2
 
3
3
 
4
- export default (request: { data: ReturnType<Router['match']> }) => {
4
+ export default <R>(request: { data: ReturnType<Router['match']> }) => {
5
5
  let { route } = request.data;
6
6
 
7
7
  if (!route) {
8
8
  throw new Error(`Routing: route dispatching failed, route is undefined!`);
9
9
  }
10
10
 
11
- return route.dispatcher(request);
11
+ return route.dispatcher(request) as Middleware<Request, R>;
12
12
  };
@@ -1,10 +1,10 @@
1
- import { Next, Request, Router } from '~/types';
1
+ import { Middleware, Request, Router } from '~/types';
2
2
 
3
3
 
4
- export default (router: Router, { spa }: { spa?: boolean } = {}) => {
4
+ export default <R>(router: Router, { spa }: { spa?: boolean } = {}): Middleware<Request, R> => {
5
5
  let subdomain: string | null = null;
6
6
 
7
- return (request: Request, next: Next<Request, unknown>) => {
7
+ return (request, next) => {
8
8
  if ((typeof request.subdomain !== 'string' && !spa) || subdomain === null) {
9
9
  if (router.subdomains) {
10
10
  for (let i = 0, n = router.subdomains.length; i < n; i++) {
@@ -1,4 +1,4 @@
1
- import { STATIC } from "~/symbols";
1
+ import { STATIC } from "~/constants";
2
2
  import { Options } from '~/types';
3
3
  import { Node } from './node';
4
4
  import { normalize, radixkey } from './path';
@@ -8,13 +8,13 @@ import { Route } from './route';
8
8
  let { isArray } = Array;
9
9
 
10
10
 
11
- function set(route: Route, key: keyof Route, value?: any) {
11
+ function set(route: Route, key: keyof Route, value?: unknown) {
12
12
  if (!value) {
13
13
  return;
14
14
  }
15
15
 
16
16
  if (!route[key]) {
17
- (route[key] as any) = value;
17
+ (route[key] as unknown) = value;
18
18
  }
19
19
  else if (typeof value === 'string') {
20
20
  if (typeof route[key] === 'string') {
@@ -23,7 +23,7 @@ function set(route: Route, key: keyof Route, value?: any) {
23
23
  }
24
24
  else if (isArray(value)) {
25
25
  if (isArray(route[key])) {
26
- (route[key] as any[]).push( ...value );
26
+ (route[key] as unknown[]).push( ...value );
27
27
  }
28
28
  }
29
29
  }
@@ -43,15 +43,15 @@ class Router {
43
43
 
44
44
 
45
45
  private add(radixkey: string, route: Route) {
46
- let node = this.root.add(radixkey, route);
47
-
48
- if (node.type === STATIC) {
46
+ if (radixkey.indexOf(':') === -1 || this.root.add(radixkey, route).type === STATIC) {
49
47
  if (this.static[radixkey]) {
50
48
  throw new Error(`Routing: static path '${radixkey}' is already in use`);
51
49
  }
52
50
 
53
51
  this.static[radixkey] = route;
54
52
  }
53
+
54
+ return this;
55
55
  }
56
56
 
57
57
  private route({ middleware, name, path, responder, subdomain }: Options) {
@@ -106,10 +106,8 @@ class Router {
106
106
  match(method: string, path: string, subdomain?: string | null): ReturnType<Node['find']> {
107
107
  let key = radixkey(path, { method, subdomain });
108
108
 
109
- if (this.static[key]) {
110
- return {
111
- route: this.static[key]
112
- };
109
+ if (key in this.static) {
110
+ return { route: this.static[key] };
113
111
  }
114
112
 
115
113
  return this.root.find(key);
@@ -155,6 +153,8 @@ class Router {
155
153
  this.subdomains.push(route.subdomain);
156
154
  }
157
155
  }
156
+
157
+ return this;
158
158
  }
159
159
 
160
160
  post(options: Options) {
@@ -168,7 +168,7 @@ class Router {
168
168
  }
169
169
 
170
170
  uri(name: string, values: unknown[] = []) {
171
- let path = this.routes?.[name]?.path;
171
+ let path = this.routes[name]?.path;
172
172
 
173
173
  if (!path) {
174
174
  throw new Error(`Routing: route name '${name}' does not exist or it does not provide a path`);
@@ -1,4 +1,4 @@
1
- import { PLACEHOLDER, STATIC, WILDCARD } from "~/symbols";
1
+ import { PLACEHOLDER, STATIC, WILDCARD } from "~/constants";
2
2
  import { Route } from './index';
3
3
 
4
4
 
package/src/spa.ts ADDED
@@ -0,0 +1,86 @@
1
+ import { Request, Router } from './types';
2
+
3
+
4
+ type Cache<T = Record<string, unknown>> = {
5
+ factory: () => T;
6
+ state: T;
7
+ };
8
+
9
+
10
+ let cache: Cache[] = [];
11
+
12
+
13
+ function request(url: string = window?.location?.href || ''): Request {
14
+ let { hash, hostname, href, origin, port, protocol } = new URL( url ),
15
+ path = hash?.replace('#/', '/')?.split('?') || ['/', ''];
16
+
17
+ return {
18
+ data: {},
19
+ href,
20
+ hostname,
21
+ method: 'GET',
22
+ origin,
23
+ path: path[0],
24
+ port,
25
+ protocol,
26
+ query: Object.fromEntries( (new URLSearchParams(path[1])).entries() )
27
+ };
28
+ }
29
+
30
+ function update() {
31
+ for (let i = 0, n = cache.length; i < n; i++) {
32
+ let { factory, state } = cache[i],
33
+ values = factory();
34
+
35
+ for (let key in values) {
36
+ state[key] = values[key];
37
+ }
38
+ }
39
+ }
40
+
41
+
42
+ const back = () => window.history.back();
43
+
44
+ const forward = () => window.history.forward();
45
+
46
+
47
+ export default (router: Router, fn: Cache['factory'] = request) => {
48
+ let state = {} as ReturnType< typeof fn >;
49
+
50
+ cache.push({
51
+ factory: fn,
52
+ state
53
+ });
54
+
55
+ update();
56
+
57
+ window.addEventListener('popstate', update);
58
+
59
+ return {
60
+ back,
61
+ forward,
62
+ redirect: (path: string, { state, values }: { state?: Record<PropertyKey, unknown>; values?: unknown[] }) => {
63
+ if (path.startsWith('http://') || path.startsWith('https://')) {
64
+ return window.location.replace(path);
65
+ }
66
+
67
+ let uri = router.uri(path, values || []);
68
+
69
+ if (uri[0] === '/') {
70
+ uri = '#' + uri;
71
+ }
72
+
73
+ window.history.pushState(state || {}, '', uri);
74
+ },
75
+ request: state,
76
+ uri: (path: string, values: unknown[] = []) => {
77
+ let uri = router.uri(path, values || []);
78
+
79
+ if (uri[0] === '/') {
80
+ uri = '#' + uri;
81
+ }
82
+
83
+ return uri;
84
+ }
85
+ };
86
+ };
package/src/types.ts CHANGED
@@ -11,14 +11,19 @@ type Options = {
11
11
  };
12
12
 
13
13
  type Request = {
14
- data: ReturnType<Router['match']>;
14
+ data: ReturnType<Router['match']> & Record<PropertyKey, unknown>;
15
+ href: string;
15
16
  hostname: string;
16
17
  method: string;
18
+ origin: string;
17
19
  path: string;
20
+ port: string;
21
+ protocol: string;
22
+ query: Record<string, unknown>;
18
23
  subdomain?: string;
19
24
  };
20
25
 
21
- type Responder = <T>(request: T) => Promise<unknown> | unknown;
26
+ type Responder = <T, U>(request: T) => Promise<U> | U;
22
27
 
23
28
 
24
29
  export { Middleware, Next, Options, Request, Responder, Route, Router };
package/src/hash.ts DELETED
@@ -1,106 +0,0 @@
1
- import { Router } from './types';
2
-
3
-
4
- let cache: {
5
- factory: typeof request;
6
- state: Record<PropertyKey, unknown>;
7
- }[] = [],
8
- registered = false;
9
-
10
-
11
- function update() {
12
- for (let i = 0, n = cache.length; i < n; i++) {
13
- let { factory, state } = cache[i],
14
- values = factory();
15
-
16
- for (let key in values) {
17
- state[key] = values[key as keyof typeof values];
18
- }
19
- }
20
- }
21
-
22
-
23
- const back = () => window.history.back();
24
-
25
- const forward = () => window.history.forward();
26
-
27
- const listener = {
28
- register: (factory: typeof cache[0]['factory'], state: typeof cache[0]['state']) => {
29
- cache.push({ factory, state });
30
-
31
- if (!registered) {
32
- registered = true;
33
- update();
34
-
35
- window.addEventListener('popstate', update);
36
- }
37
-
38
- return () => {
39
- listener.remove(state);
40
- };
41
- },
42
- remove: (state: typeof cache[0]['state']) => {
43
- for (let i = 0, n = cache.length; i < n; i++) {
44
- if (cache[i].state !== state) {
45
- continue;
46
- }
47
-
48
- cache[i] = cache[n - 1];
49
- cache.pop();
50
-
51
- if (cache.length === 0) {
52
- window.removeEventListener('popstate', update);
53
- }
54
- return;
55
- }
56
- }
57
- };
58
-
59
- const factory = {
60
- redirect: (router: Router) => {
61
- return (path: string, { state, values }: { state?: Record<PropertyKey, unknown>; values?: unknown[] }) => {
62
- if (path.startsWith('http://') || path.startsWith('https://')) {
63
- return window.location.replace(path);
64
- }
65
-
66
- let uri = router.uri(path, values || []);
67
-
68
- if (uri[0] === '/') {
69
- uri = '#' + uri;
70
- }
71
-
72
- window.history.pushState(state || {}, '', uri);
73
- };
74
- },
75
- uri: (router: Router) => {
76
- return (path: string, values: unknown[] = []) => {
77
- let uri = router.uri(path, values || []);
78
-
79
- if (uri[0] === '/') {
80
- uri = '#' + uri;
81
- }
82
-
83
- return uri;
84
- };
85
- }
86
- };
87
-
88
- const request = (url: string = window?.location?.href || '') => {
89
- let { hash, hostname, href, origin, port, protocol } = new URL( url ),
90
- path = hash?.replace('#/', '/')?.split('?') || ['/', ''];
91
-
92
- return {
93
- href,
94
- hostname,
95
- method: 'GET',
96
- origin,
97
- path: path[0],
98
- port,
99
- protocol,
100
- query: Object.fromEntries( (new URLSearchParams(path[1])).entries() )
101
- };
102
- };
103
-
104
-
105
- export default { back, factory, forward, listener, request };
106
- export { back, factory, forward, listener, request };
File without changes