@webqit/webflo 0.11.16 → 0.11.19

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2013-present, Yuxi (Evan) You
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
package/README.md CHANGED
@@ -165,7 +165,7 @@ With [npm available on your terminal](https://docs.npmjs.com/downloading-and-ins
165
165
  > System Requirements: Node.js 14.0 or later
166
166
 
167
167
  ```shell
168
- $ npm i @webqit/webflo
168
+ npm i @webqit/webflo
169
169
  ```
170
170
 
171
171
  The installation automatically creates a `package.json` file at project root, containing `@webqit/webflo` as a project dependency.
@@ -298,7 +298,7 @@ export default function(event, context, next) {
298
298
  <details>
299
299
  <summary>How it works...</summary>
300
300
 
301
- > The above function is built as part of your application's JS bundle on running the `npm run generate` command. (It is typically bundled to the file `./public/bundle.js`. And the `--auto-embed` flag in that command gets it automatically embedded on your `./public/index.html` page as `<script type="module" src="/bundle.js"></script>`.) Then it responds from right in the browser on visiting http://localhost:3000.
301
+ > The above function is built as part of your application's client-side script from the `npm run generate` command. It is typically bundled to the file `./public/bundle.js`. And the `--auto-embed` flag in that command gets it automatically embedded on your `./public/index.html` page as `<script type="module" src="/bundle.js"></script>`. Then it responds from right in the browser on visiting http://localhost:3000.
302
302
  </details>
303
303
 
304
304
  For *browser-based* applications that want to support offline usage via Service-Workers (e.g Progressive Web Apps), Webflo allows us to define equivalent handlers for requests hitting the Service Worker. These worker-based handlers go into a directory named `worker`.
@@ -319,7 +319,7 @@ export default function(event, context, next) {
319
319
  <details>
320
320
  <summary>How it works...</summary>
321
321
 
322
- > The above function is built as part of your application's Service Worker JS bundle on running the `npm run generate` command. (It is typically bundled to the file `./public/worker.js`, and the main application bundle automatically connects to it.) Then it responds from within the Service Worker on visiting http://localhost:3000. (More details [ahead](#service-workers).)
322
+ > The above function is built as part of your application's Service Worker script from the `npm run generate` command. It is typically bundled to the file `./public/worker.js`, and the main application bundle automatically connects to it. Then it responds from within the Service Worker on visiting http://localhost:3000. (More details [ahead](#service-workers).)
323
323
  </details>
324
324
 
325
325
  So, depending on what's being built, an application's handler functions may take the following form (in part or in whole):
@@ -457,7 +457,7 @@ export default async function(event, context, next) {
457
457
  </details>
458
458
  </details>
459
459
 
460
- But, workflows may be designed with *wildcard* steps using a hyphen `-` as step name. At runtime, a wildcard step matches any URL segment at its level in the layout! A `this.stepname` property could be used to see which URL segment has been matched.
460
+ However, workflows may be designed with *wildcard* steps using a hyphen `-` as step name. At runtime, a wildcard step matches any URL segment at the given level in the layout! A `this.stepname` property could be used to see which URL segment has been matched.
461
461
 
462
462
  ```js
463
463
  /**
@@ -478,12 +478,18 @@ export default function(event, context, next) {
478
478
  <details>
479
479
  <summary>More details...</summary>
480
480
 
481
- > Every handler function has a `this.stepname` and `this.pathname` property. Server-side handlers have an extra `this.dirname` property.
481
+ > Every handler function has the following contextual properties:
482
+ > + `this.stepname` - The exact name of the current step in the URL path.
483
+ > + `this.pathname` - The pathname to the current step in the URL path.
484
+ > + `next.stepname` - The exact name of the next step in the URL path.
485
+ > + `next.pathname` - The pathname for the rest of the steps in the URL path.
486
+ > Server-side handlers have the following in addition:
487
+ > + `this.dirname` - The filesystem pathname to the current step in the URL path.
482
488
  </details>
483
489
 
484
490
  Additionally, workflows may be designed with as many or as few step functions as necessary; the flow control parameters `next.stepname` and `next.pathname` can be used at any point to handle the rest of an URL that have no corresponding step functions.
485
491
 
486
- For example, it is possible to handle all URLs from the root handler alone.
492
+ This means that it is even possible to handle all URLs from the root handler alone.
487
493
 
488
494
  ```js
489
495
  /**
@@ -513,7 +519,7 @@ export default function(event, context, next) {
513
519
 
514
520
  Webflo takes a *default action* when `next()` is called at the *edge* of the workflow - the point where there are no more child steps - as in the `return next()` statement above!
515
521
 
516
- For workflows in **the `/server` directory**, the *default action* of `next()`ing at the edge is to go match and return a static file in the `public` directory.
522
+ **For workflows in the `/server` directory**, the *default action* of `next()`ing at the edge is to go match and return a static file in the `public` directory.
517
523
 
518
524
  So, above, should our handler receive static file requests like `http://localhost:3000/logo.png`, the statement `return next()` would get Webflo to match and return the logo at `public/logo.png`, if any; a `404` response otherwise.
519
525
 
@@ -526,7 +532,7 @@ my-app
526
532
  > **Note**
527
533
  > <br>The root handler effectively becomes the single point of entry to the application - being that it sees even requests for static files!
528
534
 
529
- Now, for workflows in **the `/worker` directory**, the *default action* of `next()`ing at the edge is to send the request through the network to the server. (But Webflo will know to attempt resolving the request from the application's caching system built into the Service Worker.)
535
+ **For workflows in the `/worker` directory**, the *default action* of `next()`ing at the edge is to send the request through the network to the server. (But Webflo will know to attempt resolving the request from the application's caching system built into the Service Worker.)
530
536
 
531
537
  So, above, if we defined handler functions in the `/worker` directory, we could decide to either handle the received requests or just `next()` them to the server.
532
538
 
@@ -565,10 +571,13 @@ my-app
565
571
  └── public/logo.png ------------------------- http://localhost:3000/logo.png
566
572
  ```
567
573
 
568
- > **Note**
569
- > <br>Handlers in the `/worker` directory are only designed to see Same-Origin requests since Cross-Origin URLs like `https://auth.example.com/oauth` do not belong in the application's layout! These external URLs, however, benefit from the application's caching system built into the Service Worker.
574
+ <details>
575
+ <summary>More details...</summary>
576
+
577
+ > Handlers in the `/worker` directory are only designed to see Same-Origin requests since Cross-Origin URLs like `https://auth.example.com/oauth` do not belong in the application's layout! These external URLs, however, benefit from the application's caching system built into the Service Worker.
578
+ </details>
570
579
 
571
- For workflows in **the `/client` directory**, the *default action* of `next()`ing at the edge is to send the request through the network to the server. But where there is a Service Worker layer, then that becomes the next destination.
580
+ **For workflows in the `/client` directory**, the *default action* of `next()`ing at the edge is to send the request through the network to the server. But where there is a Service Worker layer, then that becomes the next destination.
572
581
 
573
582
  So, above, if we defined handler functions in the `/client` directory, we could decide to either handle the navigation requests in-browser or just `next()` them, this time, to the Service Worker layer.
574
583
 
@@ -651,8 +660,12 @@ But, we can also access the route in a way that gets the data rendered into the
651
660
  <summary>How it works...</summary>
652
661
 
653
662
  > The `Accept` header hint is already how browsers make requests on every page load. So, it just works!
663
+ </details>
664
+
665
+ <details>
666
+ <summary>More details...</summary>
654
667
 
655
- > Note that the automatic pairing of an `index.html` file with a route works the same for nested routes! But top-level `index.html` files are implicitly inherited down the hierarchy.)
668
+ > This automatic pairing of an `index.html` file with a route works the same for nested routes! But top-level `index.html` files are implicitly inherited down the hierarchy.)
656
669
  </details>
657
670
 
658
671
  Now, for Single Page Applications, subsequent navigations, after the initial page load, just ask for the data on destination URLs and perform [Client-Side Rendering](#client-and-server-side-rendering) on the same running document. Navigation is sleek and instant!
@@ -660,7 +673,7 @@ Now, for Single Page Applications, subsequent navigations, after the initial pag
660
673
  <details>
661
674
  <summary>How it works...</summary>
662
675
 
663
- > Unless disabled, [SPA Routing](#spa-routing) is automatically built into your app's JS bundle from the `npm run generate` command. So, it just works!
676
+ > Unless disabled, [SPA Routing](#spa-routing) is automatically built into your application's client-side script from the `npm run generate` command. So, it just works!
664
677
  </details>
665
678
 
666
679
  With no extra work, your application can function as either a *Multi Page App (MPA)* or a *Single Page App (SPA)*!
@@ -873,11 +886,7 @@ my-app
873
886
  └── footer.html ------------------------------ <footer></footer> <!-- To appear at bottom of each document root -->
874
887
  ```
875
888
 
876
- <details>
877
- <summary>How it works...</summary>
878
-
879
- > The above gives us three document roots: `/index.html`, `/about/index.html`, `/prodcuts/index.html`. The `/prodcuts` route doubles as a Single Page Application such that visiting the `/prodcuts` route loads the document root `/prodcuts/index.html` and lets Webflo SPA routing determine which of `/prodcuts/main.html`, `/prodcuts/free/main.html`, `/prodcuts/paid/main.html` is imported on a given URL.
880
- </details>
889
+ The above gives us three document roots: `/index.html`, `/about/index.html`, `/prodcuts/index.html`. The `/prodcuts` route doubles as a Single Page Application such that visiting the `/prodcuts` route loads the document root `/prodcuts/index.html` and lets Webflo SPA routing determine which of `/prodcuts/main.html`, `/prodcuts/free/main.html`, `/prodcuts/paid/main.html` is imported on a given URL.
881
890
 
882
891
  Webflo ensures that only the amount of JavaScript for a document root is actually loaded! So, above, a common JavaScript build is shared across the three document roots alongside an often tiny root-specific build.
883
892
 
@@ -929,7 +938,11 @@ public
929
938
  </html>
930
939
  ```
931
940
 
932
- The Webflo `generate` command automatically figures out a given architecture and generates the appropriate scripts for the application! It also factors into the generated scripts the location of each document root so that [all navigations to these roots are handled as a regular page load](#spa-navigation).
941
+ <details>
942
+ <summary>How it works...</summary>
943
+
944
+ > The Webflo `generate` command automatically figures out a given architecture and generates the appropriate scripts for the application! It also factors into the generated scripts the location of each document root so that [all navigations to these roots are handled as a regular page load](#spa-navigation).
945
+ </details>
933
946
 
934
947
  #### Bundling
935
948
 
@@ -1376,7 +1389,7 @@ In just a few concepts, Webflo comes ready for any type of application!
1376
1389
 
1377
1390
  #### Client-Side Applications
1378
1391
 
1379
- Web pages that embed the Webflo client JS bundle deliver a great user experience. It's simple: the `npm run generate` command does both the building and embedding of the script, or scripts, for the document root, or document roots (in a [Multi Page](#in-a-multi-page-layout) / [Multi SPA](#in-a-multi-spa-layout) layout)!
1392
+ Web pages that embed the Webflo client JS deliver a great user experience. It's simple: the `npm run generate` command does both the building and embedding of the script (or scripts), for the document root (or document roots - in a [Multi Page](#in-a-multi-page-layout) / [Multi SPA](#in-a-multi-spa-layout) layout)!
1380
1393
 
1381
1394
  On being loaded, the state of the application is initialized, or is restored through hydration - where [Server-Side Rendering](#client-and-server-side-rendering) was involved to optimize for first paint, and an app-like experience kicks in! For [Single-Page Applications](#in-a-single-page-layout), [Client-Side Rendering](#client-and-server-side-rendering) is performed on each navigation.
1382
1395
 
@@ -1477,7 +1490,7 @@ On the UI, this could be used to show/hide cute error elements.
1477
1490
 
1478
1491
  This property tells when a client-side redirect is ongoing - see [Scenario 4: Single Page Navigation Requests and Responses](#scenario-4-single-page-navigation-requests-and-responses) - in which case it exposes the destination URL.
1479
1492
 
1480
- On the UI, this could be used to prevent further interactions with the outgoing page.
1493
+ On the UI, this could be used to mark the current page as stale and prevent further interactions.
1481
1494
 
1482
1495
  ```html
1483
1496
  <body>
@@ -1513,13 +1526,13 @@ Here are some additional examples with the [Observer API](#the-observer-api).
1513
1526
 
1514
1527
  ```js
1515
1528
  // Visualize the network state
1516
- let onlineVisualizer = changes => {
1529
+ let networkVisualizer = changes => {
1517
1530
  changes.forEach(e => {
1518
1531
  console.log(e.name, ':', e.value);
1519
1532
  });
1520
1533
  };
1521
- Observer.observe(document.state.network, onlineVisualizer);
1522
- // Or: Observer.observe(document, [ ['state', 'network'] ], onlineVisualizer, { subtree: true });
1534
+ Observer.observe(document.state.network, networkVisualizer);
1535
+ // Or: Observer.observe(document, [ ['state', 'network'] ], networkVisualizer, { subtree: true });
1523
1536
  ```
1524
1537
  </details>
1525
1538
 
@@ -1687,7 +1700,7 @@ This strategy tells the Service Worker to always fetch given resources from the
1687
1700
  </details>
1688
1701
  </details>
1689
1702
 
1690
- In all cases above, the convention for specifying URLs for a strategy accepts an [URL patterns](https://developer.mozilla.org/en-US/docs/Web/API/URLPattern) - against which URLs can be matched on the fly. For example, to place all files in an `/image` directory (and subdirectories) on the *Cache First* strategy, the pattern `/image/*` can be used. To place all `.svg` files in an `/icons` directory (including subdirectories) on the *Cache Only* strategy, the pattern `/icons/*.svg` can be used. (Specifically for the *Cache Only* strategy, patterns are resolved at Service Worker build-time, and each pattern must match, at least, a file.)
1703
+ In all cases above, the convention for specifying URLs for a strategy accepts an [URL pattern](https://developer.mozilla.org/en-US/docs/Web/API/URLPattern) - against which URLs can be matched on the fly. For example, to place all files in an `/image` directory (and subdirectories) on the *Cache First* strategy, the pattern `/image/*` can be used. To place all `.svg` files in an `/icons` directory (including subdirectories) on the *Cache Only* strategy, the pattern `/icons/*.svg` can be used. (Specifically for the *Cache Only* strategy, patterns are resolved at Service Worker build-time, and each pattern must match, at least, a file.)
1691
1704
 
1692
1705
  <details>
1693
1706
  <summary>Example...</summary>
@@ -1703,7 +1716,7 @@ A couple APIs exists in browsers for establishing a two-way communication channe
1703
1716
 
1704
1717
  ###### The `workport` API
1705
1718
 
1706
- This is an object with simple methods for working with *cross-thread* messages, UI and Push Notifications.
1719
+ This is an object with simple methods for working with *cross-thread* messages, UI Notifications, and Push Notifications.
1707
1720
 
1708
1721
  On both the client and worker side of your application, the `workport` object is accessible from route handlers as `this.runtime.workport`.
1709
1722
 
@@ -1792,12 +1805,12 @@ workport.nofitications.fire(title, options).then(event => {
1792
1805
  </details>
1793
1806
 
1794
1807
  <details>
1795
- <summary>Method: <code>.nofitications.listen()</code></summary>
1808
+ <summary>Method: <code>.nofitications.handle()</code></summary>
1796
1809
 
1797
- The `.nofitications.listen()` method (in Service-Workers) is used for listening to [`notificationclick`](https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerGlobalScope/notificationclick_event) events. (Handlers are called each time a notification is clicked.)
1810
+ The `.nofitications.handle()` method (in Service-Workers) is used for handling [`notificationclick`](https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerGlobalScope/notificationclick_event) events. (Handlers are called each time a notification is clicked.)
1798
1811
 
1799
1812
  ```js
1800
- workport.nofitications.listen(event => {
1813
+ workport.nofitications.handle(event => {
1801
1814
  console.log(event.action);
1802
1815
  });
1803
1816
  ```
@@ -1968,7 +1981,7 @@ Webflo applications are often built on/with the following technologies.
1968
1981
 
1969
1982
  [OOHTML](https://github.com/webqit/oohtml) is a proposed set of new features for HTML that makes it fun to hand-author your HTML documents! Within OOHTML are [HTML Modules](https://github.com/webqit/oohtml#html-modules) and [HTML Imports](https://github.com/webqit/oohtml#html-imports), [Reactive Scripts](https://github.com/webqit/oohtml#subscript) and more!
1970
1983
 
1971
- Webflo natively supports OOHTML in full! But it is also possible to switch this to none, or to partial support - when specific features aren't needed anywhere in your application. Server-side and client-side support for OOHTML exist independently. This is good when, for example, your application places more importance on SSR, and less on CSR, in which case a reduced support for OOHTML can reduce the overall client JS bundle size.
1984
+ Webflo natively supports OOHTML in full! But it is also possible to switch this to none, or to partial support - when specific features aren't needed anywhere in your application. Server-side and client-side support for OOHTML exist independently. This is good when, for example, your application places more importance on SSR, and less on CSR, in which case a reduced support for OOHTML can reduce the overall client JS size.
1972
1985
 
1973
1986
  <details>
1974
1987
  <summary>Config (Default)</summary>
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.11.16",
15
+ "version": "0.11.19",
16
16
  "license": "MIT",
17
17
  "repository": {
18
18
  "type": "git",
@@ -36,7 +36,7 @@
36
36
  },
37
37
  "dependencies": {
38
38
  "@octokit/webhooks": "^7.15.1",
39
- "@webqit/backpack": "^0.1.0",
39
+ "@webqit/backpack": "^0.1.2",
40
40
  "@webqit/oohtml-ssr": "^1.1.0",
41
41
  "@webqit/util": "^0.8.9",
42
42
  "client-sessions": "^0.8.0",
@@ -41,12 +41,13 @@ export default class Router {
41
41
  async route(method, event, arg, _default, remoteFetch = null) {
42
42
 
43
43
  const $this = this;
44
+ const $runtime = this.cx.runtime;
44
45
 
45
46
  // ----------------
46
47
  // The loop
47
48
  // ----------------
48
49
  const next = async function(thisTick) {
49
- const thisContext = { };
50
+ const thisContext = { runtime: $runtime };
50
51
  if (!thisTick.trail || thisTick.trail.length < thisTick.destination.length) {
51
52
  thisTick = await $this.readTick(thisTick);
52
53
  // -------------
@@ -15,4 +15,9 @@ export async function start(clientCallback = null) {
15
15
  return new Runtime(Context.create(cx), ( ...args ) => {
16
16
  return clientCallback ? clientCallback( ...args.concat( defaultClientCallback ) ) : defaultClientCallback( ...args );
17
17
  });
18
- }
18
+ }
19
+
20
+ /**
21
+ * @APIS
22
+ */
23
+ export * as APIS from './Runtime.js';
@@ -3,9 +3,21 @@
3
3
  * @imports
4
4
  */
5
5
  import { _any } from '@webqit/util/arr/index.js';
6
- import { HttpEvent, Request, Response, Observer } from '../Runtime.js';
7
6
  import { urlPattern } from '../../util.js';
8
7
  import Workport from './Workport.js';
8
+ import { HttpEvent, Request, Response, Observer } from '../Runtime.js';
9
+ export {
10
+ URL,
11
+ FormData,
12
+ ReadableStream,
13
+ RequestHeaders,
14
+ ResponseHeaders,
15
+ Request,
16
+ Response,
17
+ fetch,
18
+ HttpEvent,
19
+ Observer,
20
+ } from '../Runtime.js';
9
21
 
10
22
  /**
11
23
  * ---------------------------
@@ -2,7 +2,7 @@
2
2
  /**
3
3
  * @imports
4
4
  */
5
- import Router from '../Router.js';
5
+ import Router from './Worker.js';
6
6
 
7
7
  export default class WorkerClient {
8
8
 
@@ -56,7 +56,7 @@ export default class Workport {
56
56
  notification.addEventListener('close', res);
57
57
  });
58
58
  },
59
- listen: callback => {
59
+ handle: callback => {
60
60
  self.addEventListener('notificationclick', callback);
61
61
  return this.notifications;
62
62
  },
@@ -15,4 +15,9 @@ export async function start(clientCallback = null) {
15
15
  return new Worker(Context.create(cx), ( ...args ) => {
16
16
  return clientCallback ? clientCallback( ...args.concat( defaultClientCallback ) ) : defaultClientCallback( ...args );
17
17
  });
18
- }
18
+ }
19
+
20
+ /**
21
+ * @APIS
22
+ */
23
+ export * as APIS from './Worker.js';
@@ -6,20 +6,6 @@ import Context from './Context.js';
6
6
  import RuntimeClient from './RuntimeClient.js';
7
7
  import Runtime from './Runtime.js';
8
8
 
9
- /**
10
- * @desc
11
- */
12
- export const desc = {
13
- config: {
14
- headers: 'Configure automatic http headers.',
15
- prerendering: 'Configure prerendering.',
16
- redirects: 'Configure automatic redirects.',
17
- server: 'Configure server settings.',
18
- vhosts: 'Configure virtual hosts.',
19
- },
20
- start: 'Starts the Webflo server.',
21
- };
22
-
23
9
  /**
24
10
  * @start
25
11
  */
@@ -32,10 +18,6 @@ export async function start(clientCallback = null) {
32
18
  }
33
19
 
34
20
  /**
35
- * @exports
21
+ * @APIS
36
22
  */
37
- export {
38
- Context,
39
- RuntimeClient,
40
- Runtime,
41
- }
23
+ export * as APIS from './Runtime.js';