@webqit/webflo 0.11.61-0 → 1.0.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 (118) hide show
  1. package/.gitignore +7 -7
  2. package/LICENSE +20 -20
  3. package/README.md +2079 -2074
  4. package/docker/Dockerfile +42 -42
  5. package/docker/README.md +91 -91
  6. package/docker/package.json +2 -2
  7. package/package.json +80 -81
  8. package/src/{Context.js → AbstractContext.js} +71 -79
  9. package/src/config-pi/deployment/Env.js +68 -68
  10. package/src/config-pi/deployment/Layout.js +63 -63
  11. package/src/config-pi/deployment/Origins.js +139 -139
  12. package/src/config-pi/deployment/Proxy.js +74 -74
  13. package/src/config-pi/deployment/index.js +17 -17
  14. package/src/config-pi/index.js +15 -15
  15. package/src/config-pi/runtime/Client.js +116 -98
  16. package/src/config-pi/runtime/Server.js +125 -125
  17. package/src/config-pi/runtime/client/Worker.js +109 -134
  18. package/src/config-pi/runtime/client/index.js +11 -11
  19. package/src/config-pi/runtime/index.js +17 -17
  20. package/src/config-pi/runtime/server/Headers.js +74 -74
  21. package/src/config-pi/runtime/server/Redirects.js +69 -69
  22. package/src/config-pi/runtime/server/index.js +13 -13
  23. package/src/config-pi/static/Manifest.js +319 -319
  24. package/src/config-pi/static/Ssg.js +49 -49
  25. package/src/config-pi/static/index.js +13 -13
  26. package/src/deployment-pi/index.js +10 -10
  27. package/src/deployment-pi/origins/index.js +216 -216
  28. package/src/index.js +11 -19
  29. package/src/runtime-pi/HttpEvent.js +126 -106
  30. package/src/runtime-pi/HttpUser.js +126 -0
  31. package/src/runtime-pi/MessagingOverBroadcast.js +9 -0
  32. package/src/runtime-pi/MessagingOverChannel.js +85 -0
  33. package/src/runtime-pi/MessagingOverSocket.js +106 -0
  34. package/src/runtime-pi/MultiportMessagingAPI.js +81 -0
  35. package/src/runtime-pi/WebfloCookieStorage.js +27 -0
  36. package/src/runtime-pi/WebfloEventTarget.js +39 -0
  37. package/src/runtime-pi/WebfloMessageEvent.js +58 -0
  38. package/src/runtime-pi/WebfloMessagingAPI.js +69 -0
  39. package/src/runtime-pi/{Router.js → WebfloRouter.js} +99 -130
  40. package/src/runtime-pi/WebfloRuntime.js +52 -0
  41. package/src/runtime-pi/WebfloStorage.js +109 -0
  42. package/src/runtime-pi/client/ClientMessaging.js +5 -0
  43. package/src/runtime-pi/client/Context.js +3 -7
  44. package/src/runtime-pi/client/CookieStorage.js +17 -0
  45. package/src/runtime-pi/client/Router.js +38 -48
  46. package/src/runtime-pi/client/SessionStorage.js +33 -0
  47. package/src/runtime-pi/client/Url.js +156 -205
  48. package/src/runtime-pi/client/WebfloClient.js +544 -0
  49. package/src/runtime-pi/client/WebfloRootClient1.js +179 -0
  50. package/src/runtime-pi/client/WebfloRootClient2.js +109 -0
  51. package/src/runtime-pi/client/WebfloSubClient.js +165 -0
  52. package/src/runtime-pi/client/Workport.js +118 -178
  53. package/src/runtime-pi/client/generate.js +480 -471
  54. package/src/runtime-pi/client/index.js +16 -21
  55. package/src/runtime-pi/client/worker/ClientMessaging.js +5 -0
  56. package/src/runtime-pi/client/worker/Context.js +3 -7
  57. package/src/runtime-pi/client/worker/CookieStorage.js +17 -0
  58. package/src/runtime-pi/client/worker/SessionStorage.js +13 -0
  59. package/src/runtime-pi/client/worker/WebfloWorker.js +294 -0
  60. package/src/runtime-pi/client/worker/Workport.js +17 -85
  61. package/src/runtime-pi/client/worker/index.js +10 -21
  62. package/src/runtime-pi/index.js +6 -13
  63. package/src/runtime-pi/server/ClientMessaging.js +18 -0
  64. package/src/runtime-pi/server/ClientMessagingRegistry.js +57 -0
  65. package/src/runtime-pi/server/Context.js +11 -15
  66. package/src/runtime-pi/server/CookieStorage.js +17 -0
  67. package/src/runtime-pi/server/Router.js +93 -159
  68. package/src/runtime-pi/server/SessionStorage.js +53 -0
  69. package/src/runtime-pi/server/WebfloServer.js +755 -0
  70. package/src/runtime-pi/server/index.js +10 -21
  71. package/src/runtime-pi/util-http.js +322 -86
  72. package/src/runtime-pi/util-url.js +146 -146
  73. package/src/runtime-pi/xURL.js +108 -105
  74. package/src/runtime-pi/xfetch.js +22 -22
  75. package/src/services-pi/cert/http-auth-hook.js +22 -22
  76. package/src/services-pi/cert/http-cleanup-hook.js +22 -22
  77. package/src/services-pi/cert/index.js +79 -79
  78. package/src/services-pi/index.js +8 -8
  79. package/src/static-pi/index.js +10 -10
  80. package/src/webflo.js +30 -30
  81. package/test/index.test.js +26 -26
  82. package/test/site/package.json +9 -9
  83. package/test/site/public/bundle.html +5 -5
  84. package/test/site/public/bundle.html.json +3 -3
  85. package/test/site/public/bundle.js +2 -2
  86. package/test/site/public/bundle.webflo.js +15 -15
  87. package/test/site/public/index.html +29 -29
  88. package/test/site/public/index1.html +34 -34
  89. package/test/site/public/page-2/bundle.html +4 -4
  90. package/test/site/public/page-2/bundle.js +2 -2
  91. package/test/site/public/page-2/index.html +45 -45
  92. package/test/site/public/page-2/main.html +2 -2
  93. package/test/site/public/page-4/subpage/bundle.js +2 -2
  94. package/test/site/public/page-4/subpage/index.html +30 -30
  95. package/test/site/public/sparoots.json +4 -4
  96. package/test/site/public/worker.js +3 -3
  97. package/test/site/server/index.js +15 -15
  98. package/src/runtime-pi/Application.js +0 -29
  99. package/src/runtime-pi/Cookies.js +0 -82
  100. package/src/runtime-pi/Runtime.js +0 -21
  101. package/src/runtime-pi/client/Application.js +0 -100
  102. package/src/runtime-pi/client/Runtime.js +0 -332
  103. package/src/runtime-pi/client/createStorage.js +0 -57
  104. package/src/runtime-pi/client/oohtml/full.js +0 -7
  105. package/src/runtime-pi/client/oohtml/namespacing.js +0 -7
  106. package/src/runtime-pi/client/oohtml/scripting.js +0 -8
  107. package/src/runtime-pi/client/oohtml/templating.js +0 -8
  108. package/src/runtime-pi/client/worker/Application.js +0 -44
  109. package/src/runtime-pi/client/worker/Runtime.js +0 -269
  110. package/src/runtime-pi/server/Application.js +0 -116
  111. package/src/runtime-pi/server/Runtime.js +0 -557
  112. package/src/runtime-pi/xFormData.js +0 -24
  113. package/src/runtime-pi/xHeaders.js +0 -146
  114. package/src/runtime-pi/xRequest.js +0 -46
  115. package/src/runtime-pi/xRequestHeaders.js +0 -109
  116. package/src/runtime-pi/xResponse.js +0 -33
  117. package/src/runtime-pi/xResponseHeaders.js +0 -117
  118. package/src/runtime-pi/xxHttpMessage.js +0 -102
@@ -1,178 +1,118 @@
1
-
2
-
3
- /**
4
- * @imports
5
- */
6
- import { _isFunction, _isObject } from '@webqit/util/js/index.js';
7
- import { Observer } from './Runtime.js';
8
-
9
- export default class Workport {
10
-
11
- constructor(file, params = {}) {
12
- this.ready = navigator.serviceWorker ? navigator.serviceWorker.ready : new Promise(() => {});
13
-
14
- // --------
15
- // Registration and lifecycle
16
- // --------
17
- this.registration = new Promise((resolve, reject) => {
18
- if (!navigator.serviceWorker) return;
19
- const register = () => {
20
- navigator.serviceWorker.register(file, { scope: params.scope || '/' }).then(async registration => {
21
-
22
- // Helper that updates instance's state
23
- const state = target => {
24
- // instance2.state can be any of: "installing", "installed", "activating", "activated", "redundant"
25
- const equivState = target.state === 'installed' ? 'waiting' :
26
- (target.state === 'activating' || target.state === 'activated' ? 'active' : target.state)
27
- Observer.set(this, equivState, target);
28
- }
29
-
30
- // We're always installing at first for a new service worker.
31
- // An existing service would immediately be active
32
- const worker = registration.active || registration.waiting || registration.installing;
33
- state(worker);
34
- worker.addEventListener('statechange', e => state(e.target));
35
-
36
- // "updatefound" event - a new worker that will control
37
- // this page is installing somewhere
38
- registration.addEventListener('updatefound', () => {
39
- // If updatefound is fired, it means that there's
40
- // a new service worker being installed.
41
- state(registration.installing);
42
- registration.installing.addEventListener('statechange', e => state(e.target));
43
- });
44
-
45
- resolve(registration);
46
- }).catch(e => reject(e));
47
- };
48
- if (params.onWindowLoad) {
49
- window.addEventListener('load', register);
50
- } else {
51
- register();
52
- }
53
- if (params.startMessages) {
54
- navigator.serviceWorker.startMessages();
55
- }
56
- });
57
-
58
- // --------
59
- // Post messaging
60
- // --------
61
- const postSendCallback = (message, callback, onAvailability = 1) => {
62
- if (this.active) {
63
- if (_isFunction(message)) message = message();
64
- callback(this.active, message);
65
- } else if (onAvailability) {
66
- // Availability Handling
67
- const availabilityHandler = entry => {
68
- if (_isFunction(message)) message = message();
69
- callback(entry.value, message);
70
- if (onAvailability !== 2) {
71
- Observer.unobserve(this, 'active', availabilityHandler);
72
- }
73
- };
74
- Observer.observe(this, 'active', availabilityHandler);
75
- }
76
- };
77
- this.messaging = {
78
- post: (message, onAvailability = 1) => {
79
- postSendCallback(message, (active, message) => {
80
- active.postMessage(message);
81
- }, onAvailability);
82
- return this.post;
83
- },
84
- listen: callback => {
85
- if (navigator.serviceWorker) {
86
- navigator.serviceWorker.addEventListener('message', evt => {
87
- const response = callback(evt);
88
- let responsePort = evt.ports[0];
89
- if (responsePort) {
90
- if (response instanceof Promise) {
91
- response.then(data => {
92
- responsePort.postMessage(data);
93
- });
94
- } else {
95
- responsePort.postMessage(response);
96
- }
97
- }
98
- });
99
- }
100
- return this.post;
101
- },
102
- request: (message, onAvailability = 1) => {
103
- return new Promise(res => {
104
- postSendCallback(message, (active, message) => {
105
- let messageChannel = new MessageChannel();
106
- active.postMessage(message, [ messageChannel.port2 ]);
107
- messageChannel.port1.onmessage = e => res(e.data);
108
- }, onAvailability);
109
- });
110
- },
111
- channel(channelId) {
112
- if (!this.channels.has(channelId)) { this.channels.set(channelId, new BroadcastChannel(channel)); }
113
- let channel = this.channels.get(channelId);
114
- return {
115
- broadcast: message => channel.postMessage(message),
116
- listen: callback => channel.addEventListener('message', callback),
117
- };
118
- },
119
- channels: new Map,
120
- };
121
-
122
- // --------
123
- // Notifications
124
- // --------
125
- this.notifications = {
126
- fire: (title, params = {}) => {
127
- return new Promise((res, rej) => {
128
- if (typeof Notification === 'undefined' || Notification.permission !== 'granted') {
129
- return rej(typeof Notification !== 'undefined' && Notification && Notification.permission);
130
- }
131
- notification.addEventListener('error', rej);
132
- let notification = new Notification(title, params);
133
- notification.addEventListener('click', res);
134
- notification.addEventListener('close', res);
135
- });
136
- },
137
- };
138
-
139
- // --------
140
- // Push notifications
141
- // --------
142
- this.push = {
143
- getSubscription: async () => {
144
- return (await this.registration).pushManager.getSubscription();
145
- },
146
- subscribe: async (publicKey, params = {}) => {
147
- var subscription = await this.push.getSubscription();
148
- return subscription ? subscription : (await this.registration).pushManager.subscribe(
149
- _isObject(publicKey) ? publicKey : {
150
- applicationServerKey: urlBase64ToUint8Array(publicKey),
151
- ...params,
152
- }
153
- );
154
- },
155
- unsubscribe: async () => {
156
- var subscription = await this.push.getSubscription();
157
- return !subscription ? null : subscription.unsubscribe();
158
- },
159
- };
160
- }
161
-
162
- }
163
-
164
- // Public base64 to Uint
165
- function urlBase64ToUint8Array(base64String) {
166
- var padding = '='.repeat((4 - base64String.length % 4) % 4);
167
- var base64 = (base64String + padding)
168
- .replace(/\-/g, '+')
169
- .replace(/_/g, '/');
170
-
171
- var rawData = window.atob(base64);
172
- var outputArray = new Uint8Array(rawData.length);
173
-
174
- for (var i = 0; i < rawData.length; ++i) {
175
- outputArray[i] = rawData.charCodeAt(i);
176
- }
177
- return outputArray;
178
- }
1
+ export class Workport {
2
+
3
+ #swFile;
4
+ #swParams = {};
5
+
6
+ #swReady;
7
+ get swReady() { return this.#swReady; }
8
+ #swRegistration;
9
+
10
+ async registerServiceWorker(file, params = {}) {
11
+ if (this.#swRegistration) {
12
+ throw new Error('Service worker already registered');
13
+ }
14
+ this.#swFile = file;
15
+ this.#swParams = params;
16
+ this.#swReady = navigator.serviceWorker ? navigator.serviceWorker.ready : new Promise(() => {});
17
+ this.#swRegistration = await navigator.serviceWorker.register(this.#swFile, { scope: this.#swParams.scope || '/' });
18
+ // Helper that updates instance's state
19
+ const stateChange = (target) => {
20
+ // target.state can be any of: "parsed", "installing", "installed", "activating", "activated", "redundant"
21
+ if (target.state === 'redundant') {
22
+ this.remove(target);
23
+ } else if (target.state === 'activated') {
24
+ this.add(target);
25
+ }
26
+ }
27
+ // We're always installing at first for a new service worker.
28
+ // An existing service would immediately be active
29
+ const worker = this.#swRegistration.active || this.#swRegistration.waiting || this.#swRegistration.installing;
30
+ if (worker) {
31
+ stateChange(worker);
32
+ worker.addEventListener('statechange', (e) => stateChange(e.target));
33
+ // "updatefound" event - a new worker that will control
34
+ // this page is installing somewhere
35
+ this.#swRegistration.addEventListener('updatefound', () => {
36
+ // If updatefound is fired, it means that there's
37
+ // a new service worker being installed.
38
+ stateChange(this.#swRegistration.installing);
39
+ this.#swRegistration.installing.addEventListener('statechange', (e) => stateChange(e.target));
40
+ });
41
+ }
42
+ }
43
+
44
+ async requestNotificationPermission() {
45
+ return await new Promise(async (resolve, reject) => {
46
+ const permissionResult = Notification.requestPermission(resolve);
47
+ if (permissionResult) {
48
+ permissionResult.then(resolve, reject);
49
+ }
50
+ });
51
+ }
52
+
53
+ async showNotification(title, params = {}) {
54
+ await this.#swReady;
55
+ if (this.#swRegistration) {
56
+ return (await this.#swRegistration).showNotification(title, params);
57
+ }
58
+ return new Notification(title, params);
59
+ }
60
+
61
+ async pushSubscription(autoPrompt = true) {
62
+ if (!this.#swRegistration) {
63
+ throw new Error(`Service worker not registered`);
64
+ }
65
+ await this.#swReady;
66
+ const pushManager = (await this.#swRegistration).pushManager;
67
+ let subscription = await pushManager.getSubscription();
68
+ if (!subscription && autoPrompt && this.#swParams.VAPID_PUBLIC_KEY) {
69
+ subscription = await pushManager.subscribe({
70
+ userVisibleOnly: true,
71
+ applicationServerKey: urlBase64ToUint8Array(this.#swParams.VAPID_PUBLIC_KEY),
72
+ });
73
+ if (this.#swParams.PUSH_REGISTRATION_PUBLIC_URL) {
74
+ await fetch(this.#swParams.PUSH_REGISTRATION_PUBLIC_URL, {
75
+ method: 'POST',
76
+ headers: { 'Content-Type': 'application/json', },
77
+ body: JSON.stringify(subscription)
78
+ });
79
+ }
80
+ }
81
+ return subscription;
82
+ }
83
+
84
+ async pushUnsubscribe() {
85
+ if (!this.#swRegistration) {
86
+ throw new Error(`Service worker not registered`);
87
+ }
88
+ await this.#swReady;
89
+ const pushManager = (await this.#swRegistration).pushManager;
90
+ const subscription = await pushManager.getSubscription();
91
+ if (subscription) {
92
+ subscription.unsubscribe();
93
+ if (subscription && this.#swParams.PUSH_REGISTRATION_PUBLIC_URL) {
94
+ await fetch(this.#swParams.PUSH_REGISTRATION_PUBLIC_URL, {
95
+ method: 'DELETE',
96
+ headers: { 'Content-Type': 'application/json', },
97
+ body: JSON.stringify(subscription)
98
+ });
99
+ }
100
+ }
101
+ }
102
+ }
103
+
104
+ // Public base64 to Uint
105
+ function urlBase64ToUint8Array(base64String) {
106
+ var padding = '='.repeat((4 - base64String.length % 4) % 4);
107
+ var base64 = (base64String + padding)
108
+ .replace(/\-/g, '+')
109
+ .replace(/_/g, '/');
110
+
111
+ var rawData = window.atob(base64);
112
+ var outputArray = new Uint8Array(rawData.length);
113
+
114
+ for (var i = 0; i < rawData.length; ++i) {
115
+ outputArray[i] = rawData.charCodeAt(i);
116
+ }
117
+ return outputArray;
118
+ }