@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.
Files changed (235) hide show
  1. package/.github/FUNDING.yml +12 -0
  2. package/.github/workflows/publish.yml +48 -0
  3. package/.gitignore +2 -0
  4. package/LICENSE +2 -2
  5. package/README.md +71 -2050
  6. package/package.json +28 -13
  7. package/site/-/_.md +139 -0
  8. package/site/-/docs.old.md +2010 -0
  9. package/site/.vitepress/cache/deps/@braintree_sanitize-url 2.js +93 -0
  10. package/site/.vitepress/cache/deps/@braintree_sanitize-url.js +93 -0
  11. package/site/.vitepress/cache/deps/@braintree_sanitize-url.js 2.map +7 -0
  12. package/site/.vitepress/cache/deps/@braintree_sanitize-url.js.map +7 -0
  13. package/site/.vitepress/cache/deps/_metadata 2.json +85 -0
  14. package/site/.vitepress/cache/deps/_metadata.json +85 -0
  15. package/site/.vitepress/cache/deps/chunk-BUSYA2B4 2.js +9 -0
  16. package/site/.vitepress/cache/deps/chunk-BUSYA2B4.js +9 -0
  17. package/site/.vitepress/cache/deps/chunk-BUSYA2B4.js 2.map +7 -0
  18. package/site/.vitepress/cache/deps/chunk-BUSYA2B4.js.map +7 -0
  19. package/site/.vitepress/cache/deps/chunk-Q2AYPHVK 2.js +9719 -0
  20. package/site/.vitepress/cache/deps/chunk-Q2AYPHVK.js +9719 -0
  21. package/site/.vitepress/cache/deps/chunk-Q2AYPHVK.js 2.map +7 -0
  22. package/site/.vitepress/cache/deps/chunk-Q2AYPHVK.js.map +7 -0
  23. package/site/.vitepress/cache/deps/chunk-QAXAIFA7 2.js +12705 -0
  24. package/site/.vitepress/cache/deps/chunk-QAXAIFA7.js +12705 -0
  25. package/site/.vitepress/cache/deps/chunk-QAXAIFA7.js 2.map +7 -0
  26. package/site/.vitepress/cache/deps/chunk-QAXAIFA7.js.map +7 -0
  27. package/site/.vitepress/cache/deps/cytoscape 2.js +30278 -0
  28. package/site/.vitepress/cache/deps/cytoscape-cose-bilkent 2.js +4710 -0
  29. package/site/.vitepress/cache/deps/cytoscape-cose-bilkent.js +4710 -0
  30. package/site/.vitepress/cache/deps/cytoscape-cose-bilkent.js 2.map +7 -0
  31. package/site/.vitepress/cache/deps/cytoscape-cose-bilkent.js.map +7 -0
  32. package/site/.vitepress/cache/deps/cytoscape.js +30278 -0
  33. package/site/.vitepress/cache/deps/cytoscape.js 2.map +7 -0
  34. package/site/.vitepress/cache/deps/cytoscape.js.map +7 -0
  35. package/site/.vitepress/cache/deps/dayjs 2.js +285 -0
  36. package/site/.vitepress/cache/deps/dayjs.js +285 -0
  37. package/site/.vitepress/cache/deps/dayjs.js 2.map +7 -0
  38. package/site/.vitepress/cache/deps/dayjs.js.map +7 -0
  39. package/site/.vitepress/cache/deps/debug 2.js +453 -0
  40. package/site/.vitepress/cache/deps/debug.js +453 -0
  41. package/site/.vitepress/cache/deps/debug.js 2.map +7 -0
  42. package/site/.vitepress/cache/deps/debug.js.map +7 -0
  43. package/site/.vitepress/cache/deps/package 2.json +3 -0
  44. package/site/.vitepress/cache/deps/package.json +3 -0
  45. package/site/.vitepress/cache/deps/vitepress___@vue_devtools-api 2.js +4507 -0
  46. package/site/.vitepress/cache/deps/vitepress___@vue_devtools-api.js +4507 -0
  47. package/site/.vitepress/cache/deps/vitepress___@vue_devtools-api.js 2.map +7 -0
  48. package/site/.vitepress/cache/deps/vitepress___@vue_devtools-api.js.map +7 -0
  49. package/site/.vitepress/cache/deps/vitepress___@vueuse_core 2.js +584 -0
  50. package/site/.vitepress/cache/deps/vitepress___@vueuse_core.js +584 -0
  51. package/site/.vitepress/cache/deps/vitepress___@vueuse_core.js 2.map +7 -0
  52. package/site/.vitepress/cache/deps/vitepress___@vueuse_core.js.map +7 -0
  53. package/site/.vitepress/cache/deps/vitepress___@vueuse_integrations_useFocusTrap 2.js +1166 -0
  54. package/site/.vitepress/cache/deps/vitepress___@vueuse_integrations_useFocusTrap.js +1166 -0
  55. package/site/.vitepress/cache/deps/vitepress___@vueuse_integrations_useFocusTrap.js 2.map +7 -0
  56. package/site/.vitepress/cache/deps/vitepress___@vueuse_integrations_useFocusTrap.js.map +7 -0
  57. package/site/.vitepress/cache/deps/vitepress___mark__js_src_vanilla__js 2.js +1667 -0
  58. package/site/.vitepress/cache/deps/vitepress___mark__js_src_vanilla__js.js +1667 -0
  59. package/site/.vitepress/cache/deps/vitepress___mark__js_src_vanilla__js.js 2.map +7 -0
  60. package/site/.vitepress/cache/deps/vitepress___mark__js_src_vanilla__js.js.map +7 -0
  61. package/site/.vitepress/cache/deps/vitepress___minisearch 2.js +1815 -0
  62. package/site/.vitepress/cache/deps/vitepress___minisearch.js +1815 -0
  63. package/site/.vitepress/cache/deps/vitepress___minisearch.js 2.map +7 -0
  64. package/site/.vitepress/cache/deps/vitepress___minisearch.js.map +7 -0
  65. package/site/.vitepress/cache/deps/vue 2.js +344 -0
  66. package/site/.vitepress/cache/deps/vue.js +344 -0
  67. package/site/.vitepress/cache/deps/vue.js 2.map +7 -0
  68. package/site/.vitepress/cache/deps/vue.js.map +7 -0
  69. package/site/.vitepress/config.ts +147 -0
  70. package/site/.vitepress/theme/custom.css +50 -0
  71. package/site/.vitepress/theme/index.ts +6 -0
  72. package/site/api/webflo-fetch/FormData.md +0 -0
  73. package/site/api/webflo-fetch/Headers.md +0 -0
  74. package/site/api/webflo-fetch/LiveResponse.md +0 -0
  75. package/site/api/webflo-fetch/Request.md +0 -0
  76. package/site/api/webflo-fetch/Response.md +0 -0
  77. package/site/api/webflo-fetch/fetch.md +0 -0
  78. package/site/api/webflo-routing/HttpCookies.md +0 -0
  79. package/site/api/webflo-routing/HttpEvent/respondWith.md +1 -0
  80. package/site/api/webflo-routing/HttpEvent/waitUntil.md +1 -0
  81. package/site/api/webflo-routing/HttpEvent/waitUntilNavigate.md +1 -0
  82. package/site/api/webflo-routing/HttpEvent.md +30 -0
  83. package/site/api/webflo-routing/HttpSession.md +0 -0
  84. package/site/api/webflo-routing/HttpState.md +0 -0
  85. package/site/api/webflo-routing/HttpUser.md +0 -0
  86. package/site/api/webflo-routing/handler/fetch.md +42 -0
  87. package/site/api/webflo-routing/handler/next.md +54 -0
  88. package/site/api/webflo-routing/handler.md +119 -0
  89. package/site/api.md +26 -0
  90. package/site/contributing.md +16 -0
  91. package/site/docs/advanced/lifecycles.md +20 -0
  92. package/site/docs/advanced/redirects.md +0 -0
  93. package/site/docs/advanced/routing.md +1 -0
  94. package/site/docs/advanced.md +9 -0
  95. package/site/docs/concepts/realtime.md +637 -0
  96. package/site/docs/concepts/rendering.md +60 -0
  97. package/site/docs/concepts/request-response.md +47 -0
  98. package/site/docs/concepts/routing.md +656 -0
  99. package/site/docs/concepts/state.md +44 -0
  100. package/site/docs/concepts/templates.md +48 -0
  101. package/site/docs/concepts.md +97 -0
  102. package/site/docs/getting-started.md +378 -0
  103. package/site/docs/tech-stack.md +56 -0
  104. package/site/docs.md +100 -0
  105. package/site/examples/pwa.md +10 -0
  106. package/site/examples/web.md +11 -0
  107. package/site/examples.md +10 -0
  108. package/site/faq.md +13 -0
  109. package/site/guides/guide-auth.md +13 -0
  110. package/site/guides/guide-file-upload.md +11 -0
  111. package/site/guides/guide-service-worker.md +10 -0
  112. package/site/guides/tutorial-1-todo.md +24 -0
  113. package/site/guides.md +15 -0
  114. package/site/index.md +39 -0
  115. package/site/public/img/brand/logo-670x670.png +0 -0
  116. package/site/recipes/realtime.md +11 -0
  117. package/site/recipes/streaming.md +15 -0
  118. package/site/reference/cli.md +11 -0
  119. package/site/reference/config.md +13 -0
  120. package/site/reference/tools.md +9 -0
  121. package/src/Context.js +3 -11
  122. package/src/config-pi/deployment/Env.js +6 -19
  123. package/src/config-pi/deployment/Layout.js +11 -3
  124. package/src/config-pi/runtime/Client.js +40 -48
  125. package/src/config-pi/runtime/Server.js +52 -20
  126. package/src/config-pi/runtime/client/Worker.js +22 -20
  127. package/src/config-pi/static/Init.js +57 -0
  128. package/src/config-pi/static/index.js +2 -0
  129. package/src/deployment-pi/origins/index.js +1 -1
  130. package/src/deployment-pi/util.js +161 -0
  131. package/src/index.js +3 -9
  132. package/src/init-pi/index.js +117 -0
  133. package/src/init-pi/templates/pwa/app/handler.server.js +8 -0
  134. package/src/init-pi/templates/pwa/app/page.html +7 -0
  135. package/src/init-pi/templates/pwa/package.json +19 -0
  136. package/src/init-pi/templates/pwa/public/assets/app.css +16 -0
  137. package/src/init-pi/templates/pwa/public/index.html +39 -0
  138. package/src/init-pi/templates/pwa/public/manifest.json +29 -0
  139. package/src/init-pi/templates/web/app/handler.server.js +8 -0
  140. package/src/init-pi/templates/web/app/page.html +7 -0
  141. package/src/init-pi/templates/web/package.json +19 -0
  142. package/src/init-pi/templates/web/public/assets/app.css +16 -0
  143. package/src/init-pi/templates/web/public/index.html +39 -0
  144. package/src/runtime-pi/WebfloRuntime.js +350 -0
  145. package/src/runtime-pi/index.js +3 -10
  146. package/src/runtime-pi/webflo-client/ClientSideCookies.js +17 -0
  147. package/src/runtime-pi/webflo-client/ClientSideWorkport.js +63 -0
  148. package/src/runtime-pi/webflo-client/DeviceCapabilities.js +213 -0
  149. package/src/runtime-pi/webflo-client/WebfloClient.js +500 -0
  150. package/src/runtime-pi/webflo-client/WebfloRootClient1.js +206 -0
  151. package/src/runtime-pi/webflo-client/WebfloRootClient2.js +113 -0
  152. package/src/runtime-pi/webflo-client/WebfloSubClient.js +118 -0
  153. package/src/runtime-pi/webflo-client/index.js +17 -0
  154. package/src/runtime-pi/webflo-client/webflo-codegen.js +469 -0
  155. package/src/runtime-pi/webflo-client/webflo-devmode.js +243 -0
  156. package/src/runtime-pi/webflo-client/webflo-embedded.js +50 -0
  157. package/src/runtime-pi/webflo-fetch/LiveResponse.js +437 -0
  158. package/src/runtime-pi/webflo-fetch/cookies.js +10 -0
  159. package/src/runtime-pi/webflo-fetch/fetch.js +16 -0
  160. package/src/runtime-pi/webflo-fetch/formdata.js +54 -0
  161. package/src/runtime-pi/webflo-fetch/headers.js +151 -0
  162. package/src/runtime-pi/webflo-fetch/index.js +5 -0
  163. package/src/runtime-pi/webflo-fetch/message.js +49 -0
  164. package/src/runtime-pi/webflo-fetch/request.js +62 -0
  165. package/src/runtime-pi/webflo-fetch/response.js +110 -0
  166. package/src/runtime-pi/webflo-fetch/util.js +28 -0
  167. package/src/runtime-pi/webflo-messaging/WQBroadcastChannel.js +10 -0
  168. package/src/runtime-pi/webflo-messaging/WQMessageChannel.js +26 -0
  169. package/src/runtime-pi/webflo-messaging/WQMessageEvent.js +87 -0
  170. package/src/runtime-pi/webflo-messaging/WQMessagePort.js +38 -0
  171. package/src/runtime-pi/webflo-messaging/WQRelayPort.js +47 -0
  172. package/src/runtime-pi/webflo-messaging/WQSockPort.js +113 -0
  173. package/src/runtime-pi/webflo-messaging/WQStarPort.js +104 -0
  174. package/src/runtime-pi/webflo-messaging/wq-message-port.js +404 -0
  175. package/src/runtime-pi/webflo-routing/HttpCookies.js +42 -0
  176. package/src/runtime-pi/webflo-routing/HttpEvent.js +112 -0
  177. package/src/runtime-pi/webflo-routing/HttpSession.js +11 -0
  178. package/src/runtime-pi/webflo-routing/HttpState.js +153 -0
  179. package/src/runtime-pi/webflo-routing/HttpUser.js +54 -0
  180. package/src/runtime-pi/webflo-routing/WebfloRouter.js +245 -0
  181. package/src/runtime-pi/webflo-server/ServerSideCookies.js +19 -0
  182. package/src/runtime-pi/webflo-server/ServerSideSession.js +38 -0
  183. package/src/runtime-pi/webflo-server/WebfloServer.js +937 -0
  184. package/src/runtime-pi/webflo-server/index.js +11 -0
  185. package/src/runtime-pi/webflo-server/messaging/Client.js +27 -0
  186. package/src/runtime-pi/webflo-server/messaging/ClientRequestRealtime.js +50 -0
  187. package/src/runtime-pi/webflo-server/messaging/Clients.js +25 -0
  188. package/src/runtime-pi/webflo-server/webflo-devmode.js +326 -0
  189. package/src/runtime-pi/{client → webflo-url}/Url.js +27 -76
  190. package/src/runtime-pi/webflo-url/index.js +1 -0
  191. package/src/runtime-pi/webflo-url/urlpattern.js +38 -0
  192. package/src/runtime-pi/{util-url.js → webflo-url/util.js} +5 -43
  193. package/src/runtime-pi/webflo-url/xURL.js +94 -0
  194. package/src/runtime-pi/webflo-worker/WebfloWorker.js +234 -0
  195. package/src/runtime-pi/webflo-worker/WorkerSideCookies.js +19 -0
  196. package/src/runtime-pi/webflo-worker/WorkerSideWorkport.js +18 -0
  197. package/src/runtime-pi/webflo-worker/index.js +11 -0
  198. package/src/services-pi/index.js +2 -0
  199. package/src/services-pi/push/index.js +23 -0
  200. package/src/util.js +10 -0
  201. package/src/{webflo.js → webflo-cli.js} +4 -4
  202. package/src/runtime-pi/Application.js +0 -29
  203. package/src/runtime-pi/Cookies.js +0 -82
  204. package/src/runtime-pi/HttpEvent.js +0 -107
  205. package/src/runtime-pi/Router.js +0 -130
  206. package/src/runtime-pi/Runtime.js +0 -21
  207. package/src/runtime-pi/client/Application.js +0 -76
  208. package/src/runtime-pi/client/Context.js +0 -7
  209. package/src/runtime-pi/client/Router.js +0 -48
  210. package/src/runtime-pi/client/Runtime.js +0 -525
  211. package/src/runtime-pi/client/Workport.js +0 -190
  212. package/src/runtime-pi/client/createStorage.js +0 -58
  213. package/src/runtime-pi/client/generate.js +0 -481
  214. package/src/runtime-pi/client/index.js +0 -21
  215. package/src/runtime-pi/client/worker/Application.js +0 -44
  216. package/src/runtime-pi/client/worker/Context.js +0 -7
  217. package/src/runtime-pi/client/worker/Runtime.js +0 -275
  218. package/src/runtime-pi/client/worker/Workport.js +0 -78
  219. package/src/runtime-pi/client/worker/index.js +0 -21
  220. package/src/runtime-pi/server/Application.js +0 -101
  221. package/src/runtime-pi/server/Context.js +0 -16
  222. package/src/runtime-pi/server/Router.js +0 -159
  223. package/src/runtime-pi/server/Runtime.js +0 -558
  224. package/src/runtime-pi/server/index.js +0 -21
  225. package/src/runtime-pi/util-http.js +0 -86
  226. package/src/runtime-pi/xFormData.js +0 -24
  227. package/src/runtime-pi/xHeaders.js +0 -146
  228. package/src/runtime-pi/xRequest.js +0 -46
  229. package/src/runtime-pi/xRequestHeaders.js +0 -109
  230. package/src/runtime-pi/xResponse.js +0 -33
  231. package/src/runtime-pi/xResponseHeaders.js +0 -117
  232. package/src/runtime-pi/xURL.js +0 -105
  233. package/src/runtime-pi/xfetch.js +0 -23
  234. package/src/runtime-pi/xxHttpMessage.js +0 -102
  235. package/src/static-pi/index.js +0 -11
@@ -1,481 +0,0 @@
1
-
2
- /**
3
- * imports
4
- */
5
- import Fs from 'fs';
6
- import Url from 'url';
7
- import Path from 'path';
8
- import Jsdom from 'jsdom';
9
- import EsBuild from 'esbuild';
10
- import { _afterLast, _beforeLast } from '@webqit/util/str/index.js';
11
- import { _isObject, _isArray } from '@webqit/util/js/index.js';
12
- import { jsFile } from '@webqit/backpack/src/dotfile/index.js';
13
- import { gzipSync, brotliCompressSync } from 'zlib';
14
- import { pattern } from '../util-url.js';
15
-
16
- /**
17
- * @generate
18
- */
19
- export async function generate() {
20
- const cx = this || {};
21
- // -----------
22
- if (!cx.config.runtime?.Client) {
23
- throw new Error(`The Client configurator "config.runtime.Client" is required in context.`);
24
- }
25
- if (!cx.config.deployment?.Layout) {
26
- throw new Error(`The Client configurator "config.deployment.Layout" is required in context.`);
27
- }
28
- const clientConfig = await (new cx.config.runtime.Client(cx)).read();
29
- if (clientConfig.service_worker?.filename && !cx.config.runtime.client?.Worker) {
30
- throw new Error(`The Service Worker configurator "config.runtime.client.Worker" is required in context.`);
31
- }
32
- const workerConfig = await (new cx.config.runtime.client.Worker(cx)).read();
33
- // -----------
34
- if (!cx.config.deployment?.Layout) {
35
- throw new Error(`The Layout configurator "config.deployment.Layout" is required in context.`);
36
- }
37
- const layoutConfig = await (new cx.config.deployment.Layout(cx)).read();
38
- // -----------
39
- const dirPublic = Path.resolve(cx.CWD || '', layoutConfig.PUBLIC_DIR);
40
- const dirClient = Path.resolve(cx.CWD || '', layoutConfig.CLIENT_DIR);
41
- const dirWorker = Path.resolve(cx.CWD || '', layoutConfig.WORKER_DIR);
42
- const dirSelf = Path.dirname(Url.fileURLToPath(import.meta.url)).replace(/\\/g, '/');
43
- if (clientConfig.bundle_public_env || workerConfig.bundle_public_env) {
44
- if (!cx.config.deployment?.Env) {
45
- throw new Error(`The Layout configurator "config.deployment.Env" is required in context to bundle public env.`);
46
- }
47
- const envConfig = await (new cx.config.deployment.Env(cx)).read();
48
- for (const key in envConfig.entries) {
49
- if (!key.includes('PUBLIC_')) continue;
50
- if (clientConfig.bundle_public_env) {
51
- if (!clientConfig.env) { clientConfig.env = {}; }
52
- clientConfig.env[key] = envConfig.entries[key];
53
- }
54
- if (workerConfig.bundle_public_env) {
55
- if (!workerConfig.env) { workerConfig.env = {}; }
56
- workerConfig.env[key] = envConfig.entries[key];
57
- }
58
- }
59
- }
60
- // -----------
61
- // Scan Subdocuments
62
- const scanSubroots = (sparoot, rootFileName) => {
63
- let dir = Path.join(dirPublic, sparoot), passes = 0;
64
- return [ Fs.readdirSync(dir).reduce((sparoots, f) => {
65
- let resource = Path.join(dir, f);
66
- if (Fs.statSync(resource).isDirectory()) {
67
- let subsparoot = Path.join(sparoot, f);
68
- if (Fs.existsSync(Path.join(resource, rootFileName))) {
69
- return sparoots.concat(subsparoot);
70
- }
71
- passes ++;
72
- return sparoots.concat(scanSubroots(subsparoot, rootFileName)[ 0 ]);
73
- }
74
- return sparoots;
75
- }, []), passes ];
76
- };
77
- // -----------
78
- // Generate client build
79
- const generateClient = async function(sparoot, spaGraphCallback = null) {
80
- let [ subsparoots, targets ] = (sparoot && scanSubroots(sparoot, 'index.html')) || [ [], false ];
81
- if (!sparoot) sparoot = '/';
82
- let spaRouting = { root: sparoot, subroots: subsparoots, targets };
83
- let codeSplitting = !!(sparoot !== '/' || subsparoots.length);
84
- let outfileMain = Path.join(sparoot, clientConfig.bundle_filename),
85
- outfileWebflo = _beforeLast(clientConfig.bundle_filename, '.js') + '.webflo.js';
86
- let gen = { imports: {}, code: [], };
87
- // ------------------
88
- const initWebflo = gen => {
89
- gen.imports[`${dirSelf}/index.js`] = `* as Webflo`;
90
- gen.code.push(``);
91
- gen.code.push(`if (!self.webqit) {self.webqit = {};}`);
92
- gen.code.push(`webqit.Webflo = Webflo`);
93
- return gen;
94
- };
95
- // ------------------
96
- if (!codeSplitting) {
97
- initWebflo(gen);
98
- } else if (sparoot === '/') {
99
- if (cx.logger) {
100
- cx.logger.log(cx.logger.style.keyword(`-----------------`));
101
- cx.logger.log(`Base Build`);
102
- cx.logger.log(cx.logger.style.keyword(`-----------------`));
103
- }
104
- let gen1 = initWebflo({ imports: {}, code: [], });
105
- await bundle.call(cx, gen1, Path.join(dirPublic, outfileWebflo), true/* asModule */);
106
- }
107
- // ------------------
108
- if (cx.logger) {
109
- cx.logger.log(cx.logger.style.keyword(`-----------------`));
110
- cx.logger.log(`Client Build ` + cx.logger.style.comment(`(sparoot:${sparoot}; is-split:${codeSplitting})`));
111
- cx.logger.log(cx.logger.style.keyword(`-----------------`));
112
- }
113
- gen.code.push(`const { start } = webqit.Webflo`);
114
- // ------------------
115
- // Bundle
116
- declareStart.call(cx, gen, dirClient, dirPublic, clientConfig, spaRouting);
117
- await bundle.call(cx, gen, Path.join(dirPublic, outfileMain), true/* asModule */);
118
- // ------------------
119
- // Embed/unembed
120
- let targetDocumentFile = Path.join(dirPublic, sparoot, 'index.html'),
121
- outfileWebfloPublic = Path.join(clientConfig.public_base_url, outfileWebflo),
122
- outfileMainPublic = Path.join(clientConfig.public_base_url, outfileMain),
123
- embedList = [],
124
- unembedList = [];
125
- if (cx.flags['auto-embed']) {
126
- if (codeSplitting) {
127
- embedList.push(outfileWebfloPublic);
128
- } else {
129
- unembedList.push(outfileWebfloPublic);
130
- }
131
- embedList.push(outfileMainPublic);
132
- } else {
133
- unembedList.push(outfileWebfloPublic, outfileMainPublic);
134
- }
135
- handleEmbeds(targetDocumentFile, embedList, unembedList);
136
- // ------------------
137
- // Recurse
138
- spaGraphCallback && spaGraphCallback(sparoot, subsparoots);
139
- if (cx.flags.recursive) {
140
- while (subsparoots.length) {
141
- await generateClient(subsparoots.shift(), spaGraphCallback);
142
- }
143
- }
144
- };
145
- // -----------
146
- // Generate worker build
147
- const generateWorker = async function(workerroot, workerGraphCallback = null) {
148
- let [ subworkerroots, targets ] = workerroot && scanSubroots(workerroot, 'workerroot') || [ [], false ];
149
- if (!workerroot) workerroot = '/';
150
- let workerRouting = { root: workerroot, subroots: subworkerroots, targets };
151
- let gen = { imports: {}, code: [], };
152
- if (cx.logger) {
153
- cx.logger.log(cx.logger.style.comment(`-----------------`));
154
- cx.logger.log(`Worker Build - workerroot:${workerroot}`);
155
- cx.logger.log(cx.logger.style.comment(`-----------------`));
156
- }
157
- // ------------------
158
- // >> Modules import
159
- gen.imports[`${dirSelf}/worker/index.js`] = `{ start }`;
160
- gen.code.push(``);
161
- gen.code.push(`self.webqit = {}`);
162
- gen.code.push(``);
163
- // ------------------
164
- // Bundle
165
- for (const strategy of [ 'cache_first_urls', 'cache_only_urls' ]) {
166
- if (workerConfig[strategy].length) {
167
- // Separate URLs from patterns
168
- let [ urls, patterns ] = workerConfig[strategy].reduce(([ urls, patterns ], url) => {
169
- let patternInstance = pattern(url, 'http://localhost'),
170
- isPattern = patternInstance.isPattern();
171
- if (isPattern && (patternInstance.pattern.pattern.hostname !== 'localhost' || patternInstance.pattern.pattern.port)) {
172
- throw new Error(`Pattern URLs must have no origin part. Recieved "${url}".`);
173
- }
174
- return isPattern ? [ urls, patterns.concat(patternInstance) ] : [ urls.concat(url), patterns ];
175
- }, [ [], [] ]);
176
- // Resolve patterns
177
- if (patterns.length) {
178
- // List all files
179
- let scan = dir => Fs.readdirSync(dir).reduce((result, f) => {
180
- let resource = Path.join(dir, f);
181
- if (f.startsWith('.')) return result;
182
- return result.concat(Fs.statSync(resource).isDirectory() ? scan(resource) : '/' + Path.relative(dirPublic, resource));
183
- }, []);
184
- let files = scan(dirPublic);
185
- // Resolve patterns from files
186
- workerConfig[strategy] = patterns.reduce((all, pattern) => {
187
- let matchedFiles = files.filter(file => pattern.test(file, 'http://localhost'));
188
- if (matchedFiles.length) return all.concat(matchedFiles);
189
- throw new Error(`The pattern "${pattern.pattern.pattern.pathname}" didn't match any files.`);
190
- }, urls);
191
- }
192
- }
193
- }
194
- declareStart.call(cx, gen, dirWorker, dirPublic, workerConfig, workerRouting);
195
- await bundle.call(cx, gen, Path.join(dirPublic, workerroot, clientConfig.service_worker.filename));
196
- // ------------------
197
- // Recurse
198
- workerGraphCallback && workerGraphCallback(workerroot, subworkerroots);
199
- if (cx.flags.recursive) {
200
- while (subworkerroots.length) {
201
- await generateWorker(subworkerroots.shift());
202
- }
203
- }
204
- };
205
- // -----------
206
- // Generate now...
207
- let sparootsFile = Path.join(dirPublic, 'sparoots.json');
208
- if (clientConfig.spa_routing !== false) {
209
- const sparoots = [];
210
- await generateClient('/', root => sparoots.push(root));
211
- Fs.writeFileSync(sparootsFile, JSON.stringify(sparoots, null, 4));
212
- } else {
213
- await generateClient();
214
- Fs.existsSync(sparootsFile) && Fs.unlinkSync(sparootsFile);
215
- }
216
- if (clientConfig.service_worker.filename) {
217
- await generateWorker('/');
218
- }
219
- }
220
-
221
- /**
222
- * Compile routes.
223
- *
224
- * @param object gen
225
- * @param string routesDir
226
- * @param string targetPublic
227
- * @param object paramsObj
228
- * @param object routing
229
- *
230
- * @return Object
231
- */
232
- function declareStart(gen, routesDir, targetDir, paramsObj, routing) {
233
- const cx = this || {};
234
- // ------------------
235
- // >> Routes mapping
236
- gen.code.push(`// >> Routes`);
237
- declareRoutesObj.call(cx, gen, routesDir, targetDir, 'layout', routing);
238
- gen.code.push(``);
239
- // ------------------
240
- // >> Params
241
- gen.code.push(`// >> Params`);
242
- declareParamsObj.call(cx, gen, { ...paramsObj, routing }, 'params');
243
- gen.code.push(``);
244
- // ------------------
245
- // >> Startup
246
- gen.code.push(`// >> Startup`);
247
- gen.code.push(`webqit.app = await start.call({ layout, params })`);
248
- }
249
-
250
- /**
251
- * Compile routes.
252
- *
253
- * @param object gen
254
- * @param string routesDir
255
- * @param string targetDir
256
- * @param string varName
257
- * @param object routing
258
- *
259
- * @return void
260
- */
261
- function declareRoutesObj(gen, routesDir, targetDir, varName, routing) {
262
- const cx = this || {};
263
- let _routesDir = Path.join(routesDir, routing.root),
264
- _targetDir = Path.join(targetDir, routing.root);
265
- cx.logger && cx.logger.log(cx.logger.style.keyword(`> `) + `Declaring routes...`);
266
- // ----------------
267
- // Directory walker
268
- const walk = (dir, callback) => {
269
- Fs.readdirSync(dir).forEach(f => {
270
- let resource = Path.join(dir, f);
271
- let _namespace = '/' + Path.relative(routesDir, resource).replace(/\\/g, '/');
272
- let namespace = _beforeLast(_namespace, '/index.js') || '/';
273
- if (Fs.statSync(resource).isDirectory()) {
274
- if (routing.subroots.includes(namespace)) return;
275
- walk(resource, callback);
276
- } else {
277
- let relativePath = Path.relative(_targetDir, resource).replace(/\\/g, '/');
278
- callback(resource, namespace, relativePath);
279
- }
280
- });
281
- };
282
- // ----------------
283
- // >> Routes mapping
284
- gen.code.push(`const ${varName} = {};`);
285
- let indexCount = 0;
286
- if (Fs.existsSync(_routesDir)) {
287
- walk(_routesDir, (file, namespace, relativePath) => {
288
- if (relativePath.endsWith('/index.js')) {
289
- // Import code
290
- let routeName = 'index' + (++ indexCount);
291
- // IMPORTANT: we;re taking a step back here so that the parent-child relationship for
292
- // the directories be involved
293
- gen.imports[relativePath] = '* as ' + routeName;
294
- // Definition code
295
- gen.code.push(`${varName}['${namespace}'] = ${routeName};`);
296
- // Show
297
- cx.logger && cx.logger.log(cx.logger.style.comment(` [${namespace}]: `) + cx.logger.style.url(relativePath) + cx.logger.style.comment(` (${Fs.statSync(file).size / 1024} KB)`));
298
- }
299
- });
300
- }
301
- if (!indexCount) {
302
- cx.logger && cx.logger.log(cx.logger.style.comment(` (none)`));
303
- }
304
- }
305
-
306
- /**
307
- * Compile params.
308
- *
309
- * @param object gen
310
- * @param object paramsObj
311
- * @param string varName
312
- *
313
- * @return void
314
- */
315
- function declareParamsObj(gen, paramsObj, varName = null, indentation = 0) {
316
- const cx = this || {};
317
- // ----------------
318
- // Params compilation
319
- if (varName) gen.code.push(`const ${varName} = {`);
320
- _isArray(paramsObj)
321
- Object.keys(paramsObj).forEach(name => {
322
- let _name = ` ${' '.repeat(indentation)}${(_isArray(paramsObj) ? '' : (name.includes(' ') ? `'${name}'` : name) + ': ')}`;
323
- if ([ 'boolean', 'number' ].includes(typeof paramsObj[name])) {
324
- gen.code.push(`${_name}${paramsObj[name]},`);
325
- } else if (_isArray(paramsObj[name])) {
326
- gen.code.push(`${_name}[`);
327
- declareParamsObj.call(cx, gen, paramsObj[name], null, indentation + 1);
328
- gen.code.push(` ${' '.repeat(indentation)}],`);
329
- } else if (_isObject(paramsObj[name])) {
330
- gen.code.push(`${_name}{`);
331
- declareParamsObj.call(cx, gen, paramsObj[name], null, indentation + 1);
332
- gen.code.push(` ${' '.repeat(indentation)}},`);
333
- } else {
334
- gen.code.push(`${_name}'${paramsObj[name]}',`);
335
- }
336
- });
337
- if (varName) gen.code.push(`};`);
338
- }
339
-
340
- /**
341
- * Bundle generated file
342
- *
343
- * @param object gen
344
- * @param String outfile
345
- * @param boolean asModule
346
- *
347
- * @return Promise
348
- */
349
- async function bundle(gen, outfile, asModule = false) {
350
- const cx = this || {};
351
- const compression = !cx.flags.compression ? false : (
352
- cx.flags.compression === true ? ['gz'] : cx.flags.compression.split(',').map(s => s.trim())
353
- );
354
- const moduleFile = `${_beforeLast(outfile, '.')}.esm.js`;
355
-
356
- // ------------------
357
- // >> Show waiting...
358
- if (cx.logger) {
359
- let waiting = cx.logger.waiting(cx.logger.f`Writing the ES module file: ${moduleFile}`);
360
- waiting.start();
361
- jsFile.write(gen, moduleFile, 'ES Module file');
362
- waiting.stop();
363
- } else {
364
- jsFile.write(gen, moduleFile, 'ES Module file');
365
- }
366
-
367
- // ----------------
368
- // >> Webpack config
369
- const bundlingConfig = {
370
- entryPoints: [ moduleFile ],
371
- outfile,
372
- bundle: true,
373
- minify: true,
374
- banner: { js: '/** @webqit/webflo */', },
375
- footer: { js: '', },
376
- format: 'esm',
377
- };
378
- if (!asModule) {
379
- // Support top-level await
380
- // See: https://github.com/evanw/esbuild/issues/253#issuecomment-826147115
381
- bundlingConfig.banner.js += '(async () => {';
382
- bundlingConfig.footer.js += '})();';
383
- }
384
-
385
- // ----------------
386
- // The bundling process
387
- let waiting;
388
- if (cx.logger) {
389
- waiting = cx.logger.waiting(`Bundling...`);
390
- cx.logger.log(cx.logger.style.keyword(`> `) + 'Bundling...');
391
- waiting.start();
392
- }
393
- // Main
394
- await EsBuild.build(bundlingConfig);
395
- // Compress...
396
- let compressedFiles = [], removals = [];
397
- if (compression) {
398
- const contents = Fs.readFileSync(bundlingConfig.outfile);
399
- if (compression.includes('gz')) {
400
- const gzip = gzipSync(contents, {});
401
- Fs.writeFileSync(bundlingConfig.outfile + '.gz', gzip);
402
- compressedFiles.push(bundlingConfig.outfile + '.gz');
403
- } else {
404
- removals.push(bundlingConfig.outfile + '.gz');
405
- }
406
- if (compression.includes('br')) {
407
- const brotli = brotliCompressSync(contents, {});
408
- Fs.writeFileSync(bundlingConfig.outfile + '.br', brotli);
409
- compressedFiles.push(bundlingConfig.outfile + '.br');
410
- } else {
411
- removals.push(bundlingConfig.outfile + '.br');
412
- }
413
- }
414
- // Remove moduleFile build
415
- Fs.unlinkSync(bundlingConfig.entryPoints[0]);
416
- removals.forEach(file => Fs.existsSync(file) && Fs.unlinkSync(file));
417
- if (waiting) waiting.stop();
418
- // ----------------
419
- // Stats
420
- if (cx.logger) {
421
- [bundlingConfig.outfile].concat(compressedFiles).forEach(file => {
422
- let ext = '.' + _afterLast(file, '.');
423
- cx.logger.info(cx.logger.style.comment(` [${ext}]: `) + cx.logger.style.url(file) + cx.logger.style.comment(` (${Fs.statSync(file).size / 1024} KB)`));
424
- });
425
- cx.logger.log('');
426
- }
427
- }
428
-
429
- /**
430
- * Handles auto-embeds
431
- *
432
- * @param String targetDocumentFile
433
- * @param Array embedList
434
- * @param Array unembedList
435
- *
436
- * @return Void
437
- */
438
- function handleEmbeds(targetDocumentFile, embedList, unembedList) {
439
- let targetDocument, successLevel = 0;
440
- if (Fs.existsSync(targetDocumentFile) && (targetDocument = Fs.readFileSync(targetDocumentFile).toString()) && targetDocument.trim().startsWith('<!DOCTYPE html')) {
441
- successLevel = 1;
442
- let dom = new Jsdom.JSDOM(targetDocument), by = 'webflo', touched;
443
- let embed = (src, after) => {
444
- src = src.replace(/\\/g, '/');
445
- let embedded = dom.window.document.querySelector(`script[src="${src}"]`);
446
- if (!embedded) {
447
- embedded = dom.window.document.createElement('script');
448
- embedded.setAttribute('type', 'module');
449
- embedded.setAttribute('src', src);
450
- embedded.setAttribute('by', by);
451
- if (after) {
452
- after.after(embedded, `\n\t\t`);
453
- } else {
454
- dom.window.document.head.appendChild(embedded);
455
- }
456
- touched = true;
457
- }
458
- return embedded;
459
- };
460
- let unembed = src => {
461
- src = Path.join('/', src);
462
- src = src.replace(/\\/g, '/');
463
- let embedded = dom.window.document.querySelector(`script[src="${src}"][by="${by}"]`);
464
- if (embedded) {
465
- embedded.remove();
466
- touched = true;
467
- }
468
- };
469
- embedList.reduce((prev, src) => {
470
- return embed(src, prev);
471
- }, [ ...dom.window.document.head.querySelectorAll(`script[src]`) ].pop() || dom.window.document.querySelector(`script`));
472
- unembedList.forEach(src => {
473
- unembed(src);
474
- });
475
- if (touched) {
476
- Fs.writeFileSync(targetDocumentFile, dom.serialize());
477
- successLevel = 2;
478
- }
479
- }
480
- return successLevel;
481
- }
@@ -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,44 +0,0 @@
1
-
2
- /**
3
- * @imports
4
- */
5
- import Router from '../Router.js';
6
- import _Application from '../../Application.js';
7
-
8
- export default class Application extends _Application {
9
-
10
- // Returns router class
11
- get Router() {
12
- return Router;
13
- }
14
-
15
- /**
16
- * Handles HTTP events.
17
- *
18
- * @param HttpEvent httpEvent
19
- * @param Function remoteFetch
20
- *
21
- * @return Response
22
- */
23
- async handle(httpEvent, remoteFetch) {
24
- // The app router
25
- const router = new this.Router(this.cx, httpEvent.url.pathname);
26
- const handle = async () => {
27
- // --------
28
- // ROUTE FOR DATA
29
- // --------
30
- return router.route([httpEvent.request.method, 'default'], httpEvent, {}, async event => {
31
- if (event !== httpEvent) {
32
- // This was nexted()
33
- if (!event.request.headers.has('Accept')) {
34
- event.request.headers.set('Accept', 'application/json');
35
- }
36
- }
37
- return remoteFetch(event.request);
38
- }, remoteFetch);
39
- };
40
- return handle();
41
- }
42
-
43
- }
44
-
@@ -1,7 +0,0 @@
1
-
2
- /**
3
- * @imports
4
- */
5
- import _Context from '../Context.js';
6
-
7
- export default class Context extends _Context {}