@esportsplus/routing 0.0.11 → 0.0.13

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';
1
+ import spa from './spa';
2
2
  import middleware from './middleware';
3
3
  import router from './router';
4
4
  import slugify from './slugify';
5
- export { hash, middleware, router, slugify };
5
+ export { spa, middleware, router, slugify };
6
6
  export * from './types';
package/build/index.js CHANGED
@@ -1,6 +1,6 @@
1
- import hash from './hash';
1
+ import spa from './spa';
2
2
  import middleware from './middleware';
3
3
  import router from './router';
4
4
  import slugify from './slugify';
5
- export { hash, middleware, router, slugify };
5
+ export { spa, middleware, router, slugify };
6
6
  export * from './types';
@@ -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,17 @@
1
+ import { Request, Router } from './types';
2
+ type Cache = {
3
+ factory: typeof request;
4
+ state: Request;
5
+ };
6
+ declare const request: (url?: string) => Request;
7
+ declare const _default: (router: Router, state: Cache['state'], factory?: Cache['factory']) => {
8
+ back: () => void;
9
+ forward: () => void;
10
+ redirect: (path: string, { state, values }: {
11
+ state?: Record<PropertyKey, unknown> | undefined;
12
+ values?: unknown[] | undefined;
13
+ }) => void;
14
+ request: (url?: string) => Request;
15
+ uri: (path: string, values?: unknown[]) => string;
16
+ };
17
+ export default _default;
package/build/spa.js ADDED
@@ -0,0 +1,55 @@
1
+ let cache = [];
2
+ function update() {
3
+ for (let i = 0, n = cache.length; i < n; i++) {
4
+ let { factory, state } = cache[i], values = factory();
5
+ for (let key in values) {
6
+ state[key] = values[key];
7
+ }
8
+ }
9
+ }
10
+ const back = () => window.history.back();
11
+ const forward = () => window.history.forward();
12
+ const request = (url = window?.location?.href || '') => {
13
+ let { hash, hostname, href, origin, port, protocol } = new URL(url), path = hash?.replace('#/', '/')?.split('?') || ['/', ''];
14
+ return {
15
+ data: {},
16
+ href,
17
+ hostname,
18
+ method: 'GET',
19
+ origin,
20
+ path: path[0],
21
+ port,
22
+ protocol,
23
+ query: Object.fromEntries((new URLSearchParams(path[1])).entries())
24
+ };
25
+ };
26
+ export default (router, state, factory) => {
27
+ cache.push({
28
+ factory: factory || request,
29
+ state
30
+ });
31
+ update();
32
+ window.addEventListener('popstate', update);
33
+ return {
34
+ back,
35
+ forward,
36
+ redirect: (path, { state, values }) => {
37
+ if (path.startsWith('http://') || path.startsWith('https://')) {
38
+ return window.location.replace(path);
39
+ }
40
+ let uri = router.uri(path, values || []);
41
+ if (uri[0] === '/') {
42
+ uri = '#' + uri;
43
+ }
44
+ window.history.pushState(state || {}, '', uri);
45
+ },
46
+ request: factory || request,
47
+ uri: (path, values = []) => {
48
+ let uri = router.uri(path, values || []);
49
+ if (uri[0] === '/') {
50
+ uri = '#' + uri;
51
+ }
52
+ return uri;
53
+ }
54
+ };
55
+ };
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
@@ -1,7 +1,10 @@
1
1
  {
2
2
  "author": "ICJR",
3
+ "dependencies": {
4
+ "@esportsplus/middleware": "^0.0.4"
5
+ },
3
6
  "devDependencies": {
4
- "@esportsplus/rspack": "^0.0.15"
7
+ "@esportsplus/typescript": "^0.0.1"
5
8
  },
6
9
  "main": "./build/index.js",
7
10
  "name": "@esportsplus/routing",
@@ -13,8 +16,5 @@
13
16
  "prepublishOnly": "npm run build"
14
17
  },
15
18
  "types": "./build/index.d.ts",
16
- "version": "0.0.11",
17
- "dependencies": {
18
- "@esportsplus/middleware": "^0.0.4"
19
- }
19
+ "version": "0.0.13"
20
20
  }
package/src/index.ts CHANGED
@@ -1,8 +1,8 @@
1
- import hash from './hash';
1
+ import spa from './spa';
2
2
  import middleware from './middleware';
3
3
  import router from './router';
4
4
  import slugify from './slugify';
5
5
 
6
6
 
7
- export { hash, middleware, router, slugify };
7
+ export { spa, middleware, router, slugify };
8
8
  export * from './types';
@@ -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,85 @@
1
+ import { Request, Router } from './types';
2
+
3
+
4
+ type Cache = {
5
+ factory: typeof request;
6
+ state: Request;
7
+ };
8
+
9
+
10
+ let cache: Cache[] = [];
11
+
12
+
13
+ function update() {
14
+ for (let i = 0, n = cache.length; i < n; i++) {
15
+ let { factory, state } = cache[i],
16
+ values: Request = factory();
17
+
18
+ for (let key in values) {
19
+ // @ts-ignore STFU
20
+ state[key] = values[key];
21
+ }
22
+ }
23
+ }
24
+
25
+
26
+ const back = () => window.history.back();
27
+
28
+ const forward = () => window.history.forward();
29
+
30
+ const request = (url: string = window?.location?.href || ''): Request => {
31
+ let { hash, hostname, href, origin, port, protocol } = new URL( url ),
32
+ path = hash?.replace('#/', '/')?.split('?') || ['/', ''];
33
+
34
+ return {
35
+ data: {},
36
+ href,
37
+ hostname,
38
+ method: 'GET',
39
+ origin,
40
+ path: path[0],
41
+ port,
42
+ protocol,
43
+ query: Object.fromEntries( (new URLSearchParams(path[1])).entries() )
44
+ };
45
+ };
46
+
47
+
48
+ export default (router: Router, state: Cache['state'], factory?: Cache['factory']) => {
49
+ cache.push({
50
+ factory: factory || request,
51
+ state
52
+ });
53
+
54
+ update();
55
+
56
+ window.addEventListener('popstate', update);
57
+
58
+ return {
59
+ back,
60
+ forward,
61
+ redirect: (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
+ request: factory || request,
75
+ uri: (path: string, values: unknown[] = []) => {
76
+ let uri = router.uri(path, values || []);
77
+
78
+ if (uri[0] === '/') {
79
+ uri = '#' + uri;
80
+ }
81
+
82
+ return uri;
83
+ }
84
+ };
85
+ };
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/tsconfig.json CHANGED
@@ -5,6 +5,6 @@
5
5
  "outDir": "build",
6
6
  },
7
7
  "exclude": ["node_modules"],
8
- "extends": "@esportsplus/rspack/tsconfig.base.json",
8
+ "extends": "@esportsplus/typescript/tsconfig.base.json",
9
9
  "include": ["src"]
10
10
  }
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