@webqit/webflo 0.8.76 → 0.9.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.
Files changed (97) hide show
  1. package/package.json +5 -12
  2. package/src/Cli.js +131 -0
  3. package/src/Configurator.js +97 -0
  4. package/src/Context.js +76 -0
  5. package/src/config-pi/deployment/Env.js +69 -0
  6. package/src/config-pi/deployment/Layout.js +65 -0
  7. package/src/config-pi/deployment/Origins.js +133 -0
  8. package/src/config-pi/deployment/Virtualization.js +65 -0
  9. package/src/config-pi/deployment/index.js +18 -0
  10. package/src/config-pi/index.js +16 -0
  11. package/src/config-pi/runtime/Client.js +59 -0
  12. package/src/config-pi/runtime/Server.js +174 -0
  13. package/src/config-pi/runtime/client/Worker.js +117 -0
  14. package/src/config-pi/runtime/client/index.js +12 -0
  15. package/src/config-pi/runtime/index.js +18 -0
  16. package/src/config-pi/runtime/server/Headers.js +90 -0
  17. package/src/config-pi/runtime/server/Redirects.js +108 -0
  18. package/src/config-pi/runtime/server/index.js +14 -0
  19. package/src/config-pi/static/Manifest.js +321 -0
  20. package/src/config-pi/static/Ssg.js +72 -0
  21. package/src/config-pi/static/index.js +14 -0
  22. package/src/deployment-pi/index.js +10 -0
  23. package/src/{services → deployment-pi}/origins/index.js +88 -58
  24. package/src/index.js +14 -147
  25. package/src/{runtime → runtime-pi}/Router.js +19 -19
  26. package/src/runtime-pi/client/Context.js +7 -0
  27. package/src/{runtime → runtime-pi}/client/Router.js +2 -2
  28. package/src/{runtime/client/Navigator.js → runtime-pi/client/Runtime.js} +143 -102
  29. package/src/runtime-pi/client/RuntimeClient.js +114 -0
  30. package/src/{runtime → runtime-pi}/client/Storage.js +8 -7
  31. package/src/{runtime → runtime-pi}/client/Url.js +2 -6
  32. package/src/{runtime/client/WorkerClient.js → runtime-pi/client/WorkerComm.js} +2 -2
  33. package/src/runtime-pi/client/generate.js +242 -0
  34. package/src/runtime-pi/client/generate.oohtml.js +7 -0
  35. package/src/runtime-pi/client/index.js +18 -0
  36. package/src/runtime-pi/client/whatwag.js +27 -0
  37. package/src/runtime-pi/client/worker/Context.js +7 -0
  38. package/src/runtime-pi/client/worker/Worker.js +243 -0
  39. package/src/runtime-pi/client/worker/WorkerClient.js +46 -0
  40. package/src/runtime-pi/client/worker/index.js +18 -0
  41. package/src/runtime-pi/index.js +14 -0
  42. package/src/runtime-pi/server/Context.js +16 -0
  43. package/src/{runtime → runtime-pi}/server/Router.js +6 -6
  44. package/src/runtime-pi/server/Runtime.js +531 -0
  45. package/src/runtime-pi/server/RuntimeClient.js +102 -0
  46. package/src/runtime-pi/server/index.js +41 -0
  47. package/src/runtime-pi/server/whatwag.js +35 -0
  48. package/src/{runtime → runtime-pi}/util.js +0 -0
  49. package/src/{runtime/_FormData.js → runtime-pi/xFormData.js} +2 -2
  50. package/src/{runtime/_Headers.js → runtime-pi/xHeaders.js} +4 -4
  51. package/src/runtime-pi/xHttpEvent.js +93 -0
  52. package/src/runtime-pi/xHttpMessage.js +179 -0
  53. package/src/runtime-pi/xRequest.js +67 -0
  54. package/src/runtime-pi/xRequestHeaders.js +95 -0
  55. package/src/runtime-pi/xResponse.js +62 -0
  56. package/src/{runtime/_ResponseHeaders.js → runtime-pi/xResponseHeaders.js} +38 -18
  57. package/src/{runtime/_URL.js → runtime-pi/xURL.js} +4 -4
  58. package/src/runtime-pi/xfetch.js +7 -0
  59. package/src/{services → services-pi}/certbot/http-auth-hook.js +0 -0
  60. package/src/{services → services-pi}/certbot/http-cleanup-hook.js +0 -0
  61. package/src/{services → services-pi}/certbot/index.js +21 -15
  62. package/src/services-pi/index.js +9 -0
  63. package/src/static-pi/index.js +11 -0
  64. package/src/webflo.js +33 -0
  65. package/test/index.test.js +26 -0
  66. package/src/build/client/index.js +0 -261
  67. package/src/build/index.js +0 -5
  68. package/src/config/client.js +0 -191
  69. package/src/config/headers.js +0 -121
  70. package/src/config/index.js +0 -14
  71. package/src/config/layout.js +0 -83
  72. package/src/config/manifest.js +0 -341
  73. package/src/config/origins.js +0 -165
  74. package/src/config/prerendering.js +0 -100
  75. package/src/config/redirects.js +0 -137
  76. package/src/config/server.js +0 -201
  77. package/src/config/variables.js +0 -102
  78. package/src/config/vhosts.js +0 -93
  79. package/src/runtime/_MessageStream.js +0 -195
  80. package/src/runtime/_NavigationEvent.js +0 -91
  81. package/src/runtime/_Request.js +0 -61
  82. package/src/runtime/_RequestHeaders.js +0 -72
  83. package/src/runtime/_Response.js +0 -56
  84. package/src/runtime/client/Cache.js +0 -38
  85. package/src/runtime/client/Http.js +0 -225
  86. package/src/runtime/client/NavigationEvent.js +0 -21
  87. package/src/runtime/client/Runtime.js +0 -126
  88. package/src/runtime/client/StdRequest.js +0 -74
  89. package/src/runtime/client/Worker.js +0 -312
  90. package/src/runtime/client/WorkerComm.js +0 -183
  91. package/src/runtime/client/effects/sounds.js +0 -64
  92. package/src/runtime/index.js +0 -5
  93. package/src/runtime/server/NavigationEvent.js +0 -39
  94. package/src/runtime/server/Runtime.js +0 -593
  95. package/src/runtime/server/index.js +0 -183
  96. package/src/runtime/server/index.mjs +0 -10
  97. package/src/services/index.js +0 -6
@@ -1,225 +0,0 @@
1
-
2
- /**
3
- * @imports
4
- */
5
- import _before from '@webqit/util/str/before.js';
6
- import _after from '@webqit/util/str/after.js';
7
- import _toTitle from '@webqit/util/str/toTitle.js';
8
- import _arrFrom from '@webqit/util/arr/from.js';
9
- import { wwwFormUnserialize, wwwFormSet, wwwFormSerialize } from '../util.js';
10
- import StdRequest from './StdRequest.js';
11
- import { Observer } from './Runtime.js';
12
- import Url from './Url.js';
13
-
14
- /**
15
- * ---------------------------
16
- * The Client class
17
- * ---------------------------
18
- */
19
-
20
- export default class Http {
21
-
22
- /**
23
- * Constructs a new Http instance. Typically,
24
- *
25
- * @param function client
26
- * @param object params
27
- *
28
- * @return void
29
- */
30
- static async createClient(client, params = {}) {
31
-
32
- /**
33
- * ----------------
34
- * instance
35
- * ----------------
36
- */
37
- const instance = {
38
-
39
- /**
40
- * Performs a request.
41
- *
42
- * @param object|string href
43
- * @param object options
44
- *
45
- * @return void
46
- */
47
- async go(url, options = {}) {
48
- if (this.abortController) {
49
- this.abortController.abort();
50
- }
51
- this.abortController = new AbortController();
52
- let xRedirectCode = 300;
53
- // Generates request object
54
- let generateRequest = (url, options) => {
55
- return new StdRequest(url, {
56
- ...options,
57
- headers: {
58
- 'Accept': 'application/json',
59
- 'X-Redirect-Policy': 'manual-when-cross-origin',
60
- 'X-Redirect-Code': xRedirectCode,
61
- 'X-Powered-By': '@webqit/webflo',
62
- ...(options.headers || {}),
63
- },
64
- referrer: window.document.location.href,
65
- signal: this.abortController.signal,
66
- });
67
- };
68
- // Handles response object
69
- let handleResponse = (response) => {
70
- if (!response) return;
71
- if (response.redirected && this.isSameOrigin(response.url)) {
72
- Observer.set(this.location, { href: response.url }, {
73
- detail: { isRedirect: true },
74
- });
75
- } else if (response.headers.get('Location') && response.status === xRedirectCode) {
76
- window.location = response.headers.get('Location');
77
- }
78
- };
79
- url = typeof url === 'string' ? { href: url } : url;
80
- options = { referrer: this.location.href, ...options };
81
- Observer.set(this.location, url, { detail: options, });
82
- if (!(_before(url.href, '#') === _before(options.referrer, '#') && (options.method || 'GET').toUpperCase() === 'GET')) {
83
- handleResponse(await client.call(this, generateRequest(url.href, options)));
84
- }
85
- },
86
-
87
- /**
88
- * Checks if an URL is same origin.
89
- *
90
- * @param object|string url
91
- *
92
- * @return Bool
93
- */
94
- isSameOrigin(url) {
95
- if (typeof url === 'string') {
96
- let href = url;
97
- url = window.document.createElement('a');
98
- url.href = href
99
- }
100
- return !url.origin || url.origin === this.location.origin;
101
- },
102
-
103
- /**
104
- * History object
105
- */
106
- get history() {
107
- return window.history;
108
- }
109
-
110
- };
111
-
112
- // -----------------------
113
- // Initialize network
114
- Observer.set(instance, 'network', {});
115
- window.addEventListener('online', () => Observer.set(instance.network, 'online', navigator.onLine));
116
- window.addEventListener('offline', () => Observer.set(instance.network, 'online', navigator.onLine));
117
-
118
- // -----------------------
119
- // Initialize location
120
- Observer.set(instance, 'location', new Url(window.document.location));
121
- // -----------------------
122
- // Syndicate changes to the browser;s location bar
123
- Observer.observe(instance.location, [[ 'href' ]], ([e]) => {
124
- if (e.value === 'http:' || (e.detail || {}).src === window.document.location) {
125
- // Already from a "popstate" event as above, so don't push again
126
- return;
127
- }
128
- if (e.value === window.document.location.href || e.value + '/' === window.document.location.href) {
129
- instance.history.replaceState(instance.history.state, '', instance.location.href);
130
- } else {
131
- try { instance.history.pushState(instance.history.state, '', instance.location.href); } catch(e) {}
132
- }
133
- }, { diff: true });
134
-
135
- /**
136
- * ----------------
137
- * Navigation Interception
138
- * ----------------
139
- */
140
-
141
- // -----------------------
142
- // This event is triggered by
143
- // either the browser back button,
144
- // the window.history.back(),
145
- // the window.history.forward(),
146
- // or the window.history.go() action.
147
- window.addEventListener('popstate', e => {
148
- // Needed to allow window.document.location
149
- // to update to window.location
150
- let referrer = window.document.location.href;
151
- window.setTimeout(() => {
152
- instance.go(Url.copy(window.document.location), { referrer, src: window.document.location, srcType: 'history', });
153
- }, 0);
154
- });
155
-
156
- // -----------------------
157
- // Capture all link-clicks
158
- // and fire to this router.
159
- window.addEventListener('click', e => {
160
- var anchor = e.target.closest('a');
161
- if (!anchor || !anchor.href) return;
162
- if (!anchor.target && !anchor.download && (!anchor.origin || anchor.origin === instance.location.origin)) {
163
- if (e.metaKey || e.altKey || e.ctrlKey || e.shiftKey) return;
164
- // Publish everything, including hash
165
- instance.go(Url.copy(anchor), { src: anchor, srcType: 'link', });
166
- // URLs with # will cause a natural navigation
167
- // even if pointing to a different page, a natural navigation will still happen
168
- // because with the Observer.set() above, window.document.location.href would have become
169
- // the destination page, which makes it look like same page navigation
170
- if (!anchor.href.includes('#')) {
171
- e.preventDefault();
172
- }
173
- }
174
- });
175
-
176
- // -----------------------
177
- // Capture all form-submit
178
- // and fire to this router.
179
- window.addEventListener('submit', e => {
180
- var form = e.target.closest('form'), submitter = e.submitter;
181
- var submitParams = [ 'action', 'enctype', 'method', 'noValidate', 'target' ].reduce((params, prop) => {
182
- params[prop] = submitter && submitter.hasAttribute(`form${prop.toLowerCase()}`) ? submitter[`form${_toTitle(prop)}`] : form[prop];
183
- return params;
184
- }, {});
185
- // We support method hacking
186
- submitParams.method = (submitter && submitter.dataset.method) || form.dataset.method || submitParams.method;
187
- submitParams.submitter = submitter;
188
- // ---------------
189
- var actionEl = window.document.createElement('a');
190
- actionEl.href = submitParams.action;
191
- // ---------------
192
- // If not targeted and same origin...
193
- if (!submitParams.target && (!actionEl.origin || actionEl.origin === instance.location.origin)) {
194
- if (e.metaKey || e.altKey || e.ctrlKey || e.shiftKey) return;
195
- // Build data
196
- var formData = new FormData(form);
197
- if ((submitter || {}).name) {
198
- formData.set(submitter.name, submitter.value);
199
- }
200
- if (submitParams.method.toUpperCase() === 'GET') {
201
- var query = wwwFormUnserialize(actionEl.search);
202
- Array.from(formData.entries()).forEach(_entry => {
203
- wwwFormSet(query, _entry[0], _entry[1], false);
204
- });
205
- actionEl.search = wwwFormSerialize(query);
206
- formData = null;
207
- }
208
- instance.go(Url.copy(actionEl), { ...submitParams, body: formData, src: form, srcType: 'form', });
209
- // URLs with # will cause a natural navigation
210
- // even if pointing to a different page, a natural navigation will still happen
211
- // because with the Observer.set() above, window.document.location.href would have become
212
- // the destination page, which makes it look like same page navigation
213
- if (!actionEl.hash) {
214
- e.preventDefault();
215
- }
216
- }
217
- });
218
-
219
- // -----------------------
220
- // Startup route
221
- instance.go(window.document.location.href, { referrer: document.referrer });
222
- return instance;
223
- }
224
-
225
- }
@@ -1,21 +0,0 @@
1
-
2
- /**
3
- * @imports
4
- */
5
- import _NavigationEvent from '../_NavigationEvent.js';
6
- import _FormData from '../_FormData.js';
7
-
8
- /**
9
- * The ClientNavigationEvent class
10
- */
11
- export default _NavigationEvent({
12
- URL,
13
- Request,
14
- Response,
15
- Headers,
16
- FormData: _FormData(FormData),
17
- File,
18
- Blob,
19
- ReadableStream,
20
- fetch,
21
- });
@@ -1,126 +0,0 @@
1
-
2
- /**
3
- * @imports
4
- */
5
- import _isObject from '@webqit/util/js/isObject.js';
6
- import _before from '@webqit/util/str/before.js';
7
- import _unique from '@webqit/util/arr/unique.js';
8
- import _fetch from '@webqit/browser-pie/src/apis/fetch.js';
9
- import NavigationEvent from './NavigationEvent.js';
10
- import WorkerClient from './WorkerClient.js';
11
- import Storage from './Storage.js';
12
- import Router from './Router.js';
13
- import Navigator from './Navigator.js';
14
-
15
- /**
16
- * ---------------------------
17
- * The Client Initializer
18
- * ---------------------------
19
- */
20
-
21
- export const { Observer } = window.WebQit;
22
- export default function(layout, params) {
23
-
24
- layout = {...layout};
25
- params = {...params};
26
-
27
- const session = Storage();
28
- const workerClient = new WorkerClient('/worker.js', { startMessages: true });
29
- const navigator = new Navigator(async (request, params, remoteFetch) => {
30
-
31
- // The navigation event
32
- const clientNavigationEvent = new NavigationEvent(
33
- new NavigationEvent.Request(request),
34
- session,
35
- );
36
-
37
- // The app router
38
- const router = new Router(clientNavigationEvent.url.pathname, layout, {
39
- layout,
40
- onHydration: params.srcType === 'init',
41
- });
42
-
43
- // --------
44
- // ROUTE FOR DATA
45
- // --------
46
- const httpMethodName = clientNavigationEvent.request.method.toLowerCase();
47
- const response = await router.route([httpMethodName === 'delete' ? 'del' : httpMethodName, 'default'], clientNavigationEvent, document.state, async function(event) {
48
- return remoteFetch(event.request).then(response => {
49
- return new clientNavigationEvent.Response(response.body, {
50
- status: response.status,
51
- statusText: response.statusText,
52
- headers: response.headers,
53
- _proxy: {
54
- url: response.url,
55
- ok: response.ok,
56
- redirected: response.redirected
57
- },
58
- });
59
- });
60
- }).catch(e => {
61
- window.document.body.setAttribute('template', '');
62
- throw e;
63
- });
64
-
65
-
66
- // --------
67
- // Render
68
- // --------
69
- const data = response instanceof clientNavigationEvent.Response ? await response.data() : response;
70
- await router.route('render', clientNavigationEvent, data, async function(event, data) {
71
- // --------
72
- // OOHTML would waiting for DOM-ready in order to be initialized
73
- await new Promise(res => window.WebQit.DOM.ready(res));
74
- if (!window.document.state.env) {
75
- window.document.setState({
76
- env: 'client',
77
- onHydration: params.srcType === 'init',
78
- network: navigator.network,
79
- url: navigator.location,
80
- session,
81
- }, { update: true });
82
- }
83
- window.document.setState({ page: data }, { update: 'merge' });
84
- window.document.body.setAttribute('template', 'page/' + clientNavigationEvent.url.pathname.split('/').filter(a => a).map(a => a + '+-').join('/'));
85
- return new Promise(res => {
86
- window.document.addEventListener('templatesreadystatechange', () => res(window));
87
- if (window.document.templatesReadyState === 'complete') {
88
- res(window);
89
- }
90
- });
91
- });
92
-
93
- // --------
94
- // Render...
95
- // --------
96
-
97
- if (params.src instanceof Element) {
98
- setTimeout(() => {
99
- let viewportTop;
100
- if (clientNavigationEvent.url.hash && (urlTarget = document.querySelector(clientNavigationEvent.url.hash))) {
101
- urlTarget.scrollIntoView();
102
- } else if (viewportTop = Array.from(document.querySelectorAll('[data-viewport-top]')).pop()) {
103
- viewportTop.focus();
104
- } else {
105
- document.documentElement.classList.add('scroll-reset');
106
- document.body.scrollIntoView();
107
- setTimeout(() => {
108
- document.documentElement.classList.remove('scroll-reset');
109
- }, 600);
110
- }
111
- }, 0);
112
- }
113
-
114
- return response;
115
- });
116
-
117
- Observer.observe(session, changes => {
118
- //console.log('SESSION_STATE_CHANGE', changes[0].name, changes[0].value);
119
- });
120
- Observer.observe(workerClient, changes => {
121
- //console.log('SERVICE_WORKER_STATE_CHANGE', changes[0].name, changes[0].value);
122
- });
123
- Observer.observe(navigator, changes => {
124
- //console.log('NAVIGATORSTATE_CHANGE', changes[0].name, changes[0].value);
125
- });
126
- };
@@ -1,74 +0,0 @@
1
-
2
- /**
3
- * @imports
4
- */
5
- import { _isTypeObject, _isFunction } from '@webqit/util/js/index.js';
6
- import { wwwFormUnserialize, wwwFormSet } from '../util.js';
7
-
8
- /**
9
- * The Request class
10
- */
11
- export default class StdRequest extends Request {
12
-
13
- constructor(input, init) {
14
- var src;
15
- if (input instanceof Request) {
16
- src = input.clone();
17
- }
18
- super(...arguments);
19
- this.src = src;
20
- }
21
-
22
- get destination() {
23
- return this.src ? this.src.destination : '';
24
- }
25
-
26
- clone() {
27
- return new this.constructor(this.src || super.clone());
28
- }
29
-
30
- get cookies() {
31
- if (!this._cookies) {
32
- this._cookies = wwwFormUnserialize(this.headers.cookie, {}, ';');
33
- }
34
- return this._cookies;
35
- }
36
-
37
- // Payload
38
- parse(force = false) {
39
- if (!this._submits || force) {
40
- this._submits = new Promise(async resolve => {
41
- var request = this.clone();
42
- var contentType = request.headers['content-type'] || '';
43
- var submits = {
44
- inputs: {},
45
- files: {},
46
- type: contentType === 'application/x-www-form-urlencoded' || contentType.startsWith('multipart/') || (!contentType && !['get'].includes(request.method.toLowerCase())) ? 'form-data'
47
- : (contentType === 'application/json' ? 'json'
48
- : (contentType === 'text/plain' ? 'plain'
49
- : 'other')),
50
- };
51
- if (submits.type === 'form-data') {
52
- try {
53
- const payload = await request.formData();
54
- for(var [ name, value ] of payload.entries()) {
55
- if (value instanceof File) {
56
- wwwFormSet(submits.files, name, value);
57
- } else {
58
- wwwFormSet(submits.inputs, name, value);
59
- }
60
- }
61
- } catch(e) { }
62
- } else {
63
- submits.inputs = await (submits.type === 'json'
64
- ? request.json() : (
65
- submits.type === 'plain' ? request.text() : request.arrayBuffer()
66
- )
67
- )
68
- }
69
- resolve(submits);
70
- });
71
- }
72
- return this._submits;
73
- }
74
- }