@jxsuite/runtime 4.0.0 → 4.0.1
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/dist/runtime.js +94 -7
- package/dist/runtime.js.map +3 -3
- package/package.json +1 -1
- package/src/runtime.ts +294 -6
package/dist/runtime.js
CHANGED
|
@@ -3675,6 +3675,7 @@ function renderMappedArrayInto(parentEl, arrayDef, state, options) {
|
|
|
3675
3675
|
parentEl.append(anchor);
|
|
3676
3676
|
const { items: itemsSrc, map: mapDef, filter: filterRef, sort: sortRef, key: keyRef } = arrayDef;
|
|
3677
3677
|
const keyPointer = isRefObj(keyRef) ? keyRef.$ref : null;
|
|
3678
|
+
const instancePath = _instancePath;
|
|
3678
3679
|
let warned = false;
|
|
3679
3680
|
const warnOnce = (message) => {
|
|
3680
3681
|
if (!warned) {
|
|
@@ -3762,7 +3763,7 @@ function renderMappedArrayInto(parentEl, arrayDef, state, options) {
|
|
|
3762
3763
|
}
|
|
3763
3764
|
pauseTracking();
|
|
3764
3765
|
try {
|
|
3765
|
-
reconcile(list, keys);
|
|
3766
|
+
underInstancePath(reexpand(instancePath), () => reconcile(list, keys));
|
|
3766
3767
|
} finally {
|
|
3767
3768
|
resetTracking();
|
|
3768
3769
|
}
|
|
@@ -3826,6 +3827,7 @@ function resolveTagName(tagName, scope) {
|
|
|
3826
3827
|
function renderSwitch(def, state, options) {
|
|
3827
3828
|
const path = options?._path ?? [];
|
|
3828
3829
|
const container = document.createElement(resolveTagName(def.tagName, state));
|
|
3830
|
+
const instancePath = _instancePath;
|
|
3829
3831
|
if (options?.onNodeCreated) {
|
|
3830
3832
|
options.onNodeCreated(container, path, def, state);
|
|
3831
3833
|
}
|
|
@@ -3873,13 +3875,13 @@ function renderSwitch(def, state, options) {
|
|
|
3873
3875
|
return;
|
|
3874
3876
|
}
|
|
3875
3877
|
container.replaceChildren();
|
|
3876
|
-
scope.run(() => container.append(renderNode(doc, childScope, childOpts)));
|
|
3878
|
+
underInstancePath(reexpand(instancePath), () => scope.run(() => container.append(renderNode(doc, childScope, childOpts))));
|
|
3877
3879
|
}).catch((error) => console.error("Jx $switch: failed to load external case", caseDef.$ref, error));
|
|
3878
3880
|
return;
|
|
3879
3881
|
}
|
|
3880
3882
|
pauseTracking();
|
|
3881
3883
|
try {
|
|
3882
|
-
scope.run(() => container.append(renderNode(caseDef, state, childOpts)));
|
|
3884
|
+
underInstancePath(reexpand(instancePath), () => scope.run(() => container.append(renderNode(caseDef, state, childOpts))));
|
|
3883
3885
|
} finally {
|
|
3884
3886
|
resetTracking();
|
|
3885
3887
|
}
|
|
@@ -4583,6 +4585,65 @@ function injectHead(entries, _base) {
|
|
|
4583
4585
|
document.head.append(el);
|
|
4584
4586
|
}
|
|
4585
4587
|
}
|
|
4588
|
+
var MAX_COMPONENT_NESTING = 32;
|
|
4589
|
+
var ROOT_INSTANCE_PATH = { expansion: 0, frames: [] };
|
|
4590
|
+
var _instancePath = ROOT_INSTANCE_PATH;
|
|
4591
|
+
function underInstancePath(path, fn) {
|
|
4592
|
+
const was = _instancePath;
|
|
4593
|
+
_instancePath = path;
|
|
4594
|
+
try {
|
|
4595
|
+
return fn();
|
|
4596
|
+
} finally {
|
|
4597
|
+
_instancePath = was;
|
|
4598
|
+
}
|
|
4599
|
+
}
|
|
4600
|
+
function reexpand(path) {
|
|
4601
|
+
return { expansion: path.frames.length, frames: path.frames };
|
|
4602
|
+
}
|
|
4603
|
+
function samePropValue(a, b) {
|
|
4604
|
+
if (Object.is(a, b)) {
|
|
4605
|
+
return true;
|
|
4606
|
+
}
|
|
4607
|
+
if (!isPlainData(a) || !isPlainData(b)) {
|
|
4608
|
+
return false;
|
|
4609
|
+
}
|
|
4610
|
+
try {
|
|
4611
|
+
return JSON.stringify(a) === JSON.stringify(b);
|
|
4612
|
+
} catch {
|
|
4613
|
+
return false;
|
|
4614
|
+
}
|
|
4615
|
+
}
|
|
4616
|
+
function isPlainData(value) {
|
|
4617
|
+
if (typeof value !== "object" || value === null) {
|
|
4618
|
+
return false;
|
|
4619
|
+
}
|
|
4620
|
+
const raw = toRaw(value);
|
|
4621
|
+
if (Array.isArray(raw)) {
|
|
4622
|
+
return true;
|
|
4623
|
+
}
|
|
4624
|
+
const proto = Object.getPrototypeOf(raw);
|
|
4625
|
+
return proto === Object.prototype || proto === null;
|
|
4626
|
+
}
|
|
4627
|
+
function sameFrame(a, b) {
|
|
4628
|
+
if (a.tag !== b.tag) {
|
|
4629
|
+
return false;
|
|
4630
|
+
}
|
|
4631
|
+
const keys = Object.keys(a.props);
|
|
4632
|
+
if (keys.length !== Object.keys(b.props).length) {
|
|
4633
|
+
return false;
|
|
4634
|
+
}
|
|
4635
|
+
return keys.every((key) => Object.hasOwn(b.props, key) && samePropValue(a.props[key], b.props[key]));
|
|
4636
|
+
}
|
|
4637
|
+
function extendInstancePath(path, frame) {
|
|
4638
|
+
const chain = [...path.frames.map((f) => f.tag), frame.tag].join(" → ");
|
|
4639
|
+
if (path.frames.slice(path.expansion).some((f) => sameFrame(f, frame))) {
|
|
4640
|
+
throw new Error(`Component <${frame.tag}> renders itself: ${chain}. A component cannot appear inside its own ` + `definition with the same props — the expansion would never end.`);
|
|
4641
|
+
}
|
|
4642
|
+
if (path.frames.length >= MAX_COMPONENT_NESTING) {
|
|
4643
|
+
throw new Error(`Component nesting exceeds ${MAX_COMPONENT_NESTING} levels: ${chain}. A component that renders itself with changing props needs a case that stops.`);
|
|
4644
|
+
}
|
|
4645
|
+
return { expansion: path.expansion, frames: [...path.frames, frame] };
|
|
4646
|
+
}
|
|
4586
4647
|
var _definedSources = new Set;
|
|
4587
4648
|
async function defineElement(source, baseUrl) {
|
|
4588
4649
|
let base = baseUrl;
|
|
@@ -4625,6 +4686,8 @@ async function defineElement(source, baseUrl) {
|
|
|
4625
4686
|
return;
|
|
4626
4687
|
}
|
|
4627
4688
|
this._jxInitialized = true;
|
|
4689
|
+
const enclosingPath = _instancePath;
|
|
4690
|
+
const supplied = {};
|
|
4628
4691
|
const live = _elementDefs.get(tagName) ?? { base: initialBase, doc: initialDef };
|
|
4629
4692
|
const def = live.doc;
|
|
4630
4693
|
const defBase = live.base;
|
|
@@ -4632,6 +4695,7 @@ async function defineElement(source, baseUrl) {
|
|
|
4632
4695
|
for (const attr of observedAttrs) {
|
|
4633
4696
|
if (this.hasAttribute(attr)) {
|
|
4634
4697
|
absorbAttribute(state, attr, this.getAttribute(attr));
|
|
4698
|
+
supplied[attr] = this.getAttribute(attr);
|
|
4635
4699
|
}
|
|
4636
4700
|
}
|
|
4637
4701
|
const propsAttr = this.dataset.jxProps;
|
|
@@ -4644,6 +4708,7 @@ async function defineElement(source, baseUrl) {
|
|
|
4644
4708
|
}
|
|
4645
4709
|
if (key in (def.state ?? {})) {
|
|
4646
4710
|
state[key] = val;
|
|
4711
|
+
supplied[key] = val;
|
|
4647
4712
|
}
|
|
4648
4713
|
}
|
|
4649
4714
|
} catch {}
|
|
@@ -4658,6 +4723,7 @@ async function defineElement(source, baseUrl) {
|
|
|
4658
4723
|
}
|
|
4659
4724
|
if (key in (def.state ?? {})) {
|
|
4660
4725
|
state[key] = this.getAttribute(name);
|
|
4726
|
+
supplied[key] = this.getAttribute(name);
|
|
4661
4727
|
this.removeAttribute(name);
|
|
4662
4728
|
}
|
|
4663
4729
|
}
|
|
@@ -4667,8 +4733,26 @@ async function defineElement(source, baseUrl) {
|
|
|
4667
4733
|
}
|
|
4668
4734
|
if (key in this && this[key] !== undefined && instanceSupplies(this, key)) {
|
|
4669
4735
|
state[key] = this[key];
|
|
4736
|
+
supplied[key] = this[key];
|
|
4670
4737
|
}
|
|
4671
4738
|
}
|
|
4739
|
+
let ownPath;
|
|
4740
|
+
try {
|
|
4741
|
+
ownPath = extendInstancePath(enclosingPath, { props: supplied, tag: tagName });
|
|
4742
|
+
} catch (error) {
|
|
4743
|
+
this.replaceChildren();
|
|
4744
|
+
if (!this.isConnected) {
|
|
4745
|
+
return;
|
|
4746
|
+
}
|
|
4747
|
+
console.error(`Jx: <${tagName}> was not rendered:`, error);
|
|
4748
|
+
this.dispatchEvent(new ErrorEvent("jx-error", {
|
|
4749
|
+
bubbles: true,
|
|
4750
|
+
composed: true,
|
|
4751
|
+
error,
|
|
4752
|
+
message: error instanceof Error ? error.message : String(error)
|
|
4753
|
+
}));
|
|
4754
|
+
return;
|
|
4755
|
+
}
|
|
4672
4756
|
for (const key of Object.keys(def.state ?? {})) {
|
|
4673
4757
|
if (isPrivateStateKey(key)) {
|
|
4674
4758
|
continue;
|
|
@@ -4698,9 +4782,11 @@ async function defineElement(source, baseUrl) {
|
|
|
4698
4782
|
const wasInside = _canvasInsideStampedHost;
|
|
4699
4783
|
_canvasInsideStampedHost ||= this.dataset.jxPath !== undefined;
|
|
4700
4784
|
try {
|
|
4701
|
-
|
|
4702
|
-
|
|
4703
|
-
|
|
4785
|
+
underInstancePath(ownPath, () => {
|
|
4786
|
+
for (const childDef of children) {
|
|
4787
|
+
this.append(renderNode(childDef, state));
|
|
4788
|
+
}
|
|
4789
|
+
});
|
|
4704
4790
|
} finally {
|
|
4705
4791
|
_canvasInsideStampedHost = wasInside;
|
|
4706
4792
|
}
|
|
@@ -4801,6 +4887,7 @@ export {
|
|
|
4801
4887
|
COLOR_SCHEME_ATTR,
|
|
4802
4888
|
COLOR_SCHEME_STORAGE_KEY,
|
|
4803
4889
|
Jx,
|
|
4890
|
+
MAX_COMPONENT_NESTING,
|
|
4804
4891
|
RESERVED_KEYS,
|
|
4805
4892
|
SUPPORTED_SCHEMA_VERSION,
|
|
4806
4893
|
_resetPrivatePropWarnings,
|
|
@@ -4859,5 +4946,5 @@ export {
|
|
|
4859
4946
|
transposeCanvasUnits
|
|
4860
4947
|
};
|
|
4861
4948
|
|
|
4862
|
-
//# debugId=
|
|
4949
|
+
//# debugId=52C255A4DA099CA964756E2164756E21
|
|
4863
4950
|
//# sourceMappingURL=runtime.js.map
|