diff --git a/literal-html/module.js b/literal-html/module.js
index d051ae8..75d0a60 100644
--- a/literal-html/module.js
+++ b/literal-html/module.js
@@ -84,9 +84,8 @@ mapping an array of objects to template includes:
import noop from '../../fn/modules/noop.js';
-import Stream from '../../fn/modules/stream.js';
import element, { getInternals as Internals } from '../../dom/modules/element.js';
-/*import properties, { addLoading, removeLoading } from '../modules/properties.js';*/
+import LatestStream from '../modules/latest-stream.js';
import requestData from '../modules/request-data.js';
import TemplateRenderer from '../modules/renderer-template.js';
import print from '../modules/library/print.js';
@@ -113,39 +112,20 @@ function parseData(value) {
value ;
}
-function resolveData(value) {
- return rpath.test(value) ?
- requestData(value) :
- parseData(value) ;
-}
-
-function requestDataFromSrc(template, datas, value) {
- return requestData(value)
- .then((data) => datas.push(data))
- .catch((e) => onerror(e, template));
-}
-
-function requestDataFromDataset(template, datas, dataset) {
+function getDataFromDataset(dataset) {
const keys = Object.keys(dataset);
const values = Object.values(dataset);
- //addLoading(template);
-
- return Promise
- .all(values.map(resolveData))
- .then((values) => datas.push(
- values.reduce((data, value, i) => (data[keys[i]] = value, data), {})
- ))
- .catch((e) => onerror(e, template))
- //.finally(() => removeLoading(template));
+ return values
+ .map(parseData)
+ .reduce((data, value, i) => (data[keys[i]] = value, data), {}) ;
}
// tag, template, lifecycle, properties, log
export default element('', {
construct: function() {
const internals = Internals(this);
-
- internals.datas = Stream.of();
+ internals.datas = new LatestStream();
internals.renderer = new TemplateRenderer(this, {
root: document.documentElement,
body: document.body,
@@ -160,18 +140,39 @@ export default element('', {
const { datas, renderer } = internals;
let replaced = false;
+ let promise;
- datas.each((data) => {
+ const push = (data) => {
renderer.push(data);
if (!replaced) {
this.replaceWith(renderer.content);
replaced = true;
}
+ };
+
+ datas.each((promiseOrData) => {
+ // Cancel existing promise of data
+ if (promise) {
+ promise.cancelled = true;
+ promise = undefined;
+ }
+
+ if (promiseOrData.then) {
+ // Set promise
+ const p = promise = promiseOrData.then((data) => {
+ if (p.cancelled) { return; }
+ push(data);
+ });
+
+ return;
+ }
+
+ push(promiseOrData);
});
- // If data property was not set use data found in dataset
- if (!internals.hasData) {
- requestDataFromDataset(this, datas, this.dataset);
+ // If src or data was not set use data found in dataset
+ if (!promise && !replaced) {
+ datas.push(getDataFromDataset(this.dataset));
}
}
}, {
@@ -196,9 +197,9 @@ export default element('', {
get: function() { this.src; },
set: function(value) {
const internals = Internals(this);
- requestDataFromSrc(this, internals.datas, value);
- // Flag data as having come from the data property
- internals.hasData = true;
+ internals.datas.push(
+ requestData(value).catch((e) => onerror(e, this))
+ );
}
},
@@ -244,8 +245,6 @@ export default element('', {
set: function(value) {
const internals = Internals(this);
internals.datas.push(value);
- // Flag data as having come from the data property
- internals.hasData = true;
}
}
});
diff --git a/modules/latest-stream.js b/modules/latest-stream.js
new file mode 100755
index 0000000..216a07f
--- /dev/null
+++ b/modules/latest-stream.js
@@ -0,0 +1,30 @@
+
+import Stream, { pipe } from '../../fn/modules/stream/stream.js';
+
+const assign = Object.assign;
+const create = Object.create;
+
+
+/*
+LatestStream(values)
+A LatestStream may be pushed to before it is piped.
+*/
+
+function push(value) {
+ // Store latest pushed value
+ if (value === undefined) { return; }
+ this.value = value;
+}
+
+export default function LatestStream() {
+ this.push = push;
+}
+
+LatestStream.prototype = assign(create(Stream.prototype), {
+ pipe: function(output) {
+ pipe(this, output);
+ if (this.value !== undefined) { output.push(value); }
+ delete this.push;
+ return output;
+ }
+});