@webqit/webflo 0.8.47 → 0.8.51
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/docker/Dockerfile +25 -0
- package/docker/README.md +71 -0
- package/package.json +9 -8
- package/src/cmd/client.js +68 -97
- package/src/cmd/origins.js +2 -2
- package/src/cmd/server.js +1 -1
- package/src/modules/Router.js +130 -0
- package/src/modules/_FormData.js +60 -0
- package/src/modules/_Headers.js +88 -0
- package/src/modules/_MessageStream.js +191 -0
- package/src/modules/_NavigationEvent.js +89 -0
- package/src/modules/_Request.js +61 -0
- package/src/modules/_RequestHeaders.js +72 -0
- package/src/modules/_Response.js +56 -0
- package/src/modules/_ResponseHeaders.js +81 -0
- package/src/modules/_URL.js +111 -0
- package/src/modules/client/Cache.js +38 -0
- package/src/modules/client/Client.js +49 -20
- package/src/modules/client/Http.js +26 -11
- package/src/modules/client/NavigationEvent.js +20 -0
- package/src/modules/client/Router.js +30 -106
- package/src/modules/client/StdRequest.js +13 -15
- package/src/modules/client/Storage.js +56 -0
- package/src/modules/client/Url.js +1 -1
- package/src/modules/client/Worker.js +70 -66
- package/src/modules/client/WorkerClient.js +102 -0
- package/src/modules/client/WorkerComm.js +183 -0
- package/src/modules/client/effects/sounds.js +64 -0
- package/src/modules/server/NavigationEvent.js +38 -0
- package/src/modules/server/Router.js +53 -126
- package/src/modules/server/Server.js +192 -84
- package/src/modules/util.js +7 -7
- package/src/modules/NavigationEvent.js +0 -46
- package/src/modules/Response.js +0 -98
- package/src/modules/XURL.js +0 -125
- package/src/modules/client/ClientNavigationEvent.js +0 -10
- package/src/modules/client/Push.js +0 -84
- package/src/modules/server/ServerNavigationEvent.js +0 -10
- package/src/modules/server/StdIncomingMessage.js +0 -73
|
@@ -5,119 +5,50 @@
|
|
|
5
5
|
import Fs from 'fs';
|
|
6
6
|
import Url from 'url';
|
|
7
7
|
import Path from 'path';
|
|
8
|
-
import
|
|
9
|
-
import
|
|
10
|
-
import _arrFrom from '@webqit/util/arr/from.js';
|
|
8
|
+
import Mime from 'mime-types';
|
|
9
|
+
import _Router from '../Router.js';
|
|
11
10
|
|
|
12
|
-
|
|
11
|
+
/**
|
|
12
|
+
* ---------------------------
|
|
13
|
+
* The Router class
|
|
14
|
+
* ---------------------------
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
export default class Router extends _Router {
|
|
13
18
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
19
|
+
async readTick(thisTick) {
|
|
20
|
+
if (thisTick.trail) {
|
|
21
|
+
thisTick.currentSegment = thisTick.destination[thisTick.trail.length];
|
|
22
|
+
thisTick.currentSegmentOnFile = [ thisTick.currentSegment, '-' ].reduce((_segmentOnFile, _seg) => {
|
|
23
|
+
if (_segmentOnFile.index) return _segmentOnFile;
|
|
24
|
+
var _currentPath = thisTick.trailOnFile.concat(_seg).join('/'),
|
|
25
|
+
routeHandlerFile;
|
|
26
|
+
return Fs.existsSync(routeHandlerFile = Path.join(this.layout.ROOT, this.layout.SERVER_DIR, _currentPath, 'index.js')) ? { seg: _seg, index: routeHandlerFile } : (
|
|
27
|
+
Fs.existsSync(Path.join(this.layout.ROOT, this.layout.SERVER_DIR, _currentPath)) ? { seg: _seg, dirExists: true } : _segmentOnFile
|
|
28
|
+
);
|
|
29
|
+
}, { seg: null });
|
|
30
|
+
thisTick.trail.push(thisTick.currentSegment);
|
|
31
|
+
thisTick.trailOnFile.push(thisTick.currentSegmentOnFile.seg);
|
|
32
|
+
thisTick.exports = thisTick.currentSegmentOnFile.index ? await import(Url.pathToFileURL(thisTick.currentSegmentOnFile.index)) : undefined;
|
|
33
|
+
} else {
|
|
34
|
+
thisTick.trail = [];
|
|
35
|
+
thisTick.trailOnFile = [];
|
|
36
|
+
thisTick.currentSegmentOnFile = { index: Path.join(this.layout.ROOT, this.layout.SERVER_DIR, 'index.js') };
|
|
37
|
+
thisTick.exports = Fs.existsSync(thisTick.currentSegmentOnFile.index)
|
|
38
|
+
? await import(Url.pathToFileURL(thisTick.currentSegmentOnFile.index))
|
|
39
|
+
: null;
|
|
40
|
+
}
|
|
41
|
+
return thisTick;
|
|
27
42
|
}
|
|
28
43
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
* @param any input
|
|
35
|
-
* @param function _default
|
|
36
|
-
*
|
|
37
|
-
* @return object
|
|
38
|
-
*/
|
|
39
|
-
async route(target, event, input, _default) {
|
|
40
|
-
|
|
41
|
-
target = _arrFrom(target);
|
|
42
|
-
var layout = this.layout;
|
|
43
|
-
var context = this.context;
|
|
44
|
+
finalizeHandlerContext(context, thisTick) {
|
|
45
|
+
if (thisTick.currentSegmentOnFile.index) {
|
|
46
|
+
context.dirname = Path.dirname(thisTick.currentSegmentOnFile.index);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
44
49
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
// ----------------
|
|
48
|
-
const next = async function(_event, index, input, path) {
|
|
49
|
-
|
|
50
|
-
var exports, routeHandlerFile, wildcardRouteHandlerFile;
|
|
51
|
-
if (index === 0) {
|
|
52
|
-
routeHandlerFile = 'index.js';
|
|
53
|
-
} else if (path[index - 1]) {
|
|
54
|
-
var routeSlice = path.slice(0, index).join('/');
|
|
55
|
-
var wildcardRouteSlice = path.slice(0, index - 1).concat('-').join('/');
|
|
56
|
-
routeHandlerFile = Path.join(routeSlice, './index.js');
|
|
57
|
-
wildcardRouteHandlerFile = Path.join(wildcardRouteSlice, './index.js');
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
if ((routeHandlerFile && Fs.existsSync(routeHandlerFile = Path.join(layout.ROOT, layout.SERVER_DIR, routeHandlerFile)))
|
|
61
|
-
|| (wildcardRouteHandlerFile && Fs.existsSync(routeHandlerFile = Path.join(layout.ROOT, layout.SERVER_DIR, wildcardRouteHandlerFile)))) {
|
|
62
|
-
exports = await import(Url.pathToFileURL(routeHandlerFile));
|
|
63
|
-
// ---------------
|
|
64
|
-
const func = target.reduce((func, name) => func || exports[name], null);
|
|
65
|
-
if (func) {
|
|
66
|
-
// -------------
|
|
67
|
-
// Then we can call the handler
|
|
68
|
-
// -------------
|
|
69
|
-
const _next = (..._args) => {
|
|
70
|
-
var _index, __event;
|
|
71
|
-
if (_args.length > 1) {
|
|
72
|
-
if (!_isString(_args[1])) {
|
|
73
|
-
throw new Error('Router redirect must be a string!');
|
|
74
|
-
}
|
|
75
|
-
var _newPath = _args[1].startsWith('/') ? _args[1] : Path.join(path.slice(0, index).join('/'), _args[1]);
|
|
76
|
-
if (_newPath.startsWith('../')) {
|
|
77
|
-
throw new Error('Router redirect cannot traverse beyond the routing directory! (' + _args[1] + ' >> ' + _newPath + ')');
|
|
78
|
-
}
|
|
79
|
-
var [ newPath, newQuery ] = _newPath.split('?');
|
|
80
|
-
__event = _event.withRedirect('/' + _newPath);
|
|
81
|
-
_args[1] = newPath.split('/').map(a => a.trim()).filter(a => a);
|
|
82
|
-
_index = path.slice(0, index).reduce((build, seg, i) => build.length === i && seg === _args[1][i] ? build.concat(seg) : build, []).length;
|
|
83
|
-
} else {
|
|
84
|
-
__event = _event;
|
|
85
|
-
_args[1] = path;
|
|
86
|
-
_index = index;
|
|
87
|
-
}
|
|
88
|
-
return next(__event, _index + 1, ..._args);
|
|
89
|
-
};
|
|
90
|
-
_next.pathname = path.slice(index).join('/');
|
|
91
|
-
_next.stepname = _next.pathname.split('/').shift();
|
|
92
|
-
// -------------
|
|
93
|
-
const _this = {
|
|
94
|
-
pathname: '/' + path.slice(0, index).join('/'),
|
|
95
|
-
dirname: Path.dirname(routeHandlerFile),
|
|
96
|
-
...context
|
|
97
|
-
};
|
|
98
|
-
_this.stepname = _this.pathname.split('/').pop();
|
|
99
|
-
// -------------
|
|
100
|
-
return await func.bind(_this)(_event, input, _next/*next*/);
|
|
101
|
-
} else {
|
|
102
|
-
return next(_event, index + 1, input, path);
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
if (_default) {
|
|
107
|
-
// -------------
|
|
108
|
-
// Local file
|
|
109
|
-
// -------------
|
|
110
|
-
const defaultThis = {pathname: '/' + path.join('/'), ...context};
|
|
111
|
-
return await _default.call(defaultThis, input);
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
// -------------
|
|
115
|
-
// Recieved response or undefined
|
|
116
|
-
// -------------
|
|
117
|
-
return;
|
|
118
|
-
};
|
|
119
|
-
|
|
120
|
-
return next(event, 0, input, this.path);
|
|
50
|
+
pathJoin(...args) {
|
|
51
|
+
return Path.join(...args);
|
|
121
52
|
}
|
|
122
53
|
|
|
123
54
|
/**
|
|
@@ -154,14 +85,21 @@ export default class Router {
|
|
|
154
85
|
error: 'Error reading static file: ' + filename + '.',
|
|
155
86
|
});
|
|
156
87
|
} else {
|
|
88
|
+
|
|
157
89
|
// if the file is found, set Content-type and send data
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
90
|
+
const type = Mime.lookup(ext);
|
|
91
|
+
resolve(new event.Response(data, {
|
|
92
|
+
headers: {
|
|
93
|
+
contentType: type === 'application/javascript' ? 'text/javascript' : type,
|
|
94
|
+
contentLength: Buffer.byteLength(data),
|
|
95
|
+
},
|
|
96
|
+
meta: {
|
|
97
|
+
filename: _filename,
|
|
98
|
+
static: true,
|
|
99
|
+
autoIndex,
|
|
100
|
+
}
|
|
164
101
|
}));
|
|
102
|
+
|
|
165
103
|
}
|
|
166
104
|
});
|
|
167
105
|
});
|
|
@@ -208,6 +146,7 @@ const mimeTypes = {
|
|
|
208
146
|
'.json': 'application/json',
|
|
209
147
|
'.css': 'text/css',
|
|
210
148
|
'.png': 'image/png',
|
|
149
|
+
'.jpeg': 'image/jpeg',
|
|
211
150
|
'.jpg': 'image/jpeg',
|
|
212
151
|
'.wav': 'audio/wav',
|
|
213
152
|
'.mp3': 'audio/mpeg',
|
|
@@ -217,15 +156,3 @@ const mimeTypes = {
|
|
|
217
156
|
};
|
|
218
157
|
|
|
219
158
|
export { mimeTypes };
|
|
220
|
-
|
|
221
|
-
// Static response
|
|
222
|
-
export class FixedResponse {
|
|
223
|
-
// construct
|
|
224
|
-
constructor(content, contentType, filename, autoIndex) {
|
|
225
|
-
this.content = content;
|
|
226
|
-
this.contentType = contentType;
|
|
227
|
-
this.filename = filename;
|
|
228
|
-
this.autoIndex = autoIndex;
|
|
229
|
-
this.static = true;
|
|
230
|
-
}
|
|
231
|
-
};
|