@lifeart/gxt
Version:
<img align="right" width="95" height="95" alt="Philosopher’s stone, logo of PostCSS" src="./public/logo.png">
1,840 lines (1,829 loc) • 85.6 kB
JavaScript
import { C as CONSTANTS } from './symbols-KamXCUHQ.js';
const $dfi = /* @__PURE__ */ new WeakMap();
const destroyedObjects = /* @__PURE__ */ new WeakSet();
{
if (IS_DEV_MODE) {
window["getDestructors"] = () => $dfi;
}
}
function destroySync(ctx) {
destroyedObjects.add(ctx);
const destructors = $dfi.get(ctx);
if (destructors === void 0) {
return;
}
$dfi.delete(ctx);
for (let i = 0; i < destructors.length; i++) {
destructors[i]();
}
}
function destroy(ctx, promises = []) {
destroyedObjects.add(ctx);
const destructors = $dfi.get(ctx);
if (destructors === void 0) {
return;
}
$dfi.delete(ctx);
let result;
for (let i = 0; i < destructors.length; i++) {
result = destructors[i]();
if (result) {
promises.push(result);
}
}
}
function registerDestructor(ctx, ...fn) {
let existingDestructors = $dfi.get(ctx);
if (existingDestructors === void 0) {
existingDestructors = [];
$dfi.set(ctx, existingDestructors);
}
existingDestructors.push(...fn);
}
function isDestroyed(ctx) {
return destroyedObjects.has(ctx);
}
function associateDestroyableChild(parent, child) {
registerDestructor(parent, () => {
destroy(child);
});
}
const destroyable = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({
__proto__: null,
associateDestroyableChild,
destroy,
destroySync,
isDestroyed,
registerDestructor
}, Symbol.toStringTag, { value: 'Module' }));
const isTag = Symbol("isTag");
const RENDERING_CONTEXT_PROPERTY = Symbol("rendering-context");
const RENDERED_NODES_PROPERTY = Symbol("nodes");
const COMPONENT_ID_PROPERTY = Symbol("id");
let componentIdCounter = 1;
function cId() {
return componentIdCounter++;
}
const $template = "template";
const $context = "_context";
const $nodes = "nodes";
const $args = "args";
const $_debug_args = "_debug_args";
const $fwProp = "$fw";
const FRAGMENT_TYPE = 11;
const IN_SSR_ENV = location.pathname === "/tests.html";
const $DEBUG_REACTIVE_CONTEXTS = [];
function debugContext(debugName) {
return [...$DEBUG_REACTIVE_CONTEXTS.filter((el) => el !== "UnstableChildWrapper"), debugName].join(" > ");
}
function isArray(value) {
return Array.isArray(value);
}
function isFn(value) {
return typeof value === "function";
}
function isEmpty(value) {
return value === null || value === void 0;
}
function isPrimitive(value) {
const vType = typeof value;
return vType === "string" || vType === "number" || vType === "boolean" || vType === "bigint";
}
function isTagLike(child) {
return child[isTag];
}
const BOUNDS = /* @__PURE__ */ new WeakMap();
{
if (IS_DEV_MODE) {
window["getRenderTree"] = () => {
return {
TREE,
CHILD,
PARENT
};
};
window["getParentGraph"] = () => PARENT;
}
}
function getBounds(ctx) {
if (ctx[RENDERED_NODES_PROPERTY].length) {
return ctx[RENDERED_NODES_PROPERTY].slice(0);
}
return BOUNDS.get(ctx) ?? [];
}
function setBounds(component) {
const ctx = component.ctx;
if (!ctx) {
return;
}
const maybeBounds = component[$nodes].map((node) => {
const isHTMLElement = node instanceof HTMLElement;
if (!isHTMLElement) {
if (node instanceof Comment) {
return [node, node.nextSibling];
} else if (node instanceof DocumentFragment) {
return [];
}
}
if (isHTMLElement) {
return [node];
}
return [];
});
const flattenBounds = maybeBounds.flat(Infinity).filter((node) => node !== null);
if (flattenBounds.length === 0) {
return;
}
BOUNDS.set(ctx, flattenBounds);
registerDestructor(ctx, () => {
BOUNDS.delete(ctx);
});
}
const SEEN_TREE_NODES = /* @__PURE__ */ new WeakSet();
const TREE = /* @__PURE__ */ new Map();
const CHILD = /* @__PURE__ */ new Map();
const PARENT = /* @__PURE__ */ new Map();
function addToTree(ctx, node, debugName) {
if (SEEN_TREE_NODES.has(node)) {
return;
}
const ID = node[COMPONENT_ID_PROPERTY];
const PARENT_ID = ctx[COMPONENT_ID_PROPERTY];
let ch = CHILD.get(PARENT_ID);
if (ch === void 0) {
ch = [ID];
CHILD.set(PARENT_ID, ch);
} else {
ch.push(ID);
}
TREE.set(ID, node);
if (WITH_CONTEXT_API) {
PARENT.set(ID, PARENT_ID);
}
SEEN_TREE_NODES.add(node);
if (IS_DEV_MODE) {
if ("nodeType" in node) {
throw new Error("invalid node");
} else if ("ctx" in node && node.ctx === null) {
throw new Error("invalid node");
}
if (debugName) {
Object.defineProperty(node, "_debugName", {
value: debugName,
enumerable: false
});
}
if (!node) {
throw new Error("invalid node");
}
if (!ctx) {
throw new Error("invalid ctx");
}
}
registerDestructor(node, () => {
if (IS_DEV_MODE) {
SEEN_TREE_NODES.delete(node);
}
CHILD.delete(ID);
TREE.delete(ID);
if (WITH_CONTEXT_API) {
PARENT.delete(ID);
}
});
}
const LISTS_FOR_HMR = /* @__PURE__ */ new Set();
const IFS_FOR_HMR = /* @__PURE__ */ new Set();
const COMPONENTS_HMR = /* @__PURE__ */ new WeakMap();
function runEffectDestructor(destructor) {
if (destructor !== void 0) {
const result = destructor();
if (IS_DEV_MODE) {
if (result && result instanceof Promise) {
throw new Error(`Effect destructor can't be a promise: ${destructor.toString()}`);
}
}
}
}
function effect(cb) {
const sourceTag = formula(cb, "effect.internal");
let destructor;
let isDestroyCalled = false;
const tag = formula(() => {
runEffectDestructor(destructor);
destructor = void 0;
return sourceTag.value;
}, "effect");
const destroyOpcode = opcodeFor(tag, (value) => {
if (IS_DEV_MODE) {
if (value instanceof Promise) {
throw new Error(`Effect can't be a promise: ${cb.toString()}`);
}
}
if (isFn(value)) {
destructor = value;
}
});
return () => {
if (isDestroyCalled) {
return;
}
isDestroyCalled = true;
runEffectDestructor(destructor);
sourceTag.destroy();
tag.destroy();
destroyOpcode();
};
}
function trackingTransaction(cb) {
if (isRendering()) {
cb();
} else {
setIsRendering(true);
cb();
setIsRendering(false);
}
}
const executeOpcode = (tag, op) => {
const value = op(tag.value);
if (value !== void 0) {
asyncOpcodes.add(op);
}
};
function checkOpcode(tag, op) {
trackingTransaction(() => {
inNewTrackingFrame(() => {
executeOpcode(tag, op);
});
});
}
function evaluateOpcode(tag, op) {
trackingTransaction(() => {
executeOpcode(tag, op);
});
}
function opcodeFor(tag, op) {
evaluateOpcode(tag, op);
const ops = opsFor(tag);
ops.push(op);
return () => {
const index = ops.indexOf(op);
if (index > -1) {
ops.splice(index, 1);
}
if (ops.length === 0) {
opsForTag.delete(tag.id);
if ("destroy" in tag) {
tag.destroy();
}
}
};
}
const CONTEXTS = /* @__PURE__ */ new WeakMap();
const RENDERING_CONTEXT = Symbol("RENDERING_CONTEXT");
function initDOM(ctx) {
if (fastRenderingContext !== null) {
return fastRenderingContext;
}
const renderingContext = ctx[RENDERING_CONTEXT_PROPERTY];
if (renderingContext) {
return renderingContext;
}
return ctx[RENDERING_CONTEXT_PROPERTY] = getContext(ctx, RENDERING_CONTEXT);
}
function getContext(ctx, key) {
if (!WITH_CONTEXT_API) {
ctx = getRoot();
}
let current = ctx;
let context2;
while (current) {
context2 = CONTEXTS.get(current);
if (context2?.has(key)) {
const value = context2.get(key);
return isFn(value) ? value() : value;
}
current = TREE.get(PARENT.get(current[COMPONENT_ID_PROPERTY]));
}
return null;
}
let fastRenderingContext = null;
function provideContext(ctx, key, value) {
if (key === RENDERING_CONTEXT) {
if (ctx instanceof Root) {
fastRenderingContext = value;
registerDestructor(ctx, () => {
fastRenderingContext = null;
});
} else {
fastRenderingContext = null;
}
}
if (!WITH_CONTEXT_API) {
ctx = getRoot();
}
if (!CONTEXTS.has(ctx)) {
CONTEXTS.set(ctx, /* @__PURE__ */ new Map());
registerDestructor(ctx, () => {
CONTEXTS.delete(ctx);
});
}
CONTEXTS.get(ctx).set(key, value);
}
function getFirstNode(rawItem) {
if (isArray(rawItem)) {
return getFirstNode(rawItem[0]);
} else if ("nodeType" in rawItem) {
return rawItem;
} else {
return rawItem.ctx[RENDERED_NODES_PROPERTY][0];
}
}
function countLessThan(arr, target) {
let low = 0, high = arr.length;
while (low < high) {
const mid = low + high >> 1;
if (arr[mid] < target) {
low = mid + 1;
} else {
high = mid;
}
}
return low;
}
class BasicListComponent {
keyMap = /* @__PURE__ */ new Map();
indexMap = /* @__PURE__ */ new Map();
nodes = [];
[RENDERED_NODES_PROPERTY] = [];
[COMPONENT_ID_PROPERTY] = cId();
ItemComponent;
bottomMarker;
topMarker;
key = "@identity";
tag;
isSync = false;
isFirstRender = true;
get ctx() {
return this;
}
*keyGenerator(items, keyForItem) {
for (let i = 0; i < items.length; i++) {
yield keyForItem(items[i], i);
}
}
constructor({
tag,
ctx,
key,
ItemComponent
}, outlet, topMarker) {
this.api = initDOM(ctx);
this.ItemComponent = ItemComponent;
this.args = {
[$context]: ctx
};
addToTree(ctx, this, "from list constructor");
const mainNode = outlet;
this[$nodes] = [];
if (key) {
this.key = key;
}
this.setupKeyForItem();
if (IS_DEV_MODE) {
Object.defineProperty(this, $_debug_args, {
get() {
return {
list: this.tag,
key: this.key
};
}
});
LISTS_FOR_HMR.add(this);
registerDestructor(ctx, () => {
LISTS_FOR_HMR.delete(this);
});
}
if (IS_DEV_MODE) {
this.bottomMarker = this.api.comment("list bottom marker");
} else {
this.bottomMarker = this.api.comment();
}
this.topMarker = topMarker;
this.api.insert(mainNode, this.topMarker);
this.api.insert(mainNode, this.bottomMarker);
const originalTag = tag;
if (!isTagLike(tag)) {
if (isArray(tag)) {
console.warn("iterator for @each should be a cell");
tag = new Cell(tag, "list tag");
} else if (isFn(originalTag)) {
tag = formula(() => deepFnValue(originalTag), "list tag");
registerDestructor(ctx, () => {
tag.destroy();
});
}
}
this.tag = tag;
}
setupKeyForItem() {
if (this.key === "@identity") {
let cnt = 0;
const map = /* @__PURE__ */ new WeakMap();
this.keyForItem = (item, i) => {
if (isPrimitive(item) || isEmpty(item)) {
return `${String(item)}:${i}`;
}
const existing = map.get(item);
if (existing !== void 0) {
return existing;
}
const key = ++cnt;
map.set(item, key);
return key;
};
} else {
this.keyForItem = (item) => {
if (IS_DEV_MODE) {
if (this.key.split(".").length > 1) {
console.warn("Nested keys are not supported yet, likely you need to specify custom keyForItem function");
const resolvedKeyValue = this.key.split(".").reduce((acc, key) => {
return acc[key];
}, item);
console.log({
resolvedKeyValue,
key: this.key,
item
});
return String(resolvedKeyValue);
}
if (typeof item[this.key] === "undefined") {
throw new Error(`Key for item not found, ${JSON.stringify(item)} ${this.key}`);
}
}
return item[this.key];
};
}
}
// @ts-expect-error non-string return type
keyForItem(item, index) {
if (IS_DEV_MODE) {
throw new Error(`Key for item not implemented, ${JSON.stringify(item)}`);
}
}
getTargetNode(amountOfKeys) {
if (amountOfKeys > 0) {
return this.bottomMarker;
} else {
let fragment;
const marker = IS_DEV_MODE ? this.api.comment("list fragment target marker") : this.api.comment("");
if (isRehydrationScheduled()) {
fragment = marker.parentElement;
} else {
fragment = this.api.fragment();
this.api.insert(fragment, marker);
}
return marker;
}
}
updateItems(items, amountOfKeys, removedIndexes) {
const {
indexMap,
keyMap,
bottomMarker,
keyForItem,
ItemComponent,
isFirstRender,
api
} = this;
const rowsToMove = [];
const amountOfExistingKeys = amountOfKeys - removedIndexes.length;
if (removedIndexes.length > 0 && keyMap.size > 0) {
removedIndexes.sort((a, b) => a - b);
for (const key of keyMap.keys()) {
let keyIndex = indexMap.get(key);
const count = countLessThan(removedIndexes, keyIndex);
if (count !== 0) {
indexMap.set(key, keyIndex - count);
}
}
}
let targetNode = items.length ? this.getTargetNode(amountOfExistingKeys) : bottomMarker;
let seenKeys = 0;
const appendedIndexes = /* @__PURE__ */ new Set();
let isAppendOnly = isFirstRender;
items.forEach((item, index) => {
if (seenKeys === amountOfExistingKeys) {
isAppendOnly = true;
if (targetNode === bottomMarker) {
targetNode = this.getTargetNode(0);
}
}
const key = keyForItem(item, index);
const maybeRow = keyMap.get(key);
if (!maybeRow) {
if (!isAppendOnly) {
appendedIndexes.add(index);
}
let idx = index;
if (IS_DEV_MODE) {
idx = formula(() => {
if (isPrimitive(item)) {
return index;
}
const values = this.tag.value;
const itemIndex = values.indexOf(item);
if (itemIndex === -1) {
return values.findIndex((value, i) => {
return keyForItem(value, i) === key;
});
}
return itemIndex;
}, `each.index[${index}]`);
}
const row = ItemComponent(item, idx, this);
keyMap.set(key, row);
indexMap.set(key, index);
if (isAppendOnly) {
renderElement(api, this, targetNode.parentNode, row, targetNode);
} else {
rowsToMove.push([row, index]);
for (let [mapKey, value] of indexMap) {
if (value >= index) {
indexMap.set(mapKey, index + 1);
}
}
}
} else {
seenKeys++;
const expectedIndex = indexMap.get(key);
if (expectedIndex !== index && !appendedIndexes.has(expectedIndex)) {
indexMap.set(key, index);
rowsToMove.push([maybeRow, index]);
}
}
});
const childs = CHILD.get(this[COMPONENT_ID_PROPERTY]);
if (childs !== void 0) {
childs.length = 0;
}
rowsToMove.sort((r1, r2) => {
return r2[1] - r1[1];
}).forEach(([row, index]) => {
const nextItem = items[index + 1];
const insertBeforeNode = nextItem ? getFirstNode(keyMap.get(keyForItem(nextItem, index + 1))) : bottomMarker;
api.insert(insertBeforeNode.parentNode, getFirstNode(row), insertBeforeNode);
});
if (targetNode !== bottomMarker) {
const parent = targetNode.parentNode;
const trueParent = bottomMarker.parentNode;
if (!IN_SSR_ENV) {
parent && parent.removeChild(targetNode);
}
if (parent && trueParent !== parent) {
api.insert(trueParent, parent, bottomMarker);
}
}
if (isFirstRender) {
this.isFirstRender = false;
}
}
}
class SyncListComponent extends BasicListComponent {
constructor(params, outlet, topMarker) {
super(params, outlet, topMarker);
registerDestructor(params.ctx, () => this.syncList([]), opcodeFor(this.tag, (value) => {
this.syncList(value);
}));
}
fastCleanup() {
const {
keyMap,
bottomMarker,
topMarker,
indexMap
} = this;
const parent = bottomMarker.parentElement;
if (parent && parent.lastChild === bottomMarker && parent.firstChild === topMarker) {
for (const value of keyMap.values()) {
destroyElementSync(value, true);
}
parent.innerHTML = "";
parent.append(topMarker);
parent.append(bottomMarker);
keyMap.clear();
indexMap.clear();
return true;
} else {
return false;
}
}
syncList(items) {
const {
keyMap,
keyForItem,
indexMap
} = this;
if (items.length === 0) {
if (this.fastCleanup()) {
return;
}
}
let amountOfKeys = keyMap.size;
const indexesToRemove = [];
if (amountOfKeys > 0) {
const updatingKeys = new Set(this.keyGenerator(items, keyForItem));
const keysToRemove = [];
const rowsToRemove = [];
for (const [key, row] of keyMap.entries()) {
if (updatingKeys.has(key)) {
continue;
}
keysToRemove.push(key);
rowsToRemove.push(row);
indexesToRemove.push(indexMap.get(key));
}
if (keysToRemove.length) {
if (keysToRemove.length === amountOfKeys) {
if (this.fastCleanup()) {
amountOfKeys = 0;
keysToRemove.length = 0;
indexesToRemove.length = 0;
}
}
for (let i = 0; i < keysToRemove.length; i++) {
this.destroyItem(rowsToRemove[i], keysToRemove[i]);
}
}
}
this.updateItems(items, amountOfKeys, indexesToRemove);
}
destroyItem(row, key) {
this.keyMap.delete(key);
this.indexMap.delete(key);
destroyElementSync(row);
}
}
class AsyncListComponent extends BasicListComponent {
destroyPromise = null;
constructor(params, outlet, topMarker) {
super(params, outlet, topMarker);
registerDestructor(params.ctx, () => {
if (this.destroyPromise) {
return this.destroyPromise;
}
}, async () => {
await this.syncList([]);
}, opcodeFor(this.tag, async (value) => {
await this.syncList(value);
}));
}
async fastCleanup() {
const {
bottomMarker,
topMarker,
keyMap,
indexMap
} = this;
const parent = bottomMarker.parentElement;
if (parent && parent.lastChild === bottomMarker && parent.firstChild === topMarker) {
const promises = new Array(keyMap.size);
let i = 0;
for (const value of keyMap.values()) {
promises[i] = destroyElement(value, true);
i++;
}
await Promise.all(promises);
promises.length = 0;
parent.innerHTML = "";
parent.append(topMarker);
parent.append(bottomMarker);
keyMap.clear();
indexMap.clear();
return true;
} else {
return false;
}
}
async syncList(items) {
if (items.length === 0) {
if (await this.fastCleanup()) {
return;
}
}
const {
keyMap,
keyForItem,
indexMap
} = this;
let amountOfKeys = keyMap.size;
const indexesToRemove = [];
if (amountOfKeys > 0) {
const keysToRemove = [];
const rowsToRemove = [];
const removeQueue = [];
const updatingKeys = new Set(this.keyGenerator(items, keyForItem));
for (const [key, row] of keyMap.entries()) {
if (updatingKeys.has(key)) {
continue;
}
keysToRemove.push(key);
rowsToRemove.push(row);
indexesToRemove.push(indexMap.get(key));
}
if (keysToRemove.length) {
if (keysToRemove.length === amountOfKeys) {
if (await this.fastCleanup()) {
amountOfKeys = 0;
keysToRemove.length = 0;
indexesToRemove.length = 0;
}
}
for (let i = 0; i < keysToRemove.length; i++) {
removeQueue.push(this.destroyItem(rowsToRemove[i], keysToRemove[i]));
}
}
const removePromise = Promise.all(removeQueue);
if (removeQueue.length) {
this.destroyPromise = removePromise;
removePromise.then(() => {
this.destroyPromise = null;
});
}
}
this.updateItems(items, amountOfKeys, indexesToRemove);
}
async destroyItem(row, key) {
this.keyMap.delete(key);
this.indexMap.delete(key);
await destroyElement(row);
}
}
function createHotReload(component) {
return function hotReload(oldklass, newKlass) {
const renderedInstances = COMPONENTS_HMR.get(oldklass);
if (!renderedInstances) {
return;
}
const renderedBuckets = Array.from(renderedInstances);
renderedBuckets.forEach(({
parent,
instance,
args
}) => {
const newCmp = component(newKlass, args, parent);
const firstElement = getFirstNode(instance);
const parentElement = firstElement.parentNode;
if (!parentElement) {
return;
}
LISTS_FOR_HMR.forEach((list) => {
Array.from(list.keyMap).forEach(([key, lineItems]) => {
if (isArray(lineItems)) {
for (let k = 0; k < lineItems.length; k++) {
const value = lineItems[k];
if (instance === value) {
lineItems[k] = newCmp;
}
}
} else if (instance === lineItems) {
list.keyMap.set(key, instance);
}
});
});
IFS_FOR_HMR.forEach((fn) => {
const {
item: scopes,
set
} = fn();
if (scopes === instance) {
set(newCmp);
} else if (Array.isArray(scopes)) {
let dirty = false;
for (let i = 0; i < scopes.length; i++) {
if (scopes[i] === instance) {
scopes[i] = newCmp;
dirty = true;
}
}
if (dirty) {
set(scopes);
}
} else if (scopes && "nodes" in scopes) {
let dirty = false;
for (let i = 0; i < scopes.nodes.length; i++) {
if (scopes.nodes[i] === instance) {
scopes.nodes[i] = newCmp;
dirty = true;
}
}
if (dirty) {
set(scopes);
}
}
});
const api = initDOM(newCmp.ctx);
renderElement(api, newCmp.ctx, parentElement, newCmp, firstElement);
unregisterFromParent(instance);
destroyElementSync(instance);
});
COMPONENTS_HMR.delete(oldklass);
};
}
class IfCondition {
isDestructorRunning = false;
prevComponent = null;
condition;
destructors = [];
runNumber = 0;
lastValue = false;
target;
placeholder;
throwedError = null;
destroyPromise = null;
[RENDERED_NODES_PROPERTY] = [];
[COMPONENT_ID_PROPERTY] = cId();
trueBranch;
falseBranch;
constructor(parentContext, maybeCondition, target, placeholder, trueBranch, falseBranch) {
this.target = target;
this.placeholder = placeholder;
this.setupCondition(maybeCondition);
this.trueBranch = trueBranch;
this.falseBranch = falseBranch;
this.args = {
[$context]: parentContext
};
addToTree(parentContext, this, "from if constructor");
this.destructors.push(opcodeFor(this.condition, this.syncState.bind(this)));
registerDestructor(parentContext, this.destroy.bind(this));
if (IS_DEV_MODE) {
const instance = () => {
return {
item: this.prevComponent,
set: (value) => {
this.prevComponent = value;
}
};
};
IFS_FOR_HMR.add(instance);
this.destructors.push(() => {
IFS_FOR_HMR.delete(instance);
});
Object.defineProperty(this, $_debug_args, {
get() {
return {
if: this.lastValue
};
}
});
}
}
checkStatement(value) {
this.runNumber++;
if (this.runNumber > 1) {
if (this.lastValue === !!value) {
return;
}
}
if (this.isDestructorRunning) {
return;
}
this.lastValue = !!value;
return true;
}
async reInit() {
this.destructors.shift();
this.throwedError = null;
this.runNumber = 0;
this.destructors.unshift(opcodeFor(this.condition, this.syncState.bind(this)));
}
syncState(value) {
if (this.throwedError) {
Promise.resolve().then(async () => {
await this.reInit();
});
throw this.throwedError;
}
if (!this.checkStatement(value)) {
return;
}
const nextBranch = value ? this.trueBranch : this.falseBranch;
this.renderBranch(nextBranch, this.runNumber);
}
renderBranch(nextBranch, runNumber) {
if (this.destroyPromise) {
this.destroyPromise.then(() => {
this.destroyPromise = null;
this.renderBranch(nextBranch, runNumber);
});
return;
} else if (this.prevComponent) {
this.destroyBranch().then(() => {
this.renderBranch(nextBranch, runNumber);
});
return;
}
if (!this.validateEpoch(runNumber)) {
return;
}
this.renderState(nextBranch);
}
validateEpoch(runNumber) {
if (this.isDestructorRunning) {
return false;
}
if (this.runNumber !== runNumber) {
if (IS_DEV_MODE) {
this.throwedError = new Error(`
Woops, error in ifCondition, managed by ${this.condition._debugName}:
Run number mismatch, looks like some modifier is removed longer than re-rendering takes.
It may be a bug in your code. We can't sync DOM because it's always outdated.
Removing opcode to not break whole app.
`);
} else {
this.throwedError = new Error(`ERROR_0`);
}
return false;
}
return true;
}
async destroyBranch() {
const branch = this.prevComponent;
if (branch === null) {
return;
} else {
this.prevComponent = null;
}
await destroyElement(branch, false);
}
renderState(nextBranch) {
if (IS_DEV_MODE) {
$DEBUG_REACTIVE_CONTEXTS.push(`if:${String(this.lastValue)}`);
}
this.prevComponent = nextBranch(this);
if (IS_DEV_MODE) {
$DEBUG_REACTIVE_CONTEXTS.pop();
}
renderElement(initDOM(this), this, this.placeholder.parentNode || this.target, this.prevComponent, this.placeholder);
unregisterFromParent(this.prevComponent);
return;
}
async destroy() {
this.isDestructorRunning = true;
if (this.placeholder.isConnected) ;
await this.destroyBranch();
await Promise.all(this.destructors.map((destroyFn) => destroyFn()));
}
setupCondition(maybeCondition) {
if (isFn(maybeCondition)) {
this.condition = formula(() => {
const v = maybeCondition();
if (isPrimitive(v) || isEmpty(v)) {
return !!v;
} else if (isTagLike(v)) {
return !!v.value;
} else {
return !!v;
}
}, "if-condition-wrapper-fn");
} else if (isPrimitive(maybeCondition)) {
this.condition = formula(() => maybeCondition, "if-condition-primitive-wrapper");
} else {
this.condition = maybeCondition;
}
}
}
const NS_HTML = "http://www.w3.org/1999/xhtml";
const NS_MATHML = "http://www.w3.org/1998/Math/MathML";
const NS_SVG = "http://www.w3.org/2000/svg";
const NS_XLINK = "http://www.w3.org/1999/xlink";
const NS_XMLNS = "http://www.w3.org/2000/xmlns/";
const svgDomApi = {
toString() {
return "svg:dom-api";
},
text(text) {
return getDocument().createTextNode(text);
},
textContent(node, text) {
node.textContent = text;
},
element: (tagName) => {
return getDocument().createElementNS(NS_SVG, tagName);
},
attr: (element, name, value) => {
if (name.includes(":")) {
if (name.startsWith("xmlns")) {
element.setAttributeNS(NS_XMLNS, name, value);
} else if (name.startsWith("xlink")) {
element.setAttributeNS(NS_XLINK, name, value);
} else {
element.setAttributeNS(NS_SVG, name, value);
}
} else {
element.setAttribute(name, value);
}
},
prop: (element, name, value) => {
if (name === "className") {
element.setAttribute("class", value);
} else {
element.setAttribute(name, value);
}
},
append: (parent, child) => {
parent.appendChild(child);
},
insert: (parent, child) => {
parent.insertBefore(child, null);
}
};
const mathDomApi = {
toString() {
return "mathml:dom-api";
},
text(text) {
return getDocument().createTextNode(text);
},
textContent(node, text) {
node.textContent = text;
},
element: (tagName) => {
return getDocument().createElementNS(NS_MATHML, tagName);
},
attr: (element, name, value) => {
if (name.includes(":")) {
element.setAttributeNS(NS_MATHML, name, value);
} else {
element.setAttribute(name, value);
}
},
prop: (element, name, value) => {
element.setAttribute(name, value);
},
append: (parent, child) => {
parent.appendChild(child);
},
insert: (parent, child) => {
parent.insertBefore(child, null);
}
};
function SVGProvider() {
provideContext(this, RENDERING_CONTEXT, svgDomApi);
return (() => {
$_GET_ARGS(this, arguments);
const $slots = $_GET_SLOTS(this, arguments);
const roots = [$_slot("default", () => [], $slots, this)];
return $_fin(roots, this);
})();
}
function HTMLProvider() {
provideContext(this, RENDERING_CONTEXT, api$1);
return (() => {
$_GET_ARGS(this, arguments);
const $slots = $_GET_SLOTS(this, arguments);
const roots = [$_slot("default", () => [], $slots, this)];
return $_fin(roots, this);
})();
}
function MathMLProvider() {
provideContext(this, RENDERING_CONTEXT, mathDomApi);
return (() => {
$_GET_ARGS(this, arguments);
const $slots = $_GET_SLOTS(this, arguments);
const roots = [$_slot("default", () => [], $slots, this)];
return $_fin(roots, this);
})();
}
const $_edp = [[], [], []];
const $_emptySlot = Object.seal(Object.freeze({}));
const $SLOTS_SYMBOL = Symbol("slots");
const $PROPS_SYMBOL = Symbol("props");
const $_SVGProvider = SVGProvider;
const $_HTMLProvider = HTMLProvider;
const $_MathMLProvider = MathMLProvider;
const $_className = "className";
let unstableWrapperId = 0;
class Root {
[RENDERED_NODES_PROPERTY] = [];
[COMPONENT_ID_PROPERTY] = cId();
[RENDERING_CONTEXT_PROPERTY] = void 0;
constructor() {
const id = this[COMPONENT_ID_PROPERTY];
CHILD.set(id, []);
TREE.set(id, this);
if (WITH_CONTEXT_API) {
PARENT.set(id, null);
}
registerDestructor(this, () => {
CHILD.delete(id);
TREE.delete(id);
if (WITH_CONTEXT_API) {
PARENT.delete(id);
}
});
}
}
let ROOT = null;
const $_MANAGERS = {
component: {
// @ts-expect-error unused
canHandle(component2) {
return false;
},
handle(component2, args, fw, ctx) {
return;
}
},
modifier: {
// @ts-expect-error unused
canHandle(modifier) {
return false;
},
handle(modifier, element, props, args) {
return;
}
},
helper: {
// @ts-expect-error unused
canHandle(helper) {
return false;
},
// @ts-expect-error unused
handle(helper, params, hash) {
return;
}
}
};
function $_TO_VALUE(reference) {
if (isFn(reference)) {
return resolveRenderable(reference);
} else {
return reference;
}
}
function $_componentHelper(params, hash) {
const componentFn = params.shift();
return function wrappedComponent(args) {
console.log("patching component args", args, hash);
Object.keys(hash).forEach((key) => {
args[key] = hash[key];
});
return new componentFn(...arguments);
};
}
function $_modifierHelper(params, hash) {
const modifierFn = params.shift();
if (EmberFunctionalModifiers.has(modifierFn)) {
let wrappedModifier = function(node, _params, _hash) {
console.log("callingWrapperModifier", {
params,
_params,
hash,
_hash
});
return $_maybeModifier(modifierFn, node, [...params, ..._params], {
...hash,
..._hash
});
};
EmberFunctionalModifiers.add(wrappedModifier);
return wrappedModifier;
} else {
throw new Error("Unable to use modifier helper with non-ember modifiers");
}
}
function $_helperHelper(params, hash) {
const helperFn = params.shift();
console.log("helper-helper", params, hash);
if (EmberFunctionalHelpers.has(helperFn)) {
let wrappedHelper = function(_params, _hash) {
console.log("callingWrapperHelper", {
params,
_params,
hash,
_hash
});
return $_maybeHelper(helperFn, [...params, ..._params], {
...hash,
..._hash
});
};
EmberFunctionalHelpers.add(wrappedHelper);
return wrappedHelper;
} else {
if (WITH_EMBER_INTEGRATION) {
if ($_MANAGERS.helper.canHandle(helperFn)) {
return $_MANAGERS.helper.handle(helperFn, params, hash);
}
}
throw new Error("Unable to use helper with non-ember helpers");
}
}
function createRoot() {
const root = new Root();
return root;
}
function resetRoot() {
ROOT = null;
}
function setRoot(root) {
if (IS_DEV_MODE) {
if (ROOT) {
throw new Error("Root already exists");
}
}
ROOT = root;
}
function getRoot() {
return ROOT;
}
function $prop(api, element, key, value, destructors) {
const result = $_TO_VALUE(value);
if (isEmpty(result)) {
return;
}
if (isPrimitive(result)) {
if (isRehydrationScheduled()) {
return;
}
api.prop(element, key, result);
} else {
let prevPropValue = void 0;
destructors.push(opcodeFor(result, (value2) => {
if (value2 === prevPropValue) {
return;
}
prevPropValue = api.prop(element, key, value2);
}));
}
}
function $attr(api, element, key, value, destructors) {
const result = $_TO_VALUE(value);
if (isEmpty(result)) {
return;
}
if (isPrimitive(result)) {
api.attr(element, key, result);
} else {
destructors.push(opcodeFor(result, (value2) => {
api.attr(element, key, value2);
}));
}
}
function resolveRenderable(child, debugName = "resolveRenderable") {
const f = formula(() => deepFnValue(child), debugName);
let componentProps = "";
checkOpcode(f, (value) => {
componentProps = value;
});
if (f.isConst) {
f.destroy();
return componentProps;
} else {
if (isPrimitive(componentProps) || isEmpty(componentProps)) {
return f;
} else {
return componentProps;
}
}
}
const EVENT_TYPE = {
ON_CREATED: "0",
TEXT_CONTENT: "1"
};
function $ev(api, element, eventName, fn, destructors) {
if (eventName === EVENT_TYPE.TEXT_CONTENT) {
const result = $_TO_VALUE(fn);
if (isEmpty(result)) {
return;
}
if (isPrimitive(result)) {
api.textContent(element, result);
} else {
destructors.push(opcodeFor(result, (value) => {
api.textContent(element, String(value));
}));
}
} else if (eventName === EVENT_TYPE.ON_CREATED) {
if (REACTIVE_MODIFIERS) {
let destructor = () => void 0;
const updatingCell = formula(() => {
destructor();
return fn(element);
}, `${element.tagName}.modifier`);
const opcodeDestructor = opcodeFor(updatingCell, (dest) => {
if (isFn(dest)) {
destructor = dest;
}
});
if (updatingCell.isConst) {
updatingCell.destroy();
opcodeDestructor();
destructors.push(() => {
return destructor();
});
} else {
destructors.push(opcodeDestructor, () => {
updatingCell.destroy();
}, () => {
return destructor();
});
}
} else {
const destructor = fn(element);
if (isFn(destructor)) {
destructors.push(destructor);
}
}
} else {
if (RUN_EVENT_DESTRUCTORS_FOR_SCOPED_NODES) {
destructors.push(api.addEventListener(element, eventName, fn));
} else {
api.addEventListener(element, eventName, fn);
}
}
}
let NODE_COUNTER = 0;
function incrementNodeCounter() {
NODE_COUNTER++;
}
function resetNodeCounter() {
NODE_COUNTER = 0;
}
function getNodeCounter() {
return NODE_COUNTER;
}
function $_hasBlock(slots, name = "default") {
return name in slots;
}
function $_hasBlockParams(slots, slotName = "default") {
return slots[`${slotName}_`];
}
function addAttrs(api, arr, element, seenKeys, destructors) {
for (let i = 0; i < arr.length; i++) {
const key = arr[i][0];
if (seenKeys.has(key)) {
continue;
}
seenKeys.add(key);
if (IS_DEV_MODE) {
$DEBUG_REACTIVE_CONTEXTS.push(`[${key}]`);
}
$attr(api, element, key, arr[i][1], destructors);
if (IS_DEV_MODE) {
$DEBUG_REACTIVE_CONTEXTS.pop();
}
}
}
function addProperties(api, properties, element, seenKeys, destructors, classNameModifiers, setShadowMode) {
for (let i = 0; i < properties.length; i++) {
const key = properties[i][0];
const value = properties[i][1];
if (key === "") {
classNameModifiers.push(value);
continue;
}
if (SUPPORT_SHADOW_DOM) {
if (key === "shadowrootmode") {
setShadowMode(value);
continue;
}
}
if (seenKeys.has(key)) {
continue;
}
seenKeys.add(key);
if (IS_DEV_MODE) {
$DEBUG_REACTIVE_CONTEXTS.push(`[${key}]`);
}
$prop(api, element, key, value, destructors);
if (IS_DEV_MODE) {
$DEBUG_REACTIVE_CONTEXTS.pop();
}
}
}
function _DOM(tag, tagProps, children, ctx) {
NODE_COUNTER++;
const api = initDOM(ctx);
const element = api.element(tag);
if (IS_DEV_MODE) {
$DEBUG_REACTIVE_CONTEXTS.push(`${tag}`);
}
if (IN_SSR_ENV) {
api.attr(element, "data-node-id", String(NODE_COUNTER));
}
const destructors = [];
const seenKeys = /* @__PURE__ */ new Set();
const classNameModifiers = [];
const hasSplatAttrs = typeof tagProps[3] === "object";
let hasShadowMode = null;
const setShadowNode = (value) => {
hasShadowMode = value;
};
if (hasSplatAttrs === true) {
for (let i = 0; i < tagProps[3][2].length; i++) {
$ev(api, element, tagProps[3][2][i][0], tagProps[3][2][i][1], destructors);
}
}
for (let i = 0; i < tagProps[2].length; i++) {
$ev(api, element, tagProps[2][i][0], tagProps[2][i][1], destructors);
}
if (hasSplatAttrs === true) {
addAttrs(api, tagProps[3][1], element, seenKeys, destructors);
}
addAttrs(api, tagProps[1], element, seenKeys, destructors);
if (hasSplatAttrs === true) {
addProperties(api, tagProps[3][0], element, seenKeys, destructors, classNameModifiers, setShadowNode);
}
addProperties(api, tagProps[0], element, seenKeys, destructors, classNameModifiers, setShadowNode);
if (classNameModifiers.length > 0) {
if (IS_DEV_MODE) {
$DEBUG_REACTIVE_CONTEXTS.push(`[class]`);
}
if (classNameModifiers.length === 1) {
$prop(api, element, $_className, classNameModifiers[0], destructors);
} else {
const formulas = classNameModifiers.map((modifier) => {
if (isFn(modifier)) {
return formula(() => deepFnValue(modifier), "functional modifier for className");
} else {
return modifier;
}
});
$prop(api, element, $_className, formula(() => {
return formulas.join(" ");
}, element.tagName + ".className"), destructors);
}
if (IS_DEV_MODE) {
$DEBUG_REACTIVE_CONTEXTS.pop();
}
}
if (SUPPORT_SHADOW_DOM) {
let appendRef = hasShadowMode !== null ? isRehydrationScheduled() ? element.shadowRoot : element.attachShadow({
mode: hasShadowMode
}) || element.shadowRoot : element;
{
renderElement(api, ctx, appendRef, children);
}
} else {
renderElement(api, ctx, element, children);
}
registerDestructor(ctx, ...destructors);
if (IS_DEV_MODE) {
$DEBUG_REACTIVE_CONTEXTS.pop();
}
return element;
}
function $_inElement(elementRef, roots, ctx) {
const api = initDOM(ctx);
return component(function UnstableChildWrapper() {
$_GET_ARGS(this, arguments);
if (IS_DEV_MODE) {
this.debugName = `InElement-${unstableWrapperId++}`;
}
let appendRef;
if (isFn(elementRef)) {
appendRef = elementRef();
} else if (isTagLike(elementRef)) {
appendRef = elementRef.value;
} else {
appendRef = elementRef;
}
const nodes = roots(ctx);
renderElement(api, ctx, appendRef, nodes);
registerDestructor(ctx, () => {
unregisterFromParent(nodes);
appendRef.innerHTML = "";
});
return $_fin([], this);
}, {}, ctx);
}
function $_ucw(roots, ctx) {
return component(function UnstableChildWrapper() {
$_GET_ARGS(this, arguments);
if (IS_DEV_MODE) {
this.debugName = `UnstableChildWrapper-${unstableWrapperId++}`;
}
return $_fin(roots(this), this);
}, {}, ctx);
}
if (IS_DEV_MODE) {
let buildGraph = function(obj, root, children) {
if (root === null) {
console.info("root is null", TREE);
return obj;
}
const name = root.debugName || root?.constructor?.name || root?.tagName || "unknown";
if (children.size === 0) {
obj[name] = null;
return obj;
}
obj[name] = Array.from(children).map((child) => {
return buildGraph({}, child, new Set(CHILD.get(child) ?? []));
});
return obj;
}, drawTreeToConsole = function() {
const ref = buildGraph({}, ROOT, new Set(CHILD.get(ROOT[COMPONENT_ID_PROPERTY]) ?? []));
console.log(JSON.stringify(ref, null, 2));
};
{
window.drawTreeToConsole = drawTreeToConsole;
}
}
{
if (IS_DEV_MODE) {
window.utils = {
getRoot,
runDestructors
};
window.hotReload = createHotReload(component);
}
}
function $_GET_SCOPES(hash) {
return hash[CONSTANTS.SCOPE_KEY]?.() || [];
}
const $_maybeHelper = (value, args, _hash) => {
const hash = $_args(_hash, false);
if (WITH_EMBER_INTEGRATION) {
if ($_MANAGERS.helper.canHandle(value)) {
return $_MANAGERS.helper.handle(value, args, _hash);
}
}
if (isPrimitive(value)) {
const scopes = $_GET_SCOPES(hash);
const needleScope = scopes.find((scope) => {
return value in scope;
});
if (needleScope) {
return needleScope[value](...args);
} else {
return value;
}
} else if (EmberFunctionalHelpers.has(value)) {
return (...args2) => {
return value(args2, hash);
};
} else if (value.helperType === "ember") {
const helper = new value();
return (...args2) => {
return helper.compute.call(helper, args2, hash);
};
}
return value;
};
function component(comp, args, ctx) {
let label = IS_DEV_MODE ? `${// @ts-expect-error debugName may not exist
comp.debugName || comp.name || comp.constructor.name}` : "";
if (TRY_CATCH_ERROR_HANDLING) {
try {
if (IS_DEV_MODE) {
$DEBUG_REACTIVE_CONTEXTS.push(label);
const getCircularReplacer = () => {
const seen = /* @__PURE__ */ new WeakSet();
return (_, value) => {
if (typeof value === "object" && value !== null) {
if (seen.has(value)) {
return;
}
seen.add(value);
}
return value;
};
};
label = `<${label} ${JSON.stringify(args, getCircularReplacer)} />`;
}
const fw = args[$PROPS_SYMBOL];
return _component(comp, args, fw, ctx);
} catch (e) {
if (isRehydrationScheduled()) {
throw e;
}
if (IS_DEV_MODE) {
let ErrorOverlayClass = customElements.get("vite-error-overlay");
let errorOverlay;
e.message = `${label}
${e.message}`;
if (!ErrorOverlayClass) {
errorOverlay = api$1.element("pre");
api$1.textContent(errorOverlay, `${label}
${e.stack ?? e}`);
api$1.attr(errorOverlay, "style", "color:red;border:1px solid red;padding:10px;background-color:#333;");
} else {
errorOverlay = new ErrorOverlayClass(e, true);
}
console.error(label, e);
return {
ctx: {
[RENDERED_NODES_PROPERTY]: []
},
nodes: [errorOverlay]
};
} else {
return {
ctx: {
[RENDERED_NODES_PROPERTY]: []
},
// @ts-expect-error message may not exit
nodes: [api$1.text(String(e.message))]
};
}
} finally {
if (IS_DEV_MODE) {
$DEBUG_REACTIVE_CONTEXTS.pop();
}
}
} else {
const fw = args[$PROPS_SYMBOL];
return _component(comp, args, fw, ctx);
}
}
function _component(_comp, args, fw, ctx) {
args[$context] = ctx;
let comp = _comp;
if (WITH_EMBER_INTEGRATION) {
if ($_MANAGERS.component.canHandle(_comp)) {
comp = $_MANAGERS.component.handle(_comp, args, fw, ctx);
}
}
if (IS_DEV_MODE) {
if (!COMPONENTS_HMR.has(comp)) {
COMPONENTS_HMR.set(comp, /* @__PURE__ */ new Set());
}
}
if (IS_GLIMMER_COMPAT_MODE) ; else {
if (isTagLike(comp)) {
comp = comp.value;
}
}
let instance = (
// @ts-expect-error construct signature
comp.prototype === void 0 ? (
// @ts-expect-error construct signature
comp(args, fw)
) : (
// @ts-expect-error construct signature
new comp(args, fw)
)
);
if (isFn(instance)) {
instance = new instance(args, fw);
}
if ($template in instance) {
addToTree(ctx, instance, "from $template");
const result = instance[$template]();
if (IS_DEV_MODE) {
instance.debugName = comp.name;
const bucket = {
parent: ctx,
instance: result,
args
};
COMPONENTS_HMR.get(comp)?.add(bucket);
registerDestructor(ctx, () => {
COMPONENTS_HMR.get(comp)?.delete(bucket);
});
if (!result.ctx || result.ctx !== instance) {
throw new Error("Invalid context");
}
setBounds(result);
}
return result;
} else if (instance.ctx !== null) {
addToTree(ctx, instance.ctx, "from !$template");
if (IS_DEV_MODE) {
setBounds(instance);
}
} else {
if (IS_DEV_MODE) {
throw new Error(`Unknown Instance`);
}
}
if (IS_DEV_MODE) {
COMPONENTS_HMR.get(comp)?.add({
parent: ctx,
instance,
args
});
}
return instance;
}
function createSlot(value, params, name, ctx) {
if (IS_DEV_MODE) {
$DEBUG_REACTIVE_CONTEXTS.push(`:${name}`);
}
const slotContext = {
[$args]: {
[$context]: ctx
},
[RENDERED_NODES_PROPERTY]: [],
[COMPONENT_ID_PROPERTY]: cId(),
[RENDERING_CONTEXT_PROPERTY]: null
};
addToTree(ctx, slotContext);
const paramsArray = params().map((_, i) => {
const v = formula(() => params()[i], `slot:param:${i}`);
const value2 = v.value;
if (v.isConst || typeof value2 === "object") {
return value2;
} else {
return v;
}
});
const elements = value(...[slotContext, ...paramsArray]);
if (IS_DEV_MODE) {
$DEBUG_REACTIVE_CONTEXTS.pop();
slotContext.debugName = `slot:${name}`;
slotContext.debugInfo = {
parent: ctx,
params,
name
};
}
return $_fin(elements, slotContext);
}
function slot(name, params, $slot, ctx) {
const api = initDOM(ctx);
if (!(name in $slot)) {
const slotPlaceholder = IS_DEV_MODE ? api.comment(`slot-{{${name}}}-placeholder`) : api.comment("");
let isRendered = false;
let isSettled = false;
let slotValue = () => [];
Object.defineProperty($slot, name, {
set(value) {
isSettled = true;
if (IS_DEV_MODE) {
if (isRendered) {
throw new Error(`Slot ${name} is already rendered`);
}
}
slotValue = value;
const slotRoots = createSlot(slotValue, params, name, ctx);
renderElement(api, ctx, slotPlaceholder.parentNode, slotRoots, slotPlaceholder);
isRendered = true;
},
get() {
if (isSettled) {
return slotValue;
}
if (IS_DEV_MODE) {
throw new Error(`Slot ${name} is not set`);
}
}
});
return slotPlaceholder;
}
return createSlot($slot[name], params, name, ctx);
}
function cellToText(api, cell, destructors) {
const textNode = api.text("");
destructors.push(opcodeFor(cell, (value) => {
api.textContent(textNode, String(value ?? ""));
}));
return textNode;
}
function text(api, text2, destructors) {
const result = $_TO_VALUE(text2);
if (isEmpty(result)) {
return api.text("");
} else if (isPrimitive(result)) {
return api.text(result);
} else {
return cellToText(api, typeof text2 === "function" ? result : text2, destructors);
}
}
function getRenderTargets(api, debugName) {
const ifPlaceholder = IS_DEV_MODE ? api.comment(debugName) : api.comment("");
let outlet = isRehydrationScheduled() ? ifPlaceholder.parentElement || api.fragment() : api.fragment();
if (!ifPlaceholder.isConnected) {
api.insert(outlet, ifPlaceholder);
}
return {
placeholder: ifPlaceholder,
outlet
};
}
function toNodeReturnType(outlet, ctx = null) {
if (outlet.nodeType !== FRAGMENT_TYPE) {
return outlet;
}
return {
ctx,
[$nodes]: Array.from(outlet.childNodes)
};
}
function ifCond(cell, trueBranch, falseBranch, ctx) {
const api = initDOM(ctx);
const {
outlet,
placeholder
} = getRenderTargets(api, "if-entry-placeholder");
const instance = new IfCondition(ctx, cell, outlet, placeholder, trueBranch, falseBranch);
return toNodeReturnType(outlet, instance);
}
function $_eachSync(items, fn, key = null, ctx) {
const api = initDOM(ctx);
const {
outlet,
placeholder
} = getRenderTargets