aboutsummaryrefslogtreecommitdiff
path: root/examples/01-hello-world/priv/static/app.mjs
diff options
context:
space:
mode:
Diffstat (limited to 'examples/01-hello-world/priv/static/app.mjs')
-rw-r--r--examples/01-hello-world/priv/static/app.mjs160
1 files changed, 115 insertions, 45 deletions
diff --git a/examples/01-hello-world/priv/static/app.mjs b/examples/01-hello-world/priv/static/app.mjs
index 60d0114..77b01fe 100644
--- a/examples/01-hello-world/priv/static/app.mjs
+++ b/examples/01-hello-world/priv/static/app.mjs
@@ -328,6 +328,12 @@ function text(content) {
}
// build/dev/javascript/lustre/lustre/internals/runtime.mjs
+var Debug = class extends CustomType {
+ constructor(x0) {
+ super();
+ this[0] = x0;
+ }
+};
var Dispatch = class extends CustomType {
constructor(x0) {
super();
@@ -336,6 +342,12 @@ var Dispatch = class extends CustomType {
};
var Shutdown = class extends CustomType {
};
+var ForceModel = class extends CustomType {
+ constructor(x0) {
+ super();
+ this[0] = x0;
+ }
+};
// build/dev/javascript/lustre/vdom.ffi.mjs
function morph(prev, next, dispatch, isComponent = false) {
@@ -373,6 +385,13 @@ function morph(prev, next, dispatch, isComponent = false) {
parent.replaceChild(created, prev2);
}
out ??= created;
+ } else if (next2.elements !== void 0) {
+ iterateElement(next2, (fragmentElement) => {
+ stack2.unshift({ prev: prev2, next: fragmentElement, parent });
+ prev2 = prev2?.nextSibling;
+ });
+ } else if (next2.subtree !== void 0) {
+ stack2.push({ prev: prev2, next: next2, parent });
}
}
return out;
@@ -397,9 +416,11 @@ function createElementNode({ prev, next, dispatch, stack: stack2 }) {
for (const attr of next.attrs) {
const name = attr[0];
const value = attr[1];
- const isProperty = attr[2];
- if (isProperty) {
- el2[name] = value;
+ if (attr.as_property) {
+ if (el2[name] !== value)
+ el2[name] = value;
+ if (canMorph)
+ prevAttributes.delete(name);
} else if (name.startsWith("on")) {
const eventName = name.slice(2);
const callback = dispatch(value);
@@ -424,8 +445,9 @@ function createElementNode({ prev, next, dispatch, stack: stack2 }) {
} else if (name === "dangerous-unescaped-html") {
innerHTML = value;
} else {
- el2.setAttribute(name, value);
- if (name === "value")
+ if (typeof value === "string")
+ el2.setAttribute(name, value);
+ if (name === "value" || name === "selected")
el2[name] = value;
if (canMorph)
prevAttributes.delete(name);
@@ -469,45 +491,22 @@ function createElementNode({ prev, next, dispatch, stack: stack2 }) {
incomingKeyedChildren = getKeyedChildren(next);
}
for (const child of next.children) {
- if (child.key !== void 0 && seenKeys !== null) {
- while (prevChild && !incomingKeyedChildren.has(prevChild.getAttribute("data-lustre-key"))) {
- const nextChild = prevChild.nextSibling;
- el2.removeChild(prevChild);
- prevChild = nextChild;
- }
- if (keyedChildren.size === 0) {
- stack2.unshift({ prev: prevChild, next: child, parent: el2 });
- prevChild = prevChild?.nextSibling;
- continue;
- }
- if (seenKeys.has(child.key)) {
- console.warn(`Duplicate key found in Lustre vnode: ${child.key}`);
- stack2.unshift({ prev: null, next: child, parent: el2 });
- continue;
- }
- seenKeys.add(child.key);
- const keyedChild = keyedChildren.get(child.key);
- if (!keyedChild && !prevChild) {
- stack2.unshift({ prev: null, next: child, parent: el2 });
- continue;
- }
- if (!keyedChild && prevChild !== null) {
- const placeholder = document.createTextNode("");
- el2.insertBefore(placeholder, prevChild);
- stack2.unshift({ prev: placeholder, next: child, parent: el2 });
- continue;
- }
- if (!keyedChild || keyedChild === prevChild) {
- stack2.unshift({ prev: prevChild, next: child, parent: el2 });
+ iterateElement(child, (currElement) => {
+ if (currElement.key !== void 0 && seenKeys !== null) {
+ prevChild = diffKeyedChild(
+ prevChild,
+ currElement,
+ el2,
+ stack2,
+ incomingKeyedChildren,
+ keyedChildren,
+ seenKeys
+ );
+ } else {
+ stack2.unshift({ prev: prevChild, next: currElement, parent: el2 });
prevChild = prevChild?.nextSibling;
- continue;
}
- el2.insertBefore(keyedChild, prevChild);
- stack2.unshift({ prev: keyedChild, next: child, parent: el2 });
- } else {
- stack2.unshift({ prev: prevChild, next: child, parent: el2 });
- prevChild = prevChild?.nextSibling;
- }
+ });
}
while (prevChild) {
const next2 = prevChild.nextSibling;
@@ -565,13 +564,63 @@ function getKeyedChildren(el2) {
const keyedChildren = /* @__PURE__ */ new Map();
if (el2) {
for (const child of el2.children) {
- const key = child.key || child?.getAttribute("data-lustre-key");
- if (key)
- keyedChildren.set(key, child);
+ iterateElement(child, (currElement) => {
+ const key = currElement?.key || currElement?.getAttribute?.("data-lustre-key");
+ if (key)
+ keyedChildren.set(key, currElement);
+ });
}
}
return keyedChildren;
}
+function diffKeyedChild(prevChild, child, el2, stack2, incomingKeyedChildren, keyedChildren, seenKeys) {
+ while (prevChild && !incomingKeyedChildren.has(prevChild.getAttribute("data-lustre-key"))) {
+ const nextChild = prevChild.nextSibling;
+ el2.removeChild(prevChild);
+ prevChild = nextChild;
+ }
+ if (keyedChildren.size === 0) {
+ iterateElement(child, (currChild) => {
+ stack2.unshift({ prev: prevChild, next: currChild, parent: el2 });
+ prevChild = prevChild?.nextSibling;
+ });
+ return prevChild;
+ }
+ if (seenKeys.has(child.key)) {
+ console.warn(`Duplicate key found in Lustre vnode: ${child.key}`);
+ stack2.unshift({ prev: null, next: child, parent: el2 });
+ return prevChild;
+ }
+ seenKeys.add(child.key);
+ const keyedChild = keyedChildren.get(child.key);
+ if (!keyedChild && !prevChild) {
+ stack2.unshift({ prev: null, next: child, parent: el2 });
+ return prevChild;
+ }
+ if (!keyedChild && prevChild !== null) {
+ const placeholder = document.createTextNode("");
+ el2.insertBefore(placeholder, prevChild);
+ stack2.unshift({ prev: placeholder, next: child, parent: el2 });
+ return prevChild;
+ }
+ if (!keyedChild || keyedChild === prevChild) {
+ stack2.unshift({ prev: prevChild, next: child, parent: el2 });
+ prevChild = prevChild?.nextSibling;
+ return prevChild;
+ }
+ el2.insertBefore(keyedChild, prevChild);
+ stack2.unshift({ prev: keyedChild, next: child, parent: el2 });
+ return prevChild;
+}
+function iterateElement(element3, processElement) {
+ if (element3.elements !== void 0) {
+ for (const currElement of element3.elements) {
+ processElement(currElement);
+ }
+ } else {
+ processElement(element3);
+ }
+}
// build/dev/javascript/lustre/client-runtime.ffi.mjs
var LustreClientApplication2 = class _LustreClientApplication {
@@ -613,6 +662,10 @@ var LustreClientApplication2 = class _LustreClientApplication {
this.#shutdown();
return;
}
+ case action instanceof Debug: {
+ this.#debug(action[0]);
+ return;
+ }
default:
return;
}
@@ -659,6 +712,23 @@ var LustreClientApplication2 = class _LustreClientApplication {
}
}
}
+ #debug(action) {
+ switch (true) {
+ case action instanceof ForceModel: {
+ const vdom = this.#view(action[0]);
+ const dispatch = (handler) => (e) => {
+ const result = handler(e);
+ if (result instanceof Ok) {
+ this.send(new Dispatch(result[0]));
+ }
+ };
+ this.#queue = [];
+ this.#effects = [];
+ this.#didUpdate = false;
+ this.#root = morph(this.#root, vdom, dispatch, this.#isComponent);
+ }
+ }
+ }
#shutdown() {
this.#root.remove();
this.#root = null;