@webqit/webflo 0.11.6 → 0.11.7

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/README.md CHANGED
@@ -929,7 +929,9 @@ Going forward, we can get to write more succinct code! Using the [Namespaced HTM
929
929
  document.title = title;
930
930
  let { headline1, headline2 } = this.namespace;
931
931
  $(headline1).html(title);
932
- $(headline2).html(title);
932
+ if (headline2) {
933
+ $(headline2).html(title);
934
+ }
933
935
  </script>
934
936
  </body>
935
937
  </html>
@@ -1065,7 +1067,7 @@ For all things application state, Webflo leverages the [State API](https://githu
1065
1067
 
1066
1068
  #### The `document.state.data` Object
1067
1069
 
1068
- This property represents the data obtained from route handers on each navigation. Webflo simply exposes this data and lets the page's [rendering logic](#client-and-server-side-rendering), or other parts of the application, take over.
1070
+ This property reperesents the application data at any point in time - obtained from route handers on each navigation. Webflo simply updates this property and lets the page's [rendering logic](#client-and-server-side-rendering), or other parts of the application, take over.
1069
1071
 
1070
1072
  ```js
1071
1073
  Observer.observe(document.state, 'data', e => {
@@ -1073,6 +1075,13 @@ Observer.observe(document.state, 'data', e => {
1073
1075
  });
1074
1076
  ```
1075
1077
 
1078
+ ```html
1079
+ <script type="subscript">
1080
+ let { title } = document.state.data;
1081
+ document.title = title;
1082
+ </script>
1083
+ ```
1084
+
1076
1085
  #### The `document.state.url` Object
1077
1086
 
1078
1087
  This is a *live* object that reperesents the properties of the application URL at any point in time. The object exposes the same URL properties as with the [`URL`](https://developer.mozilla.org/en-US/docs/Web/API/URL) API, but as *live* properties that can be observed as navigation happens, and modified to initiate navigation - all using the [Observer API](https://github.com/webqit/observer).
@@ -1113,11 +1122,18 @@ document.addEventListener('synthetic-navigation', e => {
1113
1122
  });
1114
1123
  ```
1115
1124
 
1125
+ ```html
1126
+ <script type="subscript">
1127
+ let { query: { as: role } } = document.state.url;
1128
+ document.title = 'Login as ' + role;
1129
+ </script>
1130
+ ```
1131
+
1116
1132
  ### Requests and Responses
1117
1133
 
1118
- On each request, the event object passed to route handlers exposes the incoming request as `event.request`. This is an instance of `event.Request` - an extension of the [WHATWG Request](https://developer.mozilla.org/en-US/docs/Web/API/Request) class. The event object also exposes `event.Response` - an extension of the [WHATWG Response](https://developer.mozilla.org/en-US/docs/Web/API/Response) class, for returning instance-based responses.
1134
+ On each request, the event object passed to route handlers exposes the incoming request as `event.request`. This is an instance of `event.Request` - an extension of the [WHATWG Request](https://developer.mozilla.org/en-US/docs/Web/API/Request) class. The event object also exposes `event.Response` - an extension of the [WHATWG Response](https://developer.mozilla.org/en-US/docs/Web/API/Response) class, for returning instance-based responses. You enjoy routing that is based on standard interfaces!
1119
1135
 
1120
- Now, routes in Webflo can be designed for different types of request/response scenarios. Webflo does the heavy lifting on each request/response flow!
1136
+ Routes in Webflo can be designed for different types of request/response scenarios. Here are some important ones:
1121
1137
 
1122
1138
  #### Scenario 1: Static File Requests and Responses
1123
1139
 
@@ -1216,19 +1232,18 @@ console.log(event.request.headers.cookies); // { 'Cookie-1': 'cookie-val', 'Cook
1216
1232
 
1217
1233
  ### Webflo Applications
1218
1234
 
1219
- In just a few concepts, Webflo comes ready for any type of application! Now, here's how it all works.
1235
+ In just a few concepts, Webflo comes ready for any type of application!
1220
1236
 
1221
1237
  + [Client-Side Applications](#client-side-applications)
1238
+ + [Progressive Web Apps](#progressive-web-apps)
1222
1239
  + [API Backends](#api-backends)
1223
1240
  + [Static Sites](#static-sites)
1224
1241
 
1225
1242
  #### Client-Side Applications
1226
1243
 
1227
- Web pages that embed the Webflo client JS bundle deliver a great user experience.
1228
- + **First-paint-ready.** On the first page request, you get a [server-rendered](#client-and-server-side-rendering) HTML page that's optimized for the first paint of your application.
1229
- + **Fluid and app-like.** On being loaded, the state of the application is restored through hydration, and [subsequent navigations](#spa-navigation) are sleek and instant, while performing [Client-Side Rendering](#client-and-server-side-rendering).
1244
+ 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)!
1230
1245
 
1231
- For these client-side applications, the `npm run generate` command does both the building and embedding of the script for each document root in the application.
1246
+ 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.
1232
1247
 
1233
1248
  ##### SPA Navigation
1234
1249
 
@@ -1242,23 +1257,84 @@ Unless disabled in [config](#spa_navigation), it is factored-in at build time fo
1242
1257
 
1243
1258
  ##### SPA State
1244
1259
 
1245
- On the client side of a Webflo application, [the idea of state](#the-idea-of-state) also goes further to include the following aspects of the client-side lifecycle that can be used to provide visual cues on the UI.
1260
+ On the client side of a Webflo application, [the idea of state](#the-idea-of-state) also includes the following aspects of the client-side lifecycle that can be used to provide visual cues on the UI.
1246
1261
 
1247
1262
  ###### The `document.state.network` Object
1248
1263
 
1249
1264
  This is a *live* object that exposes the network activity and network state of the application.
1250
1265
 
1251
1266
  ```js
1252
- console.log(document.state.network) // { requesting, remote, error, redirecting, online, }
1267
+ console.log(document.state.network) // { requesting, remote, error, redirecting, connectivity, }
1253
1268
  ```
1254
1269
 
1255
1270
  + **`network.requesting`: `null|Object`** - This property tells when a request is ongoing, in which case it exposes the `params` object used to initiate the request.
1271
+
1272
+ On the UI, this could be used to hide a menu drawer that may have been open.
1273
+
1274
+ ```html
1275
+ <menu-drawer>
1276
+ <script type="subscript">
1277
+ let { network: { requesting } } = document.state;
1278
+ if (requesting) {
1279
+ $(this).attr('open', false);
1280
+ }
1281
+ </script>
1282
+ </menu-drawer>
1283
+ ```
1284
+
1256
1285
  + **`network.remote`: `null|String`** - This property tells when a remote request is ongoing - usually the same navigation requests as at `network.requesting`, but when not handled by any client-side route handlers, or when `next()`ed to this point by route handlers. The `remote` property also goes live when a route handler calls the special `fetch()` function that they recieve on their fourth parameter.
1286
+
1287
+ On the UI, this could be used to show/hide a spinner, or progress bar, to provide a visual cue.
1288
+
1289
+ ```html
1290
+ <progress-bar>
1291
+ <script type="subscript">
1292
+ let { network: { remote } } = document.state;
1293
+ $(this).attr('hidden', !remote);
1294
+ </script>
1295
+ </progress-bar>
1296
+ ```
1297
+
1257
1298
  + **`network.error`: `null|Error`** - This property tells when a request is *errored* in which case it contains an `Error` instance of the error. For requests that can be retried, the `Error` instance also has a custom `retry()` method.
1299
+
1300
+ On the UI, this could be used to show/hide cute error elements.
1301
+
1302
+ ```html
1303
+ <nice-error>
1304
+ <script type="subscript">
1305
+ let { network: { error } } = document.state;
1306
+ $(this).attr('hidden', !error);
1307
+ </script>
1308
+ </nice-error>
1309
+ ```
1310
+
1258
1311
  + **`network.redirecting`: `null|String`** - 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.
1259
- + **`network.online`: `Boolean`** - This property tells of [the browser's ability to connect to the network](https://developer.mozilla.org/en-US/docs/Web/API/Navigator/onLine).
1260
-
1261
- Now, being a *live* object means that `document.state.network` can be observed using the [Observer API](https://github.com/webqit/observer).
1312
+
1313
+ On the UI, this could be used to prevent further interactions with the outgoing page.
1314
+
1315
+ ```html
1316
+ <body>
1317
+ <script type="subscript">
1318
+ let { network: { redirecting } } = document.state;
1319
+ $(this).css(redirecting ? { pointerEvents: 'none', filter: 'blur(2)' } : { pointerEvents: 'auto', filter: 'blur(0)' });
1320
+ </script>
1321
+ </body>
1322
+ ```
1323
+
1324
+ + **`network.connectivity`: `String`** - This property tells of [the browser's ability to connect to the network](https://developer.mozilla.org/en-US/docs/Web/API/Navigator/onLine): `online`, `offline`.
1325
+
1326
+ On the UI, this could be used to show/hide a connectivity status.
1327
+
1328
+ ```html
1329
+ <body>
1330
+ <script type="subscript">
1331
+ let { network: { connectivity } } = document.state;
1332
+ $(this).attr( 'connectivity', connectivity });
1333
+ </script>
1334
+ </body>
1335
+ ```
1336
+
1337
+ Here are some additional examples with the [Observer API](https://github.com/webqit/observer).
1262
1338
 
1263
1339
  ```js
1264
1340
  // Visualize the network state
@@ -1272,12 +1348,12 @@ Observer.observe(document.state.network, onlineVisualizer);
1272
1348
  ```
1273
1349
 
1274
1350
  ```js
1275
- // Visualize the 'online' property
1276
- let onlineVisualizer = e => {
1277
- console.log('You are ', e.value ? 'online' : 'offline');
1351
+ // Visualize the 'connectivity' property
1352
+ let connectivityVisualizer = e => {
1353
+ console.log('You are ', e.value);
1278
1354
  };
1279
- Observer.observe(document.state.network, 'online', onlineVisualizer);
1280
- // Or: Observer.observe(document.state, [ ['network', 'online'] ], onlineVisualizer);
1355
+ Observer.observe(document.state.network, 'connectivity', connectivityVisualizer);
1356
+ // Or: Observer.observe(document.state, [ ['network', 'connectivity'] ], connectivityeVisualizer);
1281
1357
  ```
1282
1358
 
1283
1359
  ```js
@@ -1292,17 +1368,32 @@ Observer.observe(document.state.network, 'error', e => {
1292
1368
  });
1293
1369
  ```
1294
1370
 
1295
- ###### Form Actions
1371
+ ##### Form Actions
1372
+
1373
+ When navigation occurs [via form submissions](#scenario-4-single-page-navigation-requests-and-responses), the form element and the submit button are made to go on the *active* state while the request is being processed. For both of these elements, the Webflo client simply sets the `element.state.active` to `true` on submission, then `false`, on completion.
1374
+
1375
+ ```html
1376
+ <form method="post">
1377
+ <input name="username" placeholder="Your username..." />
1378
+ <script>
1379
+ $(this).css(this.state.active ? { pointerEvents: 'none', opacity: 'o.5' } : { pointerEvents: 'auto', opacity: '1' });
1380
+ </script>
1381
+ </form>
1382
+ ```
1296
1383
 
1297
- When navigation occurs [via form submissions](#scenario-4-single-page-navigation-requests-and-responses), the form element and the submit button are made to go on the *active* state while the request is processed. For both of these elements, the Webflo client simply sets the `element.state.active` to `true` on submission, then `false`, on completion.
1384
+ One more thing: HTML forms can only accept two HTTP methods on their `method` attribute: `GET`, `POST`! The same constraint exists on the equivalent `formmethod` attribue in submit buttons. You are able to overcome this in Webflo by using alternative `data-` attributes: `data-method`, `data-formmethod`, respectively.
1298
1385
 
1299
- <!-- TODO: method overrides -->
1386
+ ```html
1387
+ <form data-method="patch">
1388
+ <input name="price" placeholder="Enter new price..." />
1389
+ </form>
1390
+ ```
1300
1391
 
1301
- ##### Service Workers
1392
+ #### Progressive Web Apps
1302
1393
 
1303
- Webflo client-side applications are intended to provide an app-like-first experience. So unless disabled in [config](#enable_service_worker), a [Service Worker](https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API) is built as part of your application on running the `npm run generate` command. You may define [route handlers in the `/worker` directory](#handler-functions-and-layout) of your application, and these will be built into the service worker to handle Same-Origin requests of the application. Where there are no *worker* handlers, or where they forward these requests, the request is fetched, either from the cache, or from the network, depending on the fetching strategy built into the Service Worker.
1394
+ Webflo client-side applications are intended to provide an app-like-first experience. So unless disabled in [config](#enable_service_worker), a [Service Worker](https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API) is built as part of your application on running the `npm run generate` command. You may define [route handlers in the `/worker` directory](#handler-functions-and-layout) of your application, and these will be built into the service worker to handle Same-Origin requests of the application. Where there are no *worker* handlers, or where these forward incoming requests, requests are fetched, either from the cache, or from the network, depending on the fetching strategy built into the Service Worker.
1304
1395
 
1305
- ###### Fetching Strategy
1396
+ ##### Fetching Strategy
1306
1397
 
1307
1398
  + **Network First** - This strategy tells the Service Worker to always attempt fetching from the network first for given resources, before fetching from the cache. On every successful network fetch, a copy of the response is saved to the cache for next time. (This is good for resources that need to be fresh to the user on a "best effort" basis.) Unless [changed](#default_fetching_strategy), this is Webflo's default fetching strategy. When not the default strategy, a list of specific URLs that should be fetched this way can be [configured](#network_first_urls).
1308
1399
  + **Cache First** - This strategy tells the Service Worker to always attempt fetching from the cache first for given resources, before fetching from the network. After serving a cached response, or where not found in cache, a network fetch happens and a copy of the response is saved to the cache for next time. (This is good for resources that do not critially need to be fresh to the user.) When not the default strategy, a list of specific URLs that should be fetched this way can be [configured](#cache_first_urls).
@@ -1311,9 +1402,9 @@ Webflo client-side applications are intended to provide an app-like-first experi
1311
1402
 
1312
1403
  In all cases above, the convention for specifying URLs for a strategy accepts [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.)
1313
1404
 
1314
- ###### Cross-Thread Communications
1405
+ ##### Cross-Thread Communications
1315
1406
 
1316
- A couple APIs exists in browsers for establishing a two-way communication channel between a page and its service worker, for firing UI Notifications from either ends, and for implementing Push Notifications. Webflo offers to simply this with a unifying set of conventions:
1407
+ A couple APIs exists in browsers for establishing a two-way communication channel between a page and its Service Worker, for firing UI Notifications from either ends, and for implementing Push Notifications. Webflo offers to simply this with a unifying set of conventions:
1317
1408
 
1318
1409
  + The `workport` API - an object with simple methods for working with *cross-thread* messages, UI and Push Notifications.
1319
1410
 
@@ -1467,10 +1558,10 @@ And if you will partition your backend for both page routes and a formal REST AP
1467
1558
  ```shell
1468
1559
  server
1469
1560
  ├── index.js ──┐
1470
- ├── cart/index.js ├── Page Routes
1561
+ ├── cart/index.js ├─ Page Routes
1471
1562
  ├── products/index.js ──┘
1472
1563
  ├── api/v1/index.js ──┐
1473
- ├── api/v1/orders/index.js ├── REST API
1564
+ ├── api/v1/orders/index.js ├─ REST API
1474
1565
  └── api/v1/products/index.js ──┘
1475
1566
  ```
1476
1567
 
@@ -1536,12 +1627,6 @@ You could soon be taking all your ideas to Webflo! 😃
1536
1627
 
1537
1628
  All forms of contributions and PR are welcome! To report bugs or request features, please submit an [issue](https://github.com/webqit/webflo/issues). For general discussions, ideation or community help, please join our github [Discussions](https://github.com/webqit/webflo/discussions).
1538
1629
 
1539
- ## License
1540
-
1541
- MIT.
1542
-
1543
- ...
1544
-
1545
1630
  ## Getting Involved
1546
1631
 
1547
1632
  All forms of contributions and PR are welcome! To report bugs or request features, please submit an [issue](https://github.com/webqit/webflo/issues).
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.6",
15
+ "version": "0.11.7",
16
16
  "license": "MIT",
17
17
  "repository": {
18
18
  "type": "git",
@@ -118,7 +118,7 @@ export default class Runtime {
118
118
  return params;
119
119
  }, {});
120
120
  // We support method hacking
121
- submitParams.method = (submitter && submitter.dataset.method) || form.dataset.method || submitParams.method;
121
+ submitParams.method = (submitter && submitter.dataset.formmethod) || form.dataset.method || submitParams.method;
122
122
  submitParams.submitter = submitter;
123
123
  // ---------------
124
124
  var actionEl = window.document.createElement('a');
@@ -152,8 +152,8 @@ export default class Runtime {
152
152
  // -----------------------
153
153
  // Initialize network
154
154
  Observer.set(this, 'network', {});
155
- window.addEventListener('online', () => Observer.set(this.network, 'online', navigator.onLine));
156
- window.addEventListener('offline', () => Observer.set(this.network, 'online', navigator.onLine));
155
+ window.addEventListener('online', () => Observer.set(this.network, 'connectivity', 'online'));
156
+ window.addEventListener('offline', () => Observer.set(this.network, 'connectivity', 'offline'));
157
157
 
158
158
  // -----------------------
159
159
  // Service Worker && COMM