@hyperspan/framework 0.3.1 → 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.
- package/dist/assets.js +3 -8
- package/dist/server.js +31 -24
- package/package.json +1 -1
- package/src/assets.ts +9 -13
- package/src/clientjs/hyperspan-client.ts +35 -0
- package/src/server.ts +39 -26
- package/src/clientjs/md5.js +0 -176
- package/src/clientjs/preact.ts +0 -3
package/dist/assets.js
CHANGED
|
@@ -60,17 +60,12 @@ function assetHash(content) {
|
|
|
60
60
|
}
|
|
61
61
|
var ISLAND_PUBLIC_PATH = "/_hs/js/islands";
|
|
62
62
|
var ISLAND_DEFAULTS = () => ({
|
|
63
|
-
ssr: true
|
|
63
|
+
ssr: true,
|
|
64
|
+
loading: undefined
|
|
64
65
|
});
|
|
65
66
|
function renderIsland(Component, props, options = ISLAND_DEFAULTS()) {
|
|
66
67
|
if (Component.__HS_ISLAND?.render) {
|
|
67
|
-
return Component.__HS_ISLAND.render(props, options);
|
|
68
|
-
}
|
|
69
|
-
if (Component.__HS_ISLAND?.ssr && options.ssr) {
|
|
70
|
-
return Component.__HS_ISLAND.ssr(props);
|
|
71
|
-
}
|
|
72
|
-
if (Component.__HS_ISLAND?.clientOnly) {
|
|
73
|
-
return Component.__HS_ISLAND.clientOnly(props);
|
|
68
|
+
return html.raw(Component.__HS_ISLAND.render(props, options));
|
|
74
69
|
}
|
|
75
70
|
throw new Error(`Module ${Component.name} was not loaded with an island plugin! Did you forget to install an island plugin and add it to the createServer() 'islandPlugins' config?`);
|
|
76
71
|
}
|
package/dist/server.js
CHANGED
|
@@ -1847,18 +1847,6 @@ function createRoute(handler) {
|
|
|
1847
1847
|
_handlers["POST"] = handler2;
|
|
1848
1848
|
return api;
|
|
1849
1849
|
},
|
|
1850
|
-
put(handler2) {
|
|
1851
|
-
_handlers["PUT"] = handler2;
|
|
1852
|
-
return api;
|
|
1853
|
-
},
|
|
1854
|
-
delete(handler2) {
|
|
1855
|
-
_handlers["DELETE"] = handler2;
|
|
1856
|
-
return api;
|
|
1857
|
-
},
|
|
1858
|
-
patch(handler2) {
|
|
1859
|
-
_handlers["PATCH"] = handler2;
|
|
1860
|
-
return api;
|
|
1861
|
-
},
|
|
1862
1850
|
middleware(middleware) {
|
|
1863
1851
|
_middleware = middleware;
|
|
1864
1852
|
return api;
|
|
@@ -1909,7 +1897,7 @@ function createAPIRoute(handler) {
|
|
|
1909
1897
|
_handlers["GET"] = handler;
|
|
1910
1898
|
}
|
|
1911
1899
|
const api = {
|
|
1912
|
-
_kind: "
|
|
1900
|
+
_kind: "hsAPIRoute",
|
|
1913
1901
|
get(handler2) {
|
|
1914
1902
|
_handlers["GET"] = handler2;
|
|
1915
1903
|
return api;
|
|
@@ -1988,21 +1976,40 @@ function getRunnableRoute(route) {
|
|
|
1988
1976
|
throw new Error(`Route not runnable. Use "export default createRoute()" to create a Hyperspan route. Exported methods found were: ${Object.keys(route).join(", ")}`);
|
|
1989
1977
|
}
|
|
1990
1978
|
function isRunnableRoute(route) {
|
|
1991
|
-
|
|
1979
|
+
if (typeof route !== "object") {
|
|
1980
|
+
return false;
|
|
1981
|
+
}
|
|
1982
|
+
const obj = route;
|
|
1983
|
+
const runnableKind = ["hsRoute", "hsAPIRoute", "hsAction"].includes(obj?._kind);
|
|
1984
|
+
return runnableKind && "_getRouteHandlers" in obj;
|
|
1992
1985
|
}
|
|
1993
1986
|
async function showErrorReponse(context, err) {
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
|
|
1987
|
+
let status = 500;
|
|
1988
|
+
const message = err.message || "Internal Server Error";
|
|
1989
|
+
if (err instanceof HTTPException) {
|
|
1990
|
+
status = err.status;
|
|
1991
|
+
}
|
|
1992
|
+
const stack = !IS_PROD && err.stack ? err.stack.split(`
|
|
1999
1993
|
`).slice(1).join(`
|
|
2000
|
-
`) : ""
|
|
2001
|
-
|
|
1994
|
+
`) : "";
|
|
1995
|
+
const output = render(html`
|
|
1996
|
+
<!DOCTYPE html>
|
|
1997
|
+
<html lang="en">
|
|
1998
|
+
<head>
|
|
1999
|
+
<meta charset="UTF-8" />
|
|
2000
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
2001
|
+
<title>Application Error</title>
|
|
2002
|
+
</head>
|
|
2003
|
+
<body>
|
|
2004
|
+
<main>
|
|
2005
|
+
<h1>Application Error</h1>
|
|
2006
|
+
<strong>${message}</strong>
|
|
2007
|
+
${stack ? html`<pre>${stack}</pre>` : ""}
|
|
2008
|
+
</main>
|
|
2009
|
+
</body>
|
|
2010
|
+
</html>
|
|
2002
2011
|
`);
|
|
2003
|
-
return context.html(output, {
|
|
2004
|
-
status: 500
|
|
2005
|
-
});
|
|
2012
|
+
return context.html(output, { status });
|
|
2006
2013
|
}
|
|
2007
2014
|
var ROUTE_SEGMENT = /(\[[a-zA-Z_\.]+\])/g;
|
|
2008
2015
|
async function buildRoutes(config) {
|
package/package.json
CHANGED
package/src/assets.ts
CHANGED
|
@@ -3,6 +3,11 @@ import { createHash } from 'node:crypto';
|
|
|
3
3
|
import { readdir } from 'node:fs/promises';
|
|
4
4
|
import { resolve } from 'node:path';
|
|
5
5
|
|
|
6
|
+
export type THSIslandOptions = {
|
|
7
|
+
ssr?: boolean;
|
|
8
|
+
loading?: 'lazy' | undefined;
|
|
9
|
+
};
|
|
10
|
+
|
|
6
11
|
const IS_PROD = process.env.NODE_ENV === 'production';
|
|
7
12
|
const PWD = import.meta.dir;
|
|
8
13
|
|
|
@@ -97,24 +102,15 @@ export function assetHash(content: string): string {
|
|
|
97
102
|
* Island defaults
|
|
98
103
|
*/
|
|
99
104
|
export const ISLAND_PUBLIC_PATH = '/_hs/js/islands';
|
|
100
|
-
export const ISLAND_DEFAULTS = () => ({
|
|
105
|
+
export const ISLAND_DEFAULTS: () => THSIslandOptions = () => ({
|
|
101
106
|
ssr: true,
|
|
107
|
+
loading: undefined,
|
|
102
108
|
});
|
|
103
109
|
|
|
104
110
|
export function renderIsland(Component: any, props: any, options = ISLAND_DEFAULTS()) {
|
|
105
|
-
// Render
|
|
111
|
+
// Render island with its own logic
|
|
106
112
|
if (Component.__HS_ISLAND?.render) {
|
|
107
|
-
return Component.__HS_ISLAND.render(props, options);
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
// If ssr is true, render the island with the ssr function
|
|
111
|
-
if (Component.__HS_ISLAND?.ssr && options.ssr) {
|
|
112
|
-
return Component.__HS_ISLAND.ssr(props);
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
// If ssr is false, render the island with the clientOnly function
|
|
116
|
-
if (Component.__HS_ISLAND?.clientOnly) {
|
|
117
|
-
return Component.__HS_ISLAND.clientOnly(props);
|
|
113
|
+
return html.raw(Component.__HS_ISLAND.render(props, options));
|
|
118
114
|
}
|
|
119
115
|
|
|
120
116
|
throw new Error(
|
|
@@ -31,6 +31,9 @@ function htmlAsyncContentObserver() {
|
|
|
31
31
|
Idiomorph.morph(slotEl, el.content.cloneNode(true));
|
|
32
32
|
el.parentNode.removeChild(el);
|
|
33
33
|
});
|
|
34
|
+
|
|
35
|
+
// Lazy load scripts (if any) after the content is inserted
|
|
36
|
+
lazyLoadScripts();
|
|
34
37
|
}
|
|
35
38
|
} catch (e) {
|
|
36
39
|
console.error(e);
|
|
@@ -122,5 +125,37 @@ function formSubmitToRoute(e: Event, form: HTMLFormElement) {
|
|
|
122
125
|
});
|
|
123
126
|
}
|
|
124
127
|
|
|
128
|
+
/**
|
|
129
|
+
* Intersection observer for lazy loading <script> tags
|
|
130
|
+
*/
|
|
131
|
+
const lazyLoadScriptObserver = new IntersectionObserver(
|
|
132
|
+
(entries, observer) => {
|
|
133
|
+
entries
|
|
134
|
+
.filter((entry) => entry.isIntersecting)
|
|
135
|
+
.forEach((entry) => {
|
|
136
|
+
observer.unobserve(entry.target);
|
|
137
|
+
// @ts-ignore
|
|
138
|
+
if (entry.target.children[0]?.content) {
|
|
139
|
+
// @ts-ignore
|
|
140
|
+
entry.target.replaceWith(entry.target.children[0].content);
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
},
|
|
144
|
+
{ rootMargin: '0px 0px -200px 0px' }
|
|
145
|
+
);
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Lazy load <script> tags in the current document
|
|
149
|
+
*/
|
|
150
|
+
function lazyLoadScripts() {
|
|
151
|
+
document
|
|
152
|
+
.querySelectorAll('div[data-loading=lazy]')
|
|
153
|
+
.forEach((el) => lazyLoadScriptObserver.observe(el));
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
window.addEventListener('load', () => {
|
|
157
|
+
lazyLoadScripts();
|
|
158
|
+
});
|
|
159
|
+
|
|
125
160
|
// @ts-ignore
|
|
126
161
|
window.html = html;
|
package/src/server.ts
CHANGED
|
@@ -7,6 +7,7 @@ import { Hono, type Context } from 'hono';
|
|
|
7
7
|
import { serveStatic } from 'hono/bun';
|
|
8
8
|
import { HTTPException } from 'hono/http-exception';
|
|
9
9
|
import type { HandlerResponse, MiddlewareHandler } from 'hono/types';
|
|
10
|
+
import type { ContentfulStatusCode } from 'hono/utils/http-status';
|
|
10
11
|
|
|
11
12
|
export const IS_PROD = process.env.NODE_ENV === 'production';
|
|
12
13
|
const CWD = process.cwd();
|
|
@@ -22,9 +23,6 @@ export type THSRoute = {
|
|
|
22
23
|
_kind: 'hsRoute';
|
|
23
24
|
get: (handler: THSRouteHandler) => THSRoute;
|
|
24
25
|
post: (handler: THSRouteHandler) => THSRoute;
|
|
25
|
-
put: (handler: THSRouteHandler) => THSRoute;
|
|
26
|
-
delete: (handler: THSRouteHandler) => THSRoute;
|
|
27
|
-
patch: (handler: THSRouteHandler) => THSRoute;
|
|
28
26
|
middleware: (middleware: Array<MiddlewareHandler>) => THSRoute;
|
|
29
27
|
_getRouteHandlers: () => Array<MiddlewareHandler | ((context: Context) => HandlerResponse<any>)>;
|
|
30
28
|
};
|
|
@@ -65,18 +63,6 @@ export function createRoute(handler?: THSRouteHandler): THSRoute {
|
|
|
65
63
|
_handlers['POST'] = handler;
|
|
66
64
|
return api;
|
|
67
65
|
},
|
|
68
|
-
put(handler: THSRouteHandler) {
|
|
69
|
-
_handlers['PUT'] = handler;
|
|
70
|
-
return api;
|
|
71
|
-
},
|
|
72
|
-
delete(handler: THSRouteHandler) {
|
|
73
|
-
_handlers['DELETE'] = handler;
|
|
74
|
-
return api;
|
|
75
|
-
},
|
|
76
|
-
patch(handler: THSRouteHandler) {
|
|
77
|
-
_handlers['PATCH'] = handler;
|
|
78
|
-
return api;
|
|
79
|
-
},
|
|
80
66
|
middleware(middleware: Array<MiddlewareHandler>) {
|
|
81
67
|
_middleware = middleware;
|
|
82
68
|
return api;
|
|
@@ -147,7 +133,7 @@ export function createAPIRoute(handler?: THSAPIRouteHandler): THSAPIRoute {
|
|
|
147
133
|
}
|
|
148
134
|
|
|
149
135
|
const api: THSAPIRoute = {
|
|
150
|
-
_kind: '
|
|
136
|
+
_kind: 'hsAPIRoute',
|
|
151
137
|
get(handler: THSAPIRouteHandler) {
|
|
152
138
|
_handlers['GET'] = handler;
|
|
153
139
|
return api;
|
|
@@ -256,9 +242,18 @@ export function getRunnableRoute(route: unknown): THSRoute {
|
|
|
256
242
|
);
|
|
257
243
|
}
|
|
258
244
|
|
|
245
|
+
/**
|
|
246
|
+
* Check if a route is runnable by Hyperspan
|
|
247
|
+
*/
|
|
259
248
|
export function isRunnableRoute(route: unknown): boolean {
|
|
260
|
-
|
|
261
|
-
|
|
249
|
+
if (typeof route !== 'object') {
|
|
250
|
+
return false;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
const obj = route as { _kind: string; _getRouteHandlers: any };
|
|
254
|
+
const runnableKind = ['hsRoute', 'hsAPIRoute', 'hsAction'].includes(obj?._kind);
|
|
255
|
+
|
|
256
|
+
return runnableKind && '_getRouteHandlers' in obj;
|
|
262
257
|
}
|
|
263
258
|
|
|
264
259
|
/**
|
|
@@ -266,17 +261,35 @@ export function isRunnableRoute(route: unknown): boolean {
|
|
|
266
261
|
* @TODO: Should check for and load user-customizeable template with special name (app/__error.ts ?)
|
|
267
262
|
*/
|
|
268
263
|
async function showErrorReponse(context: Context, err: Error) {
|
|
264
|
+
let status: ContentfulStatusCode = 500;
|
|
265
|
+
const message = err.message || 'Internal Server Error';
|
|
266
|
+
|
|
267
|
+
// Send correct status code if HTTPException
|
|
268
|
+
if (err instanceof HTTPException) {
|
|
269
|
+
status = err.status as ContentfulStatusCode;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
const stack = !IS_PROD && err.stack ? err.stack.split('\n').slice(1).join('\n') : '';
|
|
273
|
+
|
|
269
274
|
const output = render(html`
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
<
|
|
273
|
-
|
|
274
|
-
|
|
275
|
+
<!DOCTYPE html>
|
|
276
|
+
<html lang="en">
|
|
277
|
+
<head>
|
|
278
|
+
<meta charset="UTF-8" />
|
|
279
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
280
|
+
<title>Application Error</title>
|
|
281
|
+
</head>
|
|
282
|
+
<body>
|
|
283
|
+
<main>
|
|
284
|
+
<h1>Application Error</h1>
|
|
285
|
+
<strong>${message}</strong>
|
|
286
|
+
${stack ? html`<pre>${stack}</pre>` : ''}
|
|
287
|
+
</main>
|
|
288
|
+
</body>
|
|
289
|
+
</html>
|
|
275
290
|
`);
|
|
276
291
|
|
|
277
|
-
return context.html(output, {
|
|
278
|
-
status: 500,
|
|
279
|
-
});
|
|
292
|
+
return context.html(output, { status });
|
|
280
293
|
}
|
|
281
294
|
|
|
282
295
|
export type THSServerConfig = {
|
package/src/clientjs/md5.js
DELETED
|
@@ -1,176 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Fast browser md5 function (used for static asset hashing)
|
|
3
|
-
* @link https://www.myersdaily.org/joseph/javascript/md5.js
|
|
4
|
-
*/
|
|
5
|
-
function md5cycle(x, k) {
|
|
6
|
-
var a = x[0],
|
|
7
|
-
b = x[1],
|
|
8
|
-
c = x[2],
|
|
9
|
-
d = x[3];
|
|
10
|
-
|
|
11
|
-
a = ff(a, b, c, d, k[0], 7, -680876936);
|
|
12
|
-
d = ff(d, a, b, c, k[1], 12, -389564586);
|
|
13
|
-
c = ff(c, d, a, b, k[2], 17, 606105819);
|
|
14
|
-
b = ff(b, c, d, a, k[3], 22, -1044525330);
|
|
15
|
-
a = ff(a, b, c, d, k[4], 7, -176418897);
|
|
16
|
-
d = ff(d, a, b, c, k[5], 12, 1200080426);
|
|
17
|
-
c = ff(c, d, a, b, k[6], 17, -1473231341);
|
|
18
|
-
b = ff(b, c, d, a, k[7], 22, -45705983);
|
|
19
|
-
a = ff(a, b, c, d, k[8], 7, 1770035416);
|
|
20
|
-
d = ff(d, a, b, c, k[9], 12, -1958414417);
|
|
21
|
-
c = ff(c, d, a, b, k[10], 17, -42063);
|
|
22
|
-
b = ff(b, c, d, a, k[11], 22, -1990404162);
|
|
23
|
-
a = ff(a, b, c, d, k[12], 7, 1804603682);
|
|
24
|
-
d = ff(d, a, b, c, k[13], 12, -40341101);
|
|
25
|
-
c = ff(c, d, a, b, k[14], 17, -1502002290);
|
|
26
|
-
b = ff(b, c, d, a, k[15], 22, 1236535329);
|
|
27
|
-
|
|
28
|
-
a = gg(a, b, c, d, k[1], 5, -165796510);
|
|
29
|
-
d = gg(d, a, b, c, k[6], 9, -1069501632);
|
|
30
|
-
c = gg(c, d, a, b, k[11], 14, 643717713);
|
|
31
|
-
b = gg(b, c, d, a, k[0], 20, -373897302);
|
|
32
|
-
a = gg(a, b, c, d, k[5], 5, -701558691);
|
|
33
|
-
d = gg(d, a, b, c, k[10], 9, 38016083);
|
|
34
|
-
c = gg(c, d, a, b, k[15], 14, -660478335);
|
|
35
|
-
b = gg(b, c, d, a, k[4], 20, -405537848);
|
|
36
|
-
a = gg(a, b, c, d, k[9], 5, 568446438);
|
|
37
|
-
d = gg(d, a, b, c, k[14], 9, -1019803690);
|
|
38
|
-
c = gg(c, d, a, b, k[3], 14, -187363961);
|
|
39
|
-
b = gg(b, c, d, a, k[8], 20, 1163531501);
|
|
40
|
-
a = gg(a, b, c, d, k[13], 5, -1444681467);
|
|
41
|
-
d = gg(d, a, b, c, k[2], 9, -51403784);
|
|
42
|
-
c = gg(c, d, a, b, k[7], 14, 1735328473);
|
|
43
|
-
b = gg(b, c, d, a, k[12], 20, -1926607734);
|
|
44
|
-
|
|
45
|
-
a = hh(a, b, c, d, k[5], 4, -378558);
|
|
46
|
-
d = hh(d, a, b, c, k[8], 11, -2022574463);
|
|
47
|
-
c = hh(c, d, a, b, k[11], 16, 1839030562);
|
|
48
|
-
b = hh(b, c, d, a, k[14], 23, -35309556);
|
|
49
|
-
a = hh(a, b, c, d, k[1], 4, -1530992060);
|
|
50
|
-
d = hh(d, a, b, c, k[4], 11, 1272893353);
|
|
51
|
-
c = hh(c, d, a, b, k[7], 16, -155497632);
|
|
52
|
-
b = hh(b, c, d, a, k[10], 23, -1094730640);
|
|
53
|
-
a = hh(a, b, c, d, k[13], 4, 681279174);
|
|
54
|
-
d = hh(d, a, b, c, k[0], 11, -358537222);
|
|
55
|
-
c = hh(c, d, a, b, k[3], 16, -722521979);
|
|
56
|
-
b = hh(b, c, d, a, k[6], 23, 76029189);
|
|
57
|
-
a = hh(a, b, c, d, k[9], 4, -640364487);
|
|
58
|
-
d = hh(d, a, b, c, k[12], 11, -421815835);
|
|
59
|
-
c = hh(c, d, a, b, k[15], 16, 530742520);
|
|
60
|
-
b = hh(b, c, d, a, k[2], 23, -995338651);
|
|
61
|
-
|
|
62
|
-
a = ii(a, b, c, d, k[0], 6, -198630844);
|
|
63
|
-
d = ii(d, a, b, c, k[7], 10, 1126891415);
|
|
64
|
-
c = ii(c, d, a, b, k[14], 15, -1416354905);
|
|
65
|
-
b = ii(b, c, d, a, k[5], 21, -57434055);
|
|
66
|
-
a = ii(a, b, c, d, k[12], 6, 1700485571);
|
|
67
|
-
d = ii(d, a, b, c, k[3], 10, -1894986606);
|
|
68
|
-
c = ii(c, d, a, b, k[10], 15, -1051523);
|
|
69
|
-
b = ii(b, c, d, a, k[1], 21, -2054922799);
|
|
70
|
-
a = ii(a, b, c, d, k[8], 6, 1873313359);
|
|
71
|
-
d = ii(d, a, b, c, k[15], 10, -30611744);
|
|
72
|
-
c = ii(c, d, a, b, k[6], 15, -1560198380);
|
|
73
|
-
b = ii(b, c, d, a, k[13], 21, 1309151649);
|
|
74
|
-
a = ii(a, b, c, d, k[4], 6, -145523070);
|
|
75
|
-
d = ii(d, a, b, c, k[11], 10, -1120210379);
|
|
76
|
-
c = ii(c, d, a, b, k[2], 15, 718787259);
|
|
77
|
-
b = ii(b, c, d, a, k[9], 21, -343485551);
|
|
78
|
-
|
|
79
|
-
x[0] = add32(a, x[0]);
|
|
80
|
-
x[1] = add32(b, x[1]);
|
|
81
|
-
x[2] = add32(c, x[2]);
|
|
82
|
-
x[3] = add32(d, x[3]);
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
function cmn(q, a, b, x, s, t) {
|
|
86
|
-
a = add32(add32(a, q), add32(x, t));
|
|
87
|
-
return add32((a << s) | (a >>> (32 - s)), b);
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
function ff(a, b, c, d, x, s, t) {
|
|
91
|
-
return cmn((b & c) | (~b & d), a, b, x, s, t);
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
function gg(a, b, c, d, x, s, t) {
|
|
95
|
-
return cmn((b & d) | (c & ~d), a, b, x, s, t);
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
function hh(a, b, c, d, x, s, t) {
|
|
99
|
-
return cmn(b ^ c ^ d, a, b, x, s, t);
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
function ii(a, b, c, d, x, s, t) {
|
|
103
|
-
return cmn(c ^ (b | ~d), a, b, x, s, t);
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
function md51(s) {
|
|
107
|
-
var txt = '';
|
|
108
|
-
var n = s.length,
|
|
109
|
-
state = [1732584193, -271733879, -1732584194, 271733878],
|
|
110
|
-
i;
|
|
111
|
-
for (i = 64; i <= s.length; i += 64) {
|
|
112
|
-
md5cycle(state, md5blk(s.substring(i - 64, i)));
|
|
113
|
-
}
|
|
114
|
-
s = s.substring(i - 64);
|
|
115
|
-
var tail = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
|
|
116
|
-
for (i = 0; i < s.length; i++) tail[i >> 2] |= s.charCodeAt(i) << (i % 4 << 3);
|
|
117
|
-
tail[i >> 2] |= 0x80 << (i % 4 << 3);
|
|
118
|
-
if (i > 55) {
|
|
119
|
-
md5cycle(state, tail);
|
|
120
|
-
for (i = 0; i < 16; i++) tail[i] = 0;
|
|
121
|
-
}
|
|
122
|
-
tail[14] = n * 8;
|
|
123
|
-
md5cycle(state, tail);
|
|
124
|
-
return state;
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
/* there needs to be support for Unicode here,
|
|
128
|
-
* unless we pretend that we can redefine the MD-5
|
|
129
|
-
* algorithm for multi-byte characters (perhaps
|
|
130
|
-
* by adding every four 16-bit characters and
|
|
131
|
-
* shortening the sum to 32 bits). Otherwise
|
|
132
|
-
* I suggest performing MD-5 as if every character
|
|
133
|
-
* was two bytes--e.g., 0040 0025 = @%--but then
|
|
134
|
-
* how will an ordinary MD-5 sum be matched?
|
|
135
|
-
* There is no way to standardize text to something
|
|
136
|
-
* like UTF-8 before transformation; speed cost is
|
|
137
|
-
* utterly prohibitive. The JavaScript standard
|
|
138
|
-
* itself needs to look at this: it should start
|
|
139
|
-
* providing access to strings as preformed UTF-8
|
|
140
|
-
* 8-bit unsigned value arrays.
|
|
141
|
-
*/
|
|
142
|
-
function md5blk(s) {
|
|
143
|
-
/* I figured global was faster. */
|
|
144
|
-
var md5blks = [],
|
|
145
|
-
i; /* Andy King said do it this way. */
|
|
146
|
-
for (i = 0; i < 64; i += 4) {
|
|
147
|
-
md5blks[i >> 2] =
|
|
148
|
-
s.charCodeAt(i) +
|
|
149
|
-
(s.charCodeAt(i + 1) << 8) +
|
|
150
|
-
(s.charCodeAt(i + 2) << 16) +
|
|
151
|
-
(s.charCodeAt(i + 3) << 24);
|
|
152
|
-
}
|
|
153
|
-
return md5blks;
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
var hex_chr = '0123456789abcdef'.split('');
|
|
157
|
-
|
|
158
|
-
function rhex(n) {
|
|
159
|
-
var s = '',
|
|
160
|
-
j = 0;
|
|
161
|
-
for (; j < 4; j++) s += hex_chr[(n >> (j * 8 + 4)) & 0x0f] + hex_chr[(n >> (j * 8)) & 0x0f];
|
|
162
|
-
return s;
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
function hex(x) {
|
|
166
|
-
for (var i = 0; i < x.length; i++) x[i] = rhex(x[i]);
|
|
167
|
-
return x.join('');
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
function add32(a, b) {
|
|
171
|
-
return (a + b) & 0xffffffff;
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
export function md5(s) {
|
|
175
|
-
return hex(md51(s));
|
|
176
|
-
}
|
package/src/clientjs/preact.ts
DELETED