@webqit/webflo 0.20.28 → 0.20.29
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/package.json +2 -2
- package/src/runtime-pi/AppRuntime.js +4 -4
- package/src/runtime-pi/webflo-client/WebfloClient.js +51 -23
- package/src/runtime-pi/webflo-client/WebfloRootClientA.js +3 -3
- package/src/runtime-pi/webflo-client/WebfloSubClient.js +18 -21
- package/src/runtime-pi/webflo-client/index.js +6 -2
- package/src/runtime-pi/webflo-client/webflo-elements.js +1500 -0
- package/src/runtime-pi/webflo-client/webflo-embedded.js +7 -3
- package/src/runtime-pi/webflo-routing/HttpCookies101.js +4 -1
- package/src/runtime-pi/webflo-routing/HttpEvent111.js +7 -4
- package/src/runtime-pi/webflo-routing/HttpKeyvalInterface.js +5 -4
- package/src/runtime-pi/webflo-routing/HttpSession001.js +1 -4
- package/src/runtime-pi/webflo-routing/HttpThread111.js +26 -38
- package/src/runtime-pi/webflo-routing/KeyvalsFactory001.js +2 -2
- package/src/runtime-pi/webflo-routing/KeyvalsFactory110.js +2 -2
- package/src/runtime-pi/webflo-server/WebfloServer.js +9 -5
- package/src/runtime-pi/webflo-worker/WebfloWorker.js +1 -1
package/package.json
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
"vanila-javascript"
|
|
13
13
|
],
|
|
14
14
|
"homepage": "https://webqit.io/tooling/webflo",
|
|
15
|
-
"version": "0.20.
|
|
15
|
+
"version": "0.20.29",
|
|
16
16
|
"license": "MIT",
|
|
17
17
|
"repository": {
|
|
18
18
|
"type": "git",
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
"dependencies": {
|
|
42
42
|
"@octokit/webhooks": "^7.15.1",
|
|
43
43
|
"@webqit/backpack": "^0.1.12",
|
|
44
|
-
"@webqit/fetch-plus": "^0.1.
|
|
44
|
+
"@webqit/fetch-plus": "^0.1.23",
|
|
45
45
|
"@webqit/keyval": "^0.2.17",
|
|
46
46
|
"@webqit/observer": "^3.8.14",
|
|
47
47
|
"@webqit/oohtml-ssr": "^2.2.2",
|
|
@@ -155,7 +155,7 @@ export class AppRuntime {
|
|
|
155
155
|
if (!this.isClientSide
|
|
156
156
|
&& response instanceof LiveResponse) {
|
|
157
157
|
// Must convert to Response on the server-side before returning
|
|
158
|
-
const outgoingResponse = response.toResponse({ port: httpEvent.client });
|
|
158
|
+
const outgoingResponse = response.toResponse({ port: httpEvent.client, signal: httpEvent.signal });
|
|
159
159
|
return outgoingResponse;
|
|
160
160
|
}
|
|
161
161
|
|
|
@@ -168,11 +168,11 @@ export class AppRuntime {
|
|
|
168
168
|
&& response.headers.get('Location')) return;
|
|
169
169
|
|
|
170
170
|
const status = await httpEvent.thread.consume('status', true);
|
|
171
|
-
if (!status
|
|
171
|
+
if (!status) return;
|
|
172
172
|
|
|
173
173
|
httpEvent.waitUntil(httpEvent.client.readyStateChange('open').then(async () => {
|
|
174
|
-
await new Promise((r) => setTimeout(r,
|
|
175
|
-
httpEvent.client.postMessage(status, { type: '
|
|
174
|
+
await new Promise((r) => setTimeout(r, 500));
|
|
175
|
+
httpEvent.client.postMessage(status, { type: 'status' });
|
|
176
176
|
await new Promise((r) => setTimeout(r, 100));
|
|
177
177
|
}));
|
|
178
178
|
}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { _before, _toTitle } from '@webqit/util/str/index.js';
|
|
2
|
-
import {
|
|
2
|
+
import { Observer } from '@webqit/observer';
|
|
3
|
+
import { URLPlus } from '@webqit/url-plus';
|
|
3
4
|
import { StarPort } from '@webqit/port-plus';
|
|
5
|
+
import { LiveResponse, RequestPlus } from '@webqit/fetch-plus';
|
|
4
6
|
import { HttpThread111 } from '../webflo-routing/HttpThread111.js';
|
|
5
7
|
import { HttpCookies101 } from '../webflo-routing/HttpCookies101.js';
|
|
6
8
|
import { HttpCookies110 } from '../webflo-routing/HttpCookies110.js';
|
|
@@ -11,8 +13,6 @@ import { WebfloRouter111 } from '../webflo-routing/WebfloRouter111.js';
|
|
|
11
13
|
import { KeyvalsFactory110 } from '../webflo-routing/KeyvalsFactory110.js';
|
|
12
14
|
import { ClientRequestPort100 } from '../webflo-messaging/ClientRequestPort100.js';
|
|
13
15
|
import { AppRuntime } from '../AppRuntime.js';
|
|
14
|
-
import { Observer } from '@webqit/observer';
|
|
15
|
-
import { URLPlus } from '@webqit/url-plus';
|
|
16
16
|
import { _meta } from '../../util.js';
|
|
17
17
|
|
|
18
18
|
export class WebfloClient extends AppRuntime {
|
|
@@ -69,29 +69,52 @@ export class WebfloClient extends AppRuntime {
|
|
|
69
69
|
|
|
70
70
|
// ----------
|
|
71
71
|
// Bind prompt handlers
|
|
72
|
-
const
|
|
72
|
+
const dialogHandler = (e) => {
|
|
73
73
|
window.queueMicrotask(() => {
|
|
74
74
|
if (e.defaultPrevented) return;
|
|
75
|
+
|
|
75
76
|
if (e.type === 'confirm') {
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
77
|
+
const dialogElement = document.createElement('wq-confirm');
|
|
78
|
+
dialogElement.toggleAttribute('wq-default', true);
|
|
79
|
+
|
|
80
|
+
dialogElement.render(e.data);
|
|
81
|
+
document.body.append(dialogElement);
|
|
82
|
+
dialogElement.showPopover();
|
|
83
|
+
|
|
84
|
+
dialogElement.addEventListener('response', (r) => {
|
|
85
|
+
e.respondWith(r.data);
|
|
86
|
+
setTimeout(() => dialogElement.remove(), 300);
|
|
87
|
+
}, { once: true });
|
|
79
88
|
} else if (e.type === 'prompt') {
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
+
const dialogElement = document.createElement('wq-prompt');
|
|
90
|
+
dialogElement.toggleAttribute('wq-default', true);
|
|
91
|
+
|
|
92
|
+
dialogElement.render(e.data);
|
|
93
|
+
document.body.append(dialogElement);
|
|
94
|
+
dialogElement.showPopover();
|
|
95
|
+
|
|
96
|
+
dialogElement.addEventListener('response', (r) => {
|
|
97
|
+
e.respondWith(r.data);
|
|
98
|
+
setTimeout(() => dialogElement.remove(), 300);
|
|
99
|
+
}, { once: true });
|
|
100
|
+
} else if (e.type === 'status') {
|
|
101
|
+
const dialogElement = document.createElement('wq-toast');
|
|
102
|
+
dialogElement.toggleAttribute('wq-default', true);
|
|
103
|
+
|
|
104
|
+
dialogElement.render(e.data);
|
|
105
|
+
document.body.append(dialogElement);
|
|
106
|
+
dialogElement.showPopover();
|
|
107
|
+
|
|
108
|
+
dialogElement.addEventListener('toggle', (t) => {
|
|
109
|
+
if (t.newState !== 'closed') return;
|
|
110
|
+
dialogElement.remove();
|
|
111
|
+
}, { once: true });
|
|
89
112
|
}
|
|
90
113
|
});
|
|
91
114
|
};
|
|
92
|
-
this.background.addEventListener('confirm',
|
|
93
|
-
this.background.addEventListener('prompt',
|
|
94
|
-
this.background.addEventListener('
|
|
115
|
+
this.background.addEventListener('confirm', dialogHandler, { signal: instanceController.signal });
|
|
116
|
+
this.background.addEventListener('prompt', dialogHandler, { signal: instanceController.signal });
|
|
117
|
+
this.background.addEventListener('status', dialogHandler, { signal: instanceController.signal });
|
|
95
118
|
|
|
96
119
|
// ----------
|
|
97
120
|
// Call default-init
|
|
@@ -305,7 +328,7 @@ export class WebfloClient extends AppRuntime {
|
|
|
305
328
|
if (typeof cookieStore === 'undefined') {
|
|
306
329
|
const entries = document.cookie.split(';').map((c) => c.split('=').map((s) => s.trim()));
|
|
307
330
|
const store = this.#keyvals.create({ type: 'inmemory', path: ['cookies', scopeObj.tenantID], origins });
|
|
308
|
-
entries.forEach(([key, value]) => store.set(key,
|
|
331
|
+
entries.forEach(([key, value]) => store.set({ key, value }));
|
|
309
332
|
const initial = Object.fromEntries(entries);
|
|
310
333
|
scopeObj.cookies = HttpCookies101.create({
|
|
311
334
|
context: { handlersRegistry: this.#keyvals.getHandlers('cookies', true) },
|
|
@@ -440,7 +463,7 @@ export class WebfloClient extends AppRuntime {
|
|
|
440
463
|
let response = await super.dispatchNavigationEvent({ httpEvent, crossLayerFetch, clientPortB });
|
|
441
464
|
|
|
442
465
|
// Extract interactive. mode handling
|
|
443
|
-
const handleInteractiveMode = () => {
|
|
466
|
+
const handleInteractiveMode = (returnImmediate = false) => {
|
|
444
467
|
return new Promise(async (resolve) => {
|
|
445
468
|
// Must come as first thing
|
|
446
469
|
const backgroundPort = LiveResponse.getPort(response);
|
|
@@ -450,13 +473,18 @@ export class WebfloClient extends AppRuntime {
|
|
|
450
473
|
? response
|
|
451
474
|
: LiveResponse.from(response);
|
|
452
475
|
|
|
453
|
-
liveResponse.
|
|
476
|
+
await liveResponse.readyStateChange('live');
|
|
477
|
+
// IMPORTANT: ensures we're listening to subsequent changes.
|
|
478
|
+
|
|
479
|
+
liveResponse.addEventListener('replace', () => {
|
|
454
480
|
if (liveResponse.headers.get('Location')) {
|
|
455
481
|
this.processRedirect(liveResponse);
|
|
456
482
|
} else {
|
|
457
483
|
resolve(liveResponse);
|
|
458
484
|
}
|
|
459
485
|
}, { signal: httpEvent.signal });
|
|
486
|
+
|
|
487
|
+
if (returnImmediate) resolve(liveResponse);
|
|
460
488
|
});
|
|
461
489
|
};
|
|
462
490
|
|
|
@@ -495,7 +523,7 @@ export class WebfloClient extends AppRuntime {
|
|
|
495
523
|
|
|
496
524
|
// Obtain and connect clientPortB as first thing
|
|
497
525
|
if (LiveResponse.hasPort(response)) {
|
|
498
|
-
response = await handleInteractiveMode();
|
|
526
|
+
response = await handleInteractiveMode(true);
|
|
499
527
|
}
|
|
500
528
|
}
|
|
501
529
|
|
|
@@ -100,9 +100,9 @@ export class WebfloRootClientA extends WebfloClient {
|
|
|
100
100
|
scopeObj.response.headers.set(name, metaElement.content?.trim() || '');
|
|
101
101
|
}
|
|
102
102
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
103
|
+
// Must come as first thing
|
|
104
|
+
const backgroundPort = LiveResponse.getPort(scopeObj.response);
|
|
105
|
+
if (backgroundPort) this.background.addPort(backgroundPort);
|
|
106
106
|
|
|
107
107
|
if (scopeObj.response.body || scopeObj.response.port) {
|
|
108
108
|
const httpEvent = HttpEvent111.create({ request: this.createRequest(this.location.href) }, true);
|
|
@@ -1,15 +1,10 @@
|
|
|
1
1
|
import { Observer } from '@webqit/observer';
|
|
2
2
|
import { LiveResponse } from '@webqit/fetch-plus';
|
|
3
3
|
import { WebfloClient } from './WebfloClient.js';
|
|
4
|
-
import { defineElement } from './webflo-embedded.js';
|
|
5
4
|
import { _meta } from '../../util.js';
|
|
6
5
|
|
|
7
6
|
export class WebfloSubClient extends WebfloClient {
|
|
8
7
|
|
|
9
|
-
static defineElement() {
|
|
10
|
-
defineElement(this);
|
|
11
|
-
}
|
|
12
|
-
|
|
13
8
|
static create(superRuntime, host) {
|
|
14
9
|
return new this(superRuntime, host);
|
|
15
10
|
}
|
|
@@ -67,7 +62,7 @@ export class WebfloSubClient extends WebfloClient {
|
|
|
67
62
|
const locationCallback = (newHref) => {
|
|
68
63
|
this.host.reflectLocation(newHref);
|
|
69
64
|
};
|
|
70
|
-
|
|
65
|
+
|
|
71
66
|
return super.controlClassic/*IMPORTANT*/(locationCallback);
|
|
72
67
|
}
|
|
73
68
|
|
|
@@ -99,33 +94,35 @@ export class WebfloSubClient extends WebfloClient {
|
|
|
99
94
|
|
|
100
95
|
async redirect(location, response = null) {
|
|
101
96
|
location = typeof location === 'string' ? new URL(location, this.location.origin) : location;
|
|
102
|
-
|
|
97
|
+
|
|
103
98
|
const width = Math.min(800, window.innerWidth);
|
|
104
99
|
const height = Math.min(600, window.innerHeight);
|
|
105
100
|
const left = (window.outerWidth - width) / 2;
|
|
106
101
|
const top = (window.outerHeight - height) / 2;
|
|
107
102
|
const popup = window.open(location, '_blank', `popup=true,width=${width},height=${height},left=${left},top=${top}`);
|
|
108
|
-
|
|
109
|
-
const backgroundPort = response instanceof LiveResponse
|
|
103
|
+
|
|
104
|
+
const backgroundPort = response instanceof LiveResponse
|
|
110
105
|
? response.port
|
|
111
106
|
: LiveResponse.getPort(response);
|
|
107
|
+
|
|
112
108
|
if (backgroundPort) {
|
|
113
109
|
Observer.set(this.navigator, 'redirecting', new URL(location), { diff: true });
|
|
114
|
-
|
|
115
|
-
backgroundPort.readyStateChange('close').then((e) => {
|
|
116
|
-
window.removeEventListener('message', windowMessageHandler);
|
|
117
|
-
|
|
110
|
+
backgroundPort.readyStateChange('close').then(() => {
|
|
118
111
|
Observer.set(this.navigator, 'redirecting', null);
|
|
119
|
-
popup.postMessage('timeout:5');
|
|
120
|
-
|
|
121
|
-
setTimeout(() => {
|
|
122
|
-
popup.close();
|
|
123
|
-
}, 5000);
|
|
124
112
|
});
|
|
125
|
-
|
|
113
|
+
|
|
126
114
|
const windowMessageHandler = (e) => {
|
|
127
|
-
if (e.source === popup
|
|
128
|
-
|
|
115
|
+
if (e.source === popup) {
|
|
116
|
+
window.removeEventListener('message', windowMessageHandler);
|
|
117
|
+
if (e.data === 'canclose') {
|
|
118
|
+
popup.postMessage('timeout:5');
|
|
119
|
+
setTimeout(() => {
|
|
120
|
+
popup.close();
|
|
121
|
+
}, 5000);
|
|
122
|
+
}
|
|
123
|
+
if (e.data === 'closed') {
|
|
124
|
+
backgroundPort.close();
|
|
125
|
+
}
|
|
129
126
|
}
|
|
130
127
|
};
|
|
131
128
|
|
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
import { WebfloRootClientA } from './WebfloRootClientA.js';
|
|
2
2
|
import { WebfloRootClientB } from './WebfloRootClientB.js';
|
|
3
|
-
import {
|
|
3
|
+
import { defineElement } from './webflo-embedded.js';
|
|
4
|
+
import { defineElements } from './webflo-elements.js';
|
|
4
5
|
|
|
5
6
|
export async function start(bootstrap) {
|
|
6
7
|
const WebfloRootClient = window.navigation ? WebfloRootClientB : WebfloRootClientA;
|
|
7
8
|
const instance = WebfloRootClient.create(bootstrap, document);
|
|
8
9
|
await instance.initialize();
|
|
9
|
-
|
|
10
|
+
|
|
11
|
+
defineElement();
|
|
12
|
+
defineElements();
|
|
13
|
+
|
|
10
14
|
return instance;
|
|
11
15
|
}
|