@webqit/webflo 0.11.61 → 0.20.2-next.0
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/.github/FUNDING.yml +12 -0
- package/.github/workflows/publish.yml +48 -0
- package/.gitignore +2 -0
- package/LICENSE +2 -2
- package/README.md +71 -2050
- package/package.json +28 -13
- package/site/-/_.md +139 -0
- package/site/-/docs.old.md +2010 -0
- package/site/.vitepress/cache/deps/@braintree_sanitize-url 2.js +93 -0
- package/site/.vitepress/cache/deps/@braintree_sanitize-url.js +93 -0
- package/site/.vitepress/cache/deps/@braintree_sanitize-url.js 2.map +7 -0
- package/site/.vitepress/cache/deps/@braintree_sanitize-url.js.map +7 -0
- package/site/.vitepress/cache/deps/_metadata 2.json +85 -0
- package/site/.vitepress/cache/deps/_metadata.json +85 -0
- package/site/.vitepress/cache/deps/chunk-BUSYA2B4 2.js +9 -0
- package/site/.vitepress/cache/deps/chunk-BUSYA2B4.js +9 -0
- package/site/.vitepress/cache/deps/chunk-BUSYA2B4.js 2.map +7 -0
- package/site/.vitepress/cache/deps/chunk-BUSYA2B4.js.map +7 -0
- package/site/.vitepress/cache/deps/chunk-Q2AYPHVK 2.js +9719 -0
- package/site/.vitepress/cache/deps/chunk-Q2AYPHVK.js +9719 -0
- package/site/.vitepress/cache/deps/chunk-Q2AYPHVK.js 2.map +7 -0
- package/site/.vitepress/cache/deps/chunk-Q2AYPHVK.js.map +7 -0
- package/site/.vitepress/cache/deps/chunk-QAXAIFA7 2.js +12705 -0
- package/site/.vitepress/cache/deps/chunk-QAXAIFA7.js +12705 -0
- package/site/.vitepress/cache/deps/chunk-QAXAIFA7.js 2.map +7 -0
- package/site/.vitepress/cache/deps/chunk-QAXAIFA7.js.map +7 -0
- package/site/.vitepress/cache/deps/cytoscape 2.js +30278 -0
- package/site/.vitepress/cache/deps/cytoscape-cose-bilkent 2.js +4710 -0
- package/site/.vitepress/cache/deps/cytoscape-cose-bilkent.js +4710 -0
- package/site/.vitepress/cache/deps/cytoscape-cose-bilkent.js 2.map +7 -0
- package/site/.vitepress/cache/deps/cytoscape-cose-bilkent.js.map +7 -0
- package/site/.vitepress/cache/deps/cytoscape.js +30278 -0
- package/site/.vitepress/cache/deps/cytoscape.js 2.map +7 -0
- package/site/.vitepress/cache/deps/cytoscape.js.map +7 -0
- package/site/.vitepress/cache/deps/dayjs 2.js +285 -0
- package/site/.vitepress/cache/deps/dayjs.js +285 -0
- package/site/.vitepress/cache/deps/dayjs.js 2.map +7 -0
- package/site/.vitepress/cache/deps/dayjs.js.map +7 -0
- package/site/.vitepress/cache/deps/debug 2.js +453 -0
- package/site/.vitepress/cache/deps/debug.js +453 -0
- package/site/.vitepress/cache/deps/debug.js 2.map +7 -0
- package/site/.vitepress/cache/deps/debug.js.map +7 -0
- package/site/.vitepress/cache/deps/package 2.json +3 -0
- package/site/.vitepress/cache/deps/package.json +3 -0
- package/site/.vitepress/cache/deps/vitepress___@vue_devtools-api 2.js +4507 -0
- package/site/.vitepress/cache/deps/vitepress___@vue_devtools-api.js +4507 -0
- package/site/.vitepress/cache/deps/vitepress___@vue_devtools-api.js 2.map +7 -0
- package/site/.vitepress/cache/deps/vitepress___@vue_devtools-api.js.map +7 -0
- package/site/.vitepress/cache/deps/vitepress___@vueuse_core 2.js +584 -0
- package/site/.vitepress/cache/deps/vitepress___@vueuse_core.js +584 -0
- package/site/.vitepress/cache/deps/vitepress___@vueuse_core.js 2.map +7 -0
- package/site/.vitepress/cache/deps/vitepress___@vueuse_core.js.map +7 -0
- package/site/.vitepress/cache/deps/vitepress___@vueuse_integrations_useFocusTrap 2.js +1166 -0
- package/site/.vitepress/cache/deps/vitepress___@vueuse_integrations_useFocusTrap.js +1166 -0
- package/site/.vitepress/cache/deps/vitepress___@vueuse_integrations_useFocusTrap.js 2.map +7 -0
- package/site/.vitepress/cache/deps/vitepress___@vueuse_integrations_useFocusTrap.js.map +7 -0
- package/site/.vitepress/cache/deps/vitepress___mark__js_src_vanilla__js 2.js +1667 -0
- package/site/.vitepress/cache/deps/vitepress___mark__js_src_vanilla__js.js +1667 -0
- package/site/.vitepress/cache/deps/vitepress___mark__js_src_vanilla__js.js 2.map +7 -0
- package/site/.vitepress/cache/deps/vitepress___mark__js_src_vanilla__js.js.map +7 -0
- package/site/.vitepress/cache/deps/vitepress___minisearch 2.js +1815 -0
- package/site/.vitepress/cache/deps/vitepress___minisearch.js +1815 -0
- package/site/.vitepress/cache/deps/vitepress___minisearch.js 2.map +7 -0
- package/site/.vitepress/cache/deps/vitepress___minisearch.js.map +7 -0
- package/site/.vitepress/cache/deps/vue 2.js +344 -0
- package/site/.vitepress/cache/deps/vue.js +344 -0
- package/site/.vitepress/cache/deps/vue.js 2.map +7 -0
- package/site/.vitepress/cache/deps/vue.js.map +7 -0
- package/site/.vitepress/config.ts +147 -0
- package/site/.vitepress/theme/custom.css +50 -0
- package/site/.vitepress/theme/index.ts +6 -0
- package/site/api/webflo-fetch/FormData.md +0 -0
- package/site/api/webflo-fetch/Headers.md +0 -0
- package/site/api/webflo-fetch/LiveResponse.md +0 -0
- package/site/api/webflo-fetch/Request.md +0 -0
- package/site/api/webflo-fetch/Response.md +0 -0
- package/site/api/webflo-fetch/fetch.md +0 -0
- package/site/api/webflo-routing/HttpCookies.md +0 -0
- package/site/api/webflo-routing/HttpEvent/respondWith.md +1 -0
- package/site/api/webflo-routing/HttpEvent/waitUntil.md +1 -0
- package/site/api/webflo-routing/HttpEvent/waitUntilNavigate.md +1 -0
- package/site/api/webflo-routing/HttpEvent.md +30 -0
- package/site/api/webflo-routing/HttpSession.md +0 -0
- package/site/api/webflo-routing/HttpState.md +0 -0
- package/site/api/webflo-routing/HttpUser.md +0 -0
- package/site/api/webflo-routing/handler/fetch.md +42 -0
- package/site/api/webflo-routing/handler/next.md +54 -0
- package/site/api/webflo-routing/handler.md +119 -0
- package/site/api.md +26 -0
- package/site/contributing.md +16 -0
- package/site/docs/advanced/lifecycles.md +20 -0
- package/site/docs/advanced/redirects.md +0 -0
- package/site/docs/advanced/routing.md +1 -0
- package/site/docs/advanced.md +9 -0
- package/site/docs/concepts/realtime.md +637 -0
- package/site/docs/concepts/rendering.md +60 -0
- package/site/docs/concepts/request-response.md +47 -0
- package/site/docs/concepts/routing.md +656 -0
- package/site/docs/concepts/state.md +44 -0
- package/site/docs/concepts/templates.md +48 -0
- package/site/docs/concepts.md +97 -0
- package/site/docs/getting-started.md +378 -0
- package/site/docs/tech-stack.md +56 -0
- package/site/docs.md +100 -0
- package/site/examples/pwa.md +10 -0
- package/site/examples/web.md +11 -0
- package/site/examples.md +10 -0
- package/site/faq.md +13 -0
- package/site/guides/guide-auth.md +13 -0
- package/site/guides/guide-file-upload.md +11 -0
- package/site/guides/guide-service-worker.md +10 -0
- package/site/guides/tutorial-1-todo.md +24 -0
- package/site/guides.md +15 -0
- package/site/index.md +39 -0
- package/site/public/img/brand/logo-670x670.png +0 -0
- package/site/recipes/realtime.md +11 -0
- package/site/recipes/streaming.md +15 -0
- package/site/reference/cli.md +11 -0
- package/site/reference/config.md +13 -0
- package/site/reference/tools.md +9 -0
- package/src/Context.js +3 -11
- package/src/config-pi/deployment/Env.js +6 -19
- package/src/config-pi/deployment/Layout.js +11 -3
- package/src/config-pi/runtime/Client.js +40 -48
- package/src/config-pi/runtime/Server.js +52 -20
- package/src/config-pi/runtime/client/Worker.js +22 -20
- package/src/config-pi/static/Init.js +57 -0
- package/src/config-pi/static/index.js +2 -0
- package/src/deployment-pi/origins/index.js +1 -1
- package/src/deployment-pi/util.js +161 -0
- package/src/index.js +3 -9
- package/src/init-pi/index.js +117 -0
- package/src/init-pi/templates/pwa/app/handler.server.js +8 -0
- package/src/init-pi/templates/pwa/app/page.html +7 -0
- package/src/init-pi/templates/pwa/package.json +19 -0
- package/src/init-pi/templates/pwa/public/assets/app.css +16 -0
- package/src/init-pi/templates/pwa/public/index.html +39 -0
- package/src/init-pi/templates/pwa/public/manifest.json +29 -0
- package/src/init-pi/templates/web/app/handler.server.js +8 -0
- package/src/init-pi/templates/web/app/page.html +7 -0
- package/src/init-pi/templates/web/package.json +19 -0
- package/src/init-pi/templates/web/public/assets/app.css +16 -0
- package/src/init-pi/templates/web/public/index.html +39 -0
- package/src/runtime-pi/WebfloRuntime.js +350 -0
- package/src/runtime-pi/index.js +3 -10
- package/src/runtime-pi/webflo-client/ClientSideCookies.js +17 -0
- package/src/runtime-pi/webflo-client/ClientSideWorkport.js +63 -0
- package/src/runtime-pi/webflo-client/DeviceCapabilities.js +213 -0
- package/src/runtime-pi/webflo-client/WebfloClient.js +500 -0
- package/src/runtime-pi/webflo-client/WebfloRootClient1.js +206 -0
- package/src/runtime-pi/webflo-client/WebfloRootClient2.js +113 -0
- package/src/runtime-pi/webflo-client/WebfloSubClient.js +118 -0
- package/src/runtime-pi/webflo-client/index.js +17 -0
- package/src/runtime-pi/webflo-client/webflo-codegen.js +469 -0
- package/src/runtime-pi/webflo-client/webflo-devmode.js +243 -0
- package/src/runtime-pi/webflo-client/webflo-embedded.js +50 -0
- package/src/runtime-pi/webflo-fetch/LiveResponse.js +437 -0
- package/src/runtime-pi/webflo-fetch/cookies.js +10 -0
- package/src/runtime-pi/webflo-fetch/fetch.js +16 -0
- package/src/runtime-pi/webflo-fetch/formdata.js +54 -0
- package/src/runtime-pi/webflo-fetch/headers.js +151 -0
- package/src/runtime-pi/webflo-fetch/index.js +5 -0
- package/src/runtime-pi/webflo-fetch/message.js +49 -0
- package/src/runtime-pi/webflo-fetch/request.js +62 -0
- package/src/runtime-pi/webflo-fetch/response.js +110 -0
- package/src/runtime-pi/webflo-fetch/util.js +28 -0
- package/src/runtime-pi/webflo-messaging/WQBroadcastChannel.js +10 -0
- package/src/runtime-pi/webflo-messaging/WQMessageChannel.js +26 -0
- package/src/runtime-pi/webflo-messaging/WQMessageEvent.js +87 -0
- package/src/runtime-pi/webflo-messaging/WQMessagePort.js +38 -0
- package/src/runtime-pi/webflo-messaging/WQRelayPort.js +47 -0
- package/src/runtime-pi/webflo-messaging/WQSockPort.js +113 -0
- package/src/runtime-pi/webflo-messaging/WQStarPort.js +104 -0
- package/src/runtime-pi/webflo-messaging/wq-message-port.js +404 -0
- package/src/runtime-pi/webflo-routing/HttpCookies.js +42 -0
- package/src/runtime-pi/webflo-routing/HttpEvent.js +112 -0
- package/src/runtime-pi/webflo-routing/HttpSession.js +11 -0
- package/src/runtime-pi/webflo-routing/HttpState.js +153 -0
- package/src/runtime-pi/webflo-routing/HttpUser.js +54 -0
- package/src/runtime-pi/webflo-routing/WebfloRouter.js +245 -0
- package/src/runtime-pi/webflo-server/ServerSideCookies.js +19 -0
- package/src/runtime-pi/webflo-server/ServerSideSession.js +38 -0
- package/src/runtime-pi/webflo-server/WebfloServer.js +937 -0
- package/src/runtime-pi/webflo-server/index.js +11 -0
- package/src/runtime-pi/webflo-server/messaging/Client.js +27 -0
- package/src/runtime-pi/webflo-server/messaging/ClientRequestRealtime.js +50 -0
- package/src/runtime-pi/webflo-server/messaging/Clients.js +25 -0
- package/src/runtime-pi/webflo-server/webflo-devmode.js +326 -0
- package/src/runtime-pi/{client → webflo-url}/Url.js +27 -76
- package/src/runtime-pi/webflo-url/index.js +1 -0
- package/src/runtime-pi/webflo-url/urlpattern.js +38 -0
- package/src/runtime-pi/{util-url.js → webflo-url/util.js} +5 -43
- package/src/runtime-pi/webflo-url/xURL.js +94 -0
- package/src/runtime-pi/webflo-worker/WebfloWorker.js +234 -0
- package/src/runtime-pi/webflo-worker/WorkerSideCookies.js +19 -0
- package/src/runtime-pi/webflo-worker/WorkerSideWorkport.js +18 -0
- package/src/runtime-pi/webflo-worker/index.js +11 -0
- package/src/services-pi/index.js +2 -0
- package/src/services-pi/push/index.js +23 -0
- package/src/util.js +10 -0
- package/src/{webflo.js → webflo-cli.js} +4 -4
- package/src/runtime-pi/Application.js +0 -29
- package/src/runtime-pi/Cookies.js +0 -82
- package/src/runtime-pi/HttpEvent.js +0 -107
- package/src/runtime-pi/Router.js +0 -130
- package/src/runtime-pi/Runtime.js +0 -21
- package/src/runtime-pi/client/Application.js +0 -76
- package/src/runtime-pi/client/Context.js +0 -7
- package/src/runtime-pi/client/Router.js +0 -48
- package/src/runtime-pi/client/Runtime.js +0 -525
- package/src/runtime-pi/client/Workport.js +0 -190
- package/src/runtime-pi/client/createStorage.js +0 -58
- package/src/runtime-pi/client/generate.js +0 -481
- package/src/runtime-pi/client/index.js +0 -21
- package/src/runtime-pi/client/worker/Application.js +0 -44
- package/src/runtime-pi/client/worker/Context.js +0 -7
- package/src/runtime-pi/client/worker/Runtime.js +0 -275
- package/src/runtime-pi/client/worker/Workport.js +0 -78
- package/src/runtime-pi/client/worker/index.js +0 -21
- package/src/runtime-pi/server/Application.js +0 -101
- package/src/runtime-pi/server/Context.js +0 -16
- package/src/runtime-pi/server/Router.js +0 -159
- package/src/runtime-pi/server/Runtime.js +0 -558
- package/src/runtime-pi/server/index.js +0 -21
- package/src/runtime-pi/util-http.js +0 -86
- package/src/runtime-pi/xFormData.js +0 -24
- package/src/runtime-pi/xHeaders.js +0 -146
- package/src/runtime-pi/xRequest.js +0 -46
- package/src/runtime-pi/xRequestHeaders.js +0 -109
- package/src/runtime-pi/xResponse.js +0 -33
- package/src/runtime-pi/xResponseHeaders.js +0 -117
- package/src/runtime-pi/xURL.js +0 -105
- package/src/runtime-pi/xfetch.js +0 -23
- package/src/runtime-pi/xxHttpMessage.js +0 -102
- package/src/static-pi/index.js +0 -11
|
@@ -1,275 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
/**
|
|
3
|
-
* @imports
|
|
4
|
-
*/
|
|
5
|
-
import Observer from '@webqit/observer';
|
|
6
|
-
import { _any } from '@webqit/util/arr/index.js';
|
|
7
|
-
import { pattern } from '../../util-url.js';
|
|
8
|
-
import Workport from './Workport.js';
|
|
9
|
-
import _Runtime from '../../Runtime.js';
|
|
10
|
-
import xRequest from "../../xRequest.js";
|
|
11
|
-
import xResponse from "../../xResponse.js";
|
|
12
|
-
import xfetch from '../../xfetch.js';
|
|
13
|
-
import HttpEvent from '../../HttpEvent.js';
|
|
14
|
-
|
|
15
|
-
export {
|
|
16
|
-
HttpEvent,
|
|
17
|
-
Observer,
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* ---------------------------
|
|
22
|
-
* The Runtime Initializer
|
|
23
|
-
* ---------------------------
|
|
24
|
-
*/
|
|
25
|
-
|
|
26
|
-
export default class Runtime extends _Runtime {
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* Runtime
|
|
30
|
-
*
|
|
31
|
-
* @param Object cx
|
|
32
|
-
* @param Function applicationInstance
|
|
33
|
-
*
|
|
34
|
-
* @return void
|
|
35
|
-
*/
|
|
36
|
-
constructor(cx, applicationInstance) {
|
|
37
|
-
super(cx, applicationInstance);
|
|
38
|
-
// ---------------
|
|
39
|
-
this.mockSessionStore = {};
|
|
40
|
-
// --------------
|
|
41
|
-
// ONINSTALL
|
|
42
|
-
self.addEventListener('install', evt => {
|
|
43
|
-
if (this.cx.params.skip_waiting) { self.skipWaiting(); }
|
|
44
|
-
// Manage CACHE
|
|
45
|
-
if (this.cx.params.cache_name && (this.cx.params.cache_only_urls || []).length) {
|
|
46
|
-
// Add files to cache
|
|
47
|
-
evt.waitUntil( self.caches.open(this.cx.params.cache_name).then(async cache => {
|
|
48
|
-
if (this.cx.logger) { this.cx.logger.log('[ServiceWorker] Pre-caching resources.'); }
|
|
49
|
-
for (const urls of [ 'cache_first_urls', 'cache_only_urls' ]) {
|
|
50
|
-
const _urls = (this.cx.params[urls] || []).map(c => c.trim()).filter(c => c && !pattern(c, self.origin).isPattern());
|
|
51
|
-
await cache.addAll(_urls);
|
|
52
|
-
}
|
|
53
|
-
}) );
|
|
54
|
-
}
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
// -------------
|
|
58
|
-
// ONACTIVATE
|
|
59
|
-
self.addEventListener('activate', evt => {
|
|
60
|
-
evt.waitUntil( new Promise(async resolve => {
|
|
61
|
-
if (this.cx.params.skip_waiting) { await self.clients.claim(); }
|
|
62
|
-
// Manage CACHE
|
|
63
|
-
if (this.cx.params.cache_name) {
|
|
64
|
-
// Clear outdated CACHES
|
|
65
|
-
await self.caches.keys().then(keyList => {
|
|
66
|
-
return Promise.all(keyList.map(key => {
|
|
67
|
-
if (key !== this.cx.params.cache_name && key !== this.cx.params.cache_name + '_json') {
|
|
68
|
-
if (this.cx.logger) { this.cx.logger.log('[ServiceWorker] Removing old cache:', key); }
|
|
69
|
-
return self.caches.delete(key);
|
|
70
|
-
}
|
|
71
|
-
}));
|
|
72
|
-
})
|
|
73
|
-
}
|
|
74
|
-
resolve();
|
|
75
|
-
}) );
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
// ---------------
|
|
79
|
-
Observer.set(this, 'location', {});
|
|
80
|
-
Observer.set(this, 'network', {});
|
|
81
|
-
|
|
82
|
-
// -------------
|
|
83
|
-
// ONFETCH
|
|
84
|
-
self.addEventListener('fetch', event => {
|
|
85
|
-
// URL schemes that might arrive here but not supported; e.g.: chrome-extension://
|
|
86
|
-
if (!event.request.url.startsWith('http')) return;
|
|
87
|
-
event.respondWith((async evt => {
|
|
88
|
-
let requestingClient = await self.clients.get(evt.clientId);
|
|
89
|
-
this.workport.setCurrentClient(requestingClient);
|
|
90
|
-
const [ url, requestInit ] = await xRequest.rip(evt.request);
|
|
91
|
-
// Now, the following is key:
|
|
92
|
-
// The browser likes to use "force-cache" for "navigate" requests, when, e.g: re-entering your site with the back button
|
|
93
|
-
// Problem here, force-cache forces out JSON not HTML as per webflo's design.
|
|
94
|
-
// So, we detect this scenerio and avoid it.
|
|
95
|
-
if (requestInit.cache === 'force-cache'/* && evt.request.mode === 'navigate' - even webflo client init call also comes with that... needs investigation */) {
|
|
96
|
-
requestInit.cache = 'default';
|
|
97
|
-
}
|
|
98
|
-
return this.go(url, requestInit, { event: evt });
|
|
99
|
-
})(event));
|
|
100
|
-
});
|
|
101
|
-
|
|
102
|
-
// -------------
|
|
103
|
-
// Workport
|
|
104
|
-
const workport = new Workport();
|
|
105
|
-
Observer.set(this, 'workport', workport);
|
|
106
|
-
|
|
107
|
-
// -------------
|
|
108
|
-
// Initialize
|
|
109
|
-
(async () => {
|
|
110
|
-
if (!this.app.init) return;
|
|
111
|
-
const request = this.generateRequest('/');
|
|
112
|
-
const httpEvent = new HttpEvent(request, { navigationType: 'init' }, (id = null, persistent = false) => this.getSession(httpEvent, id, persistent));
|
|
113
|
-
await this.app.init(httpEvent, ( ...args ) => this.remoteFetch( ...args ));
|
|
114
|
-
})();
|
|
115
|
-
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
/**
|
|
119
|
-
* Performs a request.
|
|
120
|
-
*
|
|
121
|
-
* @param object|string url
|
|
122
|
-
* @param object|Request init
|
|
123
|
-
* @param object detail
|
|
124
|
-
*
|
|
125
|
-
* @return Response
|
|
126
|
-
*/
|
|
127
|
-
async go(url, init = {}, detail = {}) {
|
|
128
|
-
// ------------
|
|
129
|
-
url = typeof url === 'string' ? new URL(url, self.location.origin) : url;
|
|
130
|
-
if (!(init instanceof Request) && !init.referrer) {
|
|
131
|
-
init = { referrer: this.location.href, ...init };
|
|
132
|
-
}
|
|
133
|
-
// ------------
|
|
134
|
-
// The request object
|
|
135
|
-
const request = this.generateRequest(url.href, init);
|
|
136
|
-
if (detail.event) { Object.defineProperty(detail.event, 'request', { value: request }); }
|
|
137
|
-
// The navigation event
|
|
138
|
-
const httpEvent = new HttpEvent(request, detail, (id = null, persistent = false) => this.getSession(httpEvent, id, persistent));
|
|
139
|
-
httpEvent.port.listen(message => {
|
|
140
|
-
if (message.$type === 'handler:hints' && message.session) {
|
|
141
|
-
// TODO: Sync session data from client
|
|
142
|
-
return Promise.resolve();
|
|
143
|
-
}
|
|
144
|
-
});
|
|
145
|
-
// Response
|
|
146
|
-
let response;
|
|
147
|
-
if (httpEvent.request.url.startsWith(self.origin)/* && httpEvent.request.mode === 'navigate'*/) {
|
|
148
|
-
response = await this.app.handle(httpEvent, ( ...args ) => this.remoteFetch( ...args ));
|
|
149
|
-
} else {
|
|
150
|
-
response = await this.remoteFetch(httpEvent.request);
|
|
151
|
-
}
|
|
152
|
-
const finalResponse = await this.handleResponse(httpEvent, response);
|
|
153
|
-
// Return value
|
|
154
|
-
return finalResponse;
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
// Generates request object
|
|
158
|
-
generateRequest(href, init = {}) {
|
|
159
|
-
const request = new xRequest(href, init);
|
|
160
|
-
return request;
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
// Generates session object
|
|
164
|
-
getSession(e, id = null, persistent = false) {
|
|
165
|
-
return {
|
|
166
|
-
get: () => this.mockSessionStore,
|
|
167
|
-
set: value => { this.mockSessionStore = value },
|
|
168
|
-
};
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
// Initiates remote fetch and sets the status
|
|
172
|
-
remoteFetch(request, ...args) {
|
|
173
|
-
if (arguments.length > 1) {
|
|
174
|
-
request = this.generateRequest(request, ...args);
|
|
175
|
-
}
|
|
176
|
-
const matchUrl = (patterns, url) => _any((patterns || []).map(p => p.trim()).filter(p => p), p => pattern(p, self.origin).test(url));
|
|
177
|
-
const execFetch = () => {
|
|
178
|
-
// cache_only_urls
|
|
179
|
-
if (matchUrl(this.cx.params.cache_only_urls, request.url)) {
|
|
180
|
-
Observer.set(this.network, 'strategy', 'cache-only');
|
|
181
|
-
return this.cacheFetch(request, { networkFallback: false, cacheRefresh: false });
|
|
182
|
-
}
|
|
183
|
-
// network_only_urls
|
|
184
|
-
if (matchUrl(this.cx.params.network_only_urls, request.url)) {
|
|
185
|
-
Observer.set(this.network, 'strategy', 'network-only');
|
|
186
|
-
return this.networkFetch(request, { cacheFallback: false, cacheRefresh: false });
|
|
187
|
-
}
|
|
188
|
-
// cache_first_urls
|
|
189
|
-
if (matchUrl(this.cx.params.cache_first_urls, request.url)) {
|
|
190
|
-
Observer.set(this.network, 'strategy', 'cache-first');
|
|
191
|
-
return this.cacheFetch(request, { networkFallback: true, cacheRefresh: true });
|
|
192
|
-
}
|
|
193
|
-
// network_first_urls
|
|
194
|
-
if (matchUrl(this.cx.params.network_first_urls, request.url) || !this.cx.params.default_fetching_strategy) {
|
|
195
|
-
Observer.set(this.network, 'strategy', 'network-first');
|
|
196
|
-
return this.networkFetch(request, { cacheFallback: true, cacheRefresh: true });
|
|
197
|
-
}
|
|
198
|
-
// Default strategy
|
|
199
|
-
Observer.set(this.network, 'strategy', this.cx.params.default_fetching_strategy);
|
|
200
|
-
switch (this.cx.params.default_fetching_strategy) {
|
|
201
|
-
case 'cache-only': return this.cacheFetch(request, { networkFallback: false, cacheRefresh: false });
|
|
202
|
-
case 'network-only': return this.networkFetch(request, { cacheFallback: false, cacheRefresh: false });
|
|
203
|
-
case 'cache-first': return this.cacheFetch(request, { networkFallback: true, cacheRefresh: true });
|
|
204
|
-
case 'network-first': return this.networkFetch(request, { cacheFallback: true, cacheRefresh: true });
|
|
205
|
-
}
|
|
206
|
-
};
|
|
207
|
-
let response = execFetch(request);
|
|
208
|
-
// This catch() is NOT intended to handle failure of the fetch
|
|
209
|
-
response.catch(e => Observer.set(this.network, 'error', e.message));
|
|
210
|
-
// Return xResponse
|
|
211
|
-
return response.then(_response => xResponse.compat(_response));
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
// Caching strategy: network_first
|
|
215
|
-
networkFetch(request, params = {}) {
|
|
216
|
-
if (!params.cacheFallback) {
|
|
217
|
-
Observer.set(this.network, 'remote', true);
|
|
218
|
-
return xfetch(request);
|
|
219
|
-
}
|
|
220
|
-
return xfetch(request).then(response => {
|
|
221
|
-
if (params.cacheRefresh) this.refreshCache(request, response);
|
|
222
|
-
Observer.set(this.network, 'remote', true);
|
|
223
|
-
return response;
|
|
224
|
-
}).catch(() => this.getRequestCache(request).then(cache => {
|
|
225
|
-
Observer.set(this.network, 'cache', true);
|
|
226
|
-
return cache.match(request);
|
|
227
|
-
}));
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
// Caching strategy: cache_first
|
|
231
|
-
cacheFetch(request, params = {}) {
|
|
232
|
-
return this.getRequestCache(request).then(cache => cache.match(request).then(response => {
|
|
233
|
-
// Nothing cache, use network
|
|
234
|
-
if (!response && params.networkFallback) return this.networkFetch(request, { ...params, cacheFallback: false });
|
|
235
|
-
// Note: fetch, but for refreshing purposes only... not the returned response
|
|
236
|
-
if (response && params.cacheRefresh) this.networkFetch(request, { ...params, justRefreshing: true });
|
|
237
|
-
Observer.set(this.network, 'cache', true);
|
|
238
|
-
return response;
|
|
239
|
-
}));
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
// Caches response
|
|
243
|
-
refreshCache(request, response) {
|
|
244
|
-
// Check if we received a valid response
|
|
245
|
-
if (request.method !== 'GET' || !response || response.status !== 200 || (response.type !== 'basic' && response.type !== 'cors')) {
|
|
246
|
-
return response;
|
|
247
|
-
}
|
|
248
|
-
// IMPORTANT: Clone the response. A response is a stream
|
|
249
|
-
// and because we want the browser to consume the response
|
|
250
|
-
// as well as the cache consuming the response, we need
|
|
251
|
-
// to clone it so we have two streams.
|
|
252
|
-
var responseToCache = response.clone();
|
|
253
|
-
this.getRequestCache(request).then(cache => {
|
|
254
|
-
Observer.set(this.network, 'cacheRefresh', true);
|
|
255
|
-
cache.put(request, responseToCache);
|
|
256
|
-
});
|
|
257
|
-
return response;
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
// Returns either the regular cache or a json-specific cache
|
|
261
|
-
getRequestCache(request) {
|
|
262
|
-
let cacheName = request.headers.get('Accept') === 'application/json'
|
|
263
|
-
? this.cx.params.cache_name + '_json'
|
|
264
|
-
: this.cx.params.cache_name;
|
|
265
|
-
return self.caches.open(cacheName);
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
// Handles response object
|
|
269
|
-
handleResponse(e, response) {
|
|
270
|
-
if (!response && response !== 0) { response = new xResponse(null, { status: 404 }); }
|
|
271
|
-
else if (!(response instanceof xResponse)) { response = xResponse.compat(response); }
|
|
272
|
-
return response;
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
}
|
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
export default class Workport {
|
|
3
|
-
|
|
4
|
-
constructor() {
|
|
5
|
-
// --------
|
|
6
|
-
// Post messaging
|
|
7
|
-
// --------
|
|
8
|
-
this.messaging = {
|
|
9
|
-
post: (message, client = this.client) => {
|
|
10
|
-
if (!client) throw new Error(`No client for this operation.`);
|
|
11
|
-
client.postMessage(message);
|
|
12
|
-
return this;
|
|
13
|
-
},
|
|
14
|
-
listen: (callback, client = this.client) => {
|
|
15
|
-
(client || self).addEventListener('message', evt => {
|
|
16
|
-
this.client = evt.source;
|
|
17
|
-
const response = callback(evt);
|
|
18
|
-
let responsePort = evt.ports[0];
|
|
19
|
-
if (responsePort) {
|
|
20
|
-
if (response instanceof Promise) {
|
|
21
|
-
response.then(data => {
|
|
22
|
-
responsePort.postMessage(data);
|
|
23
|
-
});
|
|
24
|
-
} else {
|
|
25
|
-
responsePort.postMessage(response);
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
});
|
|
29
|
-
return this;
|
|
30
|
-
},
|
|
31
|
-
request: (message, client = this.client) => {
|
|
32
|
-
if (!client) throw new Error(`No client for this operation.`);
|
|
33
|
-
return new Promise(res => {
|
|
34
|
-
let messageChannel = new MessageChannel();
|
|
35
|
-
client.postMessage(message, [ messageChannel.port2 ]);
|
|
36
|
-
messageChannel.port1.onmessage = e => res(e.data);
|
|
37
|
-
});
|
|
38
|
-
},
|
|
39
|
-
channel(channelId) {
|
|
40
|
-
if (!this.channels.has(channelId)) { this.channels.set(channelId, new BroadcastChannel(channel)); }
|
|
41
|
-
let channel = this.channels.get(channelId);
|
|
42
|
-
return {
|
|
43
|
-
broadcast: message => channel.postMessage(message),
|
|
44
|
-
listen: callback => channel.addEventListener('message', callback),
|
|
45
|
-
};
|
|
46
|
-
},
|
|
47
|
-
channels: new Map,
|
|
48
|
-
};
|
|
49
|
-
|
|
50
|
-
// --------
|
|
51
|
-
// Notifications
|
|
52
|
-
// --------
|
|
53
|
-
this.notifications = {
|
|
54
|
-
handle: callback => {
|
|
55
|
-
self.addEventListener('notificationclick', e => e.waitUntil(callback(e)));
|
|
56
|
-
return this;
|
|
57
|
-
},
|
|
58
|
-
fire: (title, params = {}) => {
|
|
59
|
-
return self.registration.showNotification(title, params);
|
|
60
|
-
},
|
|
61
|
-
};
|
|
62
|
-
|
|
63
|
-
// --------
|
|
64
|
-
// Push Notifications
|
|
65
|
-
// --------
|
|
66
|
-
this.push = {
|
|
67
|
-
listen: callback => {
|
|
68
|
-
self.addEventListener('push', e => e.waitUntil(callback(e)));
|
|
69
|
-
return this;
|
|
70
|
-
},
|
|
71
|
-
};
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
setCurrentClient(client) {
|
|
75
|
-
this.client = client;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
}
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
/**
|
|
3
|
-
* @imports
|
|
4
|
-
*/
|
|
5
|
-
import Context from './Context.js';
|
|
6
|
-
import Application from './Application.js';
|
|
7
|
-
import Runtime from './Runtime.js';
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* @start
|
|
11
|
-
*/
|
|
12
|
-
export async function start(applicationInstance = null) {
|
|
13
|
-
const cx = this || {};
|
|
14
|
-
const defaultApplicationInstance = _cx => new Application(_cx);
|
|
15
|
-
return new Runtime(Context.create(cx), applicationInstance || defaultApplicationInstance);
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* @APIS
|
|
20
|
-
*/
|
|
21
|
-
export * as APIS from './Runtime.js';
|
|
@@ -1,101 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
/**
|
|
3
|
-
* imports
|
|
4
|
-
*/
|
|
5
|
-
import Fs from 'fs';
|
|
6
|
-
import Url from 'url';
|
|
7
|
-
import Path from 'path';
|
|
8
|
-
import QueryString from 'querystring';
|
|
9
|
-
import Router from './Router.js';
|
|
10
|
-
import _Application from '../Application.js';
|
|
11
|
-
|
|
12
|
-
export default class Application extends _Application {
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* Application
|
|
16
|
-
*
|
|
17
|
-
* @param Context cx
|
|
18
|
-
*/
|
|
19
|
-
constructor(cx) {
|
|
20
|
-
super(cx);
|
|
21
|
-
this.renderFileCache = {};
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
// Returns router class
|
|
25
|
-
get Router() {
|
|
26
|
-
return Router;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* Handles navigation events.
|
|
31
|
-
*
|
|
32
|
-
* @param NavigationEvent httpEvent
|
|
33
|
-
* @param Function remoteFetch
|
|
34
|
-
*
|
|
35
|
-
* @return Response
|
|
36
|
-
*/
|
|
37
|
-
async handle(httpEvent, remoteFetch) {
|
|
38
|
-
// The app router
|
|
39
|
-
const router = new this.Router(this.cx, httpEvent.url.pathname);
|
|
40
|
-
const handle = async () => {
|
|
41
|
-
return await router.route([httpEvent.request.method, 'default'], httpEvent, {}, async event => {
|
|
42
|
-
return router.file(event);
|
|
43
|
-
}, remoteFetch);
|
|
44
|
-
};
|
|
45
|
-
return (this.cx.middlewares || []).concat(handle).reverse().reduce((next, fn) => {
|
|
46
|
-
return () => fn.call(this.cx, httpEvent, router, next);
|
|
47
|
-
}, null)();
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
// Renderer
|
|
51
|
-
async render(httpEvent, response) {
|
|
52
|
-
let data = await response.jsonfy();
|
|
53
|
-
const router = new this.Router(this.cx, httpEvent.url.pathname);
|
|
54
|
-
return router.route('render', httpEvent, data, async (httpEvent, data) => {
|
|
55
|
-
let renderFile, pathnameSplit = httpEvent.url.pathname.split('/');
|
|
56
|
-
while ((renderFile = Path.join(this.cx.CWD, this.cx.layout.PUBLIC_DIR, './' + pathnameSplit.join('/'), 'index.html'))
|
|
57
|
-
&& (this.renderFileCache[renderFile] === false/* false on previous runs */ || !Fs.existsSync(renderFile))) {
|
|
58
|
-
this.renderFileCache[renderFile] = false;
|
|
59
|
-
pathnameSplit.pop();
|
|
60
|
-
}
|
|
61
|
-
const dirPublic = Url.pathToFileURL( Path.resolve( Path.join(this.cx.CWD, this.cx.layout.PUBLIC_DIR) ) );
|
|
62
|
-
const instanceParams = QueryString.stringify({
|
|
63
|
-
file: renderFile,
|
|
64
|
-
url: dirPublic.href,// httpEvent.url.href,
|
|
65
|
-
root: this.cx.CWD,
|
|
66
|
-
});
|
|
67
|
-
const { window, document } = await import('@webqit/oohtml-ssr/src/instance.js?' + instanceParams);
|
|
68
|
-
await new Promise(res => {
|
|
69
|
-
if (document.readyState === 'complete') return res();
|
|
70
|
-
document.addEventListener('load', res);
|
|
71
|
-
});
|
|
72
|
-
if (window.webqit?.oohtml?.configs) {
|
|
73
|
-
const {
|
|
74
|
-
CONTEXT_API: { attr: contextConfig } = {},
|
|
75
|
-
BINDINGS_API: { api: bindingsConfig } = {},
|
|
76
|
-
HTML_IMPORTS: { attr: modulesContextAttrs } = {},
|
|
77
|
-
} = window.webqit.oohtml.configs;
|
|
78
|
-
if ( bindingsConfig ) {
|
|
79
|
-
document[ bindingsConfig.bind ]({
|
|
80
|
-
env: 'server',
|
|
81
|
-
state: this.cx.runtime,
|
|
82
|
-
...data
|
|
83
|
-
}, { diff: true });
|
|
84
|
-
}
|
|
85
|
-
if ( modulesContextAttrs ) {
|
|
86
|
-
const routingContext = document.body.querySelector(`[${ window.CSS.escape( contextConfig.contextname ) }="route"]`) || document.body;
|
|
87
|
-
routingContext.setAttribute( modulesContextAttrs.importscontext, '/' + `routes/${ httpEvent.url.pathname }`.split('/').map(a => a.trim()).filter(a => a).join('/'));
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
if (window.webqit.$qCompilerImport) {
|
|
91
|
-
await new Promise(res => {
|
|
92
|
-
window.webqit.$qCompilerImport.then(res);
|
|
93
|
-
setTimeout(res, 300);
|
|
94
|
-
});
|
|
95
|
-
}
|
|
96
|
-
await new Promise(res => setTimeout(res, 50));
|
|
97
|
-
return window;
|
|
98
|
-
});
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
}
|
|
@@ -1,159 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
/**
|
|
3
|
-
* @imports
|
|
4
|
-
*/
|
|
5
|
-
import Fs from 'fs';
|
|
6
|
-
import Url from 'url';
|
|
7
|
-
import Path from 'path';
|
|
8
|
-
import Mime from 'mime-types';
|
|
9
|
-
import _Router from '../Router.js';
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* ---------------------------
|
|
13
|
-
* The Router class
|
|
14
|
-
* ---------------------------
|
|
15
|
-
*/
|
|
16
|
-
|
|
17
|
-
export default class Router extends _Router {
|
|
18
|
-
|
|
19
|
-
async readTick(thisTick) {
|
|
20
|
-
thisTick = { ...thisTick };
|
|
21
|
-
if (thisTick.trail) {
|
|
22
|
-
thisTick.currentSegment = thisTick.destination[thisTick.trail.length];
|
|
23
|
-
thisTick.currentSegmentOnFile = [ thisTick.currentSegment, '-' ].reduce((_segmentOnFile, _seg) => {
|
|
24
|
-
if (_segmentOnFile.index) return _segmentOnFile;
|
|
25
|
-
var _currentPath = thisTick.trailOnFile.concat(_seg).join('/'),
|
|
26
|
-
routeHandlerFile;
|
|
27
|
-
return Fs.existsSync(routeHandlerFile = Path.join(this.cx.CWD, this.cx.layout.SERVER_DIR, _currentPath, 'index.js')) ? { seg: _seg, index: routeHandlerFile } : (
|
|
28
|
-
Fs.existsSync(Path.join(this.cx.CWD, this.cx.layout.SERVER_DIR, _currentPath)) ? { seg: _seg, dirExists: true } : _segmentOnFile
|
|
29
|
-
);
|
|
30
|
-
}, { seg: null });
|
|
31
|
-
thisTick.trail = thisTick.trail.concat(thisTick.currentSegment);
|
|
32
|
-
thisTick.trailOnFile = thisTick.trailOnFile.concat(thisTick.currentSegmentOnFile.seg);
|
|
33
|
-
thisTick.exports = thisTick.currentSegmentOnFile.index ? await import(Url.pathToFileURL(thisTick.currentSegmentOnFile.index)) : undefined;
|
|
34
|
-
} else {
|
|
35
|
-
thisTick.trail = [];
|
|
36
|
-
thisTick.trailOnFile = [];
|
|
37
|
-
thisTick.currentSegmentOnFile = { index: Path.join(this.cx.CWD, this.cx.layout.SERVER_DIR, 'index.js') };
|
|
38
|
-
thisTick.exports = Fs.existsSync(thisTick.currentSegmentOnFile.index)
|
|
39
|
-
? await import(Url.pathToFileURL(thisTick.currentSegmentOnFile.index))
|
|
40
|
-
: null;
|
|
41
|
-
}
|
|
42
|
-
return thisTick;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
finalizeHandlerContext(context, thisTick) {
|
|
46
|
-
if (thisTick.currentSegmentOnFile.index) {
|
|
47
|
-
context.dirname = Path.dirname(thisTick.currentSegmentOnFile.index);
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
pathJoin(...args) {
|
|
52
|
-
return Path.join(...args);
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* Reads a static file from the public directory.
|
|
57
|
-
*
|
|
58
|
-
* @param ServerNavigationEvent httpEvent
|
|
59
|
-
*
|
|
60
|
-
* @return Promise
|
|
61
|
-
*/
|
|
62
|
-
file(httpEvent) {
|
|
63
|
-
let filename = Path.join(this.cx.CWD, this.cx.layout.PUBLIC_DIR, decodeURIComponent(httpEvent.url.pathname));
|
|
64
|
-
let index, ext = Path.parse(httpEvent.url.pathname).ext;
|
|
65
|
-
// if is a directory search for index file matching the extention
|
|
66
|
-
if (!ext && Fs.existsSync(filename) && Fs.lstatSync(filename).isDirectory()) {
|
|
67
|
-
ext = '.html';
|
|
68
|
-
index = `index${ext}`;
|
|
69
|
-
filename = Path.join(filename, index);
|
|
70
|
-
}
|
|
71
|
-
let enc, acceptEncs = [], supportedEncs = { gzip: '.gz', br: '.br' };
|
|
72
|
-
// based on the URL path, extract the file extention. e.g. .js, .doc, ...
|
|
73
|
-
// and process encoding
|
|
74
|
-
if ((acceptEncs = (httpEvent.request.headers.get('Accept-Encoding') || '').split(',').map(e => e.trim())).length
|
|
75
|
-
&& (enc = acceptEncs.reduce((prev, _enc) => prev || (Fs.existsSync(filename + supportedEncs[_enc]) && _enc), null))) {
|
|
76
|
-
filename = filename + supportedEncs[enc];
|
|
77
|
-
} else {
|
|
78
|
-
if (!Fs.existsSync(filename)) return;
|
|
79
|
-
if (Object.values(supportedEncs).includes(ext)) {
|
|
80
|
-
enc = Object.keys(supportedEncs).reduce((prev, _enc) => prev || (supportedEncs[_enc] === ext && _enc), null);
|
|
81
|
-
ext = Path.parse(filename.substring(0, filename.length - ext.length)).ext;
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
// read file from file system
|
|
86
|
-
return new Promise(resolve => {
|
|
87
|
-
Fs.readFile(filename, function(err, data) {
|
|
88
|
-
let response;
|
|
89
|
-
if (err) {
|
|
90
|
-
response = new httpEvent.Response(null, { status: 500, statusText: `Error reading static file: ${filename}` } );
|
|
91
|
-
} else {
|
|
92
|
-
// if the file is found, set Content-type and send data
|
|
93
|
-
let mime = Mime.lookup(ext);
|
|
94
|
-
response = new httpEvent.Response(data, { headers: {
|
|
95
|
-
contentType: mime === 'application/javascript' ? 'text/javascript' : mime,
|
|
96
|
-
contentLength: Buffer.byteLength(data),
|
|
97
|
-
} });
|
|
98
|
-
if (enc) {
|
|
99
|
-
response.headers.set('Content-Encoding', enc);
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
response.attrs.filename = filename;
|
|
103
|
-
response.attrs.static = true;
|
|
104
|
-
response.attrs.index = index;
|
|
105
|
-
resolve(response);
|
|
106
|
-
});
|
|
107
|
-
});
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
/**
|
|
111
|
-
* Writes a file to the public directory.
|
|
112
|
-
*
|
|
113
|
-
* @param object filename
|
|
114
|
-
* @param string content
|
|
115
|
-
*
|
|
116
|
-
* @return bool
|
|
117
|
-
*/
|
|
118
|
-
putPreRendered(filename, content) {
|
|
119
|
-
var _filename = Path.join(this.cx.layout.PUBLIC_DIR, '.', filename);
|
|
120
|
-
if (!Path.parse(filename).ext && filename.lastIndexOf('.') < filename.lastIndexOf('/')) {
|
|
121
|
-
_filename = Path.join(_filename, '/index.html');
|
|
122
|
-
}
|
|
123
|
-
var dir = Path.dirname(_filename);
|
|
124
|
-
if (!Fs.existsSync(dir)) {
|
|
125
|
-
Fs.mkdirSync(dir, {recursive:true});
|
|
126
|
-
}
|
|
127
|
-
return Fs.writeFileSync(_filename, content);
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
/**
|
|
131
|
-
* Deletes a file from the public directory.
|
|
132
|
-
*
|
|
133
|
-
* @param object filename
|
|
134
|
-
*
|
|
135
|
-
* @return bool
|
|
136
|
-
*/
|
|
137
|
-
deletePreRendered(filename) {
|
|
138
|
-
return Fs.unlinkSync(filename);
|
|
139
|
-
}
|
|
140
|
-
};
|
|
141
|
-
|
|
142
|
-
// maps file extention to MIME typere
|
|
143
|
-
const mimeTypes = {
|
|
144
|
-
'.ico': 'image/x-icon',
|
|
145
|
-
'.html': 'text/html',
|
|
146
|
-
'.js': 'text/javascript',
|
|
147
|
-
'.json': 'application/json',
|
|
148
|
-
'.css': 'text/css',
|
|
149
|
-
'.png': 'image/png',
|
|
150
|
-
'.jpeg': 'image/jpeg',
|
|
151
|
-
'.jpg': 'image/jpeg',
|
|
152
|
-
'.wav': 'audio/wav',
|
|
153
|
-
'.mp3': 'audio/mpeg',
|
|
154
|
-
'.svg': 'image/svg+xml',
|
|
155
|
-
'.pdf': 'application/pdf',
|
|
156
|
-
'.doc': 'application/msword'
|
|
157
|
-
};
|
|
158
|
-
|
|
159
|
-
export { mimeTypes };
|