tutuca 0.13.3 → 0.15.0
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/tutuca-cli.js +1079 -1254
- package/dist/tutuca-dev.ext.js +1086 -1216
- package/dist/tutuca-dev.js +1095 -1225
- package/dist/tutuca-dev.min.js +4 -4
- package/dist/tutuca-extra.ext.js +1055 -1133
- package/dist/tutuca-extra.js +1061 -1139
- package/dist/tutuca-extra.min.js +3 -3
- package/dist/tutuca.ext.js +1054 -1116
- package/dist/tutuca.js +1060 -1122
- package/dist/tutuca.min.js +3 -3
- package/package.json +1 -1
- package/skill/tutuca/SKILL.md +2 -2
- package/skill/tutuca/advanced.md +48 -17
- package/skill/tutuca/component-design.md +2 -2
- package/skill/tutuca/core.md +5 -4
- package/skill/tutuca/messages-and-intents.md +9 -11
- package/skill/tutuca/patterns/README.md +1 -1
- package/skill/tutuca/patterns/edit-through-a-dynamic-target.md +11 -6
- package/skill/tutuca/patterns/share-state-across-the-tree.md +18 -3
- package/skill/tutuca/semantics.md +63 -39
- package/skill/tutuca-source/tutuca.ext.js +1054 -1116
package/dist/tutuca-dev.js
CHANGED
|
@@ -1243,8 +1243,8 @@ function hasProperty(obj, name) {
|
|
|
1243
1243
|
return name in Object(obj);
|
|
1244
1244
|
}
|
|
1245
1245
|
__name(hasProperty, "hasProperty");
|
|
1246
|
-
function parsePath(
|
|
1247
|
-
const str =
|
|
1246
|
+
function parsePath(path2) {
|
|
1247
|
+
const str = path2.replace(/([^\\])\[/g, "$1.[");
|
|
1248
1248
|
const parts = str.match(/(\\\.|[^.]+?)+/g);
|
|
1249
1249
|
return parts.map((value) => {
|
|
1250
1250
|
if (value === "constructor" || value === "__proto__" || value === "prototype") {
|
|
@@ -1282,8 +1282,8 @@ function internalGetPathValue(obj, parsed, pathDepth) {
|
|
|
1282
1282
|
return res;
|
|
1283
1283
|
}
|
|
1284
1284
|
__name(internalGetPathValue, "internalGetPathValue");
|
|
1285
|
-
function getPathInfo(obj,
|
|
1286
|
-
const parsed = parsePath(
|
|
1285
|
+
function getPathInfo(obj, path2) {
|
|
1286
|
+
const parsed = parsePath(path2);
|
|
1287
1287
|
const last = parsed[parsed.length - 1];
|
|
1288
1288
|
const info = {
|
|
1289
1289
|
parent: parsed.length > 1 ? internalGetPathValue(obj, parsed, parsed.length - 1) : obj,
|
|
@@ -4158,8 +4158,8 @@ function jestMatchers(chai, utils) {
|
|
|
4158
4158
|
expected
|
|
4159
4159
|
);
|
|
4160
4160
|
});
|
|
4161
|
-
m("toHaveProperty", function(
|
|
4162
|
-
const keys = Array.isArray(
|
|
4161
|
+
m("toHaveProperty", function(path2, ...rest) {
|
|
4162
|
+
const keys = Array.isArray(path2) ? path2 : String(path2).split(".");
|
|
4163
4163
|
let cur = this._obj;
|
|
4164
4164
|
let found = true;
|
|
4165
4165
|
for (const k of keys) {
|
|
@@ -4174,7 +4174,7 @@ function jestMatchers(chai, utils) {
|
|
|
4174
4174
|
pass,
|
|
4175
4175
|
"expected #{this} to have property #{exp}",
|
|
4176
4176
|
"expected #{this} not to have property #{exp}",
|
|
4177
|
-
|
|
4177
|
+
path2
|
|
4178
4178
|
);
|
|
4179
4179
|
});
|
|
4180
4180
|
m("toBeInstanceOf", function(ctor) {
|
|
@@ -4493,7 +4493,7 @@ function processResult(result, scope) {
|
|
|
4493
4493
|
}
|
|
4494
4494
|
return result !== NOTHING ? result : void 0;
|
|
4495
4495
|
}
|
|
4496
|
-
function finalize(rootScope, value,
|
|
4496
|
+
function finalize(rootScope, value, path2) {
|
|
4497
4497
|
if (isFrozen(value))
|
|
4498
4498
|
return value;
|
|
4499
4499
|
const useStrictIteration = rootScope.immer_.shouldUseStrictIteration();
|
|
@@ -4501,7 +4501,7 @@ function finalize(rootScope, value, path) {
|
|
|
4501
4501
|
if (!state) {
|
|
4502
4502
|
each(
|
|
4503
4503
|
value,
|
|
4504
|
-
(key, childValue) => finalizeProperty(rootScope, state, value, key, childValue,
|
|
4504
|
+
(key, childValue) => finalizeProperty(rootScope, state, value, key, childValue, path2),
|
|
4505
4505
|
useStrictIteration
|
|
4506
4506
|
);
|
|
4507
4507
|
return value;
|
|
@@ -4531,16 +4531,16 @@ function finalize(rootScope, value, path) {
|
|
|
4531
4531
|
result,
|
|
4532
4532
|
key,
|
|
4533
4533
|
childValue,
|
|
4534
|
-
|
|
4534
|
+
path2,
|
|
4535
4535
|
isSet2
|
|
4536
4536
|
),
|
|
4537
4537
|
useStrictIteration
|
|
4538
4538
|
);
|
|
4539
4539
|
maybeFreeze(rootScope, result, false);
|
|
4540
|
-
if (
|
|
4540
|
+
if (path2 && rootScope.patches_) {
|
|
4541
4541
|
getPlugin("Patches").generatePatches_(
|
|
4542
4542
|
state,
|
|
4543
|
-
|
|
4543
|
+
path2,
|
|
4544
4544
|
rootScope.patches_,
|
|
4545
4545
|
rootScope.inversePatches_
|
|
4546
4546
|
);
|
|
@@ -4562,9 +4562,9 @@ function finalizeProperty(rootScope, parentState, targetObject, prop, childValue
|
|
|
4562
4562
|
if (childValue === targetObject)
|
|
4563
4563
|
die(5);
|
|
4564
4564
|
if (isDraft(childValue)) {
|
|
4565
|
-
const
|
|
4565
|
+
const path2 = rootPath && parentState && parentState.type_ !== 3 && // Set objects are atomic since they have no keys.
|
|
4566
4566
|
!has(parentState.assigned_, prop) ? rootPath.concat(prop) : void 0;
|
|
4567
|
-
const res = finalize(rootScope, childValue,
|
|
4567
|
+
const res = finalize(rootScope, childValue, path2);
|
|
4568
4568
|
set2(targetObject, prop, res);
|
|
4569
4569
|
if (isDraft(res)) {
|
|
4570
4570
|
rootScope.canAutoFreeze_ = false;
|
|
@@ -4954,12 +4954,6 @@ var produce = immer.produce;
|
|
|
4954
4954
|
|
|
4955
4955
|
// src/path.js
|
|
4956
4956
|
var NONE = /* @__PURE__ */ Symbol("NONE");
|
|
4957
|
-
var readKey = (value, key, dval = null) => {
|
|
4958
|
-
if (value == null) return dval;
|
|
4959
|
-
if (value instanceof Map) return value.has(key) ? value.get(key) : dval;
|
|
4960
|
-
if (value instanceof Set) return value.has(key) ? key : dval;
|
|
4961
|
-
return Object.hasOwn(value, key) ? value[key] : dval;
|
|
4962
|
-
};
|
|
4963
4957
|
var writeKey = (value, key, next) => {
|
|
4964
4958
|
if (value instanceof Map) value.set(key, next);
|
|
4965
4959
|
else if (value instanceof Set) {
|
|
@@ -4967,20 +4961,15 @@ var writeKey = (value, key, next) => {
|
|
|
4967
4961
|
value.add(next);
|
|
4968
4962
|
} else value[key] = next;
|
|
4969
4963
|
};
|
|
4970
|
-
var writeSeqKey = (value, key, next) =>
|
|
4971
|
-
if (value instanceof Map || value instanceof Set || Array.isArray(value) || Object.hasOwn(value, key))
|
|
4972
|
-
writeKey(value, key, next);
|
|
4973
|
-
else if (typeof value?.set === "function") value.set(key, next);
|
|
4974
|
-
else writeKey(value, key, next);
|
|
4975
|
-
};
|
|
4964
|
+
var writeSeqKey = (value, key, next) => !(value instanceof Map || value instanceof Set || Array.isArray(value)) && !Object.hasOwn(value, key) && typeof value?.set === "function" ? value.set(key, next) : writeKey(value, key, next);
|
|
4976
4965
|
var Step = class {
|
|
4977
|
-
lookup(_v, dval = null) {
|
|
4978
|
-
return dval;
|
|
4979
|
-
}
|
|
4980
4966
|
setDraftValue(_root, _v) {
|
|
4981
4967
|
}
|
|
4982
|
-
|
|
4983
|
-
|
|
4968
|
+
// Re-enter this step while rebuilding a stack. `renderPath` is the dispatch
|
|
4969
|
+
// position AFTER this step: a rebuilt frame must carry the same render path
|
|
4970
|
+
// the renderer had there, or the provides it publishes would be located wrong.
|
|
4971
|
+
enterFrame(stack, next, renderPath) {
|
|
4972
|
+
return stack.enter(next, {}, true, renderPath);
|
|
4984
4973
|
}
|
|
4985
4974
|
toAbstractPathStep() {
|
|
4986
4975
|
return this;
|
|
@@ -4997,41 +4986,29 @@ var Step = class {
|
|
|
4997
4986
|
return null;
|
|
4998
4987
|
}
|
|
4999
4988
|
};
|
|
5000
|
-
var BindStep = class
|
|
4989
|
+
var BindStep = class extends Step {
|
|
5001
4990
|
constructor(binds) {
|
|
5002
4991
|
super();
|
|
5003
4992
|
this.binds = binds;
|
|
5004
4993
|
}
|
|
5005
|
-
lookup(v
|
|
4994
|
+
lookup(v) {
|
|
5006
4995
|
return v;
|
|
5007
4996
|
}
|
|
5008
|
-
enterFrame(stack, next) {
|
|
5009
|
-
return stack.enter(next, { ...this.binds }, false);
|
|
5010
|
-
}
|
|
5011
|
-
withIndex(i) {
|
|
5012
|
-
return new _BindStep({ ...this.binds, key: i });
|
|
5013
|
-
}
|
|
5014
|
-
withKey(key) {
|
|
5015
|
-
return new _BindStep({ ...this.binds, key });
|
|
4997
|
+
enterFrame(stack, next, renderPath) {
|
|
4998
|
+
return stack.enter(next, { ...this.binds }, false, renderPath);
|
|
5016
4999
|
}
|
|
5017
5000
|
toAbstractPathStep() {
|
|
5018
5001
|
return null;
|
|
5019
5002
|
}
|
|
5020
5003
|
};
|
|
5021
|
-
var ScopeBindStep = class
|
|
5004
|
+
var ScopeBindStep = class extends BindStep {
|
|
5022
5005
|
constructor(val, binds = {}) {
|
|
5023
5006
|
super(binds);
|
|
5024
5007
|
this.val = val;
|
|
5025
5008
|
}
|
|
5026
|
-
enterFrame(stack, next) {
|
|
5009
|
+
enterFrame(stack, next, renderPath) {
|
|
5027
5010
|
const dyn = this.val.evalAsHandler(stack)?.call(stack.it) ?? {};
|
|
5028
|
-
return stack.enter(next, { ...this.binds, ...dyn }, false);
|
|
5029
|
-
}
|
|
5030
|
-
withIndex(i) {
|
|
5031
|
-
return new _ScopeBindStep(this.val, { ...this.binds, key: i });
|
|
5032
|
-
}
|
|
5033
|
-
withKey(key) {
|
|
5034
|
-
return new _ScopeBindStep(this.val, { ...this.binds, key });
|
|
5011
|
+
return stack.enter(next, { ...this.binds, ...dyn }, false, renderPath);
|
|
5035
5012
|
}
|
|
5036
5013
|
};
|
|
5037
5014
|
var FieldStep = class extends Step {
|
|
@@ -5039,18 +5016,12 @@ var FieldStep = class extends Step {
|
|
|
5039
5016
|
super();
|
|
5040
5017
|
this.field = field;
|
|
5041
5018
|
}
|
|
5042
|
-
lookup(v
|
|
5043
|
-
return
|
|
5019
|
+
lookup(v) {
|
|
5020
|
+
return seqGet(v, this.field, NONE);
|
|
5044
5021
|
}
|
|
5045
5022
|
setDraftValue(root, v) {
|
|
5046
5023
|
writeKey(root, this.field, v);
|
|
5047
5024
|
}
|
|
5048
|
-
withIndex(i) {
|
|
5049
|
-
return new SeqStep(this.field, i);
|
|
5050
|
-
}
|
|
5051
|
-
withKey(k) {
|
|
5052
|
-
return new SeqStep(this.field, k);
|
|
5053
|
-
}
|
|
5054
5025
|
toKey() {
|
|
5055
5026
|
return { field: this.field };
|
|
5056
5027
|
}
|
|
@@ -5061,15 +5032,15 @@ var SeqStep = class extends Step {
|
|
|
5061
5032
|
this.field = field;
|
|
5062
5033
|
this.key = key;
|
|
5063
5034
|
}
|
|
5064
|
-
lookup(v
|
|
5065
|
-
return seqGet(
|
|
5035
|
+
lookup(v) {
|
|
5036
|
+
return seqGet(seqGet(v, this.field, null), this.key, NONE);
|
|
5066
5037
|
}
|
|
5067
5038
|
setDraftValue(root, v) {
|
|
5068
|
-
const seq =
|
|
5039
|
+
const seq = seqGet(root, this.field, null);
|
|
5069
5040
|
if (seq != null) writeSeqKey(seq, this.key, v);
|
|
5070
5041
|
}
|
|
5071
|
-
enterFrame(stack, next) {
|
|
5072
|
-
return stack.enter(next, { key: this.key }, true);
|
|
5042
|
+
enterFrame(stack, next, renderPath) {
|
|
5043
|
+
return stack.enter(next, { key: this.key }, true, renderPath);
|
|
5073
5044
|
}
|
|
5074
5045
|
toKey() {
|
|
5075
5046
|
return { field: this.field, key: this.key };
|
|
@@ -5081,20 +5052,20 @@ var SeqAccessStep = class extends Step {
|
|
|
5081
5052
|
this.seqField = seqField;
|
|
5082
5053
|
this.keyField = keyField;
|
|
5083
5054
|
}
|
|
5084
|
-
lookup(v
|
|
5085
|
-
const seq =
|
|
5086
|
-
const key =
|
|
5087
|
-
return key !== NONE && seq !== NONE ? seqGet(seq, key,
|
|
5055
|
+
lookup(v) {
|
|
5056
|
+
const seq = seqGet(v, this.seqField, NONE);
|
|
5057
|
+
const key = seqGet(v, this.keyField, NONE);
|
|
5058
|
+
return key !== NONE && seq !== NONE ? seqGet(seq, key, NONE) : NONE;
|
|
5088
5059
|
}
|
|
5089
5060
|
setDraftValue(root, v) {
|
|
5090
|
-
const seq =
|
|
5091
|
-
const key =
|
|
5061
|
+
const seq = seqGet(root, this.seqField, NONE);
|
|
5062
|
+
const key = seqGet(root, this.keyField, NONE);
|
|
5092
5063
|
if (seq !== NONE && key !== NONE) writeSeqKey(seq, key, v);
|
|
5093
5064
|
}
|
|
5094
5065
|
// Resolve `keyField` against `v` now and freeze it as a literal-key `SeqStep`, so a
|
|
5095
5066
|
// later lookup/setValue lands on this same item even if `keyField` changes meanwhile.
|
|
5096
5067
|
pinKey(v) {
|
|
5097
|
-
const key =
|
|
5068
|
+
const key = seqGet(v, this.keyField, NONE);
|
|
5098
5069
|
return key === NONE ? this : new SeqStep(this.seqField, key);
|
|
5099
5070
|
}
|
|
5100
5071
|
// The key is a *field reference* resolved live, so it is unknown without a value;
|
|
@@ -5105,70 +5076,62 @@ var SeqAccessStep = class extends Step {
|
|
|
5105
5076
|
}
|
|
5106
5077
|
};
|
|
5107
5078
|
var EachBindStep = class extends Step {
|
|
5108
|
-
constructor(
|
|
5079
|
+
constructor(eachNode, key) {
|
|
5109
5080
|
super();
|
|
5110
|
-
this.
|
|
5081
|
+
this.eachNode = eachNode;
|
|
5111
5082
|
this.key = key;
|
|
5112
5083
|
}
|
|
5113
|
-
lookup(v
|
|
5084
|
+
lookup(v) {
|
|
5114
5085
|
return v;
|
|
5115
5086
|
}
|
|
5116
5087
|
// Replay the renderer's per-item binds (key, value + any @enrich-with binds)
|
|
5117
5088
|
// so a rebuilt stack matches the one @each rendered with.
|
|
5118
|
-
enterFrame(stack, next) {
|
|
5119
|
-
return stack.enter(next, this.
|
|
5089
|
+
enterFrame(stack, next, renderPath) {
|
|
5090
|
+
return stack.enter(next, this.eachNode.enrichBinds(stack, this.key), false, renderPath);
|
|
5120
5091
|
}
|
|
5121
5092
|
toAbstractPathStep() {
|
|
5122
5093
|
return null;
|
|
5123
5094
|
}
|
|
5124
5095
|
};
|
|
5125
5096
|
var EachRenderItStep = class extends SeqStep {
|
|
5126
|
-
enterFrame(stack, next) {
|
|
5127
|
-
return stack.enter(next, { key: this.key, value: next }, false).enter(next, {}, true);
|
|
5097
|
+
enterFrame(stack, next, renderPath) {
|
|
5098
|
+
return stack.enter(next, { key: this.key, value: next }, false, renderPath).enter(next, {}, true, renderPath);
|
|
5128
5099
|
}
|
|
5129
5100
|
toAbstractPathStep() {
|
|
5130
5101
|
return new SeqStep(this.field, this.key);
|
|
5131
5102
|
}
|
|
5132
5103
|
};
|
|
5133
|
-
function
|
|
5134
|
-
|
|
5104
|
+
function stepToJson(step) {
|
|
5105
|
+
if (step instanceof SeqStep) return { f: step.field, k: step.key };
|
|
5106
|
+
if (step instanceof FieldStep) return { f: step.field };
|
|
5107
|
+
if (step instanceof SeqAccessStep) return { f: step.seqField, a: step.keyField };
|
|
5108
|
+
return null;
|
|
5135
5109
|
}
|
|
5136
|
-
|
|
5137
|
-
|
|
5138
|
-
|
|
5139
|
-
|
|
5140
|
-
|
|
5141
|
-
|
|
5142
|
-
|
|
5143
|
-
|
|
5144
|
-
|
|
5145
|
-
|
|
5146
|
-
|
|
5147
|
-
|
|
5148
|
-
warnRawDynStep("lookup", this);
|
|
5149
|
-
return dval;
|
|
5150
|
-
}
|
|
5151
|
-
enterFrame(stack, _next) {
|
|
5152
|
-
warnRawDynStep("enterFrame", this);
|
|
5153
|
-
return stack;
|
|
5154
|
-
}
|
|
5155
|
-
};
|
|
5156
|
-
var DynEachStep = class extends DynStep {
|
|
5157
|
-
constructor(producerCompId, producerSteps, key) {
|
|
5158
|
-
super(producerCompId, producerSteps);
|
|
5159
|
-
this.key = key;
|
|
5110
|
+
function stepFromJson(j) {
|
|
5111
|
+
if (j == null || typeof j.f !== "string") return null;
|
|
5112
|
+
if (j.k !== void 0) return new SeqStep(j.f, j.k);
|
|
5113
|
+
if (j.a !== void 0) return new SeqAccessStep(j.f, j.a);
|
|
5114
|
+
return new FieldStep(j.f);
|
|
5115
|
+
}
|
|
5116
|
+
function pathToJson(path2) {
|
|
5117
|
+
const out = [];
|
|
5118
|
+
for (const step of path2.steps) {
|
|
5119
|
+
const j = stepToJson(step);
|
|
5120
|
+
if (j === null) return null;
|
|
5121
|
+
out.push(j);
|
|
5160
5122
|
}
|
|
5161
|
-
|
|
5162
|
-
|
|
5163
|
-
|
|
5164
|
-
|
|
5165
|
-
|
|
5166
|
-
|
|
5167
|
-
|
|
5168
|
-
|
|
5169
|
-
|
|
5123
|
+
return out;
|
|
5124
|
+
}
|
|
5125
|
+
function pathFromJson(j) {
|
|
5126
|
+
if (!Array.isArray(j)) return null;
|
|
5127
|
+
const steps = [];
|
|
5128
|
+
for (const item of j) {
|
|
5129
|
+
const step = stepFromJson(item);
|
|
5130
|
+
if (step === null) return null;
|
|
5131
|
+
steps.push(step);
|
|
5170
5132
|
}
|
|
5171
|
-
|
|
5133
|
+
return new Path(steps);
|
|
5134
|
+
}
|
|
5172
5135
|
var Path = class _Path {
|
|
5173
5136
|
constructor(steps = []) {
|
|
5174
5137
|
this.steps = steps;
|
|
@@ -5176,43 +5139,13 @@ var Path = class _Path {
|
|
|
5176
5139
|
concat(steps) {
|
|
5177
5140
|
return new _Path(this.steps.concat(steps));
|
|
5178
5141
|
}
|
|
5179
|
-
popStep
|
|
5180
|
-
|
|
5181
|
-
}
|
|
5182
|
-
// The dispatch path: frame-only steps removed, one step per crossed component
|
|
5183
|
-
// (DynStep included). `popStep` over it bubbles through every component.
|
|
5142
|
+
// Frame-only steps removed, one step per crossed component: `popStep` over the
|
|
5143
|
+
// result bubbles through every component.
|
|
5184
5144
|
compact() {
|
|
5185
5145
|
const out = [];
|
|
5186
5146
|
for (const step of this.steps) {
|
|
5187
5147
|
const s = step.toAbstractPathStep();
|
|
5188
|
-
if (s !== null)
|
|
5189
|
-
if (s !== step) s._originCid = step._originCid;
|
|
5190
|
-
out.push(s);
|
|
5191
|
-
}
|
|
5192
|
-
}
|
|
5193
|
-
return new _Path(out);
|
|
5194
|
-
}
|
|
5195
|
-
// The abstract path used to apply a transaction: every DynStep is teleported —
|
|
5196
|
-
// the steps interior to its producer..consumer span are dropped and the
|
|
5197
|
-
// producer's own path spliced in — so a mutation lands on the data's real
|
|
5198
|
-
// location. A path with no DynStep is returned unchanged.
|
|
5199
|
-
toTransactionPath() {
|
|
5200
|
-
let hasDyn = false;
|
|
5201
|
-
for (const step of this.steps)
|
|
5202
|
-
if (step instanceof DynStep) {
|
|
5203
|
-
hasDyn = true;
|
|
5204
|
-
break;
|
|
5205
|
-
}
|
|
5206
|
-
if (!hasDyn) return this;
|
|
5207
|
-
const out = [];
|
|
5208
|
-
for (const step of this.steps) {
|
|
5209
|
-
if (step instanceof DynStep) {
|
|
5210
|
-
while (out.length > 0 && step.interiorCids.has(out[out.length - 1]._originCid)) out.pop();
|
|
5211
|
-
for (const ts of step.teleportSteps()) {
|
|
5212
|
-
ts._originCid = step.producerCompId;
|
|
5213
|
-
out.push(ts);
|
|
5214
|
-
}
|
|
5215
|
-
} else out.push(step);
|
|
5148
|
+
if (s !== null) out.push(s);
|
|
5216
5149
|
}
|
|
5217
5150
|
return new _Path(out);
|
|
5218
5151
|
}
|
|
@@ -5220,7 +5153,6 @@ var Path = class _Path {
|
|
|
5220
5153
|
// key as it is *now* so a later lookup/setValue lands on the same item even if the
|
|
5221
5154
|
// keyField changed meanwhile (e.g. the selected tab moved while an intent was in
|
|
5222
5155
|
// flight). Returns a new Path with those steps replaced; `this` if nothing pinned.
|
|
5223
|
-
// Must be called on a transaction path (no DynSteps — call toTransactionPath first).
|
|
5224
5156
|
pinKeys(root) {
|
|
5225
5157
|
let curVal = root;
|
|
5226
5158
|
let out = null;
|
|
@@ -5228,7 +5160,7 @@ var Path = class _Path {
|
|
|
5228
5160
|
const step = this.steps[i];
|
|
5229
5161
|
const pinned = step.pinKey(curVal);
|
|
5230
5162
|
if (pinned !== step) (out ??= this.steps.slice())[i] = pinned;
|
|
5231
|
-
curVal = step.lookup(curVal
|
|
5163
|
+
curVal = step.lookup(curVal);
|
|
5232
5164
|
if (curVal === NONE) break;
|
|
5233
5165
|
}
|
|
5234
5166
|
return out ? new _Path(out) : this;
|
|
@@ -5236,20 +5168,20 @@ var Path = class _Path {
|
|
|
5236
5168
|
lookup(v, dval = null) {
|
|
5237
5169
|
let curVal = v;
|
|
5238
5170
|
for (const step of this.steps) {
|
|
5239
|
-
curVal = step.lookup(curVal
|
|
5171
|
+
curVal = step.lookup(curVal);
|
|
5240
5172
|
if (curVal === NONE) return dval;
|
|
5241
5173
|
}
|
|
5242
5174
|
return curVal;
|
|
5243
5175
|
}
|
|
5244
5176
|
// The values entered along the path, root→leaf (root included): index 0 is `root`,
|
|
5245
5177
|
// the last entry is the leaf this path resolves to. Stops early at the first
|
|
5246
|
-
// unresolvable step.
|
|
5247
|
-
//
|
|
5178
|
+
// unresolvable step. Used to walk the component instances on a dispatch path
|
|
5179
|
+
// (filter via Components.getCompFor).
|
|
5248
5180
|
resolveChain(root) {
|
|
5249
5181
|
const out = [root];
|
|
5250
5182
|
let curVal = root;
|
|
5251
5183
|
for (const step of this.steps) {
|
|
5252
|
-
curVal = step.lookup(curVal
|
|
5184
|
+
curVal = step.lookup(curVal);
|
|
5253
5185
|
if (curVal === NONE) break;
|
|
5254
5186
|
out.push(curVal);
|
|
5255
5187
|
}
|
|
@@ -5258,7 +5190,7 @@ var Path = class _Path {
|
|
|
5258
5190
|
// A flat `[{ field, key? }]` list of the addressing steps, skipping frame-only
|
|
5259
5191
|
// steps (binds). Generic path introspection so tooling (e.g. the storybook
|
|
5260
5192
|
// activity log) can identify which subtree a transaction touched without
|
|
5261
|
-
// depending on Step internals.
|
|
5193
|
+
// depending on Step internals.
|
|
5262
5194
|
toKeys() {
|
|
5263
5195
|
const out = [];
|
|
5264
5196
|
for (const step of this.steps) {
|
|
@@ -5272,69 +5204,146 @@ var Path = class _Path {
|
|
|
5272
5204
|
return produce(root, (draft) => {
|
|
5273
5205
|
let parent = draft;
|
|
5274
5206
|
for (let i = 0; i < this.steps.length - 1; i++) {
|
|
5275
|
-
parent = this.steps[i].lookup(parent
|
|
5207
|
+
parent = this.steps[i].lookup(parent);
|
|
5276
5208
|
if (parent === NONE) return;
|
|
5277
5209
|
}
|
|
5278
5210
|
this.steps.at(-1).setDraftValue(parent, v);
|
|
5279
5211
|
});
|
|
5280
5212
|
}
|
|
5213
|
+
};
|
|
5214
|
+
function walkItems(stack, items, renderPath, path2) {
|
|
5215
|
+
let prev = stack.it;
|
|
5216
|
+
for (const step of items) {
|
|
5217
|
+
const next = step.lookup(prev);
|
|
5218
|
+
if (next === NONE) {
|
|
5219
|
+
console.warn("bad PathItem", { root: stack.it, step, path: path2 });
|
|
5220
|
+
return null;
|
|
5221
|
+
}
|
|
5222
|
+
renderPath = renderPath.pushItem(step);
|
|
5223
|
+
stack = step.enterFrame(stack, next, renderPath);
|
|
5224
|
+
prev = next;
|
|
5225
|
+
}
|
|
5226
|
+
return [stack, renderPath];
|
|
5227
|
+
}
|
|
5228
|
+
var EMPTY_PATH = new Path([]);
|
|
5229
|
+
var DispatchPath = class _DispatchPath {
|
|
5230
|
+
constructor(frames = [{ base: EMPTY_PATH, items: [] }]) {
|
|
5231
|
+
this.frames = frames;
|
|
5232
|
+
}
|
|
5233
|
+
// Plain addressing steps in one frame based at the root: what a caller means
|
|
5234
|
+
// by "this position" when it has no continuation of its own.
|
|
5235
|
+
static ofSteps(steps) {
|
|
5236
|
+
return new _DispatchPath([{ base: EMPTY_PATH, items: steps.slice() }]);
|
|
5237
|
+
}
|
|
5238
|
+
get top() {
|
|
5239
|
+
return this.frames[this.frames.length - 1];
|
|
5240
|
+
}
|
|
5241
|
+
_withTopItems(items) {
|
|
5242
|
+
const frames = this.frames.slice();
|
|
5243
|
+
frames[frames.length - 1] = { base: this.top.base, items };
|
|
5244
|
+
return new _DispatchPath(frames);
|
|
5245
|
+
}
|
|
5246
|
+
concat(steps) {
|
|
5247
|
+
return this._withTopItems(this.top.items.concat(steps));
|
|
5248
|
+
}
|
|
5249
|
+
pushItem(step) {
|
|
5250
|
+
return this.concat([step]);
|
|
5251
|
+
}
|
|
5252
|
+
pushFrame(base) {
|
|
5253
|
+
return new _DispatchPath(this.frames.concat({ base, items: [] }));
|
|
5254
|
+
}
|
|
5255
|
+
// Whether bubbling has anywhere left to go: another step in this frame, or a
|
|
5256
|
+
// visual caller underneath it. (A path always has at least one frame.)
|
|
5257
|
+
canPop() {
|
|
5258
|
+
return this.frames.length > 1 || this.frames[0].items.length > 0;
|
|
5259
|
+
}
|
|
5260
|
+
// One component closer to the root. At the top of a frame that is popping back
|
|
5261
|
+
// to the visual caller, not to the producer's own parent — the caller is where
|
|
5262
|
+
// the `*name` was written, and where an unhandled message should keep going.
|
|
5263
|
+
popStep() {
|
|
5264
|
+
const { top } = this;
|
|
5265
|
+
if (top.items.length > 0) return this._withTopItems(top.items.slice(0, -1));
|
|
5266
|
+
if (this.frames.length > 1) return new _DispatchPath(this.frames.slice(0, -1));
|
|
5267
|
+
return this;
|
|
5268
|
+
}
|
|
5269
|
+
// Drop frame-only steps inside every frame independently; a frame's base is
|
|
5270
|
+
// already addressing-only.
|
|
5271
|
+
compact() {
|
|
5272
|
+
return new _DispatchPath(
|
|
5273
|
+
this.frames.map(({ base, items }) => ({ base, items: new Path(items).compact().steps }))
|
|
5274
|
+
);
|
|
5275
|
+
}
|
|
5276
|
+
// A stable string for the ADDRESS this path denotes, for the render cache. The
|
|
5277
|
+
// same immutable value can sit at two places in the tree, and a subtree rendered
|
|
5278
|
+
// at one of them bakes that address in — the provides it publishes are located
|
|
5279
|
+
// there. Frame-only steps address nothing, so they are compacted out: two sites
|
|
5280
|
+
// that differ only in binds do render the same subtree.
|
|
5281
|
+
get addressKey() {
|
|
5282
|
+
this._addressKey ??= renderPathText(this.toTransactionPath().compact());
|
|
5283
|
+
return this._addressKey;
|
|
5284
|
+
}
|
|
5285
|
+
// The active transaction address: the top frame's absolute base followed by
|
|
5286
|
+
// its ordinary descendant steps. This is where a mutation lands.
|
|
5287
|
+
toTransactionPath() {
|
|
5288
|
+
const { base, items } = this.top;
|
|
5289
|
+
return base.concat(items);
|
|
5290
|
+
}
|
|
5291
|
+
// Rebuild the render stack this path was dispatched from. A frame with a base
|
|
5292
|
+
// re-enters at that absolute value first — replaying the resume a `*name`
|
|
5293
|
+
// render performed — and then walks its ordinary items.
|
|
5281
5294
|
buildStack(stack) {
|
|
5282
|
-
let
|
|
5283
|
-
for (
|
|
5284
|
-
const
|
|
5285
|
-
if (
|
|
5286
|
-
|
|
5287
|
-
|
|
5295
|
+
let renderPath = new _DispatchPath();
|
|
5296
|
+
for (let i = 0; i < this.frames.length; i++) {
|
|
5297
|
+
const { base, items } = this.frames[i];
|
|
5298
|
+
if (i > 0 || base.steps.length > 0) {
|
|
5299
|
+
const baseValue = base.lookup(stack.root, NONE);
|
|
5300
|
+
if (baseValue === NONE) {
|
|
5301
|
+
console.warn("bad frame base", { base, path: this });
|
|
5302
|
+
return null;
|
|
5303
|
+
}
|
|
5304
|
+
renderPath = renderPath.pushFrame(base);
|
|
5305
|
+
stack = stack.enter(baseValue, {}, true, renderPath);
|
|
5288
5306
|
}
|
|
5289
|
-
|
|
5290
|
-
|
|
5307
|
+
const walked = walkItems(stack, items, renderPath, this);
|
|
5308
|
+
if (walked === null) return null;
|
|
5309
|
+
[stack, renderPath] = walked;
|
|
5291
5310
|
}
|
|
5292
5311
|
return stack;
|
|
5293
5312
|
}
|
|
5294
|
-
|
|
5295
|
-
|
|
5296
|
-
|
|
5313
|
+
// Reconstruct the dispatch position of a DOM event from the `data-*` stamps and
|
|
5314
|
+
// `§…§` meta comments the renderer left on the way down. `stopOnNoEvent` is off for
|
|
5315
|
+
// drag events, whose path is needed even where no handler is registered.
|
|
5316
|
+
static fromNodeAndEventName(node, eventName, rootNode, comps, stopOnNoEvent = true) {
|
|
5317
|
+
const parts = [];
|
|
5297
5318
|
const bubbles = BUBBLING_EVENTS.has(eventName);
|
|
5298
|
-
let depth = 0;
|
|
5299
5319
|
let eventIds = [];
|
|
5300
5320
|
let handlers = null;
|
|
5301
|
-
let
|
|
5321
|
+
let nodeRefs = [];
|
|
5302
5322
|
let isLeafComponent = true;
|
|
5303
5323
|
const crossComponent = (cidNum, vid) => {
|
|
5304
5324
|
const comp = comps.getComponentForId(cidNum);
|
|
5305
|
-
let
|
|
5325
|
+
let pushPart = true;
|
|
5306
5326
|
if (handlers === null && (isLeafComponent || bubbles)) {
|
|
5307
5327
|
handlers = findHandlers(comp, eventIds, vid, eventName);
|
|
5308
5328
|
if (handlers === null) {
|
|
5309
5329
|
if (isLeafComponent && stopOnNoEvent && !bubbles) return false;
|
|
5310
5330
|
} else if (!isLeafComponent) {
|
|
5311
|
-
|
|
5312
|
-
|
|
5313
|
-
pushStep = false;
|
|
5331
|
+
parts.length = 0;
|
|
5332
|
+
pushPart = false;
|
|
5314
5333
|
}
|
|
5315
5334
|
}
|
|
5316
5335
|
isLeafComponent = false;
|
|
5317
|
-
|
|
5318
|
-
|
|
5319
|
-
|
|
5320
|
-
if (step) {
|
|
5321
|
-
step._originCid = cidNum;
|
|
5322
|
-
pathSteps.push(step);
|
|
5323
|
-
if (step instanceof DynStep) {
|
|
5324
|
-
step.interiorCids.add(cidNum);
|
|
5325
|
-
pendingDyns.push(step);
|
|
5326
|
-
}
|
|
5327
|
-
}
|
|
5336
|
+
if (pushPart) {
|
|
5337
|
+
const part = resolvePathPart(comp, nodeRefs, vid);
|
|
5338
|
+
if (part) parts.push(part);
|
|
5328
5339
|
}
|
|
5329
|
-
for (let i = pendingDyns.length - 1; i >= 0; i--)
|
|
5330
|
-
if (pendingDyns[i].producerCompId === cidNum) pendingDyns.splice(i, 1);
|
|
5331
5340
|
eventIds = [];
|
|
5332
|
-
|
|
5341
|
+
nodeRefs = [];
|
|
5333
5342
|
return true;
|
|
5334
5343
|
};
|
|
5335
|
-
while (node && node !== rootNode
|
|
5344
|
+
while (node && node !== rootNode) {
|
|
5336
5345
|
if (node?.dataset) {
|
|
5337
|
-
const { eid, cid, vid } = node.dataset;
|
|
5346
|
+
const { eid, cid, vid, rp } = node.dataset;
|
|
5338
5347
|
if (eid !== void 0) eventIds.push(eid);
|
|
5339
5348
|
const metas = metaChain(node.previousSibling);
|
|
5340
5349
|
let sawComp = false;
|
|
@@ -5342,21 +5351,46 @@ var Path = class _Path {
|
|
|
5342
5351
|
if (m.$ === "Comp") {
|
|
5343
5352
|
sawComp = true;
|
|
5344
5353
|
if (!crossComponent(m.cid, m.vid)) return NO_EVENT_INFO;
|
|
5345
|
-
|
|
5354
|
+
nodeRefs.push({ nid: m.nid, base: pathFromJson(m.base) });
|
|
5346
5355
|
} else {
|
|
5347
|
-
|
|
5356
|
+
nodeRefs.push({ nid: m.nid, si: m.si, sk: m.sk });
|
|
5357
|
+
}
|
|
5358
|
+
}
|
|
5359
|
+
if (!sawComp && cid !== void 0) {
|
|
5360
|
+
if (!crossComponent(+cid, vid)) return NO_EVENT_INFO;
|
|
5361
|
+
if (rp !== void 0) {
|
|
5362
|
+
const base = parseRenderPath(rp);
|
|
5363
|
+
if (base !== null) nodeRefs.push({ base });
|
|
5348
5364
|
}
|
|
5349
5365
|
}
|
|
5350
|
-
if (!sawComp && cid !== void 0 && !crossComponent(+cid, vid)) return NO_EVENT_INFO;
|
|
5351
5366
|
}
|
|
5352
|
-
depth += 1;
|
|
5353
5367
|
node = node.parentNode;
|
|
5354
5368
|
}
|
|
5355
|
-
|
|
5356
|
-
|
|
5357
|
-
|
|
5369
|
+
parts.reverse();
|
|
5370
|
+
let path2 = new _DispatchPath();
|
|
5371
|
+
for (const part of parts)
|
|
5372
|
+
path2 = part.base !== void 0 ? path2.pushFrame(part.base) : path2.pushItem(part.step);
|
|
5373
|
+
return [path2, handlers];
|
|
5358
5374
|
}
|
|
5359
5375
|
};
|
|
5376
|
+
function keyedPath(path2, key) {
|
|
5377
|
+
const steps = path2.steps;
|
|
5378
|
+
const last = steps[steps.length - 1];
|
|
5379
|
+
if (last instanceof SeqStep || last instanceof FieldStep)
|
|
5380
|
+
return new Path(steps.slice(0, -1).concat(new SeqStep(last.field, key)));
|
|
5381
|
+
return null;
|
|
5382
|
+
}
|
|
5383
|
+
function renderPathText(path2) {
|
|
5384
|
+
return JSON.stringify(pathToJson(path2));
|
|
5385
|
+
}
|
|
5386
|
+
function parseRenderPath(text) {
|
|
5387
|
+
try {
|
|
5388
|
+
return pathFromJson(JSON.parse(text));
|
|
5389
|
+
} catch (err) {
|
|
5390
|
+
console.warn("bad render path", err, text);
|
|
5391
|
+
return null;
|
|
5392
|
+
}
|
|
5393
|
+
}
|
|
5360
5394
|
function metaChain(n) {
|
|
5361
5395
|
const out = [];
|
|
5362
5396
|
while (n?.nodeType === 8 && n.textContent[0] === "§") {
|
|
@@ -5401,28 +5435,28 @@ var StepCtx = class _StepCtx {
|
|
|
5401
5435
|
resolveNode() {
|
|
5402
5436
|
return this.comp.getNodeForId(+this.meta.nid, this.vid);
|
|
5403
5437
|
}
|
|
5404
|
-
applyKey(pi) {
|
|
5405
|
-
if (pi === null) return null;
|
|
5406
|
-
const m = this.meta;
|
|
5407
|
-
if (m.si !== void 0) return pi.withIndex(+m.si);
|
|
5408
|
-
if (m.sk !== void 0) return pi.withKey(m.sk);
|
|
5409
|
-
return pi;
|
|
5410
|
-
}
|
|
5411
5438
|
};
|
|
5412
|
-
function
|
|
5413
|
-
for (let i = 0; i <
|
|
5414
|
-
const
|
|
5415
|
-
|
|
5416
|
-
if (
|
|
5439
|
+
function resolvePathPart(comp, nodeRefs, vid) {
|
|
5440
|
+
for (let i = 0; i < nodeRefs.length; i++) {
|
|
5441
|
+
const ref = nodeRefs[i];
|
|
5442
|
+
if (ref.base != null) return { base: ref.base };
|
|
5443
|
+
if (ref.nid === void 0 || ref.nid === null) continue;
|
|
5444
|
+
const ctx = new StepCtx(comp, nodeRefs, i, vid);
|
|
5445
|
+
const step = ctx.resolveNode()?.toPathStep(ctx) ?? null;
|
|
5446
|
+
if (step !== null) return { step };
|
|
5417
5447
|
}
|
|
5418
5448
|
return null;
|
|
5419
5449
|
}
|
|
5420
5450
|
var NO_EVENT_INFO = [null, null];
|
|
5421
5451
|
var BUBBLING_EVENTS = /* @__PURE__ */ new Set(["drop"]);
|
|
5452
|
+
var path = () => new PathBuilder();
|
|
5422
5453
|
var PathBuilder = class {
|
|
5423
5454
|
constructor() {
|
|
5424
5455
|
this.pathChanges = [];
|
|
5425
5456
|
}
|
|
5457
|
+
toPath() {
|
|
5458
|
+
return new Path(this.pathChanges);
|
|
5459
|
+
}
|
|
5426
5460
|
add(pathChange) {
|
|
5427
5461
|
this.pathChanges.push(pathChange);
|
|
5428
5462
|
return this;
|
|
@@ -5438,10 +5472,8 @@ var PathBuilder = class {
|
|
|
5438
5472
|
}
|
|
5439
5473
|
};
|
|
5440
5474
|
|
|
5441
|
-
// src/util/env.js
|
|
5442
|
-
var isMac = (globalThis.navigator?.userAgent ?? "").toLowerCase().includes("mac");
|
|
5443
|
-
|
|
5444
5475
|
// src/value.js
|
|
5476
|
+
var isMac = (globalThis.navigator?.userAgent ?? "").toLowerCase().includes("mac");
|
|
5445
5477
|
var VALID_VAL_ID_RE = /^[a-zA-Z][a-zA-Z0-9_]*\??$/;
|
|
5446
5478
|
var isValidValId = (name) => VALID_VAL_ID_RE.test(name);
|
|
5447
5479
|
var VALID_FLOAT_RE = /^-?[0-9]+(\.[0-9]+)?$/;
|
|
@@ -5623,22 +5655,10 @@ function _parsePredicate(s, tokens, px) {
|
|
|
5623
5655
|
}
|
|
5624
5656
|
return new PredicateVal(pred, args);
|
|
5625
5657
|
}
|
|
5626
|
-
|
|
5627
|
-
if (val === null) return 0;
|
|
5628
|
-
if (val instanceof ConstVal) return val.kind;
|
|
5629
|
-
if (val instanceof StrTplVal) return val.kind;
|
|
5630
|
-
if (val instanceof SeqAccessVal) return K_SEQ;
|
|
5631
|
-
if (val instanceof FieldVal) return K_FIELD;
|
|
5632
|
-
if (val instanceof MethodVal) return K_METHOD;
|
|
5633
|
-
if (val instanceof BindVal) return K_BIND;
|
|
5634
|
-
if (val instanceof DynVal) return K_DYN;
|
|
5635
|
-
if (val instanceof NameVal) return K_NAME;
|
|
5636
|
-
if (val instanceof EventMemberVal) return K_EVENT;
|
|
5637
|
-
return 0;
|
|
5638
|
-
}
|
|
5658
|
+
var kindOf = (val) => val?.kind ?? 0;
|
|
5639
5659
|
var BaseVal = class {
|
|
5640
|
-
|
|
5641
|
-
|
|
5660
|
+
// No kind: never accepted by a group (PredicateVal, which only parseBool builds).
|
|
5661
|
+
kind = 0;
|
|
5642
5662
|
eval(_stack) {
|
|
5643
5663
|
}
|
|
5644
5664
|
toPathItem() {
|
|
@@ -5658,9 +5678,6 @@ var ConstVal = class extends BaseVal {
|
|
|
5658
5678
|
this.val = val;
|
|
5659
5679
|
this.kind = kind;
|
|
5660
5680
|
}
|
|
5661
|
-
render(_stack, _rx) {
|
|
5662
|
-
return this.val;
|
|
5663
|
-
}
|
|
5664
5681
|
eval(_stack) {
|
|
5665
5682
|
return this.val;
|
|
5666
5683
|
}
|
|
@@ -5686,9 +5703,7 @@ var PredicateVal = class extends BaseVal {
|
|
|
5686
5703
|
return `${this.pred.name} ${this.args.map(String).join(" ")}`;
|
|
5687
5704
|
}
|
|
5688
5705
|
};
|
|
5689
|
-
var
|
|
5690
|
-
};
|
|
5691
|
-
var StrTplVal = class _StrTplVal extends VarVal {
|
|
5706
|
+
var StrTplVal = class _StrTplVal extends BaseVal {
|
|
5692
5707
|
constructor(vals) {
|
|
5693
5708
|
super();
|
|
5694
5709
|
this.vals = vals;
|
|
@@ -5701,9 +5716,6 @@ var StrTplVal = class _StrTplVal extends VarVal {
|
|
|
5701
5716
|
for (const v of this.vals) if (!(v instanceof ConstVal) || v.fromMacroVar) return false;
|
|
5702
5717
|
return true;
|
|
5703
5718
|
}
|
|
5704
|
-
render(stack, _rx) {
|
|
5705
|
-
return this.eval(stack);
|
|
5706
|
-
}
|
|
5707
5719
|
eval(stack) {
|
|
5708
5720
|
const strs = new Array(this.vals.length);
|
|
5709
5721
|
for (let i = 0; i < this.vals.length; i++) strs[i] = this.vals[i]?.eval(stack, "");
|
|
@@ -5740,7 +5752,8 @@ var StrTplVal = class _StrTplVal extends VarVal {
|
|
|
5740
5752
|
return new _StrTplVal(lo === 0 && hi === vals.length ? vals : vals.slice(lo, hi));
|
|
5741
5753
|
}
|
|
5742
5754
|
};
|
|
5743
|
-
var NameVal = class extends
|
|
5755
|
+
var NameVal = class extends BaseVal {
|
|
5756
|
+
kind = K_NAME;
|
|
5744
5757
|
constructor(name) {
|
|
5745
5758
|
super();
|
|
5746
5759
|
this.name = name;
|
|
@@ -5790,6 +5803,7 @@ var EVENT_CONVENIENCES = {
|
|
|
5790
5803
|
dragKey: nullSafe((info) => info.lookupBind("key"))
|
|
5791
5804
|
};
|
|
5792
5805
|
var EventMemberVal = class extends BaseVal {
|
|
5806
|
+
kind = K_EVENT;
|
|
5793
5807
|
constructor(members) {
|
|
5794
5808
|
super();
|
|
5795
5809
|
this.members = members;
|
|
@@ -5812,24 +5826,21 @@ var EventMemberVal = class extends BaseVal {
|
|
|
5812
5826
|
return `e.${this.members.join(".")}`;
|
|
5813
5827
|
}
|
|
5814
5828
|
};
|
|
5815
|
-
var
|
|
5816
|
-
render(stack, _rx) {
|
|
5817
|
-
return this.eval(stack);
|
|
5818
|
-
}
|
|
5819
|
-
};
|
|
5820
|
-
var RenderNameVal = class extends RenderVal {
|
|
5829
|
+
var SigilNameVal = class extends BaseVal {
|
|
5821
5830
|
constructor(name) {
|
|
5822
5831
|
super();
|
|
5823
5832
|
this.name = name;
|
|
5824
5833
|
}
|
|
5834
|
+
toString() {
|
|
5835
|
+
return this.sigil + this.name;
|
|
5836
|
+
}
|
|
5825
5837
|
};
|
|
5826
|
-
var BindVal = class extends
|
|
5838
|
+
var BindVal = class extends SigilNameVal {
|
|
5839
|
+
kind = K_BIND;
|
|
5840
|
+
sigil = "@";
|
|
5827
5841
|
eval(stack) {
|
|
5828
5842
|
return stack.lookupBind(this.name);
|
|
5829
5843
|
}
|
|
5830
|
-
toString() {
|
|
5831
|
-
return `@${this.name}`;
|
|
5832
|
-
}
|
|
5833
5844
|
};
|
|
5834
5845
|
var BindMemberVal = class extends BindVal {
|
|
5835
5846
|
constructor(name, member) {
|
|
@@ -5844,37 +5855,35 @@ var BindMemberVal = class extends BindVal {
|
|
|
5844
5855
|
return `@${this.name}.${this.member}`;
|
|
5845
5856
|
}
|
|
5846
5857
|
};
|
|
5847
|
-
var DynVal = class extends
|
|
5858
|
+
var DynVal = class extends SigilNameVal {
|
|
5859
|
+
kind = K_DYN;
|
|
5860
|
+
sigil = "*";
|
|
5848
5861
|
eval(stack) {
|
|
5849
5862
|
return stack.lookupDynamic(this.name);
|
|
5850
5863
|
}
|
|
5851
|
-
toString() {
|
|
5852
|
-
return `*${this.name}`;
|
|
5853
|
-
}
|
|
5854
5864
|
};
|
|
5855
|
-
var FieldVal = class extends
|
|
5865
|
+
var FieldVal = class extends SigilNameVal {
|
|
5866
|
+
kind = K_FIELD;
|
|
5867
|
+
sigil = ".";
|
|
5856
5868
|
eval(stack) {
|
|
5857
5869
|
return stack.lookupFieldRaw(this.name);
|
|
5858
5870
|
}
|
|
5859
5871
|
toPathItem() {
|
|
5860
5872
|
return new FieldStep(this.name);
|
|
5861
5873
|
}
|
|
5862
|
-
toString() {
|
|
5863
|
-
return `.${this.name}`;
|
|
5864
|
-
}
|
|
5865
5874
|
};
|
|
5866
|
-
var MethodVal = class extends
|
|
5875
|
+
var MethodVal = class extends SigilNameVal {
|
|
5876
|
+
kind = K_METHOD;
|
|
5877
|
+
sigil = "$";
|
|
5867
5878
|
eval(stack) {
|
|
5868
5879
|
return stack.lookupMethod(this.name);
|
|
5869
5880
|
}
|
|
5870
5881
|
evalAsHandler(stack) {
|
|
5871
5882
|
return stack.lookupFieldRaw(this.name);
|
|
5872
5883
|
}
|
|
5873
|
-
toString() {
|
|
5874
|
-
return `$${this.name}`;
|
|
5875
|
-
}
|
|
5876
5884
|
};
|
|
5877
|
-
var SeqAccessVal = class extends
|
|
5885
|
+
var SeqAccessVal = class extends BaseVal {
|
|
5886
|
+
kind = K_SEQ;
|
|
5878
5887
|
constructor(seqVal, keyVal) {
|
|
5879
5888
|
super();
|
|
5880
5889
|
this.seqVal = seqVal;
|
|
@@ -5897,9 +5906,6 @@ var Attributes = class {
|
|
|
5897
5906
|
constructor(items) {
|
|
5898
5907
|
this.items = items;
|
|
5899
5908
|
}
|
|
5900
|
-
static parse(attributes, px, parseAll = false) {
|
|
5901
|
-
return new AttrParser(px).parse(attributes, parseAll);
|
|
5902
|
-
}
|
|
5903
5909
|
isConstant() {
|
|
5904
5910
|
return false;
|
|
5905
5911
|
}
|
|
@@ -5917,10 +5923,16 @@ function parseDirectiveValue(px, directiveName, source, parser) {
|
|
|
5917
5923
|
}
|
|
5918
5924
|
return val;
|
|
5919
5925
|
}
|
|
5926
|
+
var ITER_DIRECTIVES = {
|
|
5927
|
+
when: "whenVal",
|
|
5928
|
+
"loop-with": "loopWithVal",
|
|
5929
|
+
"enrich-with": "enrichWithVal"
|
|
5930
|
+
};
|
|
5931
|
+
var parseIterDirective = (px, name, s) => parseDirectiveValue(px, name, s, parseAlterHandler);
|
|
5920
5932
|
function parseIterationDirectives(attributes, px) {
|
|
5921
5933
|
const parseNamed = (name) => {
|
|
5922
5934
|
const attr = attributes.getNamedItem(`@${name}`);
|
|
5923
|
-
return attr ?
|
|
5935
|
+
return attr ? parseIterDirective(px, name, attr.value) : null;
|
|
5924
5936
|
};
|
|
5925
5937
|
return { whenVal: parseNamed("when"), loopWithVal: parseNamed("loop-with") };
|
|
5926
5938
|
}
|
|
@@ -5961,11 +5973,22 @@ var AttrParser = class {
|
|
|
5961
5973
|
this.px.onParseIssue("bad-value", info);
|
|
5962
5974
|
}
|
|
5963
5975
|
}
|
|
5964
|
-
|
|
5965
|
-
|
|
5976
|
+
// `@then` / `@else` fill the branches of the `@if.<attr>` on the same element.
|
|
5977
|
+
parseBranch(slot, name, s) {
|
|
5978
|
+
if (this.ifAttr === null) return this._orphan(name, s, "if");
|
|
5979
|
+
this.ifAttr[slot] = parseText(s, this.px) ?? NOT_SET_VAL;
|
|
5966
5980
|
}
|
|
5967
|
-
|
|
5968
|
-
|
|
5981
|
+
// `@when` / `@loop-with` / `@enrich-with` amend the `@each` on the same element. A
|
|
5982
|
+
// loop-less `@enrich-with` is a scope of its own; the other two need the loop.
|
|
5983
|
+
parseIter(name, s) {
|
|
5984
|
+
const val = parseIterDirective(this.px, name, s);
|
|
5985
|
+
if (this.eachAttr !== null) this.eachAttr[ITER_DIRECTIVES[name]] = val;
|
|
5986
|
+
else if (name === "enrich-with") this.pushWrapper("scope", s, val);
|
|
5987
|
+
else this._orphan(name, s, "each");
|
|
5988
|
+
}
|
|
5989
|
+
// A directive that only means something next to another one, written alone.
|
|
5990
|
+
_orphan(name, value, needs) {
|
|
5991
|
+
this.px.onParseIssue("orphan-directive", { name, value, needs });
|
|
5969
5992
|
}
|
|
5970
5993
|
parseEvent(directiveName, value) {
|
|
5971
5994
|
const [eventName, ...modifiers] = directiveName.slice(3).split("+");
|
|
@@ -5979,77 +6002,51 @@ var AttrParser = class {
|
|
|
5979
6002
|
this.events.add(eventName, handler, modifiers);
|
|
5980
6003
|
}
|
|
5981
6004
|
}
|
|
5982
|
-
_parseDirectiveValue(directiveName, s, parserFn) {
|
|
5983
|
-
return parseDirectiveValue(this.px, directiveName, s, parserFn);
|
|
5984
|
-
}
|
|
5985
6005
|
parseDirective(s, directiveName) {
|
|
5986
6006
|
switch (directiveName) {
|
|
5987
6007
|
case "dangerouslysetinnerhtml":
|
|
5988
6008
|
this.attrs ??= [];
|
|
5989
|
-
this.attrs.push(new RawHtmlAttr(this.
|
|
6009
|
+
this.attrs.push(new RawHtmlAttr(parseDirectiveValue(this.px, directiveName, s, parseText)));
|
|
5990
6010
|
this.hasDynamic = true;
|
|
5991
6011
|
return;
|
|
5992
6012
|
case "push-view":
|
|
5993
|
-
this.pushWrapper("push-view", s, this.
|
|
6013
|
+
this.pushWrapper("push-view", s, parseDirectiveValue(this.px, directiveName, s, parseText));
|
|
5994
6014
|
return;
|
|
5995
6015
|
case "text":
|
|
5996
|
-
this.textChild = this.
|
|
6016
|
+
this.textChild = parseDirectiveValue(this.px, directiveName, s, parseText);
|
|
5997
6017
|
return;
|
|
5998
6018
|
case "show":
|
|
5999
|
-
this.pushWrapper("show", s, this.
|
|
6019
|
+
this.pushWrapper("show", s, parseDirectiveValue(this.px, directiveName, s, parseBool));
|
|
6000
6020
|
return;
|
|
6001
6021
|
case "hide":
|
|
6002
|
-
this.pushWrapper("hide", s, this.
|
|
6022
|
+
this.pushWrapper("hide", s, parseDirectiveValue(this.px, directiveName, s, parseBool));
|
|
6003
6023
|
return;
|
|
6004
6024
|
case "each": {
|
|
6005
|
-
const val = this.
|
|
6025
|
+
const val = parseDirectiveValue(this.px, directiveName, s, parseSequence);
|
|
6006
6026
|
this.eachAttr = this.pushWrapper("each", s, val);
|
|
6007
6027
|
return;
|
|
6008
6028
|
}
|
|
6009
|
-
case "enrich-with":
|
|
6010
|
-
if (this.eachAttr !== null)
|
|
6011
|
-
this.eachAttr.enrichWithVal = this._parseDirectiveValue(
|
|
6012
|
-
directiveName,
|
|
6013
|
-
s,
|
|
6014
|
-
parseAlterHandler
|
|
6015
|
-
);
|
|
6016
|
-
else
|
|
6017
|
-
this.pushWrapper(
|
|
6018
|
-
"scope",
|
|
6019
|
-
s,
|
|
6020
|
-
this._parseDirectiveValue(directiveName, s, parseAlterHandler)
|
|
6021
|
-
);
|
|
6022
|
-
return;
|
|
6023
6029
|
case "when":
|
|
6024
|
-
this._parseWhen(s);
|
|
6025
|
-
return;
|
|
6026
6030
|
case "loop-with":
|
|
6027
|
-
|
|
6031
|
+
case "enrich-with":
|
|
6032
|
+
this.parseIter(directiveName, s);
|
|
6028
6033
|
return;
|
|
6029
6034
|
case "then":
|
|
6030
|
-
this.
|
|
6035
|
+
this.parseBranch("thenVal", directiveName, s);
|
|
6031
6036
|
return;
|
|
6032
6037
|
case "else":
|
|
6033
|
-
this.
|
|
6038
|
+
this.parseBranch("elseVal", directiveName, s);
|
|
6034
6039
|
return;
|
|
6035
6040
|
}
|
|
6036
6041
|
if (directiveName.startsWith("on.")) this.parseEvent(directiveName, s);
|
|
6037
6042
|
else if (directiveName.startsWith("if.")) this.parseIf(directiveName, s);
|
|
6038
|
-
else if (directiveName.startsWith("then.")) this.
|
|
6039
|
-
else if (directiveName.startsWith("else.")) this.
|
|
6043
|
+
else if (directiveName.startsWith("then.")) this.parseBranch("thenVal", directiveName, s);
|
|
6044
|
+
else if (directiveName.startsWith("else.")) this.parseBranch("elseVal", directiveName, s);
|
|
6040
6045
|
else {
|
|
6041
6046
|
const info = { name: directiveName, value: s };
|
|
6042
6047
|
this.px.onParseIssue("unknown-directive", info);
|
|
6043
6048
|
}
|
|
6044
6049
|
}
|
|
6045
|
-
_parseWhen(s) {
|
|
6046
|
-
if (this.eachAttr !== null)
|
|
6047
|
-
this.eachAttr.whenVal = this._parseDirectiveValue("when", s, parseAlterHandler);
|
|
6048
|
-
}
|
|
6049
|
-
_parseLoopWith(s) {
|
|
6050
|
-
if (this.eachAttr !== null)
|
|
6051
|
-
this.eachAttr.loopWithVal = this._parseDirectiveValue("loop-with", s, parseAlterHandler);
|
|
6052
|
-
}
|
|
6053
6050
|
parse(attributes, parseAll = false) {
|
|
6054
6051
|
for (const { name, value } of attributes) {
|
|
6055
6052
|
const charCode = name.charCodeAt(0);
|
|
@@ -6402,19 +6399,21 @@ var VNode = class _VNode extends VBase {
|
|
|
6402
6399
|
const createOpts = attrs.is != null ? { is: attrs.is } : void 0;
|
|
6403
6400
|
const node = ns === null ? doc.createElement(tag, createOpts) : doc.createElementNS(ns, tag, createOpts);
|
|
6404
6401
|
const cOpts = childOpts(this, ns, opts);
|
|
6405
|
-
|
|
6406
|
-
const { value, checked, ...rest } = attrs;
|
|
6407
|
-
applyProperties(node, rest);
|
|
6408
|
-
appendChildNodes(node, this.childs, cOpts);
|
|
6409
|
-
if (value !== void 0) applyValueLast(node, value);
|
|
6410
|
-
if (checked !== void 0) setProp(node, "checked", checked, false);
|
|
6411
|
-
} else {
|
|
6412
|
-
applyProperties(node, attrs);
|
|
6413
|
-
appendChildNodes(node, this.childs, cOpts);
|
|
6414
|
-
}
|
|
6402
|
+
applyAttrs(node, attrs, () => appendChildNodes(node, this.childs, cOpts));
|
|
6415
6403
|
return node;
|
|
6416
6404
|
}
|
|
6417
6405
|
};
|
|
6406
|
+
function applyAttrs(node, attrs, placeChildren) {
|
|
6407
|
+
const hasValue = "value" in attrs;
|
|
6408
|
+
const hasChecked = "checked" in attrs;
|
|
6409
|
+
if (hasValue || hasChecked) {
|
|
6410
|
+
const { value: _v, checked: _c, ...rest } = attrs;
|
|
6411
|
+
applyProperties(node, rest);
|
|
6412
|
+
} else applyProperties(node, attrs);
|
|
6413
|
+
placeChildren();
|
|
6414
|
+
if (hasValue) applyValueLast(node, attrs.value);
|
|
6415
|
+
if (hasChecked) setProp(node, "checked", attrs.checked, isNamespaced(node));
|
|
6416
|
+
}
|
|
6418
6417
|
function diffProps(a, b) {
|
|
6419
6418
|
if (a === b) return null;
|
|
6420
6419
|
let diff = null;
|
|
@@ -6445,22 +6444,16 @@ function morphNode(domNode, source, target, opts) {
|
|
|
6445
6444
|
}
|
|
6446
6445
|
if (type3 === 1 && source.isSameKind(target)) {
|
|
6447
6446
|
const propsDiff = diffProps(source.attrs, target.attrs);
|
|
6448
|
-
const
|
|
6449
|
-
|
|
6450
|
-
if (propsDiff) {
|
|
6451
|
-
if (hasValue || hasChecked) {
|
|
6452
|
-
const { value: _v, checked: _c, ...rest } = propsDiff;
|
|
6453
|
-
applyProperties(domNode, rest);
|
|
6454
|
-
} else applyProperties(domNode, propsDiff);
|
|
6455
|
-
}
|
|
6456
|
-
if (!target.attrs.dangerouslySetInnerHTML) {
|
|
6447
|
+
const placeChildren = () => {
|
|
6448
|
+
if (target.attrs.dangerouslySetInnerHTML) return;
|
|
6457
6449
|
const ns = effectiveNs(target, opts);
|
|
6458
6450
|
morphChildren(domNode, source.childs, target.childs, childOpts(target, ns, opts));
|
|
6451
|
+
};
|
|
6452
|
+
if (propsDiff) applyAttrs(domNode, propsDiff, placeChildren);
|
|
6453
|
+
else placeChildren();
|
|
6454
|
+
if (!(propsDiff && "value" in propsDiff) && source.tag === "SELECT") {
|
|
6455
|
+
if (target.attrs.value !== void 0) applyValueLast(domNode, target.attrs.value);
|
|
6459
6456
|
}
|
|
6460
|
-
if (hasValue) applyValueLast(domNode, propsDiff.value);
|
|
6461
|
-
else if (source.tag === "SELECT" && target.attrs.value !== void 0)
|
|
6462
|
-
applyValueLast(domNode, target.attrs.value);
|
|
6463
|
-
if (hasChecked) setProp(domNode, "checked", propsDiff.checked, false);
|
|
6464
6457
|
return domNode;
|
|
6465
6458
|
}
|
|
6466
6459
|
if (type3 === 11) {
|
|
@@ -6579,20 +6572,26 @@ function h(tagName, properties, children, namespace) {
|
|
|
6579
6572
|
}
|
|
6580
6573
|
|
|
6581
6574
|
// src/anode.js
|
|
6582
|
-
function
|
|
6583
|
-
|
|
6584
|
-
|
|
6585
|
-
|
|
6586
|
-
|
|
6587
|
-
|
|
6588
|
-
|
|
6575
|
+
function renderTarget(val, stack) {
|
|
6576
|
+
if (val instanceof DynVal) {
|
|
6577
|
+
const loc = stack.lookupDynamicLocated(val.name);
|
|
6578
|
+
if (loc?.path == null) return [loc?.value ?? null, stack.renderPath, null];
|
|
6579
|
+
return [loc.value, stack.renderPath.pushFrame(loc.path), loc.path];
|
|
6580
|
+
}
|
|
6581
|
+
const step = val.toPathItem?.() ?? null;
|
|
6582
|
+
if (step === null) return [val.eval(stack), stack.renderPath, null];
|
|
6583
|
+
const path2 = stack.renderPath.pushItem(step);
|
|
6584
|
+
return [val.eval(stack), path2, stack.pendingFrame ? path2.toTransactionPath() : null];
|
|
6589
6585
|
}
|
|
6590
6586
|
var BaseNode = class {
|
|
6591
6587
|
render(_stack, _rx) {
|
|
6592
6588
|
return null;
|
|
6593
6589
|
}
|
|
6594
|
-
|
|
6595
|
-
|
|
6590
|
+
// Stamp a `data-*` attribute on the element(s) this node renders. A no-op for
|
|
6591
|
+
// nodes that produce no element of their own (text, `<x render*>`): a view whose
|
|
6592
|
+
// root is one of those records its component boundary in the `§Comp§` meta
|
|
6593
|
+
// comment instead (see Renderer._rValComp).
|
|
6594
|
+
setDataAttr(_key, _val) {
|
|
6596
6595
|
}
|
|
6597
6596
|
isConstant() {
|
|
6598
6597
|
return false;
|
|
@@ -6631,21 +6630,12 @@ var TextNode = class extends BaseNode {
|
|
|
6631
6630
|
isConstant() {
|
|
6632
6631
|
return true;
|
|
6633
6632
|
}
|
|
6634
|
-
setDataAttr(_key, _val) {
|
|
6635
|
-
}
|
|
6636
6633
|
};
|
|
6637
6634
|
var CommentNode = class extends TextNode {
|
|
6638
6635
|
render(_stack, rx) {
|
|
6639
6636
|
return rx.renderComment(this.val);
|
|
6640
6637
|
}
|
|
6641
6638
|
};
|
|
6642
|
-
function optimizeChilds(childs) {
|
|
6643
|
-
for (let i = 0; i < childs.length; i++) {
|
|
6644
|
-
const child = childs[i];
|
|
6645
|
-
if (child.isConstant()) childs[i] = new RenderOnceNode(child);
|
|
6646
|
-
else child.optimize();
|
|
6647
|
-
}
|
|
6648
|
-
}
|
|
6649
6639
|
function optimizeNode(node) {
|
|
6650
6640
|
if (node.isConstant()) return new RenderOnceNode(node);
|
|
6651
6641
|
node.optimize();
|
|
@@ -6660,7 +6650,8 @@ var ChildsNode = class extends BaseNode {
|
|
|
6660
6650
|
return this.childs.every((v) => v.isConstant());
|
|
6661
6651
|
}
|
|
6662
6652
|
optimize() {
|
|
6663
|
-
|
|
6653
|
+
const { childs } = this;
|
|
6654
|
+
for (let i = 0; i < childs.length; i++) childs[i] = optimizeNode(childs[i]);
|
|
6664
6655
|
}
|
|
6665
6656
|
};
|
|
6666
6657
|
var DomNode = class extends ChildsNode {
|
|
@@ -6672,8 +6663,7 @@ var DomNode = class extends ChildsNode {
|
|
|
6672
6663
|
}
|
|
6673
6664
|
render(stack, rx) {
|
|
6674
6665
|
const childNodes = new Array(this.childs.length);
|
|
6675
|
-
for (let i = 0; i < childNodes.length; i++)
|
|
6676
|
-
childNodes[i] = this.childs[i]?.render?.(stack, rx) ?? null;
|
|
6666
|
+
for (let i = 0; i < childNodes.length; i++) childNodes[i] = this.childs[i].render(stack, rx);
|
|
6677
6667
|
return rx.renderTag(this.tagName, this.attrs.eval(stack), childNodes, this.namespace);
|
|
6678
6668
|
}
|
|
6679
6669
|
setDataAttr(key, val) {
|
|
@@ -6685,7 +6675,7 @@ var DomNode = class extends ChildsNode {
|
|
|
6685
6675
|
};
|
|
6686
6676
|
var FragmentNode = class extends ChildsNode {
|
|
6687
6677
|
render(stack, rx) {
|
|
6688
|
-
return rx.renderFragment(this.childs.map((c) => c
|
|
6678
|
+
return rx.renderFragment(this.childs.map((c) => c.render(stack, rx)));
|
|
6689
6679
|
}
|
|
6690
6680
|
setDataAttr(key, val) {
|
|
6691
6681
|
for (const child of this.childs) child.setDataAttr(key, val);
|
|
@@ -6699,8 +6689,10 @@ var ANode = class _ANode extends BaseNode {
|
|
|
6699
6689
|
this.nodeId = nodeId;
|
|
6700
6690
|
this.val = val;
|
|
6701
6691
|
}
|
|
6702
|
-
|
|
6703
|
-
|
|
6692
|
+
// The addressing step this node contributes to an event's dispatch path, given
|
|
6693
|
+
// the `StepCtx` of the meta that named it; null when it addresses nothing.
|
|
6694
|
+
toPathStep(_ctx) {
|
|
6695
|
+
return this.val?.toPathItem?.() ?? null;
|
|
6704
6696
|
}
|
|
6705
6697
|
static parse(html2, px) {
|
|
6706
6698
|
const nodes = px.parseHTML(html2);
|
|
@@ -6716,8 +6708,8 @@ var ANode = class _ANode extends BaseNode {
|
|
|
6716
6708
|
return maybeFragment(trimmed);
|
|
6717
6709
|
}
|
|
6718
6710
|
static fromDOM(node, px) {
|
|
6719
|
-
if (node
|
|
6720
|
-
|
|
6711
|
+
if (node.nodeType === 3) return new TextNode(node.textContent);
|
|
6712
|
+
if (node.nodeType === 8) return new CommentNode(node.textContent);
|
|
6721
6713
|
const { childNodes, attributes: attrs, tagName: tag } = node;
|
|
6722
6714
|
const childs = [];
|
|
6723
6715
|
for (let i = 0; i < childNodes.length; i++) {
|
|
@@ -6735,11 +6727,11 @@ var ANode = class _ANode extends BaseNode {
|
|
|
6735
6727
|
const slotName = attrs.getNamedItem("name")?.value ?? "_";
|
|
6736
6728
|
return px.frame.macroSlots[slotName] ?? maybeFragment(childs);
|
|
6737
6729
|
}
|
|
6738
|
-
const [nAttrs, wrappers] =
|
|
6730
|
+
const [nAttrs, wrappers] = new AttrParser(px).parse(attrs, true);
|
|
6739
6731
|
px.onAttributes(nAttrs, wrappers, null, true, tag);
|
|
6740
6732
|
return wrap(px.newMacroNode(macroName, nAttrs.toMacroVars(), childs), px, wrappers);
|
|
6741
6733
|
} else if (VALID_NODE_RE.test(tag)) {
|
|
6742
|
-
const [nAttrs, wrappers, textChild] =
|
|
6734
|
+
const [nAttrs, wrappers, textChild] = new AttrParser(px).parse(attrs);
|
|
6743
6735
|
px.onAttributes(nAttrs, wrappers, textChild, false, tag);
|
|
6744
6736
|
if (textChild) childs.unshift(new RenderTextNode(null, textChild));
|
|
6745
6737
|
const domChilds = tag !== "PRE" ? condenseChildsWhites(childs) : childs;
|
|
@@ -6901,39 +6893,32 @@ var RenderViewId = class extends ANode {
|
|
|
6901
6893
|
evalViewName(stack) {
|
|
6902
6894
|
return this.viewVal ? this.viewVal.eval(stack) : null;
|
|
6903
6895
|
}
|
|
6904
|
-
// A `<x render*>` produces no DOM element of its own to carry `data-cid`;
|
|
6905
|
-
// when it is a view's root the component boundary is recorded in the `Comp`
|
|
6906
|
-
// meta comment instead (see Renderer._rValComp), so this is a no-op.
|
|
6907
|
-
setDataAttr(_key, _val) {
|
|
6908
|
-
}
|
|
6909
6896
|
};
|
|
6910
|
-
function dynRenderStep(comp, name, key) {
|
|
6911
|
-
const p = resolveDynProducer(comp, name);
|
|
6912
|
-
if (!p) return null;
|
|
6913
|
-
return key === void 0 ? new DynStep(p.producerCompId, p.producerSteps) : new DynEachStep(p.producerCompId, p.producerSteps, key);
|
|
6914
|
-
}
|
|
6915
6897
|
var RenderNode = class extends RenderViewId {
|
|
6916
6898
|
render(stack, rx) {
|
|
6917
|
-
const
|
|
6918
|
-
|
|
6899
|
+
const [value, renderPath, base] = renderTarget(this.val, stack);
|
|
6900
|
+
const newStack = stack.enter(value, {}, true, renderPath, false);
|
|
6901
|
+
return rx.renderIt(newStack, this, this.evalViewName(stack), base);
|
|
6919
6902
|
}
|
|
6903
|
+
// A `*name` target contributes no step: the site recorded the absolute base it
|
|
6904
|
+
// resumed at, and event reconstruction turns that into a continuation frame.
|
|
6920
6905
|
toPathStep(ctx) {
|
|
6921
|
-
if (this.val instanceof DynVal) return
|
|
6906
|
+
if (this.val instanceof DynVal) return null;
|
|
6922
6907
|
return super.toPathStep(ctx);
|
|
6923
6908
|
}
|
|
6924
6909
|
};
|
|
6925
6910
|
var RenderItNode = class extends RenderViewId {
|
|
6926
6911
|
render(stack, rx) {
|
|
6927
|
-
const
|
|
6928
|
-
|
|
6912
|
+
const base = stack.pendingFrame ? stack.renderPath.toTransactionPath() : null;
|
|
6913
|
+
const newStack = stack.enter(stack.it, {}, true, stack.renderPath, false);
|
|
6914
|
+
return rx.renderIt(newStack, this, this.evalViewName(stack), base);
|
|
6929
6915
|
}
|
|
6930
6916
|
toPathStep(ctx) {
|
|
6931
6917
|
const next = ctx.next();
|
|
6932
6918
|
if (next === null) return null;
|
|
6933
6919
|
const nextNode = next.resolveNode();
|
|
6934
6920
|
if (nextNode instanceof EachNode && next.hasKey) {
|
|
6935
|
-
if (nextNode.val instanceof DynVal)
|
|
6936
|
-
return dynRenderStep(ctx.comp, nextNode.val.name, next.key);
|
|
6921
|
+
if (nextNode.val instanceof DynVal) return null;
|
|
6937
6922
|
return new EachRenderItStep(nextNode.val.name, next.key);
|
|
6938
6923
|
}
|
|
6939
6924
|
return null;
|
|
@@ -6955,9 +6940,6 @@ var RenderTextNode = class extends ANode {
|
|
|
6955
6940
|
render(stack, _rx) {
|
|
6956
6941
|
return this.val.eval(stack);
|
|
6957
6942
|
}
|
|
6958
|
-
// Renders to a text node, which can't carry `data-cid`.
|
|
6959
|
-
setDataAttr(_key, _val) {
|
|
6960
|
-
}
|
|
6961
6943
|
};
|
|
6962
6944
|
var RenderOnceNode = class extends BaseNode {
|
|
6963
6945
|
constructor(node) {
|
|
@@ -7032,36 +7014,46 @@ var ScopeNode = class extends WrapperNode {
|
|
|
7032
7014
|
var EachNode = class extends WrapperNode {
|
|
7033
7015
|
constructor(nodeId, val) {
|
|
7034
7016
|
super(nodeId, val);
|
|
7035
|
-
this.iterInfo = new IterInfo(
|
|
7017
|
+
this.iterInfo = new IterInfo();
|
|
7036
7018
|
}
|
|
7037
7019
|
render(stack, rx) {
|
|
7038
|
-
return rx.renderEachWhen(stack, this
|
|
7020
|
+
return rx.renderEachWhen(stack, this);
|
|
7039
7021
|
}
|
|
7040
|
-
|
|
7041
|
-
|
|
7042
|
-
|
|
7043
|
-
|
|
7044
|
-
|
|
7045
|
-
|
|
7046
|
-
|
|
7047
|
-
|
|
7048
|
-
|
|
7049
|
-
this.loopWithVal = loopWithVal;
|
|
7050
|
-
this.enrichWithVal = enrichWithVal;
|
|
7051
|
-
}
|
|
7052
|
-
eval(stack) {
|
|
7053
|
-
const seq = this.val.eval(stack) ?? [];
|
|
7054
|
-
const filter = this.whenVal?.evalAsHandler(stack) ?? filterAlwaysTrue;
|
|
7055
|
-
const loopWith = this.loopWithVal?.evalAsHandler(stack) ?? nullLoopWith;
|
|
7056
|
-
const enricher = this.enrichWithVal?.evalAsHandler(stack) ?? null;
|
|
7057
|
-
return { seq, filter, loopWith, enricher };
|
|
7022
|
+
// The sequence and the three loop handlers, resolved against `stack`.
|
|
7023
|
+
evalIter(stack) {
|
|
7024
|
+
const { whenVal, loopWithVal, enrichWithVal } = this.iterInfo;
|
|
7025
|
+
return {
|
|
7026
|
+
seq: this.val.eval(stack) ?? [],
|
|
7027
|
+
filter: whenVal?.evalAsHandler(stack) ?? filterAlwaysTrue,
|
|
7028
|
+
loopWith: loopWithVal?.evalAsHandler(stack) ?? nullLoopWith,
|
|
7029
|
+
enricher: enrichWithVal?.evalAsHandler(stack) ?? null
|
|
7030
|
+
};
|
|
7058
7031
|
}
|
|
7059
7032
|
// Rebuild the per-item binds for `key` (see iteration.js bindsForKey).
|
|
7060
7033
|
enrichBinds(stack, key) {
|
|
7061
|
-
const { seq, filter, loopWith, enricher } = this.
|
|
7034
|
+
const { seq, filter, loopWith, enricher } = this.evalIter(stack);
|
|
7062
7035
|
const ctx = makeLoopCtx(stack, filter);
|
|
7063
7036
|
return bindsForKey({ seq, it: stack.it, loopWith, enricher, ctx }, key);
|
|
7064
7037
|
}
|
|
7038
|
+
toPathStep(ctx) {
|
|
7039
|
+
return ctx.hasKey ? new EachBindStep(this, ctx.key) : null;
|
|
7040
|
+
}
|
|
7041
|
+
// Where one item lives, for the render path. `@each` re-binds `it` to the item
|
|
7042
|
+
// whether or not the body is a component, so the position moves either way and
|
|
7043
|
+
// the step has to address it — `.rows` iterated at `key` IS `rows[key]`.
|
|
7044
|
+
// Null for a dynamic sequence: `*rows` carries its own absolute path and enters
|
|
7045
|
+
// a continuation frame instead (see Renderer.renderEachWhen).
|
|
7046
|
+
itemStep(key) {
|
|
7047
|
+
return this.val instanceof FieldVal ? new SeqStep(this.val.name, key) : null;
|
|
7048
|
+
}
|
|
7049
|
+
static register = true;
|
|
7050
|
+
};
|
|
7051
|
+
var IterInfo = class {
|
|
7052
|
+
constructor() {
|
|
7053
|
+
this.whenVal = null;
|
|
7054
|
+
this.loopWithVal = null;
|
|
7055
|
+
this.enrichWithVal = null;
|
|
7056
|
+
}
|
|
7065
7057
|
};
|
|
7066
7058
|
function xOp(consumed = [], { wrappable = false, wrapper = null, ignoresChildren = false } = {}) {
|
|
7067
7059
|
return { consumed: new Set(consumed), wrappable, wrapper, ignoresChildren };
|
|
@@ -7088,26 +7080,31 @@ var WRAPPER_NODES = {
|
|
|
7088
7080
|
scope: ScopeNode,
|
|
7089
7081
|
"push-view": PushViewNameNode
|
|
7090
7082
|
};
|
|
7091
|
-
var ParseContext = class
|
|
7092
|
-
constructor(document2
|
|
7093
|
-
this.
|
|
7094
|
-
this.
|
|
7095
|
-
this.
|
|
7096
|
-
this.
|
|
7097
|
-
this.
|
|
7098
|
-
this.
|
|
7099
|
-
this.Text = Text ?? globalThis.Text;
|
|
7100
|
-
this.Comment = Comment ?? globalThis.Comment;
|
|
7101
|
-
this.cacheConstNodes = true;
|
|
7083
|
+
var ParseContext = class {
|
|
7084
|
+
constructor(document2 = globalThis.document) {
|
|
7085
|
+
this.document = document2;
|
|
7086
|
+
this.nodes = [];
|
|
7087
|
+
this.events = [];
|
|
7088
|
+
this.macroNodes = [];
|
|
7089
|
+
this.parent = null;
|
|
7090
|
+
this.frame = {};
|
|
7102
7091
|
this.currentTag = null;
|
|
7103
7092
|
}
|
|
7104
7093
|
isInsideMacro(name) {
|
|
7105
7094
|
return this.frame.macroName === name || this.parent?.isInsideMacro(name);
|
|
7106
7095
|
}
|
|
7096
|
+
// A macro body parses in a child context that shares every accumulator with
|
|
7097
|
+
// its parent (nodes, events, macroNodes, and whatever a subclass collects) and
|
|
7098
|
+
// differs only in its frame. Cloned rather than constructed so a subclass
|
|
7099
|
+
// keeps collecting inside macro bodies without re-implementing this — the
|
|
7100
|
+
// lint and class-set contexts used to lose (or had to copy) exactly that.
|
|
7107
7101
|
enterMacro(macroName, macroVars, macroSlots) {
|
|
7108
|
-
const
|
|
7109
|
-
|
|
7110
|
-
|
|
7102
|
+
const child = Object.create(Object.getPrototypeOf(this));
|
|
7103
|
+
return Object.assign(child, this, {
|
|
7104
|
+
frame: { macroName, macroVars, macroSlots },
|
|
7105
|
+
parent: this,
|
|
7106
|
+
currentTag: null
|
|
7107
|
+
});
|
|
7111
7108
|
}
|
|
7112
7109
|
parseHTML(html2) {
|
|
7113
7110
|
const t = this.document.createElement("template");
|
|
@@ -7172,10 +7169,10 @@ var isBlockDomNode = (n) => {
|
|
|
7172
7169
|
return node instanceof DomNode && HTML_BLOCK_TAGS.has(node.tagName);
|
|
7173
7170
|
};
|
|
7174
7171
|
var isEmptyText = (c) => c instanceof TextNode && c.val === "";
|
|
7175
|
-
var isIgnorableXChild = (c) => c instanceof CommentNode ||
|
|
7172
|
+
var isIgnorableXChild = (c) => c instanceof CommentNode || c.isWhiteSpace();
|
|
7176
7173
|
var hasMeaningfulChilds = (childs) => childs.some((c) => !isIgnorableXChild(c));
|
|
7177
7174
|
function trimEdgeWhite(node) {
|
|
7178
|
-
if (!node.isWhiteSpace
|
|
7175
|
+
if (!node.isWhiteSpace()) return false;
|
|
7179
7176
|
node.condenseWhiteSpace();
|
|
7180
7177
|
return true;
|
|
7181
7178
|
}
|
|
@@ -7186,7 +7183,7 @@ function condenseChildsWhites(childs) {
|
|
|
7186
7183
|
if (last > 0 && trimEdgeWhite(childs[last])) emptied = true;
|
|
7187
7184
|
for (let i = 1; i < last; i++) {
|
|
7188
7185
|
const cur = childs[i];
|
|
7189
|
-
if (!(cur.isWhiteSpace
|
|
7186
|
+
if (!(cur.isWhiteSpace() && cur.hasNewLine())) continue;
|
|
7190
7187
|
const bothBlock = isBlockDomNode(childs[i - 1]) && isBlockDomNode(childs[i + 1]);
|
|
7191
7188
|
cur.condenseWhiteSpace(bothBlock ? "" : " ");
|
|
7192
7189
|
if (bothBlock) emptied = true;
|
|
@@ -7194,12 +7191,12 @@ function condenseChildsWhites(childs) {
|
|
|
7194
7191
|
return emptied ? childs.filter((c) => !isEmptyText(c)) : childs;
|
|
7195
7192
|
}
|
|
7196
7193
|
var View = class {
|
|
7197
|
-
constructor(name, rawView = "No View Defined", style = ""
|
|
7194
|
+
constructor(name, rawView = "No View Defined", style = "") {
|
|
7198
7195
|
this.name = name;
|
|
7199
|
-
this.anode = anode;
|
|
7200
|
-
this.style = style;
|
|
7201
|
-
this.ctx = ctx;
|
|
7202
7196
|
this.rawView = rawView;
|
|
7197
|
+
this.style = style;
|
|
7198
|
+
this.anode = null;
|
|
7199
|
+
this.ctx = null;
|
|
7203
7200
|
}
|
|
7204
7201
|
compile(ctx, scope, cid) {
|
|
7205
7202
|
this.ctx = ctx;
|
|
@@ -7207,7 +7204,7 @@ var View = class {
|
|
|
7207
7204
|
this.anode.setDataAttr("data-cid", cid);
|
|
7208
7205
|
this.anode.setDataAttr("data-vid", this.name);
|
|
7209
7206
|
this.ctx.compile(scope);
|
|
7210
|
-
|
|
7207
|
+
this.anode = optimizeNode(this.anode);
|
|
7211
7208
|
}
|
|
7212
7209
|
render(stack, rx) {
|
|
7213
7210
|
if (this.anode === null) {
|
|
@@ -7232,7 +7229,7 @@ var NodeEvents = class {
|
|
|
7232
7229
|
getHandlersFor(eventName) {
|
|
7233
7230
|
let r = null;
|
|
7234
7231
|
for (const handler of this.handlers)
|
|
7235
|
-
if (handler.
|
|
7232
|
+
if (handler.name === eventName) {
|
|
7236
7233
|
r ??= [];
|
|
7237
7234
|
r.push(handler);
|
|
7238
7235
|
}
|
|
@@ -7246,9 +7243,6 @@ var NodeEvent = class {
|
|
|
7246
7243
|
this.modifierWrapper = compileModifiers(name, modifiers);
|
|
7247
7244
|
this.modifiers = modifiers;
|
|
7248
7245
|
}
|
|
7249
|
-
handlesEventName(name) {
|
|
7250
|
-
return this.name === name;
|
|
7251
|
-
}
|
|
7252
7246
|
getHandlerAndArgs(stack, event) {
|
|
7253
7247
|
const r = this.handlerCall.getHandlerAndArgs(stack, event);
|
|
7254
7248
|
r[0] = this.modifierWrapper(r[0], event);
|
|
@@ -7300,92 +7294,209 @@ function compileModifiers(eventName, names) {
|
|
|
7300
7294
|
};
|
|
7301
7295
|
}
|
|
7302
7296
|
|
|
7303
|
-
// src/
|
|
7304
|
-
var
|
|
7305
|
-
|
|
7306
|
-
|
|
7307
|
-
|
|
7308
|
-
|
|
7309
|
-
|
|
7310
|
-
|
|
7311
|
-
|
|
7312
|
-
|
|
7297
|
+
// src/stack.js
|
|
7298
|
+
var STOP = /* @__PURE__ */ Symbol("STOP");
|
|
7299
|
+
var NEXT = /* @__PURE__ */ Symbol("NEXT");
|
|
7300
|
+
var DEFAULT_ROUTE = ["dyn", "lex"];
|
|
7301
|
+
var isTypeName = (s) => {
|
|
7302
|
+
const c = s.charCodeAt(0);
|
|
7303
|
+
return c >= 65 && c <= 90;
|
|
7304
|
+
};
|
|
7305
|
+
function lookup(chain, name, dv = null) {
|
|
7306
|
+
let n = chain;
|
|
7307
|
+
while (n !== null) {
|
|
7308
|
+
const r = n[0].lookup(name);
|
|
7309
|
+
if (r === STOP) return dv;
|
|
7310
|
+
if (r !== NEXT) return r;
|
|
7311
|
+
n = n[1];
|
|
7313
7312
|
}
|
|
7314
|
-
|
|
7315
|
-
|
|
7316
|
-
|
|
7317
|
-
|
|
7318
|
-
|
|
7319
|
-
|
|
7320
|
-
|
|
7321
|
-
nodes,
|
|
7322
|
-
events2,
|
|
7323
|
-
macroNodes,
|
|
7324
|
-
frame,
|
|
7325
|
-
this
|
|
7326
|
-
);
|
|
7327
|
-
v.classes = this.classes;
|
|
7328
|
-
return v;
|
|
7313
|
+
return dv;
|
|
7314
|
+
}
|
|
7315
|
+
var BindFrame = class {
|
|
7316
|
+
constructor(it, binds, isFrame) {
|
|
7317
|
+
this.it = it;
|
|
7318
|
+
this.binds = binds;
|
|
7319
|
+
this.isFrame = isFrame;
|
|
7329
7320
|
}
|
|
7330
|
-
|
|
7331
|
-
|
|
7332
|
-
|
|
7333
|
-
if (attr.name !== "class") {
|
|
7334
|
-
continue;
|
|
7335
|
-
}
|
|
7336
|
-
const { val, thenVal, elseVal } = attr;
|
|
7337
|
-
if (thenVal !== void 0) {
|
|
7338
|
-
this._maybeAddVal(thenVal);
|
|
7339
|
-
this._maybeAddVal(elseVal);
|
|
7340
|
-
} else {
|
|
7341
|
-
this._maybeAddVal(val);
|
|
7342
|
-
}
|
|
7343
|
-
}
|
|
7344
|
-
} else {
|
|
7345
|
-
const attr = attrs.items.class;
|
|
7346
|
-
if (attr) {
|
|
7347
|
-
this._addClasses(attr);
|
|
7348
|
-
}
|
|
7349
|
-
}
|
|
7321
|
+
lookup(name) {
|
|
7322
|
+
const v = this.binds[name];
|
|
7323
|
+
return v === void 0 ? this.isFrame ? STOP : NEXT : v;
|
|
7350
7324
|
}
|
|
7351
|
-
|
|
7352
|
-
|
|
7353
|
-
|
|
7354
|
-
|
|
7325
|
+
};
|
|
7326
|
+
var DynFrame = class {
|
|
7327
|
+
constructor(binds, types) {
|
|
7328
|
+
this.binds = binds;
|
|
7329
|
+
this.types = types;
|
|
7355
7330
|
}
|
|
7356
|
-
|
|
7357
|
-
|
|
7358
|
-
|
|
7359
|
-
if (val instanceof ConstVal && val.val !== "") {
|
|
7360
|
-
this._addClasses(val.val);
|
|
7361
|
-
}
|
|
7362
|
-
}
|
|
7363
|
-
return true;
|
|
7364
|
-
}
|
|
7365
|
-
return false;
|
|
7331
|
+
lookup(name) {
|
|
7332
|
+
const v = (isTypeName(name) ? this.types : this.binds)[name];
|
|
7333
|
+
return v === void 0 ? NEXT : v;
|
|
7366
7334
|
}
|
|
7367
7335
|
};
|
|
7368
|
-
function
|
|
7369
|
-
|
|
7370
|
-
|
|
7371
|
-
|
|
7372
|
-
|
|
7373
|
-
|
|
7374
|
-
classes.add(name);
|
|
7375
|
-
}
|
|
7376
|
-
}
|
|
7336
|
+
function computeViewsId(views) {
|
|
7337
|
+
let s = "";
|
|
7338
|
+
let n = views;
|
|
7339
|
+
while (n !== null) {
|
|
7340
|
+
s += n[0];
|
|
7341
|
+
n = n[1];
|
|
7377
7342
|
}
|
|
7378
|
-
return
|
|
7343
|
+
return s === "main" ? "" : s;
|
|
7379
7344
|
}
|
|
7380
|
-
|
|
7381
|
-
|
|
7382
|
-
|
|
7383
|
-
|
|
7345
|
+
var Stack = class _Stack {
|
|
7346
|
+
constructor(fields) {
|
|
7347
|
+
Object.assign(this, fields);
|
|
7348
|
+
}
|
|
7349
|
+
_with(patch) {
|
|
7350
|
+
return new _Stack({ ...this, ...patch });
|
|
7351
|
+
}
|
|
7352
|
+
// Evaluate every provide the entered component publishes and push them as one
|
|
7353
|
+
// dynBinds frame, keyed by NAME. A value is published together with the absolute
|
|
7354
|
+
// path it lives at: the same declaration is read as `*name` AND resumed at by
|
|
7355
|
+
// `<x render="*name">`, so a consumer needs both halves. Types go in the same
|
|
7356
|
+
// frame's other map. No-op with no provides.
|
|
7357
|
+
_pushProvides() {
|
|
7358
|
+
const comp = this.comps.getCompFor(this.it);
|
|
7359
|
+
if (comp == null) return this;
|
|
7360
|
+
const { provide, provideType } = comp;
|
|
7361
|
+
const binds = {};
|
|
7362
|
+
const types = {};
|
|
7363
|
+
let has2 = false;
|
|
7364
|
+
const base = this._publishBase();
|
|
7365
|
+
for (const k in provide) {
|
|
7366
|
+
const step = provide[k].toPathItem?.() ?? null;
|
|
7367
|
+
if (step === null) continue;
|
|
7368
|
+
const value = provide[k].eval(this);
|
|
7369
|
+
binds[k] = { value, path: base === null ? null : base.concat([step]) };
|
|
7370
|
+
has2 = true;
|
|
7371
|
+
}
|
|
7372
|
+
for (const k in provideType) {
|
|
7373
|
+
types[k] = provideType[k];
|
|
7374
|
+
has2 = true;
|
|
7375
|
+
}
|
|
7376
|
+
if (!has2) return this;
|
|
7377
|
+
return this._with({ dynBinds: [new DynFrame(binds, types), this.dynBinds] });
|
|
7378
|
+
}
|
|
7379
|
+
// The absolute address of the component being entered, or null when this
|
|
7380
|
+
// position cannot be written down as one. Frame-only steps carry bindings and
|
|
7381
|
+
// address nothing, so they are compacted away first; what is left is checked
|
|
7382
|
+
// against the value actually being rendered, because a scope CAN move the
|
|
7383
|
+
// render position without contributing an addressing step (a plain `@each`
|
|
7384
|
+
// body re-binds `it` to the item while its rebuild step is an identity).
|
|
7385
|
+
//
|
|
7386
|
+
// A null base still publishes the VALUE — `*name` reads it fine — but there is
|
|
7387
|
+
// nowhere to resume, so `<x render="*name">` renders nothing rather than
|
|
7388
|
+
// editing whatever happens to live at the address we guessed.
|
|
7389
|
+
_publishBase() {
|
|
7390
|
+
const base = this.renderPath.toTransactionPath().compact();
|
|
7391
|
+
return base.lookup(this.root, NOT_FOUND) === this.it ? base : null;
|
|
7392
|
+
}
|
|
7393
|
+
static root(comps, it, ctx = null) {
|
|
7394
|
+
return new _Stack({
|
|
7395
|
+
comps,
|
|
7396
|
+
root: it,
|
|
7397
|
+
it,
|
|
7398
|
+
binds: [new BindFrame(it, {}, true), null],
|
|
7399
|
+
dynBinds: [new DynFrame({}, {}), null],
|
|
7400
|
+
views: ["main", null],
|
|
7401
|
+
viewsId: "",
|
|
7402
|
+
renderPath: new DispatchPath(),
|
|
7403
|
+
pendingFrame: false,
|
|
7404
|
+
ctx
|
|
7405
|
+
})._pushProvides();
|
|
7406
|
+
}
|
|
7407
|
+
// `renderPath` defaults to this stack's own: an ordinary scope does not move.
|
|
7408
|
+
// `pendingFrame` clears on a component frame (which emits the base) and is
|
|
7409
|
+
// inherited by transparent scopes, which have to carry it to the next boundary.
|
|
7410
|
+
enter(it, bindings = {}, isFrame = true, renderPath = this.renderPath, pendingFrame = null) {
|
|
7411
|
+
const stack = this._with({
|
|
7412
|
+
it,
|
|
7413
|
+
binds: [new BindFrame(it, bindings, isFrame), this.binds],
|
|
7414
|
+
renderPath,
|
|
7415
|
+
pendingFrame: pendingFrame ?? (isFrame ? false : this.pendingFrame)
|
|
7416
|
+
});
|
|
7417
|
+
return isFrame ? stack._pushProvides() : stack;
|
|
7418
|
+
}
|
|
7419
|
+
pushViewName(name) {
|
|
7420
|
+
const views = [name, this.views];
|
|
7421
|
+
return this._with({ views, viewsId: computeViewsId(views) });
|
|
7422
|
+
}
|
|
7423
|
+
// Published types are stable per scope and would only churn the render cache, so
|
|
7424
|
+
// the cache key covers values alone.
|
|
7425
|
+
_pushDynBindValuesToArray(arr, comp) {
|
|
7426
|
+
for (const k in comp.provide) arr.push(this.lookupDynamic(k));
|
|
7427
|
+
for (const k in comp.lookup) arr.push(this.lookupDynamic(k));
|
|
7428
|
+
}
|
|
7429
|
+
// `*name`: the nearest binding above (including this component's own provides,
|
|
7430
|
+
// pushed on entering it), else a path registered in the component's lexical
|
|
7431
|
+
// scope, else this component's declared default, else null.
|
|
7432
|
+
//
|
|
7433
|
+
// One chain walk and no producer resolution: a lookup names what it WANTS, so the
|
|
7434
|
+
// frame it wants is keyed by that name. The default belongs to the CONSUMER's
|
|
7435
|
+
// declaration and is evaluated against the consumer's stack, which is why it is
|
|
7436
|
+
// consulted only after the whole chain has missed.
|
|
7437
|
+
lookupDynamicLocated(name) {
|
|
7438
|
+
if (isTypeName(name)) return null;
|
|
7439
|
+
const v = lookup(this.dynBinds, name);
|
|
7440
|
+
if (v != null) return v;
|
|
7441
|
+
const comp = this.comps.getCompFor(this.it);
|
|
7442
|
+
if (comp == null) return null;
|
|
7443
|
+
const path2 = comp.scope?.lookupPath?.(name) ?? null;
|
|
7444
|
+
if (path2 !== null) {
|
|
7445
|
+
const value2 = path2.lookup(this.root, NOT_FOUND);
|
|
7446
|
+
if (value2 !== NOT_FOUND) return { value: value2, path: path2 };
|
|
7447
|
+
}
|
|
7448
|
+
const dval = comp.lookup[name] ?? null;
|
|
7449
|
+
if (dval === null) return null;
|
|
7450
|
+
const step = dval.toPathItem?.() ?? null;
|
|
7451
|
+
const value = dval.eval(this);
|
|
7452
|
+
return step === null ? { value, path: null } : { value, path: this.renderPath.toTransactionPath().concat([step]) };
|
|
7453
|
+
}
|
|
7454
|
+
lookupDynamic(name) {
|
|
7455
|
+
if (isTypeName(name)) return lookup(this.dynBinds, name);
|
|
7456
|
+
return this.lookupDynamicLocated(name)?.value ?? null;
|
|
7457
|
+
}
|
|
7458
|
+
lookupBind(name) {
|
|
7459
|
+
return lookup(this.binds, name);
|
|
7460
|
+
}
|
|
7461
|
+
lookupFieldRaw(name) {
|
|
7462
|
+
return this.it[name] ?? null;
|
|
7463
|
+
}
|
|
7464
|
+
lookupMethod(name) {
|
|
7465
|
+
const fn = this.it[name];
|
|
7466
|
+
return fn instanceof Function ? fn.call(this.it) : null;
|
|
7467
|
+
}
|
|
7468
|
+
// The dispatched DOM event / drag info, read only by EventMemberVal's
|
|
7469
|
+
// `e.<member>` handler args. Null outside a live event transaction (`ctx` is
|
|
7470
|
+
// then a send/intent transaction, which carries no `e`).
|
|
7471
|
+
lookupEvent() {
|
|
7472
|
+
return this.ctx?.e ?? null;
|
|
7473
|
+
}
|
|
7474
|
+
lookupDragInfo() {
|
|
7475
|
+
return this.ctx?.dragInfo ?? null;
|
|
7476
|
+
}
|
|
7477
|
+
getHandlerFor(name, key) {
|
|
7478
|
+
return this.comps.getHandlerFor(this.it, name, key);
|
|
7479
|
+
}
|
|
7480
|
+
lookupBestView(views, defaultViewName) {
|
|
7481
|
+
let n = this.views;
|
|
7482
|
+
while (n !== null) {
|
|
7483
|
+
const view = views[n[0]];
|
|
7484
|
+
if (view !== void 0) return view;
|
|
7485
|
+
n = n[1];
|
|
7486
|
+
}
|
|
7487
|
+
return views[defaultViewName];
|
|
7488
|
+
}
|
|
7489
|
+
};
|
|
7490
|
+
var NOT_FOUND = /* @__PURE__ */ Symbol("NOT_FOUND");
|
|
7491
|
+
|
|
7492
|
+
// src/components.js
|
|
7493
|
+
var COMPONENT = /* @__PURE__ */ Symbol.for("tutuca.component");
|
|
7494
|
+
var Components = class {
|
|
7384
7495
|
constructor() {
|
|
7385
7496
|
this.byId = /* @__PURE__ */ new Map();
|
|
7386
7497
|
}
|
|
7387
7498
|
registerComponent(Comp) {
|
|
7388
|
-
this.byId.set(Comp
|
|
7499
|
+
this.byId.set(Comp.id, Comp);
|
|
7389
7500
|
}
|
|
7390
7501
|
getComponentForId(id) {
|
|
7391
7502
|
return this.byId.get(id) ?? null;
|
|
@@ -7405,7 +7516,7 @@ var Components = class {
|
|
|
7405
7516
|
}
|
|
7406
7517
|
compileStyles() {
|
|
7407
7518
|
const styles2 = [];
|
|
7408
|
-
for (const Comp of this.byId.values()) styles2.push(Comp
|
|
7519
|
+
for (const Comp of this.byId.values()) styles2.push(Comp.compileStyle());
|
|
7409
7520
|
return styles2.join("\n");
|
|
7410
7521
|
}
|
|
7411
7522
|
};
|
|
@@ -7416,15 +7527,17 @@ var ComponentStack = class _ComponentStack {
|
|
|
7416
7527
|
this.byName = {};
|
|
7417
7528
|
this.intentsByName = {};
|
|
7418
7529
|
this.macros = {};
|
|
7530
|
+
this.paths = {};
|
|
7419
7531
|
}
|
|
7420
7532
|
enter() {
|
|
7421
7533
|
return new _ComponentStack(this.comps, this);
|
|
7422
7534
|
}
|
|
7423
7535
|
registerComponents(comps, opts) {
|
|
7424
|
-
const { aliases: aliases2 = {} } = opts ?? {};
|
|
7536
|
+
const { aliases: aliases2 = {}, paths } = opts ?? {};
|
|
7537
|
+
if (paths) this.registerPaths(paths);
|
|
7425
7538
|
for (let i = 0; i < comps.length; i++) {
|
|
7426
7539
|
const Comp = comps[i];
|
|
7427
|
-
Comp
|
|
7540
|
+
Comp.scope = this.enter();
|
|
7428
7541
|
this.comps.registerComponent(Comp);
|
|
7429
7542
|
this.byName[Comp.name] = Comp;
|
|
7430
7543
|
}
|
|
@@ -7435,6 +7548,27 @@ var ComponentStack = class _ComponentStack {
|
|
|
7435
7548
|
else console.warn("alias", alias, "to inexistent component", aliases2[alias]);
|
|
7436
7549
|
}
|
|
7437
7550
|
}
|
|
7551
|
+
// Register lowercase names as absolute paths from the app state root. A
|
|
7552
|
+
// descendant that declares one in its `lookup` reads and renders `*name` without
|
|
7553
|
+
// anything above it publishing one — which is what makes a session, a theme or a
|
|
7554
|
+
// host-owned value available in its natural registration scope, instead of forcing
|
|
7555
|
+
// an application root whose only job is to `provide` it. Register on a nested
|
|
7556
|
+
// scope to narrow a name; nearest registration wins.
|
|
7557
|
+
//
|
|
7558
|
+
// Uppercase names are ignored: a component TYPE is what `lookupComponent` already
|
|
7559
|
+
// answers, and a type has no path.
|
|
7560
|
+
registerPaths(paths) {
|
|
7561
|
+
for (const name in paths) {
|
|
7562
|
+
if (isTypeName(name)) {
|
|
7563
|
+
console.warn("registerPaths: a type name has no path", name);
|
|
7564
|
+
continue;
|
|
7565
|
+
}
|
|
7566
|
+
this.paths[name] = paths[name].toPath();
|
|
7567
|
+
}
|
|
7568
|
+
}
|
|
7569
|
+
lookupPath(name) {
|
|
7570
|
+
return this.paths[name] ?? this.parent?.lookupPath(name) ?? null;
|
|
7571
|
+
}
|
|
7438
7572
|
registerMacros(macros) {
|
|
7439
7573
|
for (const key in macros) {
|
|
7440
7574
|
const lower = key.toLowerCase();
|
|
@@ -7466,97 +7600,82 @@ var ComponentStack = class _ComponentStack {
|
|
|
7466
7600
|
lookupComponent(name) {
|
|
7467
7601
|
return this.byName[name] ?? this.parent?.lookupComponent(name) ?? null;
|
|
7468
7602
|
}
|
|
7469
|
-
//
|
|
7470
|
-
// names
|
|
7471
|
-
//
|
|
7472
|
-
//
|
|
7473
|
-
//
|
|
7474
|
-
|
|
7603
|
+
// Whether anything in this scope chain provides `name`. Existence only: a lookup
|
|
7604
|
+
// names what it WANTS and takes whoever is nearest above it at render time, so
|
|
7605
|
+
// there is no producer to identify — several components may publish one name and
|
|
7606
|
+
// the live render ancestry decides. Used by the linter to tell a lookup that can
|
|
7607
|
+
// be satisfied from one that never will be.
|
|
7608
|
+
hasProvider(name) {
|
|
7475
7609
|
for (const compName in this.byName) {
|
|
7476
|
-
|
|
7477
|
-
if (Comp.provide?.[name] !== void 0) return Comp;
|
|
7610
|
+
if (this.byName[compName].provide?.[name] !== void 0) return true;
|
|
7478
7611
|
}
|
|
7479
|
-
return this.parent?.
|
|
7612
|
+
return this.parent?.hasProvider(name) ?? false;
|
|
7480
7613
|
}
|
|
7481
7614
|
lookupMacro(name) {
|
|
7482
7615
|
return this.macros[name] ?? this.parent?.lookupMacro(name) ?? null;
|
|
7483
7616
|
}
|
|
7484
7617
|
};
|
|
7485
|
-
var ProvideInfo = class {
|
|
7486
|
-
constructor(val) {
|
|
7487
|
-
this.val = val;
|
|
7488
|
-
}
|
|
7489
|
-
};
|
|
7490
|
-
var LookupInfo = class {
|
|
7491
|
-
constructor(val) {
|
|
7492
|
-
this.val = val;
|
|
7493
|
-
}
|
|
7494
|
-
};
|
|
7495
7618
|
var isString = (v) => typeof v === "string";
|
|
7496
|
-
var isTypeName = (s) => {
|
|
7497
|
-
const c = s.charCodeAt(0);
|
|
7498
|
-
return c >= 65 && c <= 90;
|
|
7499
|
-
};
|
|
7500
7619
|
var _rawSpecKeys = "name view style commonStyle globalStyle receive intent alter views provide lookup fields methods statics";
|
|
7501
7620
|
var KNOWN_SPEC_KEYS = new Set(_rawSpecKeys.split(" "));
|
|
7502
7621
|
var _compId = 0;
|
|
7503
|
-
|
|
7504
|
-
|
|
7505
|
-
|
|
7506
|
-
|
|
7507
|
-
|
|
7508
|
-
|
|
7509
|
-
|
|
7510
|
-
|
|
7511
|
-
|
|
7512
|
-
|
|
7513
|
-
|
|
7514
|
-
|
|
7515
|
-
|
|
7516
|
-
|
|
7517
|
-
|
|
7518
|
-
|
|
7519
|
-
|
|
7520
|
-
|
|
7521
|
-
|
|
7522
|
-
|
|
7523
|
-
|
|
7524
|
-
|
|
7525
|
-
|
|
7526
|
-
|
|
7527
|
-
|
|
7528
|
-
|
|
7622
|
+
function initComponent(Class, o) {
|
|
7623
|
+
Class[COMPONENT] = Class;
|
|
7624
|
+
Class.id = _compId++;
|
|
7625
|
+
Class.views = { main: new View("main", o.view, o.style) };
|
|
7626
|
+
Class.commonStyle = o.commonStyle ?? "";
|
|
7627
|
+
Class.globalStyle = o.globalStyle ?? "";
|
|
7628
|
+
Class.receive = o.receive ?? {};
|
|
7629
|
+
Class.intent = o.intent ?? {};
|
|
7630
|
+
Class.alter = o.alter ?? {};
|
|
7631
|
+
for (const name in o.views ?? {}) {
|
|
7632
|
+
const v = o.views[name];
|
|
7633
|
+
const { view, style } = isString(v) ? { view: v } : v;
|
|
7634
|
+
Class.views[name] = new View(name, view, style);
|
|
7635
|
+
}
|
|
7636
|
+
Class._rawProvide = o.provide ?? {};
|
|
7637
|
+
Class._rawLookup = o.lookup ?? [];
|
|
7638
|
+
Class.provide = {};
|
|
7639
|
+
Class.provideType = {};
|
|
7640
|
+
Class.lookup = {};
|
|
7641
|
+
Class.scope = null;
|
|
7642
|
+
Class.spec = o;
|
|
7643
|
+
Class.extra = {};
|
|
7644
|
+
for (const key of Object.keys(o)) if (!KNOWN_SPEC_KEYS.has(key)) Class.extra[key] = o[key];
|
|
7645
|
+
return Object.assign(Class, COMPONENT_METHODS);
|
|
7646
|
+
}
|
|
7647
|
+
var COMPONENT_METHODS = {
|
|
7529
7648
|
compile(ParseContext2) {
|
|
7530
7649
|
for (const name in this.views)
|
|
7531
7650
|
this.views[name].compile(new ParseContext2(), this.scope, this.id);
|
|
7532
7651
|
const ctx = this.views.main.ctx;
|
|
7533
7652
|
for (const key in this._rawProvide) {
|
|
7534
7653
|
if (isTypeName(key)) {
|
|
7535
|
-
if (this._rawProvide[key] === "self") this.provideType[key] = this
|
|
7654
|
+
if (this._rawProvide[key] === "self") this.provideType[key] = this;
|
|
7536
7655
|
continue;
|
|
7537
7656
|
}
|
|
7538
7657
|
const val = parseProvide(this._rawProvide[key], ctx);
|
|
7539
|
-
if (val) this.provide[key] =
|
|
7658
|
+
if (val) this.provide[key] = val;
|
|
7540
7659
|
}
|
|
7541
7660
|
for (const entry of this._rawLookup) {
|
|
7542
7661
|
const name = isString(entry) ? entry : isString(entry?.name) ? entry.name : null;
|
|
7543
7662
|
if (name === null) continue;
|
|
7544
7663
|
const defStr = isString(entry?.default) ? entry.default : null;
|
|
7545
|
-
this.lookup[name] =
|
|
7664
|
+
this.lookup[name] = defStr === null ? null : parseField(defStr, ctx);
|
|
7546
7665
|
}
|
|
7547
7666
|
for (const key in this.lookup)
|
|
7548
7667
|
if (this.provide[key] !== void 0)
|
|
7549
7668
|
console.warn("name declared in both provide and lookup", this.name, key);
|
|
7550
|
-
}
|
|
7669
|
+
},
|
|
7551
7670
|
getView(name) {
|
|
7552
7671
|
return this.views[name] ?? this.views.main;
|
|
7553
|
-
}
|
|
7554
|
-
getEventForId(id,
|
|
7555
|
-
return this.getView(
|
|
7556
|
-
}
|
|
7557
|
-
getNodeForId(id,
|
|
7558
|
-
return this.getView(
|
|
7559
|
-
}
|
|
7672
|
+
},
|
|
7673
|
+
getEventForId(id, viewName) {
|
|
7674
|
+
return this.getView(viewName).ctx.getEventForId(id);
|
|
7675
|
+
},
|
|
7676
|
+
getNodeForId(id, viewName) {
|
|
7677
|
+
return this.getView(viewName).ctx.getNodeForId(id);
|
|
7678
|
+
},
|
|
7560
7679
|
compileStyle() {
|
|
7561
7680
|
const { id, commonStyle, globalStyle, views } = this;
|
|
7562
7681
|
const styles2 = commonStyle ? [`[data-cid="${id}"]{${commonStyle}}`] : [];
|
|
@@ -7569,6 +7688,68 @@ var Component = class {
|
|
|
7569
7688
|
}
|
|
7570
7689
|
};
|
|
7571
7690
|
|
|
7691
|
+
// src/util/parsectx.js
|
|
7692
|
+
var ParseCtxClassSetCollector = class extends ParseContext {
|
|
7693
|
+
constructor(...args) {
|
|
7694
|
+
super(...args);
|
|
7695
|
+
this.classes = /* @__PURE__ */ new Set();
|
|
7696
|
+
}
|
|
7697
|
+
_addClasses(s) {
|
|
7698
|
+
for (const v of s.split(/\s+/)) {
|
|
7699
|
+
this.classes.add(v);
|
|
7700
|
+
}
|
|
7701
|
+
}
|
|
7702
|
+
onAttributes(attrs, _wrapperAttrs, _textChild, _isMacroCall, _tag) {
|
|
7703
|
+
if (Array.isArray(attrs.items)) {
|
|
7704
|
+
for (const attr of attrs.items) {
|
|
7705
|
+
if (attr.name !== "class") {
|
|
7706
|
+
continue;
|
|
7707
|
+
}
|
|
7708
|
+
const { val, thenVal, elseVal } = attr;
|
|
7709
|
+
if (thenVal !== void 0) {
|
|
7710
|
+
this._maybeAddVal(thenVal);
|
|
7711
|
+
this._maybeAddVal(elseVal);
|
|
7712
|
+
} else {
|
|
7713
|
+
this._maybeAddVal(val);
|
|
7714
|
+
}
|
|
7715
|
+
}
|
|
7716
|
+
} else {
|
|
7717
|
+
const attr = attrs.items.class;
|
|
7718
|
+
if (attr) {
|
|
7719
|
+
this._addClasses(attr);
|
|
7720
|
+
}
|
|
7721
|
+
}
|
|
7722
|
+
}
|
|
7723
|
+
_maybeAddVal(value) {
|
|
7724
|
+
if (!this._maybeAddStrTpl(value) && typeof value?.val === "string") {
|
|
7725
|
+
this._addClasses(value.val);
|
|
7726
|
+
}
|
|
7727
|
+
}
|
|
7728
|
+
_maybeAddStrTpl(value) {
|
|
7729
|
+
if (value?.vals !== void 0) {
|
|
7730
|
+
for (const val of value.vals) {
|
|
7731
|
+
if (val instanceof ConstVal && val.val !== "") {
|
|
7732
|
+
this._addClasses(val.val);
|
|
7733
|
+
}
|
|
7734
|
+
}
|
|
7735
|
+
return true;
|
|
7736
|
+
}
|
|
7737
|
+
return false;
|
|
7738
|
+
}
|
|
7739
|
+
};
|
|
7740
|
+
function collectAppClassesInSet(app) {
|
|
7741
|
+
const classes = /* @__PURE__ */ new Set();
|
|
7742
|
+
for (const Comp of app.comps.byId.values()) {
|
|
7743
|
+
for (const key in Comp.views) {
|
|
7744
|
+
const view = Comp.views[key];
|
|
7745
|
+
for (const name of view.ctx.classes) {
|
|
7746
|
+
classes.add(name);
|
|
7747
|
+
}
|
|
7748
|
+
}
|
|
7749
|
+
}
|
|
7750
|
+
return classes;
|
|
7751
|
+
}
|
|
7752
|
+
|
|
7572
7753
|
// tools/core/html-tokenizer.js
|
|
7573
7754
|
var CharCodes = {
|
|
7574
7755
|
Tab: 9,
|
|
@@ -9860,7 +10041,6 @@ var DYN_VAL_NOT_DEFINED = "DYN_VAL_NOT_DEFINED";
|
|
|
9860
10041
|
var DYN_ALIAS_NOT_REFERENCED = "DYN_ALIAS_NOT_REFERENCED";
|
|
9861
10042
|
var PROVIDE_NOT_ADDRESSABLE = "PROVIDE_NOT_ADDRESSABLE";
|
|
9862
10043
|
var PROVIDE_TYPE_BAD_SHAPE = "PROVIDE_TYPE_BAD_SHAPE";
|
|
9863
|
-
var PROVIDE_NAME_COLLISION = "PROVIDE_NAME_COLLISION";
|
|
9864
10044
|
var LOOKUP_BAD_SHAPE = "LOOKUP_BAD_SHAPE";
|
|
9865
10045
|
var LOOKUP_NO_PROVIDER = "LOOKUP_NO_PROVIDER";
|
|
9866
10046
|
var RENDER_IT_OUTSIDE_OF_LOOP = "RENDER_IT_OUTSIDE_OF_LOOP";
|
|
@@ -9877,6 +10057,7 @@ var IF_NO_BRANCH_SET = "IF_NO_BRANCH_SET";
|
|
|
9877
10057
|
var UNKNOWN_COMPONENT_NAME = "UNKNOWN_COMPONENT_NAME";
|
|
9878
10058
|
var UNKNOWN_MACRO_ARG = "UNKNOWN_MACRO_ARG";
|
|
9879
10059
|
var UNKNOWN_DIRECTIVE = "UNKNOWN_DIRECTIVE";
|
|
10060
|
+
var ORPHAN_DIRECTIVE = "ORPHAN_DIRECTIVE";
|
|
9880
10061
|
var UNKNOWN_X_OP = "UNKNOWN_X_OP";
|
|
9881
10062
|
var UNKNOWN_X_ATTR = "UNKNOWN_X_ATTR";
|
|
9882
10063
|
var X_OP_IGNORES_CHILDREN = "X_OP_IGNORES_CHILDREN";
|
|
@@ -9911,6 +10092,7 @@ var LEVEL_ERROR2 = "error";
|
|
|
9911
10092
|
var LEVEL_HINT = "hint";
|
|
9912
10093
|
var PARSE_ISSUES = {
|
|
9913
10094
|
"unknown-directive": { id: UNKNOWN_DIRECTIVE, candidates: KNOWN_DIRECTIVE_NAMES },
|
|
10095
|
+
"orphan-directive": { id: ORPHAN_DIRECTIVE },
|
|
9914
10096
|
"unknown-x-op": { id: UNKNOWN_X_OP, candidates: X_KNOWN_OP_NAMES, atPrefix: X_KNOWN_OP_NAMES },
|
|
9915
10097
|
"unknown-x-attr": {
|
|
9916
10098
|
id: UNKNOWN_X_ATTR,
|
|
@@ -9983,7 +10165,6 @@ function checkComponent(Comp, lx = new LintContext(), { wellKnownExtras = EMPTY_
|
|
|
9983
10165
|
checkFieldMethodNameCollisions(lx, Comp);
|
|
9984
10166
|
checkProvidesAreAddressable(lx, Comp);
|
|
9985
10167
|
checkProvidedTypes(lx, Comp);
|
|
9986
|
-
checkProvideNameCollisions(lx, Comp);
|
|
9987
10168
|
checkLookupShapes(lx, Comp);
|
|
9988
10169
|
checkLookupTypesResolve(lx, Comp);
|
|
9989
10170
|
checkLookupsHaveProviders(lx, Comp);
|
|
@@ -10667,19 +10848,6 @@ function checkProvidedTypes(lx, Comp) {
|
|
|
10667
10848
|
if (raw !== "self") lx.error(PROVIDE_TYPE_BAD_SHAPE, { name, value: raw });
|
|
10668
10849
|
}
|
|
10669
10850
|
}
|
|
10670
|
-
function checkProvideNameCollisions(lx, Comp) {
|
|
10671
|
-
const scope = Comp.scope;
|
|
10672
|
-
if (!scope) return;
|
|
10673
|
-
for (const name in Comp.provide) {
|
|
10674
|
-
for (let s = scope; s; s = s.parent) {
|
|
10675
|
-
for (const otherName in s.byName) {
|
|
10676
|
-
const Other = s.byName[otherName];
|
|
10677
|
-
if (Other !== Comp && Other.provide?.[name] !== void 0)
|
|
10678
|
-
lx.error(PROVIDE_NAME_COLLISION, { name, other: Other.name });
|
|
10679
|
-
}
|
|
10680
|
-
}
|
|
10681
|
-
}
|
|
10682
|
-
}
|
|
10683
10851
|
var KNOWN_LOOKUP_KEYS = /* @__PURE__ */ new Set(["name", "default"]);
|
|
10684
10852
|
function checkLookupShapes(lx, Comp) {
|
|
10685
10853
|
const raw = Comp._rawLookup;
|
|
@@ -10721,8 +10889,8 @@ function checkLookupsHaveProviders(lx, Comp) {
|
|
|
10721
10889
|
if (!scope) return;
|
|
10722
10890
|
for (const name in Comp.lookup) {
|
|
10723
10891
|
if (isTypeName2(name)) continue;
|
|
10724
|
-
if (scope.
|
|
10725
|
-
const info = { name, hasDefault: Comp.lookup[name]
|
|
10892
|
+
if (scope.hasProvider?.(name) || scope.lookupPath?.(name)) continue;
|
|
10893
|
+
const info = { name, hasDefault: Comp.lookup[name] != null };
|
|
10726
10894
|
if (info.hasDefault) lx.hint(LOOKUP_NO_PROVIDER, info);
|
|
10727
10895
|
else lx.error(LOOKUP_NO_PROVIDER, info);
|
|
10728
10896
|
}
|
|
@@ -10770,13 +10938,14 @@ var LintContext = class {
|
|
|
10770
10938
|
this.reports.push({ id, info, level, context: { ...this.frame }, suggestion });
|
|
10771
10939
|
}
|
|
10772
10940
|
};
|
|
10773
|
-
var LintParseContext = class extends
|
|
10774
|
-
constructor(document2
|
|
10775
|
-
super(document2
|
|
10941
|
+
var LintParseContext = class extends ParseCtxClassSetCollector {
|
|
10942
|
+
constructor(document2) {
|
|
10943
|
+
super(document2);
|
|
10776
10944
|
this.attrs = [];
|
|
10777
10945
|
this.parseIssues = [];
|
|
10778
10946
|
}
|
|
10779
10947
|
onAttributes(attrs, wrapperAttrs, textChild, isMacroCall = false, tag = null) {
|
|
10948
|
+
super.onAttributes(attrs, wrapperAttrs, textChild, isMacroCall, tag);
|
|
10780
10949
|
this.attrs.push({ attrs, wrapperAttrs, textChild, isMacroCall, tag });
|
|
10781
10950
|
}
|
|
10782
10951
|
onParseIssue(kind, info) {
|
|
@@ -10813,14 +10982,36 @@ function dispatchPhase(dispatcher, targetPath, phase, self) {
|
|
|
10813
10982
|
|
|
10814
10983
|
// src/oo.js
|
|
10815
10984
|
var BAD_VALUE2 = /* @__PURE__ */ Symbol("BadValue");
|
|
10816
|
-
var
|
|
10985
|
+
var COERCE_NONE = (_v) => null;
|
|
10986
|
+
var COERCE_MAP = (v) => {
|
|
10987
|
+
if (v instanceof Map) return new Map(v);
|
|
10988
|
+
if (Array.isArray(v) || isPlainObject(v))
|
|
10989
|
+
return new Map(Array.isArray(v) ? v : Object.entries(v));
|
|
10990
|
+
return null;
|
|
10991
|
+
};
|
|
10992
|
+
var FIELD_TYPES = {
|
|
10993
|
+
any: [(_v) => true, COERCE_NONE, () => null],
|
|
10994
|
+
text: [(v) => typeof v === "string", (v) => v?.toString?.() ?? "", () => ""],
|
|
10995
|
+
int: [Number.isInteger, (v) => Number.isFinite(v) ? Math.trunc(v) : null, () => 0],
|
|
10996
|
+
float: [Number.isFinite, COERCE_NONE, () => 0],
|
|
10997
|
+
bool: [(v) => typeof v === "boolean", (v) => !!v, () => false],
|
|
10998
|
+
list: [Array.isArray, (v) => Array.isArray(v) ? [...v] : null, () => []],
|
|
10999
|
+
object: [isPlainObject, (v) => isPlainObject(v) ? { ...v } : null, () => ({})],
|
|
11000
|
+
map: [(v) => v instanceof Map, COERCE_MAP, () => /* @__PURE__ */ new Map()],
|
|
11001
|
+
set: [
|
|
11002
|
+
(v) => v instanceof Set,
|
|
11003
|
+
(v) => v instanceof Set || Array.isArray(v) ? new Set(v) : null,
|
|
11004
|
+
() => /* @__PURE__ */ new Set()
|
|
11005
|
+
]
|
|
11006
|
+
};
|
|
10817
11007
|
var Field = class {
|
|
10818
|
-
|
|
11008
|
+
// `type` names an entry of FIELD_TYPES; `defaultValue` falls back to the type's own.
|
|
11009
|
+
constructor(type3, name, defaultValue, [typeCheck, coercer, makeDefault] = FIELD_TYPES[type3]) {
|
|
10819
11010
|
this.type = type3;
|
|
10820
11011
|
this.name = name;
|
|
10821
11012
|
this.typeCheck = typeCheck;
|
|
10822
11013
|
this.coercer = coercer;
|
|
10823
|
-
this.defaultValue = defaultValue;
|
|
11014
|
+
this.defaultValue = defaultValue === void 0 ? makeDefault() : defaultValue;
|
|
10824
11015
|
}
|
|
10825
11016
|
isValid(v) {
|
|
10826
11017
|
return this.typeCheck(v);
|
|
@@ -10834,81 +11025,14 @@ var Field = class {
|
|
|
10834
11025
|
return this.coerceOr(v, this.defaultValue);
|
|
10835
11026
|
}
|
|
10836
11027
|
};
|
|
10837
|
-
var
|
|
10838
|
-
var CHECK_TYPE_INT = Number.isInteger;
|
|
10839
|
-
var CHECK_TYPE_FLOAT = Number.isFinite;
|
|
10840
|
-
var CHECK_TYPE_BOOL = (v) => typeof v === "boolean";
|
|
10841
|
-
var CHECK_TYPE_STRING = (v) => typeof v === "string";
|
|
10842
|
-
var CHECK_TYPE_LIST = Array.isArray;
|
|
10843
|
-
var CHECK_TYPE_OBJECT = isPlainObject;
|
|
10844
|
-
var CHECK_TYPE_MAP = (v) => v instanceof Map;
|
|
10845
|
-
var CHECK_TYPE_SET = (v) => v instanceof Set;
|
|
10846
|
-
var COERCE_NONE = (_v) => null;
|
|
10847
|
-
var COERCE_BOOL = (v) => !!v;
|
|
10848
|
-
var COERCE_STRING = (v) => v?.toString?.() ?? "";
|
|
10849
|
-
var COERCE_INT = (v) => Number.isFinite(v) ? Math.trunc(v) : null;
|
|
10850
|
-
var COERCE_LIST = (v) => Array.isArray(v) ? [...v] : null;
|
|
10851
|
-
var COERCE_OBJECT = (v) => isPlainObject(v) ? { ...v } : null;
|
|
10852
|
-
var COERCE_MAP = (v) => {
|
|
10853
|
-
if (v instanceof Map) return new Map(v);
|
|
10854
|
-
if (Array.isArray(v) || isPlainObject(v))
|
|
10855
|
-
return new Map(Array.isArray(v) ? v : Object.entries(v));
|
|
10856
|
-
return null;
|
|
10857
|
-
};
|
|
10858
|
-
var COERCE_SET = (v) => v instanceof Set || Array.isArray(v) ? new Set(v) : null;
|
|
10859
|
-
var FieldBool = class extends Field {
|
|
10860
|
-
constructor(name, defaultValue = false) {
|
|
10861
|
-
super("bool", name, CHECK_TYPE_BOOL, COERCE_BOOL, defaultValue);
|
|
10862
|
-
}
|
|
10863
|
-
};
|
|
10864
|
-
var FieldAny = class extends Field {
|
|
10865
|
-
constructor(name, defaultValue = null) {
|
|
10866
|
-
super("any", name, CHECK_TYPE_ANY, nullCoercer, defaultValue);
|
|
10867
|
-
}
|
|
10868
|
-
};
|
|
10869
|
-
var FieldString = class extends Field {
|
|
10870
|
-
constructor(name, defaultValue = "") {
|
|
10871
|
-
super("text", name, CHECK_TYPE_STRING, COERCE_STRING, defaultValue);
|
|
10872
|
-
}
|
|
10873
|
-
};
|
|
10874
|
-
var FieldInt = class extends Field {
|
|
10875
|
-
constructor(name, defaultValue = 0) {
|
|
10876
|
-
super("int", name, CHECK_TYPE_INT, COERCE_INT, defaultValue);
|
|
10877
|
-
}
|
|
10878
|
-
};
|
|
10879
|
-
var FieldFloat = class extends Field {
|
|
10880
|
-
constructor(name, defaultValue = 0) {
|
|
10881
|
-
super("float", name, CHECK_TYPE_FLOAT, COERCE_NONE, defaultValue);
|
|
10882
|
-
}
|
|
10883
|
-
};
|
|
10884
|
-
var metaOf = (v) => v?.constructor?.[COMPONENT] ?? v?.constructor?.getMetaClass?.();
|
|
11028
|
+
var metaOf = (v) => v?.constructor?.getMetaClass?.();
|
|
10885
11029
|
var getTypeName = (v) => metaOf(v)?.name ?? null;
|
|
10886
11030
|
var FieldComp = class extends Field {
|
|
10887
11031
|
constructor(type3, name, args) {
|
|
10888
|
-
super(type3, name, (v) => getTypeName(v) === type3,
|
|
11032
|
+
super(type3, name, null, [(v) => getTypeName(v) === type3, COERCE_NONE, () => null]);
|
|
10889
11033
|
this.args = args;
|
|
10890
11034
|
}
|
|
10891
11035
|
};
|
|
10892
|
-
var FieldList = class extends Field {
|
|
10893
|
-
constructor(name, defaultValue = []) {
|
|
10894
|
-
super("list", name, CHECK_TYPE_LIST, COERCE_LIST, defaultValue);
|
|
10895
|
-
}
|
|
10896
|
-
};
|
|
10897
|
-
var FieldObject = class extends Field {
|
|
10898
|
-
constructor(name, defaultValue = {}) {
|
|
10899
|
-
super("object", name, CHECK_TYPE_OBJECT, COERCE_OBJECT, defaultValue);
|
|
10900
|
-
}
|
|
10901
|
-
};
|
|
10902
|
-
var FieldMap = class extends Field {
|
|
10903
|
-
constructor(name, defaultValue = /* @__PURE__ */ new Map()) {
|
|
10904
|
-
super("map", name, CHECK_TYPE_MAP, COERCE_MAP, defaultValue);
|
|
10905
|
-
}
|
|
10906
|
-
};
|
|
10907
|
-
var FieldSet = class extends Field {
|
|
10908
|
-
constructor(name, defaultValue = /* @__PURE__ */ new Set()) {
|
|
10909
|
-
super("set", name, CHECK_TYPE_SET, COERCE_SET, defaultValue);
|
|
10910
|
-
}
|
|
10911
|
-
};
|
|
10912
11036
|
function mkCompField(field, scope, args) {
|
|
10913
11037
|
const Comp = scope?.lookupComponent(field.type) ?? null;
|
|
10914
11038
|
if (Comp === null)
|
|
@@ -10917,112 +11041,66 @@ function mkCompField(field, scope, args) {
|
|
|
10917
11041
|
);
|
|
10918
11042
|
return Comp?.make({ ...field.args, ...args }, { scope }) ?? null;
|
|
10919
11043
|
}
|
|
10920
|
-
|
|
10921
|
-
|
|
10922
|
-
|
|
10923
|
-
|
|
10924
|
-
|
|
10925
|
-
|
|
10926
|
-
|
|
10927
|
-
|
|
10928
|
-
|
|
10929
|
-
const
|
|
10930
|
-
const
|
|
10931
|
-
|
|
10932
|
-
|
|
10933
|
-
|
|
10934
|
-
|
|
10935
|
-
|
|
10936
|
-
|
|
10937
|
-
|
|
11044
|
+
function fieldFromSpec(name, value) {
|
|
11045
|
+
const type3 = typeof value;
|
|
11046
|
+
if (type3 === "string") return new Field("text", name, value);
|
|
11047
|
+
if (type3 === "number") return new Field("float", name, value);
|
|
11048
|
+
if (type3 === "boolean") return new Field("bool", name, value);
|
|
11049
|
+
if (Array.isArray(value)) return new Field("list", name, [...value]);
|
|
11050
|
+
if (value instanceof Set) return new Field("set", name, new Set(value));
|
|
11051
|
+
if (value instanceof Map) return new Field("map", name, new Map(value));
|
|
11052
|
+
if (value?.type && Object.hasOwn(value, "defaultValue")) {
|
|
11053
|
+
const t = value.type in FIELD_TYPES ? value.type : "any";
|
|
11054
|
+
const probe = new Field(t, name);
|
|
11055
|
+
return new Field(t, name, probe.coerceOr(value.defaultValue, probe.defaultValue));
|
|
11056
|
+
}
|
|
11057
|
+
if (value?.component && value?.args !== void 0)
|
|
11058
|
+
return new FieldComp(value.component, name, value.args);
|
|
11059
|
+
if (isPlainObject(value)) return new Field("object", name, { ...value });
|
|
11060
|
+
return new Field("any", name, value);
|
|
11061
|
+
}
|
|
11062
|
+
function classFromData(name, { fields: spec = {}, methods = {}, statics = {} }) {
|
|
11063
|
+
const fields = {};
|
|
11064
|
+
for (const key in spec) fields[key] = fieldFromSpec(key, spec[key]);
|
|
11065
|
+
const defaults = Object.fromEntries(
|
|
11066
|
+
Object.entries(fields).map(([key, field]) => [key, field.defaultValue])
|
|
11067
|
+
);
|
|
11068
|
+
const Class = {
|
|
11069
|
+
[name]: class {
|
|
11070
|
+
constructor(values = {}) {
|
|
11071
|
+
Object.assign(this, defaults, values);
|
|
10938
11072
|
}
|
|
10939
|
-
}[name];
|
|
10940
|
-
Class[DRAFTABLE] = true;
|
|
10941
|
-
Object.assign(Class.prototype, _methods);
|
|
10942
|
-
const metaClass = { fields, name, methods: _methods };
|
|
10943
|
-
Object.assign(
|
|
10944
|
-
Class,
|
|
10945
|
-
{
|
|
10946
|
-
getMetaClass: () => metaClass,
|
|
10947
|
-
make(inArgs = {}, opts = {}) {
|
|
10948
|
-
const args = {};
|
|
10949
|
-
const scope = opts.scope ?? this[COMPONENT]?.scope ?? this.scope;
|
|
10950
|
-
for (const key in inArgs) {
|
|
10951
|
-
const field = fields[key];
|
|
10952
|
-
if (compFields.has(key)) args[key] = mkCompField(field, scope, inArgs[key]);
|
|
10953
|
-
else if (field === void 0)
|
|
10954
|
-
console.warn("extra argument to constructor:", name, key, inArgs);
|
|
10955
|
-
else args[key] = field.coerceOrDefault(inArgs[key]);
|
|
10956
|
-
}
|
|
10957
|
-
for (const key of compFields)
|
|
10958
|
-
if (args[key] === void 0) args[key] = mkCompField(fields[key], scope, inArgs[key]);
|
|
10959
|
-
return freeze(new this(args), true);
|
|
10960
|
-
}
|
|
10961
|
-
},
|
|
10962
|
-
this._statics
|
|
10963
|
-
);
|
|
10964
|
-
return Class;
|
|
10965
|
-
}
|
|
10966
|
-
methods(proto) {
|
|
10967
|
-
for (const k in proto) this._methods[k] = proto[k];
|
|
10968
|
-
}
|
|
10969
|
-
statics(proto) {
|
|
10970
|
-
for (const k in proto) this._statics[k] = proto[k];
|
|
10971
|
-
}
|
|
10972
|
-
addField(name, dval, FieldCls) {
|
|
10973
|
-
const field = new FieldCls(name, dval);
|
|
10974
|
-
this.fields[name] = field;
|
|
10975
|
-
return field;
|
|
10976
|
-
}
|
|
10977
|
-
addCompField(name, type3, args) {
|
|
10978
|
-
const field = new FieldComp(type3, name, args);
|
|
10979
|
-
this.compFields.add(name);
|
|
10980
|
-
this.fields[name] = field;
|
|
10981
|
-
return field;
|
|
10982
|
-
}
|
|
10983
|
-
};
|
|
10984
|
-
var FIELD_CLASS = /* @__PURE__ */ Symbol.for("tutuca.fieldClass");
|
|
10985
|
-
var fieldsByTypeName = {
|
|
10986
|
-
text: FieldString,
|
|
10987
|
-
int: FieldInt,
|
|
10988
|
-
float: FieldFloat,
|
|
10989
|
-
bool: FieldBool,
|
|
10990
|
-
list: FieldList,
|
|
10991
|
-
object: FieldObject,
|
|
10992
|
-
map: FieldMap,
|
|
10993
|
-
set: FieldSet,
|
|
10994
|
-
any: FieldAny
|
|
10995
|
-
};
|
|
10996
|
-
function fieldFromDescriptor(name, value) {
|
|
10997
|
-
const FieldCls = fieldsByTypeName[value.type] ?? FieldAny;
|
|
10998
|
-
const probe = new FieldCls(name);
|
|
10999
|
-
return [FieldCls, probe.coerceOr(value.defaultValue, probe.defaultValue)];
|
|
11000
|
-
}
|
|
11001
|
-
function classFromData(name, { fields = {}, methods, statics }) {
|
|
11002
|
-
const b = new ClassBuilder(name);
|
|
11003
|
-
for (const field in fields) {
|
|
11004
|
-
const value = fields[field];
|
|
11005
|
-
const type3 = typeof value;
|
|
11006
|
-
if (type3 === "string") b.addField(field, value, FieldString);
|
|
11007
|
-
else if (type3 === "number") b.addField(field, value, FieldFloat);
|
|
11008
|
-
else if (type3 === "boolean") b.addField(field, value, FieldBool);
|
|
11009
|
-
else if (Array.isArray(value)) b.addField(field, [...value], FieldList);
|
|
11010
|
-
else if (value instanceof Set) b.addField(field, new Set(value), FieldSet);
|
|
11011
|
-
else if (value instanceof Map) b.addField(field, new Map(value), FieldMap);
|
|
11012
|
-
else if (value?.type && Object.hasOwn(value, "defaultValue")) {
|
|
11013
|
-
const [FieldCls, dval] = fieldFromDescriptor(field, value);
|
|
11014
|
-
b.addField(field, dval, FieldCls);
|
|
11015
|
-
} else if (value?.component && value?.args !== void 0)
|
|
11016
|
-
b.addCompField(field, value.component, value.args);
|
|
11017
|
-
else if (isPlainObject(value)) b.addField(field, { ...value }, FieldObject);
|
|
11018
|
-
else {
|
|
11019
|
-
const FieldCls = value?.[FIELD_CLASS] ?? FieldAny;
|
|
11020
|
-
b.addField(field, value, FieldCls);
|
|
11021
11073
|
}
|
|
11022
|
-
}
|
|
11023
|
-
|
|
11024
|
-
|
|
11025
|
-
|
|
11074
|
+
}[name];
|
|
11075
|
+
Class[DRAFTABLE] = true;
|
|
11076
|
+
Object.assign(Class.prototype, methods);
|
|
11077
|
+
Object.assign(
|
|
11078
|
+
Class,
|
|
11079
|
+
{
|
|
11080
|
+
fields,
|
|
11081
|
+
methods,
|
|
11082
|
+
// The documented way for instance code to reach its class's fields
|
|
11083
|
+
// (`this.constructor.getMetaClass().fields.x.defaultValue`).
|
|
11084
|
+
getMetaClass: () => Class,
|
|
11085
|
+
make(inArgs = {}, opts = {}) {
|
|
11086
|
+
const args = {};
|
|
11087
|
+
const scope = opts.scope ?? this.scope;
|
|
11088
|
+
for (const key in inArgs) {
|
|
11089
|
+
const field = fields[key];
|
|
11090
|
+
if (field === void 0)
|
|
11091
|
+
console.warn("extra argument to constructor:", name, key, inArgs);
|
|
11092
|
+
else if (field instanceof FieldComp) args[key] = mkCompField(field, scope, inArgs[key]);
|
|
11093
|
+
else args[key] = field.coerceOrDefault(inArgs[key]);
|
|
11094
|
+
}
|
|
11095
|
+
for (const key in fields)
|
|
11096
|
+
if (fields[key] instanceof FieldComp && args[key] === void 0)
|
|
11097
|
+
args[key] = mkCompField(fields[key], scope, void 0);
|
|
11098
|
+
return freeze(new this(args), true);
|
|
11099
|
+
}
|
|
11100
|
+
},
|
|
11101
|
+
statics
|
|
11102
|
+
);
|
|
11103
|
+
return Class;
|
|
11026
11104
|
}
|
|
11027
11105
|
function validateDraftFields(current2, draft) {
|
|
11028
11106
|
const meta = metaOf(current2);
|
|
@@ -11038,14 +11116,11 @@ function validateDraftFields(current2, draft) {
|
|
|
11038
11116
|
}
|
|
11039
11117
|
}
|
|
11040
11118
|
}
|
|
11041
|
-
var META_KEYS = "name id fields methods views receive intent alter provide provideType lookup spec extra commonStyle globalStyle scope _rawProvide _rawLookup".split(
|
|
11042
|
-
" "
|
|
11043
|
-
);
|
|
11044
11119
|
var RESERVED_COMPONENT_STATICS = /* @__PURE__ */ new Set([
|
|
11045
|
-
...
|
|
11046
|
-
|
|
11047
|
-
|
|
11048
|
-
...Object.
|
|
11120
|
+
..."name id fields methods views receive intent alter provide provideType lookup spec extra commonStyle globalStyle scope _rawProvide _rawLookup make getMetaClass".split(
|
|
11121
|
+
" "
|
|
11122
|
+
),
|
|
11123
|
+
...Object.keys(COMPONENT_METHODS)
|
|
11049
11124
|
]);
|
|
11050
11125
|
function assertNoReservedComponentStatics(statics = {}) {
|
|
11051
11126
|
for (const name in statics) {
|
|
@@ -11054,186 +11129,10 @@ function assertNoReservedComponentStatics(statics = {}) {
|
|
|
11054
11129
|
}
|
|
11055
11130
|
}
|
|
11056
11131
|
}
|
|
11057
|
-
|
|
11132
|
+
function component(opts) {
|
|
11058
11133
|
assertNoReservedComponentStatics(opts.statics);
|
|
11059
|
-
|
|
11060
|
-
const comp = new Component(Class, opts);
|
|
11061
|
-
const metaClass = Class.getMetaClass();
|
|
11062
|
-
comp.fields = metaClass.fields;
|
|
11063
|
-
comp.methods = metaClass.methods;
|
|
11064
|
-
Class.getMetaClass = () => comp;
|
|
11065
|
-
Class[COMPONENT] = comp;
|
|
11066
|
-
for (const key of META_KEYS)
|
|
11067
|
-
if (!Object.hasOwn(Class, key))
|
|
11068
|
-
Object.defineProperty(Class, key, {
|
|
11069
|
-
get() {
|
|
11070
|
-
return comp[key];
|
|
11071
|
-
},
|
|
11072
|
-
set(v) {
|
|
11073
|
-
comp[key] = v;
|
|
11074
|
-
},
|
|
11075
|
-
configurable: true
|
|
11076
|
-
});
|
|
11077
|
-
for (const key of Object.getOwnPropertyNames(Component.prototype))
|
|
11078
|
-
if (key !== "constructor" && !Object.hasOwn(Class, key))
|
|
11079
|
-
Class[key] = (...args) => comp[key](...args);
|
|
11080
|
-
return Class;
|
|
11081
|
-
};
|
|
11082
|
-
var component = (opts) => Component.fromSpec(opts);
|
|
11083
|
-
|
|
11084
|
-
// src/stack.js
|
|
11085
|
-
var STOP = /* @__PURE__ */ Symbol("STOP");
|
|
11086
|
-
var NEXT = /* @__PURE__ */ Symbol("NEXT");
|
|
11087
|
-
var DEFAULT_ROUTE = ["dyn", "lex"];
|
|
11088
|
-
function routeLookup(route, lex, dyn) {
|
|
11089
|
-
for (let i = 0; i < route.length; i++) {
|
|
11090
|
-
const leg = route[i];
|
|
11091
|
-
if (leg === "dyn") {
|
|
11092
|
-
const v = dyn();
|
|
11093
|
-
if (v != null) return v;
|
|
11094
|
-
} else if (leg === "lex") {
|
|
11095
|
-
const v = lex();
|
|
11096
|
-
if (v != null) return v;
|
|
11097
|
-
} else {
|
|
11098
|
-
console.warn("unknown lookup route leg", leg, '- expected "dyn" or "lex"');
|
|
11099
|
-
}
|
|
11100
|
-
}
|
|
11101
|
-
return null;
|
|
11102
|
-
}
|
|
11103
|
-
function lookup(chain, name, dv = null) {
|
|
11104
|
-
let n = chain;
|
|
11105
|
-
while (n !== null) {
|
|
11106
|
-
const r = n[0].lookup(name);
|
|
11107
|
-
if (r === STOP) return dv;
|
|
11108
|
-
if (r !== NEXT) return r;
|
|
11109
|
-
n = n[1];
|
|
11110
|
-
}
|
|
11111
|
-
return dv;
|
|
11112
|
-
}
|
|
11113
|
-
var BindFrame = class {
|
|
11114
|
-
constructor(it, binds, isFrame) {
|
|
11115
|
-
this.it = it;
|
|
11116
|
-
this.binds = binds;
|
|
11117
|
-
this.isFrame = isFrame;
|
|
11118
|
-
}
|
|
11119
|
-
lookup(name) {
|
|
11120
|
-
const v = this.binds[name];
|
|
11121
|
-
return v === void 0 ? this.isFrame ? STOP : NEXT : v;
|
|
11122
|
-
}
|
|
11123
|
-
};
|
|
11124
|
-
var ObjectFrame = class {
|
|
11125
|
-
constructor(binds) {
|
|
11126
|
-
this.binds = binds;
|
|
11127
|
-
}
|
|
11128
|
-
lookup(key) {
|
|
11129
|
-
const v = this.binds[key];
|
|
11130
|
-
return v === void 0 ? NEXT : v;
|
|
11131
|
-
}
|
|
11132
|
-
};
|
|
11133
|
-
function computeViewsId(views) {
|
|
11134
|
-
let s = "";
|
|
11135
|
-
let n = views;
|
|
11136
|
-
while (n !== null) {
|
|
11137
|
-
s += n[0];
|
|
11138
|
-
n = n[1];
|
|
11139
|
-
}
|
|
11140
|
-
return s === "main" ? "" : s;
|
|
11134
|
+
return initComponent(classFromData(opts.name ?? "UnkComp", opts), opts);
|
|
11141
11135
|
}
|
|
11142
|
-
var Stack = class _Stack {
|
|
11143
|
-
constructor(comps, it, binds, dynBinds, views, viewsId, ctx = null) {
|
|
11144
|
-
this.comps = comps;
|
|
11145
|
-
this.it = it;
|
|
11146
|
-
this.binds = binds;
|
|
11147
|
-
this.dynBinds = dynBinds;
|
|
11148
|
-
this.views = views;
|
|
11149
|
-
this.viewsId = viewsId;
|
|
11150
|
-
this.ctx = ctx;
|
|
11151
|
-
}
|
|
11152
|
-
// Evaluate every provide the entered component publishes and push them as one
|
|
11153
|
-
// dynBinds frame, keyed by NAME. Published types go in the same frame: a type name
|
|
11154
|
-
// starts A-Z and a value name does not, so the two namespaces cannot collide and
|
|
11155
|
-
// nearest-ancestor-wins falls out of frame order for both. No-op with no provides.
|
|
11156
|
-
_pushProvides() {
|
|
11157
|
-
const comp = this.comps.getCompFor(this.it);
|
|
11158
|
-
if (comp == null) return this;
|
|
11159
|
-
const { provide, provideType } = comp;
|
|
11160
|
-
const dynObj = {};
|
|
11161
|
-
let has2 = false;
|
|
11162
|
-
for (const k in provide) {
|
|
11163
|
-
dynObj[k] = provide[k].val.eval(this);
|
|
11164
|
-
has2 = true;
|
|
11165
|
-
}
|
|
11166
|
-
for (const k in provideType) {
|
|
11167
|
-
dynObj[k] = provideType[k];
|
|
11168
|
-
has2 = true;
|
|
11169
|
-
}
|
|
11170
|
-
if (!has2) return this;
|
|
11171
|
-
const newDynBinds = [new ObjectFrame(dynObj), this.dynBinds];
|
|
11172
|
-
const { comps, it, binds, views, viewsId, ctx } = this;
|
|
11173
|
-
return new _Stack(comps, it, binds, newDynBinds, views, viewsId, ctx);
|
|
11174
|
-
}
|
|
11175
|
-
static root(comps, it, ctx) {
|
|
11176
|
-
const binds = [new BindFrame(it, {}, true), null];
|
|
11177
|
-
const dynBinds = [new ObjectFrame({}), null];
|
|
11178
|
-
const views = ["main", null];
|
|
11179
|
-
return new _Stack(comps, it, binds, dynBinds, views, "", ctx)._pushProvides();
|
|
11180
|
-
}
|
|
11181
|
-
enter(it, bindings = {}, isFrame = true) {
|
|
11182
|
-
const { comps, binds, dynBinds, views, viewsId, ctx } = this;
|
|
11183
|
-
const newBinds = [new BindFrame(it, bindings, isFrame), binds];
|
|
11184
|
-
const stack = new _Stack(comps, it, newBinds, dynBinds, views, viewsId, ctx);
|
|
11185
|
-
return isFrame ? stack._pushProvides() : stack;
|
|
11186
|
-
}
|
|
11187
|
-
pushViewName(name) {
|
|
11188
|
-
const { comps, it, binds, dynBinds, views, ctx } = this;
|
|
11189
|
-
const newViews = [name, views];
|
|
11190
|
-
return new _Stack(comps, it, binds, dynBinds, newViews, computeViewsId(newViews), ctx);
|
|
11191
|
-
}
|
|
11192
|
-
// Published types are stable per scope and would only churn the render cache, so
|
|
11193
|
-
// the cache key covers values alone.
|
|
11194
|
-
_pushDynBindValuesToArray(arr, comp) {
|
|
11195
|
-
for (const k in comp.provide) arr.push(this.lookupDynamic(k));
|
|
11196
|
-
for (const k in comp.lookup) arr.push(this.lookupDynamic(k));
|
|
11197
|
-
}
|
|
11198
|
-
// `*name`: the nearest binding above (including this component's own provides,
|
|
11199
|
-
// pushed on entering it), else this component's declared default, else null.
|
|
11200
|
-
lookupDynamic(name) {
|
|
11201
|
-
const v = lookup(this.dynBinds, name);
|
|
11202
|
-
if (v != null) return v;
|
|
11203
|
-
const comp = this.comps.getCompFor(this.it);
|
|
11204
|
-
return comp?.lookup[name]?.val?.eval(this) ?? null;
|
|
11205
|
-
}
|
|
11206
|
-
lookupBind(name) {
|
|
11207
|
-
return lookup(this.binds, name);
|
|
11208
|
-
}
|
|
11209
|
-
lookupFieldRaw(name) {
|
|
11210
|
-
return this.it[name] ?? null;
|
|
11211
|
-
}
|
|
11212
|
-
lookupMethod(name) {
|
|
11213
|
-
const fn = this.it[name];
|
|
11214
|
-
return fn instanceof Function ? fn.call(this.it) : null;
|
|
11215
|
-
}
|
|
11216
|
-
// The dispatched DOM event / drag info, read only by EventMemberVal's
|
|
11217
|
-
// `e.<member>` handler args. Null outside a live event transaction.
|
|
11218
|
-
lookupEvent() {
|
|
11219
|
-
return this.ctx?.event ?? null;
|
|
11220
|
-
}
|
|
11221
|
-
lookupDragInfo() {
|
|
11222
|
-
return this.ctx?.dragInfo ?? null;
|
|
11223
|
-
}
|
|
11224
|
-
getHandlerFor(name, key) {
|
|
11225
|
-
return this.comps.getHandlerFor(this.it, name, key);
|
|
11226
|
-
}
|
|
11227
|
-
lookupBestView(views, defaultViewName) {
|
|
11228
|
-
let n = this.views;
|
|
11229
|
-
while (n !== null) {
|
|
11230
|
-
const view = views[n[0]];
|
|
11231
|
-
if (view !== void 0) return view;
|
|
11232
|
-
n = n[1];
|
|
11233
|
-
}
|
|
11234
|
-
return views[defaultViewName];
|
|
11235
|
-
}
|
|
11236
|
-
};
|
|
11237
11136
|
|
|
11238
11137
|
// src/transactor.js
|
|
11239
11138
|
var State2 = class {
|
|
@@ -11274,14 +11173,7 @@ var Transactor = class {
|
|
|
11274
11173
|
// carry: kind, name, args, path, pathKeys, targetPath, handler, handlerName,
|
|
11275
11174
|
// matched, before, after, parent, timestamp. Purely observational.
|
|
11276
11175
|
observe(cb) {
|
|
11277
|
-
this._observers
|
|
11278
|
-
return () => {
|
|
11279
|
-
const i = this._observers.indexOf(cb);
|
|
11280
|
-
if (i !== -1) this._observers.splice(i, 1);
|
|
11281
|
-
};
|
|
11282
|
-
}
|
|
11283
|
-
_emit(record) {
|
|
11284
|
-
for (const cb of this._observers) cb(record);
|
|
11176
|
+
return subscribe(this._observers, cb);
|
|
11285
11177
|
}
|
|
11286
11178
|
// Record a refusal: a dispatch the runtime could not carry out. Kinds are
|
|
11287
11179
|
// open strings; today the runtime raises NO_HANDLER (a receive name with no
|
|
@@ -11300,20 +11192,16 @@ var Transactor = class {
|
|
|
11300
11192
|
// Subscribe to refusal records as they happen. Returns an unsubscribe fn,
|
|
11301
11193
|
// like observe().
|
|
11302
11194
|
observeRefusals(cb) {
|
|
11303
|
-
this._refusalObservers
|
|
11304
|
-
return () => {
|
|
11305
|
-
const i = this._refusalObservers.indexOf(cb);
|
|
11306
|
-
if (i !== -1) this._refusalObservers.splice(i, 1);
|
|
11307
|
-
};
|
|
11195
|
+
return subscribe(this._refusalObservers, cb);
|
|
11308
11196
|
}
|
|
11309
11197
|
// Build and dispatch one observer record. Pins field-resolved keys (e.g. a
|
|
11310
11198
|
// `.a[.selId]` render target reconstructed from a DOM event) against the root the
|
|
11311
11199
|
// handler read, so pathKeys carries concrete keys instead of dropping the dynamic
|
|
11312
11200
|
// step. No-op when nobody is observing.
|
|
11313
|
-
_emitRecord(root, { kind, name, args, path, targetPath, handler, handlerName, matched, before, after, parent }) {
|
|
11201
|
+
_emitRecord(root, { kind, name, args, path: path2, targetPath, handler, handlerName, matched, before, after, parent }) {
|
|
11314
11202
|
if (this._observers.length === 0) return;
|
|
11315
|
-
const pinned =
|
|
11316
|
-
|
|
11203
|
+
const pinned = path2.pinKeys(root);
|
|
11204
|
+
const record = {
|
|
11317
11205
|
kind,
|
|
11318
11206
|
name,
|
|
11319
11207
|
args: args ?? null,
|
|
@@ -11327,14 +11215,14 @@ var Transactor = class {
|
|
|
11327
11215
|
after,
|
|
11328
11216
|
parent,
|
|
11329
11217
|
timestamp: Date.now()
|
|
11330
|
-
}
|
|
11218
|
+
};
|
|
11219
|
+
for (const cb of this._observers) cb(record);
|
|
11331
11220
|
}
|
|
11332
11221
|
// The observer record for a settled transaction. The resolved handler
|
|
11333
11222
|
// (`_resolvedHandler`/`_matched`) and per-leaf before/after (`_before`/`_after`)
|
|
11334
11223
|
// were captured while the handler ran (see callHandler / Transaction.run).
|
|
11335
11224
|
_emitTransaction(transaction, root) {
|
|
11336
11225
|
if (this._observers.length === 0) return;
|
|
11337
|
-
if (transaction._resolvedHandler === void 0) return;
|
|
11338
11226
|
this._emitRecord(root, {
|
|
11339
11227
|
kind: transaction.observeKind,
|
|
11340
11228
|
name: transaction.observeName,
|
|
@@ -11348,33 +11236,29 @@ var Transactor = class {
|
|
|
11348
11236
|
parent: transaction.parentTransaction
|
|
11349
11237
|
});
|
|
11350
11238
|
}
|
|
11351
|
-
// Make `child` a tracked unit of `parent`'s subtree: the parent's completion stays open
|
|
11352
|
-
// until the child's *whole* subtree settles. Tracking happens at dispatch time — during
|
|
11353
|
-
// the parent's handler or afterTransaction — while the parent's self-unit is still held,
|
|
11354
|
-
// so the parent counter can't reach zero before the child is registered. Returns `child`.
|
|
11355
|
-
_link(child, parent) {
|
|
11356
|
-
if (parent) {
|
|
11357
|
-
const release = parent.completion.track();
|
|
11358
|
-
child.completion.whenSubtreeSettled().then(release);
|
|
11359
|
-
}
|
|
11360
|
-
return child;
|
|
11361
|
-
}
|
|
11362
11239
|
// `origin` is where the message came FROM, pinned now for the same reason an
|
|
11363
11240
|
// intent's answerPath is: a reply must reach the sender that asked even if a key
|
|
11364
11241
|
// moved while the message was in flight. Null when nobody is waiting — a host
|
|
11365
11242
|
// sendAtRoot or a view's own `@on.*` — and ctx.sendReply refuses on that.
|
|
11366
|
-
|
|
11367
|
-
|
|
11368
|
-
|
|
11243
|
+
//
|
|
11244
|
+
// The parent's subtree stays open until this message's whole subtree settles. The
|
|
11245
|
+
// unit is taken now, at dispatch — during the parent's handler or afterTransaction,
|
|
11246
|
+
// while the parent's self-unit is still held — so its counter can't reach zero first.
|
|
11247
|
+
pushSend(path2, name, args = [], parent = null, origin = null, txnPath = null) {
|
|
11248
|
+
const t = new SendEvent(path2, this, name, args, parent);
|
|
11249
|
+
t.txnPath = txnPath;
|
|
11250
|
+
t.origin = origin;
|
|
11251
|
+
t.originPinned = origin === null ? null : origin.toTransactionPath().pinKeys(this.state.val);
|
|
11369
11252
|
this.pushTransaction(t);
|
|
11370
|
-
|
|
11253
|
+
if (parent) t.completion.carry(parent.completion.track());
|
|
11254
|
+
return t;
|
|
11371
11255
|
}
|
|
11372
11256
|
// Raise an intent: a job the sender did not address, walked along a route until
|
|
11373
11257
|
// something answers. `opts.route` is a list of legs (see DEFAULT_ROUTE) and
|
|
11374
11258
|
// `opts.livePath` opts out of pinning the answer's destination keys.
|
|
11375
|
-
pushIntent(
|
|
11259
|
+
pushIntent(path2, name, args = [], opts = {}, parent = null) {
|
|
11376
11260
|
const release = parent ? parent.completion.track() : null;
|
|
11377
|
-
const walk = new IntentWalk(this,
|
|
11261
|
+
const walk = new IntentWalk(this, path2, name, args, opts, parent, release);
|
|
11378
11262
|
walk.advance();
|
|
11379
11263
|
return walk;
|
|
11380
11264
|
}
|
|
@@ -11391,7 +11275,7 @@ var Transactor = class {
|
|
|
11391
11275
|
return this.transactions.length > 0;
|
|
11392
11276
|
}
|
|
11393
11277
|
transactNext() {
|
|
11394
|
-
|
|
11278
|
+
this.transact(this.transactions.shift());
|
|
11395
11279
|
}
|
|
11396
11280
|
transact(transaction) {
|
|
11397
11281
|
try {
|
|
@@ -11404,20 +11288,31 @@ var Transactor = class {
|
|
|
11404
11288
|
} else console.warn("undefined new state", { curState, transaction });
|
|
11405
11289
|
} finally {
|
|
11406
11290
|
transaction.ensureWalkAdvanced?.();
|
|
11407
|
-
transaction._completion?.
|
|
11408
|
-
transaction._completion?.releaseSelf();
|
|
11291
|
+
transaction._completion?.finish();
|
|
11409
11292
|
}
|
|
11410
11293
|
}
|
|
11411
|
-
transactInputNow(
|
|
11412
|
-
this.transact(new InputEvent(
|
|
11294
|
+
transactInputNow(path2, event, eventHandler, dragInfo) {
|
|
11295
|
+
this.transact(new InputEvent(path2, event, eventHandler, this, dragInfo));
|
|
11413
11296
|
}
|
|
11414
11297
|
};
|
|
11415
11298
|
function nullHandler() {
|
|
11416
11299
|
return this;
|
|
11417
11300
|
}
|
|
11301
|
+
function subscribe(list, cb) {
|
|
11302
|
+
list.push(cb);
|
|
11303
|
+
return () => {
|
|
11304
|
+
const i = list.indexOf(cb);
|
|
11305
|
+
if (i !== -1) list.splice(i, 1);
|
|
11306
|
+
};
|
|
11307
|
+
}
|
|
11308
|
+
function warnUnknownLeg(what, leg) {
|
|
11309
|
+
console.warn(`unknown ${what} route leg`, leg, '- expected "dyn" or "lex"');
|
|
11310
|
+
return null;
|
|
11311
|
+
}
|
|
11418
11312
|
var Transaction = class {
|
|
11419
|
-
constructor(
|
|
11420
|
-
this.path =
|
|
11313
|
+
constructor(path2, transactor, parentTransaction = null) {
|
|
11314
|
+
this.path = path2;
|
|
11315
|
+
this.txnPath = null;
|
|
11421
11316
|
this.transactor = transactor;
|
|
11422
11317
|
this.parentTransaction = parentTransaction;
|
|
11423
11318
|
this._completion = null;
|
|
@@ -11437,39 +11332,41 @@ var Transaction = class {
|
|
|
11437
11332
|
whenSubtreeSettled() {
|
|
11438
11333
|
return this.completion.whenSubtreeSettled();
|
|
11439
11334
|
}
|
|
11440
|
-
|
|
11441
|
-
|
|
11442
|
-
//
|
|
11443
|
-
// rather than throwing, so a stray call from the wrong place is a message and not a
|
|
11444
|
-
// crash. `walk` is undefined here, which is how ctx.reply/ctx.fail tell the two apart.
|
|
11445
|
-
stop() {
|
|
11446
|
-
warnNotIntent("stop");
|
|
11447
|
-
}
|
|
11448
|
-
forward(_opts) {
|
|
11449
|
-
console.warn('ctx.forward() needs a "receive" or "intent" handler - ignored');
|
|
11450
|
-
}
|
|
11451
|
-
// The kind reported to observers (see Transactor.observe); null on the base.
|
|
11452
|
-
get observeKind() {
|
|
11453
|
-
return null;
|
|
11454
|
-
}
|
|
11455
|
-
// The name reported to observers; null on the base. Overridden by NameArgs (the
|
|
11456
|
-
// dispatched message name) and InputEvent (the DOM event type). Kept separate from
|
|
11457
|
-
// `name`/`ctx.name` so it can't change handler-visible behavior.
|
|
11458
|
-
get observeName() {
|
|
11459
|
-
return null;
|
|
11460
|
-
}
|
|
11335
|
+
// Every transaction kind defines `observeKind` / `observeName` (what observers see;
|
|
11336
|
+
// kept apart from `name`/`ctx.name` so they can't change handler-visible behavior),
|
|
11337
|
+
// `getHandlerAndArgs(root, instance, comps)`, and the three `_forward*` hooks below.
|
|
11461
11338
|
callHandler(root, instance, draft, comps) {
|
|
11462
11339
|
const [handler, args] = this.getHandlerAndArgs(root, instance, comps);
|
|
11463
11340
|
this._resolvedHandler = handler;
|
|
11464
11341
|
return handler.apply(instance, [draft, ...args]);
|
|
11465
11342
|
}
|
|
11466
|
-
|
|
11467
|
-
|
|
11343
|
+
// `forward` is where a name can LEAVE the component: the message being handled is
|
|
11344
|
+
// raised again as an INTENT under the same name (`_forwardName()`) with the same
|
|
11345
|
+
// arguments unless `opts.args` says otherwise, from the position `_forwardPath()`
|
|
11346
|
+
// names. Deferred to afterTransaction so the state the handler produced is in place
|
|
11347
|
+
// before the walk starts. (`IntentEvent` overrides both: in an intent body, forward
|
|
11348
|
+
// amends the walk that is already running.)
|
|
11349
|
+
forward(opts) {
|
|
11350
|
+
this._forward = opts ?? {};
|
|
11351
|
+
}
|
|
11352
|
+
afterTransaction() {
|
|
11353
|
+
const f = this._forward;
|
|
11354
|
+
if (f === void 0) return;
|
|
11355
|
+
this._forward = void 0;
|
|
11356
|
+
const name = this._forwardName();
|
|
11357
|
+
if (name === void 0) {
|
|
11358
|
+
this.transactor.refuse("FORWARD_NO_NAME", {});
|
|
11359
|
+
return;
|
|
11360
|
+
}
|
|
11361
|
+
const { args = this._forwardArgs(), ...rest } = f;
|
|
11362
|
+
this.transactor.pushIntent(this._forwardPath(), name, args, rest, this);
|
|
11468
11363
|
}
|
|
11469
|
-
// The path used to apply the mutation
|
|
11470
|
-
//
|
|
11364
|
+
// The path used to apply the mutation: the ACTIVE frame of the dispatch path, so
|
|
11365
|
+
// an event inside a `<x render="*name">` subtree updates the value where it
|
|
11366
|
+
// really lives (the dispatch `this.path` keeps the visual callers, for bubbling).
|
|
11367
|
+
// `txnPath`, when pinned by the sender, wins.
|
|
11471
11368
|
getTransactionPath() {
|
|
11472
|
-
return this.path.toTransactionPath()
|
|
11369
|
+
return this.txnPath ?? this.path.toTransactionPath();
|
|
11473
11370
|
}
|
|
11474
11371
|
run(curRoot, comps) {
|
|
11475
11372
|
const txnPath = this.getTransactionPath();
|
|
@@ -11486,19 +11383,27 @@ var Transaction = class {
|
|
|
11486
11383
|
}
|
|
11487
11384
|
};
|
|
11488
11385
|
var InputEvent = class extends Transaction {
|
|
11489
|
-
constructor(
|
|
11490
|
-
super(
|
|
11386
|
+
constructor(path2, e, handler, transactor, dragInfo) {
|
|
11387
|
+
super(path2, transactor);
|
|
11491
11388
|
this.e = e;
|
|
11492
11389
|
this.handler = handler;
|
|
11493
11390
|
this.dragInfo = dragInfo;
|
|
11494
11391
|
this._dispatchPath = null;
|
|
11495
11392
|
}
|
|
11496
|
-
// Frame steps removed,
|
|
11497
|
-
//
|
|
11393
|
+
// Frame-only steps removed, one step per crossed component kept — inside every
|
|
11394
|
+
// continuation frame independently, so bubbling it visits every component and
|
|
11395
|
+
// then returns to the caller that wrote the `*name`.
|
|
11498
11396
|
get dispatchPath() {
|
|
11499
11397
|
this._dispatchPath ??= this.path.compact();
|
|
11500
11398
|
return this._dispatchPath;
|
|
11501
11399
|
}
|
|
11400
|
+
// Only a DOM event's path carries frame-only bind steps (they replay the handler's
|
|
11401
|
+
// arguments, but address no state); the compacted path is where the mutation lands,
|
|
11402
|
+
// so a handler inside @each still updates the component that owns the view. Every
|
|
11403
|
+
// other transaction is dispatched at an already-compacted position.
|
|
11404
|
+
getTransactionPath() {
|
|
11405
|
+
return this.dispatchPath.toTransactionPath();
|
|
11406
|
+
}
|
|
11502
11407
|
// A DOM event is an ADDRESSED message like any other — it reaches the component that
|
|
11503
11408
|
// owns the view and stops. It keeps its own class only because it resolves its handler
|
|
11504
11409
|
// from the compiled view and runs synchronously, not because it is a different channel.
|
|
@@ -11508,47 +11413,36 @@ var InputEvent = class extends Transaction {
|
|
|
11508
11413
|
get observeName() {
|
|
11509
11414
|
return this.e?.type ?? null;
|
|
11510
11415
|
}
|
|
11511
|
-
// A view's name is a message
|
|
11512
|
-
//
|
|
11513
|
-
//
|
|
11514
|
-
//
|
|
11515
|
-
|
|
11516
|
-
|
|
11517
|
-
}
|
|
11518
|
-
afterTransaction() {
|
|
11519
|
-
const f = this._forward;
|
|
11520
|
-
if (f === void 0) return;
|
|
11521
|
-
this._forward = void 0;
|
|
11522
|
-
const { args = this._handlerArgs ?? [], ...rest } = f;
|
|
11416
|
+
// A view's name is a message, and forwarding it means a view that says
|
|
11417
|
+
// `@on.click="saveDraft .text"` never has to change when an ancestor takes the job
|
|
11418
|
+
// over. (A `$method` handler has a name too, so forwarding one raises an intent under
|
|
11419
|
+
// it.) `handler` is a NodeEvent, whose own `name` is the DOM event type; the MESSAGE
|
|
11420
|
+
// name is the one the view wrote, on the handler call it wraps.
|
|
11421
|
+
_forwardName() {
|
|
11523
11422
|
const hv = this.handler?.handlerCall?.handlerVal ?? this.handler?.handlerVal;
|
|
11524
|
-
|
|
11525
|
-
|
|
11526
|
-
|
|
11527
|
-
|
|
11528
|
-
|
|
11529
|
-
|
|
11423
|
+
return hv?.name;
|
|
11424
|
+
}
|
|
11425
|
+
_forwardArgs() {
|
|
11426
|
+
return this._handlerArgs ?? [];
|
|
11427
|
+
}
|
|
11428
|
+
_forwardPath() {
|
|
11429
|
+
return this.dispatchPath;
|
|
11530
11430
|
}
|
|
11531
11431
|
getHandlerAndArgs(root, _instance, comps) {
|
|
11532
|
-
const stack = this.path.
|
|
11432
|
+
const stack = this.path.buildStack(Stack.root(comps, root, this));
|
|
11533
11433
|
const [handler, args] = this.handler.getHandlerAndArgs(stack, this);
|
|
11534
11434
|
this._handlerArgs = [...args];
|
|
11535
|
-
const
|
|
11536
|
-
args.push(new EventContext(
|
|
11435
|
+
const path2 = this.dispatchPath;
|
|
11436
|
+
args.push(new EventContext(path2, this.transactor, this));
|
|
11537
11437
|
return [handler, args];
|
|
11538
11438
|
}
|
|
11539
|
-
// The dispatched DOM event, read only through `e.<member>` handler args
|
|
11540
|
-
// (src/value.js EventMemberVal via Stack.lookupEvent). There is no bare
|
|
11541
|
-
// implicit-name vocabulary anymore: every arg carries a sigil.
|
|
11542
|
-
get event() {
|
|
11543
|
-
return this.e;
|
|
11544
|
-
}
|
|
11545
11439
|
};
|
|
11546
11440
|
var NameArgsTransaction = class extends Transaction {
|
|
11547
|
-
constructor(
|
|
11548
|
-
super(
|
|
11441
|
+
constructor(path2, transactor, name, args, parentTransaction) {
|
|
11442
|
+
super(path2, transactor, parentTransaction);
|
|
11549
11443
|
this.name = name;
|
|
11550
11444
|
this.args = args;
|
|
11551
|
-
this.targetPath =
|
|
11445
|
+
this.targetPath = path2;
|
|
11552
11446
|
}
|
|
11553
11447
|
handlerProp = null;
|
|
11554
11448
|
// NameArgs verbs map their handler bucket straight to the observed kind:
|
|
@@ -11559,6 +11453,17 @@ var NameArgsTransaction = class extends Transaction {
|
|
|
11559
11453
|
get observeName() {
|
|
11560
11454
|
return this.name;
|
|
11561
11455
|
}
|
|
11456
|
+
// `forward` in a RECEIVE body starts a walk: the message that arrived becomes an
|
|
11457
|
+
// intent, keeping its name and payload.
|
|
11458
|
+
_forwardName() {
|
|
11459
|
+
return this.name;
|
|
11460
|
+
}
|
|
11461
|
+
_forwardArgs() {
|
|
11462
|
+
return this.args;
|
|
11463
|
+
}
|
|
11464
|
+
_forwardPath() {
|
|
11465
|
+
return this.path;
|
|
11466
|
+
}
|
|
11562
11467
|
getHandlerForName(comp) {
|
|
11563
11468
|
const handlers = comp?.[this.handlerProp];
|
|
11564
11469
|
const exact = handlers?.[this.name];
|
|
@@ -11589,24 +11494,11 @@ var SendEvent = class extends NameArgsTransaction {
|
|
|
11589
11494
|
get observeKind() {
|
|
11590
11495
|
return this._isAnswer ? "answer" : "receive";
|
|
11591
11496
|
}
|
|
11592
|
-
// `forward` in a RECEIVE body starts a walk: the message that arrived becomes an
|
|
11593
|
-
// intent, keeping its name and payload. This is what lets a view's name leave the
|
|
11594
|
-
// component without the view changing.
|
|
11595
|
-
forward(opts) {
|
|
11596
|
-
this._forward = opts ?? {};
|
|
11597
|
-
}
|
|
11598
|
-
afterTransaction() {
|
|
11599
|
-
const f = this._forward;
|
|
11600
|
-
if (f === void 0) return;
|
|
11601
|
-
this._forward = void 0;
|
|
11602
|
-
const { args = this.args, ...rest } = f;
|
|
11603
|
-
this.transactor.pushIntent(this.path, this.name, args, rest, this);
|
|
11604
|
-
}
|
|
11605
11497
|
};
|
|
11606
11498
|
var IntentEvent = class extends NameArgsTransaction {
|
|
11607
11499
|
handlerProp = "intent";
|
|
11608
|
-
constructor(
|
|
11609
|
-
super(
|
|
11500
|
+
constructor(path2, transactor, walk) {
|
|
11501
|
+
super(path2, transactor, walk.name, walk.args, walk.parent);
|
|
11610
11502
|
this.walk = walk;
|
|
11611
11503
|
this.targetPath = walk.origin;
|
|
11612
11504
|
}
|
|
@@ -11615,9 +11507,6 @@ var IntentEvent = class extends NameArgsTransaction {
|
|
|
11615
11507
|
forward(opts) {
|
|
11616
11508
|
this.walk.amend(opts, this.path);
|
|
11617
11509
|
}
|
|
11618
|
-
stop() {
|
|
11619
|
-
this.walk.finish(null, null);
|
|
11620
|
-
}
|
|
11621
11510
|
afterTransaction() {
|
|
11622
11511
|
this.ensureWalkAdvanced();
|
|
11623
11512
|
}
|
|
@@ -11633,17 +11522,17 @@ var PASS = /* @__PURE__ */ Symbol.for("tutuca.intent.pass");
|
|
|
11633
11522
|
var REFUSAL_RING_CAP = 200;
|
|
11634
11523
|
var INTENT_DEPTH = 64;
|
|
11635
11524
|
var IntentWalk = class {
|
|
11636
|
-
constructor(transactor,
|
|
11525
|
+
constructor(transactor, path2, name, args, opts, parent, release) {
|
|
11637
11526
|
this.transactor = transactor;
|
|
11638
11527
|
this.name = name;
|
|
11639
11528
|
this.args = args;
|
|
11640
11529
|
this.route = opts?.route ?? DEFAULT_ROUTE;
|
|
11641
11530
|
this.parent = parent;
|
|
11642
11531
|
this.release = release;
|
|
11643
|
-
this.origin =
|
|
11644
|
-
this.answerPath = opts?.livePath ? null :
|
|
11532
|
+
this.origin = path2;
|
|
11533
|
+
this.answerPath = opts?.livePath ? null : path2.toTransactionPath().pinKeys(transactor.state.val);
|
|
11645
11534
|
this.legIndex = 0;
|
|
11646
|
-
this.dynAt =
|
|
11535
|
+
this.dynAt = path2;
|
|
11647
11536
|
this.hops = 0;
|
|
11648
11537
|
this.ended = false;
|
|
11649
11538
|
}
|
|
@@ -11655,7 +11544,7 @@ var IntentWalk = class {
|
|
|
11655
11544
|
while (this.legIndex < this.route.length) {
|
|
11656
11545
|
const leg = this.route[this.legIndex];
|
|
11657
11546
|
if (leg === "dyn") {
|
|
11658
|
-
if (this.dynAt.
|
|
11547
|
+
if (!this.dynAt.canPop()) {
|
|
11659
11548
|
this.legIndex++;
|
|
11660
11549
|
continue;
|
|
11661
11550
|
}
|
|
@@ -11667,7 +11556,7 @@ var IntentWalk = class {
|
|
|
11667
11556
|
this.legIndex++;
|
|
11668
11557
|
return this._tryLex();
|
|
11669
11558
|
}
|
|
11670
|
-
|
|
11559
|
+
warnUnknownLeg("intent", leg);
|
|
11671
11560
|
this.legIndex++;
|
|
11672
11561
|
}
|
|
11673
11562
|
this.exhaust("noHandler");
|
|
@@ -11752,11 +11641,11 @@ var IntentWalk = class {
|
|
|
11752
11641
|
if (this.ended) return;
|
|
11753
11642
|
this.ended = true;
|
|
11754
11643
|
if (name === null) return this.release?.();
|
|
11755
|
-
const
|
|
11756
|
-
|
|
11644
|
+
const t = new SendEvent(this.origin, this.transactor, name, args, this.parent);
|
|
11645
|
+
t.txnPath = this.answerPath;
|
|
11757
11646
|
t._isAnswer = true;
|
|
11758
11647
|
this.transactor.pushTransaction(t);
|
|
11759
|
-
if (this.release) t.completion.
|
|
11648
|
+
if (this.release) t.completion.carry(this.release);
|
|
11760
11649
|
}
|
|
11761
11650
|
};
|
|
11762
11651
|
var Completion = class {
|
|
@@ -11764,12 +11653,12 @@ var Completion = class {
|
|
|
11764
11653
|
this.val = void 0;
|
|
11765
11654
|
this.selfSettled = false;
|
|
11766
11655
|
this.subtreeSettled = false;
|
|
11767
|
-
this.pending =
|
|
11656
|
+
this.pending = 0;
|
|
11768
11657
|
this._selfResolve = null;
|
|
11769
11658
|
this._selfPromise = null;
|
|
11770
11659
|
this._subtreeResolve = null;
|
|
11771
11660
|
this._subtreePromise = null;
|
|
11772
|
-
this.
|
|
11661
|
+
this._releaseSelf = this.track();
|
|
11773
11662
|
}
|
|
11774
11663
|
whenSettled() {
|
|
11775
11664
|
if (this.selfSettled) return Promise.resolve(this.val);
|
|
@@ -11792,38 +11681,38 @@ var Completion = class {
|
|
|
11792
11681
|
this.val = val;
|
|
11793
11682
|
this._selfResolve?.(val);
|
|
11794
11683
|
}
|
|
11795
|
-
//
|
|
11796
|
-
|
|
11797
|
-
|
|
11684
|
+
// The transaction is done processing: self is settled (with the value the handler
|
|
11685
|
+
// produced, or none on the undefined-state / throw paths) and the self-unit goes.
|
|
11686
|
+
finish() {
|
|
11687
|
+
this.markSelfSettled(this.val);
|
|
11688
|
+
this._releaseSelf();
|
|
11798
11689
|
}
|
|
11799
|
-
// Register an outstanding unit; returns
|
|
11690
|
+
// Register an outstanding unit; returns its one-shot release. The subtree settles
|
|
11691
|
+
// when the last unit is released.
|
|
11800
11692
|
track() {
|
|
11801
11693
|
this.pending++;
|
|
11802
11694
|
let done = false;
|
|
11803
11695
|
return () => {
|
|
11804
11696
|
if (done) return;
|
|
11805
11697
|
done = true;
|
|
11806
|
-
this.
|
|
11698
|
+
if (--this.pending === 0) {
|
|
11699
|
+
this.subtreeSettled = true;
|
|
11700
|
+
this._subtreeResolve?.(this.val);
|
|
11701
|
+
}
|
|
11807
11702
|
};
|
|
11808
11703
|
}
|
|
11809
|
-
|
|
11810
|
-
|
|
11811
|
-
|
|
11812
|
-
this.
|
|
11813
|
-
}
|
|
11814
|
-
_release() {
|
|
11815
|
-
if (--this.pending === 0) {
|
|
11816
|
-
this.subtreeSettled = true;
|
|
11817
|
-
this._subtreeResolve?.(this.val);
|
|
11818
|
-
}
|
|
11704
|
+
// Hand a unit held elsewhere to this subtree: `release` runs once this transaction
|
|
11705
|
+
// and everything it spawned have settled.
|
|
11706
|
+
carry(release) {
|
|
11707
|
+
this.whenSubtreeSettled().then(release);
|
|
11819
11708
|
}
|
|
11820
11709
|
};
|
|
11821
11710
|
var Dispatcher = class {
|
|
11822
|
-
constructor(
|
|
11823
|
-
this.path =
|
|
11711
|
+
constructor(path2, transactor, parentTransaction) {
|
|
11712
|
+
this.path = path2;
|
|
11824
11713
|
this.transactor = transactor;
|
|
11825
11714
|
this.parent = parentTransaction;
|
|
11826
|
-
this.root =
|
|
11715
|
+
this.root = transactor.state.val;
|
|
11827
11716
|
}
|
|
11828
11717
|
// Walk the component instances on this ctx's path, leaf→root, calling
|
|
11829
11718
|
// callback(Component, instance). Return false from the callback to stop early.
|
|
@@ -11848,28 +11737,37 @@ var Dispatcher = class {
|
|
|
11848
11737
|
// replayed; provides are pushed on every component frame either way, so a provide
|
|
11849
11738
|
// that reads a loop binding is the one case this cannot reproduce faithfully.
|
|
11850
11739
|
_stack() {
|
|
11851
|
-
this._stackMemo ??= this.path.
|
|
11740
|
+
this._stackMemo ??= this.path.buildStack(
|
|
11741
|
+
Stack.root(this.transactor.comps, this.root, this.parent)
|
|
11742
|
+
);
|
|
11852
11743
|
return this._stackMemo;
|
|
11853
11744
|
}
|
|
11854
11745
|
// Resolve a name the way the renderer would. `opts.route` takes the same legs in
|
|
11855
11746
|
// the same spelling as `ctx.intent` — `["dyn"]` the render ancestry, `["lex"]` the
|
|
11856
11747
|
// registration scope, default both.
|
|
11748
|
+
// Legs are tried in route order, like the intent walker's; an unknown leg warns and
|
|
11749
|
+
// is skipped, and an empty route resolves to null.
|
|
11857
11750
|
lookup(name, opts) {
|
|
11858
|
-
|
|
11859
|
-
|
|
11860
|
-
()
|
|
11861
|
-
|
|
11862
|
-
|
|
11751
|
+
for (const leg of opts?.route ?? DEFAULT_ROUTE) {
|
|
11752
|
+
const v = leg === "dyn" ? this._stack()?.lookupDynamic(name) ?? null : leg === "lex" ? this._lookupLex(name) : warnUnknownLeg("lookup", leg);
|
|
11753
|
+
if (v != null) return v;
|
|
11754
|
+
}
|
|
11755
|
+
return null;
|
|
11863
11756
|
}
|
|
11864
11757
|
// The `lex` leg without a Stack: the scope of the component whose handler is
|
|
11865
|
-
// running, which is the leaf of this ctx's path.
|
|
11758
|
+
// running, which is the leaf of this ctx's path. A type name resolves to the
|
|
11759
|
+
// component registered under it; a value name to a path registered under it
|
|
11760
|
+
// (see ComponentStack.registerPaths), read against the current root.
|
|
11866
11761
|
_lookupLex(name) {
|
|
11867
11762
|
let Comp = null;
|
|
11868
11763
|
this.walkPath((c) => {
|
|
11869
11764
|
Comp = c;
|
|
11870
11765
|
return false;
|
|
11871
11766
|
});
|
|
11872
|
-
|
|
11767
|
+
const scope = Comp?.scope;
|
|
11768
|
+
if (scope == null) return null;
|
|
11769
|
+
if (isTypeName(name)) return scope.lookupComponent(name) ?? null;
|
|
11770
|
+
return scope.lookupPath(name)?.lookup(this.root) ?? null;
|
|
11873
11771
|
}
|
|
11874
11772
|
// A component lookup is a value lookup constrained to a component. The `lex` leg
|
|
11875
11773
|
// can only ever answer with one; the `dyn` leg reads a binding an ancestor
|
|
@@ -11891,8 +11789,8 @@ var Dispatcher = class {
|
|
|
11891
11789
|
send(name, args) {
|
|
11892
11790
|
return this.sendAtPath(this.path, name, args);
|
|
11893
11791
|
}
|
|
11894
|
-
sendAtPath(
|
|
11895
|
-
return this.transactor.pushSend(
|
|
11792
|
+
sendAtPath(path2, name, args) {
|
|
11793
|
+
return this.transactor.pushSend(path2, name, args, this.parent, this.path);
|
|
11896
11794
|
}
|
|
11897
11795
|
// An intent is ROUTED: it names a job and walks until something answers. The verb
|
|
11898
11796
|
// does not decide which scope answers — `opts.route` does, written here at the call
|
|
@@ -11900,8 +11798,8 @@ var Dispatcher = class {
|
|
|
11900
11798
|
intent(name, args, opts) {
|
|
11901
11799
|
return this.intentAtPath(this.path, name, args, opts);
|
|
11902
11800
|
}
|
|
11903
|
-
intentAtPath(
|
|
11904
|
-
return this.transactor.pushIntent(
|
|
11801
|
+
intentAtPath(path2, name, args, opts) {
|
|
11802
|
+
return this.transactor.pushIntent(path2, name, args, opts, this.parent);
|
|
11905
11803
|
}
|
|
11906
11804
|
};
|
|
11907
11805
|
var EventContext = class extends Dispatcher {
|
|
@@ -11930,11 +11828,19 @@ var EventContext = class extends Dispatcher {
|
|
|
11930
11828
|
this.transactor.refuse("NO_SENDER", { name });
|
|
11931
11829
|
return null;
|
|
11932
11830
|
}
|
|
11933
|
-
return this.
|
|
11831
|
+
return this.transactor.pushSend(
|
|
11832
|
+
origin,
|
|
11833
|
+
name,
|
|
11834
|
+
args,
|
|
11835
|
+
this.parent,
|
|
11836
|
+
this.path,
|
|
11837
|
+
this.parent.originPinned
|
|
11838
|
+
);
|
|
11934
11839
|
}
|
|
11935
|
-
// End the walk answering nothing — "served, and no answer".
|
|
11840
|
+
// End the walk answering nothing — "served, and no answer". Like reply/fail,
|
|
11841
|
+
// legal only in an `intent` handler.
|
|
11936
11842
|
stop() {
|
|
11937
|
-
return this.parent.stop();
|
|
11843
|
+
return this.parent.walk === void 0 ? warnNotIntent("stop") : this.parent.walk.finish(null, null);
|
|
11938
11844
|
}
|
|
11939
11845
|
// From an `intent` body: hand the intent to the next hop, optionally amending it.
|
|
11940
11846
|
// From a `receive` body: turn the message that arrived into an intent. One word from
|
|
@@ -11962,13 +11868,13 @@ var PathChanges = class extends PathBuilder {
|
|
|
11962
11868
|
}
|
|
11963
11869
|
};
|
|
11964
11870
|
function rootDispatcher(transactor) {
|
|
11965
|
-
return new Dispatcher(new
|
|
11871
|
+
return new Dispatcher(new DispatchPath(), transactor, null);
|
|
11966
11872
|
}
|
|
11967
11873
|
|
|
11968
11874
|
// tools/core/results.js
|
|
11969
11875
|
var ModuleInfo = class {
|
|
11970
|
-
constructor({ path = null, present = /* @__PURE__ */ new Set(), counts = {}, warnings = [] }) {
|
|
11971
|
-
this.path =
|
|
11876
|
+
constructor({ path: path2 = null, present = /* @__PURE__ */ new Set(), counts = {}, warnings = [] }) {
|
|
11877
|
+
this.path = path2;
|
|
11972
11878
|
this.present = present;
|
|
11973
11879
|
this.counts = counts;
|
|
11974
11880
|
this.warnings = warnings;
|
|
@@ -12078,8 +11984,8 @@ var DescribeResult = class {
|
|
|
12078
11984
|
}
|
|
12079
11985
|
};
|
|
12080
11986
|
var ModuleTestReport = class {
|
|
12081
|
-
constructor({ path = null, suites = [], counts = { pass: 0, fail: 0, skip: 0, total: 0 } }) {
|
|
12082
|
-
this.path =
|
|
11987
|
+
constructor({ path: path2 = null, suites = [], counts = { pass: 0, fail: 0, skip: 0, total: 0 } }) {
|
|
11988
|
+
this.path = path2;
|
|
12083
11989
|
this.suites = suites;
|
|
12084
11990
|
this.counts = counts;
|
|
12085
11991
|
}
|
|
@@ -12122,8 +12028,8 @@ var Test = class {
|
|
|
12122
12028
|
}
|
|
12123
12029
|
};
|
|
12124
12030
|
var ModuleTests = class {
|
|
12125
|
-
constructor({ path = null, suites = [] } = {}) {
|
|
12126
|
-
this.path =
|
|
12031
|
+
constructor({ path: path2 = null, suites = [] } = {}) {
|
|
12032
|
+
this.path = path2;
|
|
12127
12033
|
this.suites = suites;
|
|
12128
12034
|
}
|
|
12129
12035
|
};
|
|
@@ -12145,8 +12051,8 @@ function titleFromArg(arg) {
|
|
|
12145
12051
|
if (typeof arg === "function") return arg.name || "(anonymous)";
|
|
12146
12052
|
return String(arg);
|
|
12147
12053
|
}
|
|
12148
|
-
function makeCollector({ path = null, components = [] } = {}) {
|
|
12149
|
-
const moduleTests = new ModuleTests({ path, suites: [] });
|
|
12054
|
+
function makeCollector({ path: path2 = null, components = [] } = {}) {
|
|
12055
|
+
const moduleTests = new ModuleTests({ path: path2, suites: [] });
|
|
12150
12056
|
const stack = [];
|
|
12151
12057
|
function describe(...args) {
|
|
12152
12058
|
let head;
|
|
@@ -12247,7 +12153,7 @@ async function driveStack(stack, value, phase, opts = {}) {
|
|
|
12247
12153
|
val
|
|
12248
12154
|
);
|
|
12249
12155
|
});
|
|
12250
|
-
dispatchPhase(rootDispatcher(transactor), new
|
|
12156
|
+
dispatchPhase(rootDispatcher(transactor), new DispatchPath(), phase, value);
|
|
12251
12157
|
await transactor.settle();
|
|
12252
12158
|
return transactor.state.val;
|
|
12253
12159
|
}
|
|
@@ -12257,7 +12163,7 @@ async function drive(cfg, value, phase, opts = {}) {
|
|
|
12257
12163
|
async function runTests({
|
|
12258
12164
|
getTests,
|
|
12259
12165
|
components = [],
|
|
12260
|
-
path = null,
|
|
12166
|
+
path: path2 = null,
|
|
12261
12167
|
expect: expect2,
|
|
12262
12168
|
name = null,
|
|
12263
12169
|
grep = null,
|
|
@@ -12268,13 +12174,13 @@ async function runTests({
|
|
|
12268
12174
|
const counts = { pass: 0, fail: 0, skip: 0, total: 0 };
|
|
12269
12175
|
if (typeof getTests !== "function") {
|
|
12270
12176
|
return new TestReport({
|
|
12271
|
-
modules: [new ModuleTestReport({ path, suites: [], counts })]
|
|
12177
|
+
modules: [new ModuleTestReport({ path: path2, suites: [], counts })]
|
|
12272
12178
|
});
|
|
12273
12179
|
}
|
|
12274
12180
|
if (typeof expect2 !== "function") {
|
|
12275
12181
|
throw new Error("runTests: expect must be provided (e.g. chai's expect)");
|
|
12276
12182
|
}
|
|
12277
|
-
const { describe, test: test3, moduleTests } = makeCollector({ path, components });
|
|
12183
|
+
const { describe, test: test3, moduleTests } = makeCollector({ path: path2, components });
|
|
12278
12184
|
let _stack = null;
|
|
12279
12185
|
const getStack = () => _stack ??= buildStack({ components, macros, intentHandlers });
|
|
12280
12186
|
const driveLocal = (value, phase, opts = {}) => driveStack(getStack(), value, phase, opts);
|
|
@@ -12337,7 +12243,7 @@ async function runTests({
|
|
|
12337
12243
|
if (r !== null) suiteResults.push(r);
|
|
12338
12244
|
}
|
|
12339
12245
|
return new TestReport({
|
|
12340
|
-
modules: [new ModuleTestReport({ path, suites: suiteResults, counts })]
|
|
12246
|
+
modules: [new ModuleTestReport({ path: path2, suites: suiteResults, counts })]
|
|
12341
12247
|
});
|
|
12342
12248
|
}
|
|
12343
12249
|
|
|
@@ -12506,19 +12412,19 @@ function lintIdToMessage(id, info) {
|
|
|
12506
12412
|
case "DYN_ALIAS_NOT_REFERENCED":
|
|
12507
12413
|
return `Lookup '${info.name}' is defined but never used — remove it or reference it as '*${info.name}' in a view`;
|
|
12508
12414
|
case "PROVIDE_NOT_ADDRESSABLE":
|
|
12509
|
-
return `Provide '${info.name}' value '${info.value}' must be a field ('.f') or seq-access ('.s[.k]') — a
|
|
12415
|
+
return `Provide '${info.name}' value '${info.value}' must be a field ('.f') or seq-access ('.s[.k]') — a provide doubles as the path '<x render="*${info.name}">' resumes at, so this one is dropped and '*${info.name}' resolves to nothing`;
|
|
12510
12416
|
case "LOOKUP_BAD_SHAPE":
|
|
12511
12417
|
return `Lookup '${info.name}' has an invalid shape: ${info.problem}`;
|
|
12512
12418
|
case "LOOKUP_NO_PROVIDER":
|
|
12513
|
-
return info.hasDefault ? `Lookup '${info.name}' is provided by no component in scope, so it always resolves to its default` : `Lookup '${info.name}' is provided by no component in scope — add a 'provide' for it, or give this lookup a default`;
|
|
12419
|
+
return info.hasDefault ? `Lookup '${info.name}' is provided by no component in scope and matches no registered path, so it always resolves to its default` : `Lookup '${info.name}' is provided by no component in scope and matches no registered path — add a 'provide' for it, register a path under that name, or give this lookup a default`;
|
|
12514
12420
|
case "PROVIDE_TYPE_BAD_SHAPE":
|
|
12515
12421
|
return `Provide '${info.name}' starts uppercase, so it publishes a component type — its value must be 'self', not '${info.value}'`;
|
|
12516
|
-
case "PROVIDE_NAME_COLLISION":
|
|
12517
|
-
return `Provide '${info.name}' is also provided by '${info.other}' in the same scope — one name, one provider, so a lookup can find it`;
|
|
12518
12422
|
case "UNKNOWN_MACRO_ARG":
|
|
12519
12423
|
return `Argument '${info.name}' is not declared in macro '${info.macroName}'`;
|
|
12520
12424
|
case "UNKNOWN_DIRECTIVE":
|
|
12521
12425
|
return `Unknown directive '@${info.name}=${JSON.stringify(info.value)}'${fmtTagSuffix(info)}`;
|
|
12426
|
+
case "ORPHAN_DIRECTIVE":
|
|
12427
|
+
return `'@${info.name}=${JSON.stringify(info.value)}' needs an '@${info.needs}' on the same element — it was ignored${fmtTagSuffix(info)}`;
|
|
12522
12428
|
case "UNKNOWN_X_OP":
|
|
12523
12429
|
return `Unknown <x> op '${info.name}=${JSON.stringify(info.value)}'${fmtTagSuffix(info)}`;
|
|
12524
12430
|
case "UNKNOWN_X_ATTR":
|
|
@@ -12652,7 +12558,6 @@ var App = class {
|
|
|
12652
12558
|
this.transactor = new Transactor(comps, null);
|
|
12653
12559
|
this.ParseContext = ParseContext2;
|
|
12654
12560
|
this.renderer = renderer;
|
|
12655
|
-
this.maxEventNodeDepth = Infinity;
|
|
12656
12561
|
this._transactNextBatchId = this._evictCacheId = null;
|
|
12657
12562
|
this._eventNames = new Set(_evs);
|
|
12658
12563
|
this.dragInfo = this.curDragOver = null;
|
|
@@ -12679,18 +12584,17 @@ var App = class {
|
|
|
12679
12584
|
_dispatchEvent(e) {
|
|
12680
12585
|
const { type: type3 } = e;
|
|
12681
12586
|
const isDrag = type3 === "dragover" || type3 === "dragstart" || type3 === "dragend" || type3 === "drop";
|
|
12682
|
-
const { rootNode
|
|
12683
|
-
const [
|
|
12587
|
+
const { rootNode, comps, transactor } = this;
|
|
12588
|
+
const [path2, handlers] = DispatchPath.fromNodeAndEventName(
|
|
12684
12589
|
e.target,
|
|
12685
12590
|
type3,
|
|
12686
|
-
|
|
12687
|
-
maxDepth,
|
|
12591
|
+
rootNode,
|
|
12688
12592
|
comps,
|
|
12689
12593
|
!isDrag
|
|
12690
12594
|
);
|
|
12691
|
-
if (isDrag) this._handleDragEvent(e, type3,
|
|
12692
|
-
if (
|
|
12693
|
-
for (const handler of handlers) transactor.transactInputNow(
|
|
12595
|
+
if (isDrag) this._handleDragEvent(e, type3, path2);
|
|
12596
|
+
if (path2 !== null && handlers !== null)
|
|
12597
|
+
for (const handler of handlers) transactor.transactInputNow(path2, e, handler, this.dragInfo);
|
|
12694
12598
|
}
|
|
12695
12599
|
_handleTouchEvent(e) {
|
|
12696
12600
|
const { type: type3 } = e;
|
|
@@ -12733,7 +12637,7 @@ var App = class {
|
|
|
12733
12637
|
this._touch = null;
|
|
12734
12638
|
}
|
|
12735
12639
|
}
|
|
12736
|
-
_handleDragEvent(e, type3,
|
|
12640
|
+
_handleDragEvent(e, type3, path2) {
|
|
12737
12641
|
if (type3 === "dragover") {
|
|
12738
12642
|
const dropTarget = getClosestDropTarget(e.target, this.rootNode, Infinity);
|
|
12739
12643
|
if (dropTarget !== null) {
|
|
@@ -12745,10 +12649,10 @@ var App = class {
|
|
|
12745
12649
|
} else if (type3 === "dragstart") {
|
|
12746
12650
|
e.target.dataset.dragging = 1;
|
|
12747
12651
|
const rootValue = this.state.val;
|
|
12748
|
-
const txnPath =
|
|
12652
|
+
const txnPath = path2.compact().toTransactionPath();
|
|
12749
12653
|
const value = txnPath.lookup(rootValue);
|
|
12750
12654
|
const dragType = e.target.dataset.dragtype ?? "?";
|
|
12751
|
-
const stack =
|
|
12655
|
+
const stack = path2.buildStack(this.makeStack(rootValue));
|
|
12752
12656
|
this.dragInfo = new DragInfo(stack, value, dragType, e.target);
|
|
12753
12657
|
} else if (type3 === "drop") {
|
|
12754
12658
|
e.preventDefault();
|
|
@@ -12793,10 +12697,9 @@ var App = class {
|
|
|
12793
12697
|
}
|
|
12794
12698
|
compile() {
|
|
12795
12699
|
for (const Comp of this.comps.byId.values()) {
|
|
12796
|
-
|
|
12797
|
-
|
|
12798
|
-
|
|
12799
|
-
for (const name of meta.views[key].ctx.genEventNames()) this._eventNames.add(name);
|
|
12700
|
+
Comp.compile(this.ParseContext);
|
|
12701
|
+
for (const key in Comp.views)
|
|
12702
|
+
for (const name of Comp.views[key].ctx.genEventNames()) this._eventNames.add(name);
|
|
12800
12703
|
}
|
|
12801
12704
|
this._compiled = true;
|
|
12802
12705
|
}
|
|
@@ -12819,11 +12722,13 @@ var App = class {
|
|
|
12819
12722
|
}
|
|
12820
12723
|
stop() {
|
|
12821
12724
|
this.stopCacheEvictionInterval();
|
|
12725
|
+
clearTimeout(this._transactNextBatchId);
|
|
12726
|
+
this._transactNextBatchId = null;
|
|
12822
12727
|
for (const name of this._eventNames)
|
|
12823
12728
|
this.rootNode.removeEventListener(name, this, listenerOpts(name));
|
|
12824
12729
|
}
|
|
12825
12730
|
sendAtRoot(name, args) {
|
|
12826
|
-
this.transactor.pushSend(new
|
|
12731
|
+
this.transactor.pushSend(new DispatchPath(), name, args);
|
|
12827
12732
|
}
|
|
12828
12733
|
registerComponents(comps, opts) {
|
|
12829
12734
|
const scope = this.compStack.enter();
|
|
@@ -12905,28 +12810,21 @@ var NullDomCache = class {
|
|
|
12905
12810
|
set(_keys, _cacheKey, _v) {
|
|
12906
12811
|
}
|
|
12907
12812
|
evict() {
|
|
12908
|
-
return { hit: 0, miss: 0, badKey: 0 };
|
|
12909
12813
|
}
|
|
12910
12814
|
};
|
|
12911
12815
|
var WeakMapDomCache = class {
|
|
12912
12816
|
constructor() {
|
|
12913
|
-
this.hit = this.miss = this.badKey = 0;
|
|
12914
12817
|
this.keysByLen = /* @__PURE__ */ new Map();
|
|
12915
12818
|
}
|
|
12916
|
-
_returnValue(r) {
|
|
12917
|
-
if (r === void 0) this.miss += 1;
|
|
12918
|
-
else this.hit += 1;
|
|
12919
|
-
return r;
|
|
12920
|
-
}
|
|
12921
12819
|
get(keys, cacheKey) {
|
|
12922
12820
|
const len = keys.length;
|
|
12923
12821
|
let cur = this.keysByLen.get(len);
|
|
12924
|
-
if (!cur) return
|
|
12822
|
+
if (!cur) return void 0;
|
|
12925
12823
|
for (let i = 0; i < len - 1; i++) {
|
|
12926
12824
|
cur = cur.get(keys[i]);
|
|
12927
|
-
if (!cur) return
|
|
12825
|
+
if (!cur) return void 0;
|
|
12928
12826
|
}
|
|
12929
|
-
return
|
|
12827
|
+
return cur.get(keys[len - 1])?.[cacheKey];
|
|
12930
12828
|
}
|
|
12931
12829
|
set(keys, cacheKey, v) {
|
|
12932
12830
|
const len = keys.length;
|
|
@@ -12939,10 +12837,7 @@ var WeakMapDomCache = class {
|
|
|
12939
12837
|
const key = keys[i];
|
|
12940
12838
|
let next = cur.get(key);
|
|
12941
12839
|
if (!next) {
|
|
12942
|
-
if (!isWeakKey(key))
|
|
12943
|
-
this.badKey += 1;
|
|
12944
|
-
return;
|
|
12945
|
-
}
|
|
12840
|
+
if (!isWeakKey(key)) return;
|
|
12946
12841
|
next = /* @__PURE__ */ new WeakMap();
|
|
12947
12842
|
cur.set(key, next);
|
|
12948
12843
|
}
|
|
@@ -12952,23 +12847,38 @@ var WeakMapDomCache = class {
|
|
|
12952
12847
|
const leaf = cur.get(lastKey);
|
|
12953
12848
|
if (leaf) leaf[cacheKey] = v;
|
|
12954
12849
|
else if (isWeakKey(lastKey)) cur.set(lastKey, { [cacheKey]: v });
|
|
12955
|
-
else this.badKey += 1;
|
|
12956
12850
|
}
|
|
12957
12851
|
evict() {
|
|
12958
|
-
const { hit, miss, badKey } = this;
|
|
12959
|
-
this.hit = this.miss = this.badKey = 0;
|
|
12960
12852
|
this.keysByLen = /* @__PURE__ */ new Map();
|
|
12961
|
-
return { hit, miss, badKey };
|
|
12962
12853
|
}
|
|
12963
12854
|
};
|
|
12964
12855
|
|
|
12965
12856
|
// src/renderer.js
|
|
12966
|
-
|
|
12857
|
+
function stampRenderBase(vdom, text) {
|
|
12858
|
+
if (vdom instanceof VNode)
|
|
12859
|
+
return new VNode(
|
|
12860
|
+
vdom.tag,
|
|
12861
|
+
{ ...vdom.attrs, "data-rp": text },
|
|
12862
|
+
vdom.childs,
|
|
12863
|
+
vdom.key,
|
|
12864
|
+
vdom.namespace
|
|
12865
|
+
);
|
|
12866
|
+
if (vdom instanceof VFragment)
|
|
12867
|
+
return new VFragment(vdom.childs.map((c) => stampRenderBase(c, text)));
|
|
12868
|
+
return vdom;
|
|
12869
|
+
}
|
|
12967
12870
|
var Renderer = class {
|
|
12968
12871
|
constructor(comps) {
|
|
12969
12872
|
this.comps = comps;
|
|
12970
12873
|
this.cache = new WeakMapDomCache();
|
|
12971
|
-
|
|
12874
|
+
}
|
|
12875
|
+
// Parse nodes build their VDOM through the renderer, never by importing vdom.js
|
|
12876
|
+
// themselves: a component may have been compiled by ANOTHER copy of the library
|
|
12877
|
+
// (a docs example imports the dist bundle while the host app runs from src), and
|
|
12878
|
+
// `render()` recognizes VNodes by `instanceof` against ITS copy's classes. Going
|
|
12879
|
+
// through `rx` guarantees the rendering copy makes them.
|
|
12880
|
+
renderTag(tag, attrs, childs, namespace) {
|
|
12881
|
+
return h(tag, attrs, childs, namespace);
|
|
12972
12882
|
}
|
|
12973
12883
|
renderFragment(childs) {
|
|
12974
12884
|
return new VFragment(childs);
|
|
@@ -12979,38 +12889,24 @@ var Renderer = class {
|
|
|
12979
12889
|
setNullCache() {
|
|
12980
12890
|
this.cache = new NullDomCache();
|
|
12981
12891
|
}
|
|
12982
|
-
// Library utilities for consumers embedding tutuca: render a value to a detached
|
|
12983
|
-
// DOM node / an HTML string. Not called by the framework itself.
|
|
12984
|
-
renderToDOM(stack, val) {
|
|
12985
|
-
const rootNode = document.createElement("div");
|
|
12986
|
-
const rOpts = { document };
|
|
12987
|
-
render(h("DIV", null, [this.renderRoot(stack, val)]), rootNode, rOpts);
|
|
12988
|
-
return rootNode.childNodes[0];
|
|
12989
|
-
}
|
|
12990
|
-
renderToString(stack, val, cleanAttrs = true) {
|
|
12991
|
-
const dom = this.renderToDOM(stack, val);
|
|
12992
|
-
if (cleanAttrs) {
|
|
12993
|
-
const nodes = dom.querySelectorAll("[data-nid],[data-cid],[data-eid]");
|
|
12994
|
-
for (const { dataset } of nodes) for (const name of DATASET_ATTRS) delete dataset[name];
|
|
12995
|
-
}
|
|
12996
|
-
return dom.innerHTML;
|
|
12997
|
-
}
|
|
12998
12892
|
renderRoot(stack, val, viewName = null) {
|
|
12999
12893
|
const comp = this.comps.getCompFor(val);
|
|
13000
12894
|
if (comp === null) return null;
|
|
13001
12895
|
return this._rValComp(stack, val, comp, comp.getView(viewName).anode, "ROOT", viewName);
|
|
13002
12896
|
}
|
|
13003
|
-
|
|
12897
|
+
// Render `stack.it` at a `<x render*>` site (`node`). `base` is the absolute
|
|
12898
|
+
// path the site resumed at, when it rendered a `*name` (see _rValComp).
|
|
12899
|
+
renderIt(stack, node, viewName, base = null) {
|
|
13004
12900
|
const comp = this.comps.getCompFor(stack.it);
|
|
13005
|
-
return comp ? this._rValComp(stack, stack.it, comp, node,
|
|
12901
|
+
return comp ? this._rValComp(stack, stack.it, comp, node, "", viewName, base) : null;
|
|
13006
12902
|
}
|
|
13007
12903
|
// `node` is the parse node of the render site (`<x render>` / `render-it` /
|
|
13008
12904
|
// `render-each`, or the view's root anode for the app root). It keys the
|
|
13009
12905
|
// cache as a globally-unique object: node ids alone are unique only within a
|
|
13010
12906
|
// single view, so the same value rendered by two components (e.g. through a
|
|
13011
12907
|
// shared dynamic-var sequence) would otherwise collide in the cache.
|
|
13012
|
-
_rValComp(stack, val, comp, node, key, viewName) {
|
|
13013
|
-
const cacheKey = `${viewName ?? ""}${stack.viewsId ?? ""}${key}`;
|
|
12908
|
+
_rValComp(stack, val, comp, node, key, viewName, base = null) {
|
|
12909
|
+
const cacheKey = `${viewName ?? ""}${stack.viewsId ?? ""}${key}${stack.renderPath.addressKey}`;
|
|
13014
12910
|
const cachePath = [node, val];
|
|
13015
12911
|
stack._pushDynBindValuesToArray(cachePath, comp);
|
|
13016
12912
|
const cachedNode = this.cache.get(cachePath, cacheKey);
|
|
@@ -13018,30 +12914,43 @@ var Renderer = class {
|
|
|
13018
12914
|
const view = viewName ? comp.getView(viewName) : stack.lookupBestView(comp.views, "main");
|
|
13019
12915
|
const body = this.renderView(view, stack);
|
|
13020
12916
|
if (body == null) return null;
|
|
12917
|
+
const baseJson = base === null ? null : pathToJson(base);
|
|
13021
12918
|
const meta = this._renderMetadata({
|
|
13022
12919
|
$: "Comp",
|
|
13023
12920
|
nid: node?.nodeId ?? null,
|
|
13024
12921
|
cid: comp.id,
|
|
13025
|
-
vid: view.name
|
|
12922
|
+
vid: view.name,
|
|
12923
|
+
...baseJson === null ? null : { base: baseJson }
|
|
13026
12924
|
});
|
|
13027
|
-
const dom = new VFragment([
|
|
12925
|
+
const dom = new VFragment([
|
|
12926
|
+
meta,
|
|
12927
|
+
baseJson === null ? body : stampRenderBase(body, JSON.stringify(baseJson))
|
|
12928
|
+
]);
|
|
13028
12929
|
this.cache.set(cachePath, cacheKey, dom);
|
|
13029
12930
|
return dom;
|
|
13030
12931
|
}
|
|
13031
12932
|
pushEachEntry(r, nid, attrName, key, dom) {
|
|
13032
12933
|
r.push(this._renderMetadata({ $: "Each", nid, [attrName]: key }), dom);
|
|
13033
12934
|
}
|
|
13034
|
-
renderEachWhen(stack,
|
|
13035
|
-
const {
|
|
12935
|
+
renderEachWhen(stack, each2) {
|
|
12936
|
+
const { val: seqVal, node: view, nodeId: nid } = each2;
|
|
12937
|
+
const { seq, filter, loopWith, enricher } = each2.evalIter(stack);
|
|
12938
|
+
const seqPath = seqVal instanceof DynVal ? stack.lookupDynamicLocated(seqVal.name)?.path ?? null : null;
|
|
13036
12939
|
const r = [];
|
|
13037
12940
|
const it = stack.it;
|
|
13038
12941
|
const renderOne = (key, value, attrName, binds) => {
|
|
12942
|
+
const itemBase = seqPath === null ? null : keyedPath(seqPath, key);
|
|
12943
|
+
const itemStep = itemBase === null ? each2.itemStep(key) : null;
|
|
12944
|
+
const itemPath = itemBase !== null ? stack.renderPath.pushFrame(itemBase) : itemStep !== null ? stack.renderPath.pushItem(itemStep) : stack.renderPath;
|
|
13039
12945
|
const cachePath = enricher ? [view, it, value] : [view, value];
|
|
13040
|
-
const cacheKey = `${stack.viewsId ?? ""}${nid}${key}`;
|
|
12946
|
+
const cacheKey = `${stack.viewsId ?? ""}${nid}${key}${itemPath.addressKey}`;
|
|
13041
12947
|
const cachedNode = this.cache.get(cachePath, cacheKey);
|
|
13042
12948
|
if (cachedNode) this.pushEachEntry(r, nid, attrName, key, cachedNode);
|
|
13043
12949
|
else {
|
|
13044
|
-
const dom = this.renderView(
|
|
12950
|
+
const dom = this.renderView(
|
|
12951
|
+
view,
|
|
12952
|
+
stack.enter(value, binds, false, itemPath, itemBase !== null)
|
|
12953
|
+
);
|
|
13045
12954
|
if (dom != null) this.pushEachEntry(r, nid, attrName, key, dom);
|
|
13046
12955
|
this.cache.set(cachePath, cacheKey, dom);
|
|
13047
12956
|
}
|
|
@@ -13190,12 +13099,7 @@ function shadowCheckComponent(Comp) {
|
|
|
13190
13099
|
shadowViews[name] = { name, ctx, rawView };
|
|
13191
13100
|
}
|
|
13192
13101
|
const shadowComp = Object.create(Comp);
|
|
13193
|
-
|
|
13194
|
-
value: shadowViews,
|
|
13195
|
-
writable: true,
|
|
13196
|
-
enumerable: true,
|
|
13197
|
-
configurable: true
|
|
13198
|
-
});
|
|
13102
|
+
shadowComp.views = shadowViews;
|
|
13199
13103
|
return checkComponent(shadowComp).reports;
|
|
13200
13104
|
}
|
|
13201
13105
|
function check(app) {
|
|
@@ -13221,39 +13125,6 @@ function check(app) {
|
|
|
13221
13125
|
);
|
|
13222
13126
|
return counts;
|
|
13223
13127
|
}
|
|
13224
|
-
var LintClassCollectorCtx = class _LintClassCollectorCtx extends ParseCtxClassSetCollector {
|
|
13225
|
-
constructor(...args) {
|
|
13226
|
-
super(...args);
|
|
13227
|
-
this.attrs = [];
|
|
13228
|
-
this.parseIssues = [];
|
|
13229
|
-
}
|
|
13230
|
-
enterMacro(macroName, macroVars, macroSlots) {
|
|
13231
|
-
const { document: document2, Text, Comment, nodes, events: events2, macroNodes } = this;
|
|
13232
|
-
const frame = { macroName, macroVars, macroSlots };
|
|
13233
|
-
const v = new _LintClassCollectorCtx(
|
|
13234
|
-
document2,
|
|
13235
|
-
Text,
|
|
13236
|
-
Comment,
|
|
13237
|
-
nodes,
|
|
13238
|
-
events2,
|
|
13239
|
-
macroNodes,
|
|
13240
|
-
frame,
|
|
13241
|
-
this
|
|
13242
|
-
);
|
|
13243
|
-
v.classes = this.classes;
|
|
13244
|
-
v.attrs = this.attrs;
|
|
13245
|
-
v.parseIssues = this.parseIssues;
|
|
13246
|
-
return v;
|
|
13247
|
-
}
|
|
13248
|
-
onAttributes(attrs, wrapperAttrs, textChild, isMacroCall = false, tag = null) {
|
|
13249
|
-
super.onAttributes(attrs, wrapperAttrs, textChild, isMacroCall, tag);
|
|
13250
|
-
this.attrs.push({ attrs, wrapperAttrs, textChild, isMacroCall, tag });
|
|
13251
|
-
}
|
|
13252
|
-
onParseIssue(kind, info) {
|
|
13253
|
-
const tag = this.currentTag;
|
|
13254
|
-
this.parseIssues.push({ kind, info: tag && info.tag === void 0 ? { ...info, tag } : info });
|
|
13255
|
-
}
|
|
13256
|
-
};
|
|
13257
13128
|
export {
|
|
13258
13129
|
ALT_HANDLER_NOT_DEFINED,
|
|
13259
13130
|
ALT_HANDLER_NOT_REFERENCED,
|
|
@@ -13273,7 +13144,6 @@ export {
|
|
|
13273
13144
|
DescribeResult,
|
|
13274
13145
|
EVENT_HANDLER_METHOD_NOT_ALLOWED,
|
|
13275
13146
|
ExampleIndex,
|
|
13276
|
-
FIELD_CLASS,
|
|
13277
13147
|
FIELD_METHOD_NAME_COLLISION,
|
|
13278
13148
|
FIELD_VAL_IS_METHOD,
|
|
13279
13149
|
FIELD_VAL_NOT_DEFINED,
|
|
@@ -13282,7 +13152,6 @@ export {
|
|
|
13282
13152
|
IF_NO_BRANCH_SET,
|
|
13283
13153
|
LOOKUP_BAD_SHAPE,
|
|
13284
13154
|
LOOKUP_NO_PROVIDER,
|
|
13285
|
-
LintClassCollectorCtx,
|
|
13286
13155
|
LintComponentResult,
|
|
13287
13156
|
LintContext,
|
|
13288
13157
|
LintFinding,
|
|
@@ -13295,9 +13164,9 @@ export {
|
|
|
13295
13164
|
ModuleInfo,
|
|
13296
13165
|
ModuleTestReport,
|
|
13297
13166
|
ModuleTests,
|
|
13167
|
+
ORPHAN_DIRECTIVE,
|
|
13298
13168
|
PASS,
|
|
13299
13169
|
PLACEHOLDERLESS_TEMPLATE_STRING,
|
|
13300
|
-
PROVIDE_NAME_COLLISION,
|
|
13301
13170
|
PROVIDE_NOT_ADDRESSABLE,
|
|
13302
13171
|
PROVIDE_TYPE_BAD_SHAPE,
|
|
13303
13172
|
ParseContext,
|
|
@@ -13338,6 +13207,7 @@ export {
|
|
|
13338
13207
|
lintIdToMessage,
|
|
13339
13208
|
macro,
|
|
13340
13209
|
makeCollector,
|
|
13210
|
+
path,
|
|
13341
13211
|
phaseOps,
|
|
13342
13212
|
reportTestReportToConsole,
|
|
13343
13213
|
resolveArgs,
|