tutuca 0.13.2 → 0.14.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 +611 -458
- package/dist/tutuca-dev.ext.js +642 -486
- package/dist/tutuca-dev.js +653 -497
- package/dist/tutuca-dev.min.js +4 -4
- package/dist/tutuca-extra.ext.js +625 -451
- package/dist/tutuca-extra.js +632 -458
- package/dist/tutuca-extra.min.js +3 -3
- package/dist/tutuca.ext.js +625 -451
- package/dist/tutuca.js +632 -458
- 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 +7 -1
- package/skill/tutuca/messages-and-intents.md +1 -1
- 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 +43 -28
- package/skill/tutuca-source/tutuca.ext.js +625 -451
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;
|
|
@@ -4979,8 +4979,11 @@ var Step = class {
|
|
|
4979
4979
|
}
|
|
4980
4980
|
setDraftValue(_root, _v) {
|
|
4981
4981
|
}
|
|
4982
|
-
|
|
4983
|
-
|
|
4982
|
+
// Re-enter this step while rebuilding a stack. `renderPath` is the dispatch
|
|
4983
|
+
// position AFTER this step: a rebuilt frame must carry the same render path
|
|
4984
|
+
// the renderer had there, or the provides it publishes would be located wrong.
|
|
4985
|
+
enterFrame(stack, next, renderPath) {
|
|
4986
|
+
return stack.enter(next, {}, true, renderPath);
|
|
4984
4987
|
}
|
|
4985
4988
|
toAbstractPathStep() {
|
|
4986
4989
|
return this;
|
|
@@ -5005,8 +5008,8 @@ var BindStep = class _BindStep extends Step {
|
|
|
5005
5008
|
lookup(v, _dval) {
|
|
5006
5009
|
return v;
|
|
5007
5010
|
}
|
|
5008
|
-
enterFrame(stack, next) {
|
|
5009
|
-
return stack.enter(next, { ...this.binds }, false);
|
|
5011
|
+
enterFrame(stack, next, renderPath) {
|
|
5012
|
+
return stack.enter(next, { ...this.binds }, false, renderPath);
|
|
5010
5013
|
}
|
|
5011
5014
|
withIndex(i) {
|
|
5012
5015
|
return new _BindStep({ ...this.binds, key: i });
|
|
@@ -5023,9 +5026,9 @@ var ScopeBindStep = class _ScopeBindStep extends BindStep {
|
|
|
5023
5026
|
super(binds);
|
|
5024
5027
|
this.val = val;
|
|
5025
5028
|
}
|
|
5026
|
-
enterFrame(stack, next) {
|
|
5029
|
+
enterFrame(stack, next, renderPath) {
|
|
5027
5030
|
const dyn = this.val.evalAsHandler(stack)?.call(stack.it) ?? {};
|
|
5028
|
-
return stack.enter(next, { ...this.binds, ...dyn }, false);
|
|
5031
|
+
return stack.enter(next, { ...this.binds, ...dyn }, false, renderPath);
|
|
5029
5032
|
}
|
|
5030
5033
|
withIndex(i) {
|
|
5031
5034
|
return new _ScopeBindStep(this.val, { ...this.binds, key: i });
|
|
@@ -5068,8 +5071,8 @@ var SeqStep = class extends Step {
|
|
|
5068
5071
|
const seq = readKey(root, this.field, null);
|
|
5069
5072
|
if (seq != null) writeSeqKey(seq, this.key, v);
|
|
5070
5073
|
}
|
|
5071
|
-
enterFrame(stack, next) {
|
|
5072
|
-
return stack.enter(next, { key: this.key }, true);
|
|
5074
|
+
enterFrame(stack, next, renderPath) {
|
|
5075
|
+
return stack.enter(next, { key: this.key }, true, renderPath);
|
|
5073
5076
|
}
|
|
5074
5077
|
toKey() {
|
|
5075
5078
|
return { field: this.field, key: this.key };
|
|
@@ -5115,60 +5118,52 @@ var EachBindStep = class extends Step {
|
|
|
5115
5118
|
}
|
|
5116
5119
|
// Replay the renderer's per-item binds (key, value + any @enrich-with binds)
|
|
5117
5120
|
// so a rebuilt stack matches the one @each rendered with.
|
|
5118
|
-
enterFrame(stack, next) {
|
|
5119
|
-
return stack.enter(next, this.iterInfo.enrichBinds(stack, this.key), false);
|
|
5121
|
+
enterFrame(stack, next, renderPath) {
|
|
5122
|
+
return stack.enter(next, this.iterInfo.enrichBinds(stack, this.key), false, renderPath);
|
|
5120
5123
|
}
|
|
5121
5124
|
toAbstractPathStep() {
|
|
5122
5125
|
return null;
|
|
5123
5126
|
}
|
|
5124
5127
|
};
|
|
5125
5128
|
var EachRenderItStep = class extends SeqStep {
|
|
5126
|
-
enterFrame(stack, next) {
|
|
5127
|
-
return stack.enter(next, { key: this.key, value: next }, false).enter(next, {}, true);
|
|
5129
|
+
enterFrame(stack, next, renderPath) {
|
|
5130
|
+
return stack.enter(next, { key: this.key, value: next }, false, renderPath).enter(next, {}, true, renderPath);
|
|
5128
5131
|
}
|
|
5129
5132
|
toAbstractPathStep() {
|
|
5130
5133
|
return new SeqStep(this.field, this.key);
|
|
5131
5134
|
}
|
|
5132
5135
|
};
|
|
5133
|
-
function
|
|
5134
|
-
|
|
5136
|
+
function stepToJson(step) {
|
|
5137
|
+
if (step instanceof SeqStep) return { f: step.field, k: step.key };
|
|
5138
|
+
if (step instanceof FieldStep) return { f: step.field };
|
|
5139
|
+
if (step instanceof SeqAccessStep) return { f: step.seqField, a: step.keyField };
|
|
5140
|
+
return null;
|
|
5135
5141
|
}
|
|
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;
|
|
5142
|
+
function stepFromJson(j) {
|
|
5143
|
+
if (j == null || typeof j.f !== "string") return null;
|
|
5144
|
+
if (j.k !== void 0) return new SeqStep(j.f, j.k);
|
|
5145
|
+
if (j.a !== void 0) return new SeqAccessStep(j.f, j.a);
|
|
5146
|
+
return new FieldStep(j.f);
|
|
5147
|
+
}
|
|
5148
|
+
function pathToJson(path2) {
|
|
5149
|
+
const out = [];
|
|
5150
|
+
for (const step of path2.steps) {
|
|
5151
|
+
const j = stepToJson(step);
|
|
5152
|
+
if (j === null) return null;
|
|
5153
|
+
out.push(j);
|
|
5160
5154
|
}
|
|
5161
|
-
|
|
5162
|
-
|
|
5163
|
-
|
|
5164
|
-
|
|
5165
|
-
|
|
5166
|
-
|
|
5167
|
-
|
|
5168
|
-
|
|
5169
|
-
|
|
5155
|
+
return out;
|
|
5156
|
+
}
|
|
5157
|
+
function pathFromJson(j) {
|
|
5158
|
+
if (!Array.isArray(j)) return null;
|
|
5159
|
+
const steps = [];
|
|
5160
|
+
for (const item of j) {
|
|
5161
|
+
const step = stepFromJson(item);
|
|
5162
|
+
if (step === null) return null;
|
|
5163
|
+
steps.push(step);
|
|
5170
5164
|
}
|
|
5171
|
-
|
|
5165
|
+
return new Path(steps);
|
|
5166
|
+
}
|
|
5172
5167
|
var Path = class _Path {
|
|
5173
5168
|
constructor(steps = []) {
|
|
5174
5169
|
this.steps = steps;
|
|
@@ -5179,40 +5174,13 @@ var Path = class _Path {
|
|
|
5179
5174
|
popStep() {
|
|
5180
5175
|
return new _Path(this.steps.slice(0, -1));
|
|
5181
5176
|
}
|
|
5182
|
-
//
|
|
5183
|
-
//
|
|
5177
|
+
// Frame-only steps removed, one step per crossed component: `popStep` over the
|
|
5178
|
+
// result bubbles through every component.
|
|
5184
5179
|
compact() {
|
|
5185
5180
|
const out = [];
|
|
5186
5181
|
for (const step of this.steps) {
|
|
5187
5182
|
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);
|
|
5183
|
+
if (s !== null) out.push(s);
|
|
5216
5184
|
}
|
|
5217
5185
|
return new _Path(out);
|
|
5218
5186
|
}
|
|
@@ -5220,7 +5188,6 @@ var Path = class _Path {
|
|
|
5220
5188
|
// key as it is *now* so a later lookup/setValue lands on the same item even if the
|
|
5221
5189
|
// keyField changed meanwhile (e.g. the selected tab moved while an intent was in
|
|
5222
5190
|
// 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
5191
|
pinKeys(root) {
|
|
5225
5192
|
let curVal = root;
|
|
5226
5193
|
let out = null;
|
|
@@ -5243,8 +5210,8 @@ var Path = class _Path {
|
|
|
5243
5210
|
}
|
|
5244
5211
|
// The values entered along the path, root→leaf (root included): index 0 is `root`,
|
|
5245
5212
|
// the last entry is the leaf this path resolves to. Stops early at the first
|
|
5246
|
-
// unresolvable step.
|
|
5247
|
-
//
|
|
5213
|
+
// unresolvable step. Used to walk the component instances on a dispatch path
|
|
5214
|
+
// (filter via Components.getCompFor).
|
|
5248
5215
|
resolveChain(root) {
|
|
5249
5216
|
const out = [root];
|
|
5250
5217
|
let curVal = root;
|
|
@@ -5258,7 +5225,7 @@ var Path = class _Path {
|
|
|
5258
5225
|
// A flat `[{ field, key? }]` list of the addressing steps, skipping frame-only
|
|
5259
5226
|
// steps (binds). Generic path introspection so tooling (e.g. the storybook
|
|
5260
5227
|
// activity log) can identify which subtree a transaction touched without
|
|
5261
|
-
// depending on Step internals.
|
|
5228
|
+
// depending on Step internals.
|
|
5262
5229
|
toKeys() {
|
|
5263
5230
|
const out = [];
|
|
5264
5231
|
for (const step of this.steps) {
|
|
@@ -5279,62 +5246,147 @@ var Path = class _Path {
|
|
|
5279
5246
|
});
|
|
5280
5247
|
}
|
|
5281
5248
|
buildStack(stack) {
|
|
5282
|
-
|
|
5283
|
-
|
|
5284
|
-
|
|
5285
|
-
|
|
5286
|
-
|
|
5287
|
-
|
|
5249
|
+
return walkItems(stack, this.steps, stack.renderPath ?? new DispatchPath(), this)?.[0] ?? null;
|
|
5250
|
+
}
|
|
5251
|
+
};
|
|
5252
|
+
function walkItems(stack, items, renderPath, path2) {
|
|
5253
|
+
let prev = stack.it;
|
|
5254
|
+
for (const step of items) {
|
|
5255
|
+
const next = step.lookup(prev, NONE);
|
|
5256
|
+
if (next === NONE) {
|
|
5257
|
+
console.warn("bad PathItem", { root: stack.it, step, path: path2 });
|
|
5258
|
+
return null;
|
|
5259
|
+
}
|
|
5260
|
+
renderPath = renderPath.pushItem(step);
|
|
5261
|
+
stack = step.enterFrame(stack, next, renderPath);
|
|
5262
|
+
prev = next;
|
|
5263
|
+
}
|
|
5264
|
+
return [stack, renderPath];
|
|
5265
|
+
}
|
|
5266
|
+
var EMPTY_PATH = new Path([]);
|
|
5267
|
+
var DispatchPath = class _DispatchPath {
|
|
5268
|
+
constructor(frames = [{ base: EMPTY_PATH, items: [] }]) {
|
|
5269
|
+
this.frames = frames;
|
|
5270
|
+
}
|
|
5271
|
+
// Plain addressing steps in one frame based at the root: what a caller means
|
|
5272
|
+
// by "this position" when it has no continuation of its own.
|
|
5273
|
+
static ofSteps(steps) {
|
|
5274
|
+
return new _DispatchPath([{ base: EMPTY_PATH, items: steps.slice() }]);
|
|
5275
|
+
}
|
|
5276
|
+
get top() {
|
|
5277
|
+
return this.frames[this.frames.length - 1];
|
|
5278
|
+
}
|
|
5279
|
+
_withTopItems(items) {
|
|
5280
|
+
const frames = this.frames.slice();
|
|
5281
|
+
frames[frames.length - 1] = { base: this.top.base, items };
|
|
5282
|
+
return new _DispatchPath(frames);
|
|
5283
|
+
}
|
|
5284
|
+
concat(steps) {
|
|
5285
|
+
if (this.frames.length === 0) return _DispatchPath.ofSteps(steps);
|
|
5286
|
+
return this._withTopItems(this.top.items.concat(steps));
|
|
5287
|
+
}
|
|
5288
|
+
pushItem(step) {
|
|
5289
|
+
return this.concat([step]);
|
|
5290
|
+
}
|
|
5291
|
+
pushFrame(base) {
|
|
5292
|
+
return new _DispatchPath(this.frames.concat({ base, items: [] }));
|
|
5293
|
+
}
|
|
5294
|
+
// Whether bubbling has anywhere left to go: another step in this frame, or a
|
|
5295
|
+
// visual caller underneath it.
|
|
5296
|
+
canPop() {
|
|
5297
|
+
const n = this.frames.length;
|
|
5298
|
+
return n > 1 || n === 1 && this.frames[0].items.length > 0;
|
|
5299
|
+
}
|
|
5300
|
+
isRoot() {
|
|
5301
|
+
return this.toTransactionPath().steps.length === 0;
|
|
5302
|
+
}
|
|
5303
|
+
// One component closer to the root. At the top of a frame that is popping back
|
|
5304
|
+
// to the visual caller, not to the producer's own parent — the caller is where
|
|
5305
|
+
// the `*name` was written, and where an unhandled message should keep going.
|
|
5306
|
+
popStep() {
|
|
5307
|
+
const n = this.frames.length;
|
|
5308
|
+
if (n === 0) return this;
|
|
5309
|
+
const top = this.frames[n - 1];
|
|
5310
|
+
if (top.items.length > 0) return this._withTopItems(top.items.slice(0, -1));
|
|
5311
|
+
if (n > 1) return new _DispatchPath(this.frames.slice(0, -1));
|
|
5312
|
+
return this;
|
|
5313
|
+
}
|
|
5314
|
+
// Drop frame-only steps inside every frame independently; a frame's base is
|
|
5315
|
+
// already addressing-only.
|
|
5316
|
+
compact() {
|
|
5317
|
+
return new _DispatchPath(
|
|
5318
|
+
this.frames.map(({ base, items }) => ({ base, items: new Path(items).compact().steps }))
|
|
5319
|
+
);
|
|
5320
|
+
}
|
|
5321
|
+
// A stable string for the ADDRESS this path denotes, for the render cache. The
|
|
5322
|
+
// same immutable value can sit at two places in the tree, and a subtree rendered
|
|
5323
|
+
// at one of them bakes that address in — the provides it publishes are located
|
|
5324
|
+
// there. Frame-only steps address nothing, so they are compacted out: two sites
|
|
5325
|
+
// that differ only in binds do render the same subtree.
|
|
5326
|
+
get addressKey() {
|
|
5327
|
+
this._addressKey ??= renderPathText(this.toTransactionPath().compact());
|
|
5328
|
+
return this._addressKey;
|
|
5329
|
+
}
|
|
5330
|
+
// The active transaction address: the top frame's absolute base followed by
|
|
5331
|
+
// its ordinary descendant steps. This is where a mutation lands.
|
|
5332
|
+
toTransactionPath() {
|
|
5333
|
+
const top = this.top;
|
|
5334
|
+
return top === void 0 ? EMPTY_PATH : top.base.concat(top.items);
|
|
5335
|
+
}
|
|
5336
|
+
// Rebuild the render stack this path was dispatched from. A frame with a base
|
|
5337
|
+
// re-enters at that absolute value first — replaying the resume a `*name`
|
|
5338
|
+
// render performed — and then walks its ordinary items.
|
|
5339
|
+
buildStack(stack) {
|
|
5340
|
+
let renderPath = new _DispatchPath();
|
|
5341
|
+
for (let i = 0; i < this.frames.length; i++) {
|
|
5342
|
+
const { base, items } = this.frames[i];
|
|
5343
|
+
if (i > 0 || base.steps.length > 0) {
|
|
5344
|
+
const baseValue = base.lookup(stack.root, NONE);
|
|
5345
|
+
if (baseValue === NONE) {
|
|
5346
|
+
console.warn("bad frame base", { base, path: this });
|
|
5347
|
+
return null;
|
|
5348
|
+
}
|
|
5349
|
+
renderPath = renderPath.pushFrame(base);
|
|
5350
|
+
stack = stack.enter(baseValue, {}, true, renderPath);
|
|
5288
5351
|
}
|
|
5289
|
-
|
|
5290
|
-
|
|
5352
|
+
const walked = walkItems(stack, items, renderPath, this);
|
|
5353
|
+
if (walked === null) return null;
|
|
5354
|
+
[stack, renderPath] = walked;
|
|
5291
5355
|
}
|
|
5292
5356
|
return stack;
|
|
5293
5357
|
}
|
|
5294
5358
|
static fromNodeAndEventName(node, eventName, rootNode, maxDepth, comps, stopOnNoEvent = true) {
|
|
5295
|
-
const
|
|
5296
|
-
const pendingDyns = [];
|
|
5359
|
+
const parts = [];
|
|
5297
5360
|
const bubbles = BUBBLING_EVENTS.has(eventName);
|
|
5298
5361
|
let depth = 0;
|
|
5299
5362
|
let eventIds = [];
|
|
5300
5363
|
let handlers = null;
|
|
5301
|
-
let
|
|
5364
|
+
let nodeRefs = [];
|
|
5302
5365
|
let isLeafComponent = true;
|
|
5303
5366
|
const crossComponent = (cidNum, vid) => {
|
|
5304
5367
|
const comp = comps.getComponentForId(cidNum);
|
|
5305
|
-
let
|
|
5368
|
+
let pushPart = true;
|
|
5306
5369
|
if (handlers === null && (isLeafComponent || bubbles)) {
|
|
5307
5370
|
handlers = findHandlers(comp, eventIds, vid, eventName);
|
|
5308
5371
|
if (handlers === null) {
|
|
5309
5372
|
if (isLeafComponent && stopOnNoEvent && !bubbles) return false;
|
|
5310
5373
|
} else if (!isLeafComponent) {
|
|
5311
|
-
|
|
5312
|
-
|
|
5313
|
-
pushStep = false;
|
|
5374
|
+
parts.length = 0;
|
|
5375
|
+
pushPart = false;
|
|
5314
5376
|
}
|
|
5315
5377
|
}
|
|
5316
5378
|
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
|
-
}
|
|
5379
|
+
if (pushPart) {
|
|
5380
|
+
const part = resolvePathPart(comp, nodeRefs, vid);
|
|
5381
|
+
if (part) parts.push(part);
|
|
5328
5382
|
}
|
|
5329
|
-
for (let i = pendingDyns.length - 1; i >= 0; i--)
|
|
5330
|
-
if (pendingDyns[i].producerCompId === cidNum) pendingDyns.splice(i, 1);
|
|
5331
5383
|
eventIds = [];
|
|
5332
|
-
|
|
5384
|
+
nodeRefs = [];
|
|
5333
5385
|
return true;
|
|
5334
5386
|
};
|
|
5335
5387
|
while (node && node !== rootNode && depth < maxDepth) {
|
|
5336
5388
|
if (node?.dataset) {
|
|
5337
|
-
const { eid, cid, vid } = node.dataset;
|
|
5389
|
+
const { eid, cid, vid, rp } = node.dataset;
|
|
5338
5390
|
if (eid !== void 0) eventIds.push(eid);
|
|
5339
5391
|
const metas = metaChain(node.previousSibling);
|
|
5340
5392
|
let sawComp = false;
|
|
@@ -5342,21 +5394,47 @@ var Path = class _Path {
|
|
|
5342
5394
|
if (m.$ === "Comp") {
|
|
5343
5395
|
sawComp = true;
|
|
5344
5396
|
if (!crossComponent(m.cid, m.vid)) return NO_EVENT_INFO;
|
|
5345
|
-
|
|
5397
|
+
nodeRefs.push({ nid: m.nid, base: pathFromJson(m.base) });
|
|
5346
5398
|
} else {
|
|
5347
|
-
|
|
5399
|
+
nodeRefs.push({ nid: m.nid, si: m.si, sk: m.sk });
|
|
5400
|
+
}
|
|
5401
|
+
}
|
|
5402
|
+
if (!sawComp && cid !== void 0) {
|
|
5403
|
+
if (!crossComponent(+cid, vid)) return NO_EVENT_INFO;
|
|
5404
|
+
if (rp !== void 0) {
|
|
5405
|
+
const base = parseRenderPath(rp);
|
|
5406
|
+
if (base !== null) nodeRefs.push({ base });
|
|
5348
5407
|
}
|
|
5349
5408
|
}
|
|
5350
|
-
if (!sawComp && cid !== void 0 && !crossComponent(+cid, vid)) return NO_EVENT_INFO;
|
|
5351
5409
|
}
|
|
5352
5410
|
depth += 1;
|
|
5353
5411
|
node = node.parentNode;
|
|
5354
5412
|
}
|
|
5355
|
-
|
|
5356
|
-
|
|
5357
|
-
|
|
5413
|
+
parts.reverse();
|
|
5414
|
+
let path2 = new _DispatchPath();
|
|
5415
|
+
for (const part of parts)
|
|
5416
|
+
path2 = part.base !== void 0 ? path2.pushFrame(part.base) : path2.pushItem(part.step);
|
|
5417
|
+
return [path2, handlers];
|
|
5358
5418
|
}
|
|
5359
5419
|
};
|
|
5420
|
+
function keyedPath(path2, key) {
|
|
5421
|
+
const steps = path2.steps;
|
|
5422
|
+
const last = steps[steps.length - 1];
|
|
5423
|
+
if (last instanceof SeqStep || last instanceof FieldStep)
|
|
5424
|
+
return new Path(steps.slice(0, -1).concat(new SeqStep(last.field, key)));
|
|
5425
|
+
return null;
|
|
5426
|
+
}
|
|
5427
|
+
function renderPathText(path2) {
|
|
5428
|
+
return JSON.stringify(pathToJson(path2));
|
|
5429
|
+
}
|
|
5430
|
+
function parseRenderPath(text) {
|
|
5431
|
+
try {
|
|
5432
|
+
return pathFromJson(JSON.parse(text));
|
|
5433
|
+
} catch (err) {
|
|
5434
|
+
console.warn("bad render path", err, text);
|
|
5435
|
+
return null;
|
|
5436
|
+
}
|
|
5437
|
+
}
|
|
5360
5438
|
function metaChain(n) {
|
|
5361
5439
|
const out = [];
|
|
5362
5440
|
while (n?.nodeType === 8 && n.textContent[0] === "§") {
|
|
@@ -5409,20 +5487,27 @@ var StepCtx = class _StepCtx {
|
|
|
5409
5487
|
return pi;
|
|
5410
5488
|
}
|
|
5411
5489
|
};
|
|
5412
|
-
function
|
|
5413
|
-
for (let i = 0; i <
|
|
5414
|
-
const
|
|
5415
|
-
|
|
5416
|
-
if (
|
|
5490
|
+
function resolvePathPart(comp, nodeRefs, vid) {
|
|
5491
|
+
for (let i = 0; i < nodeRefs.length; i++) {
|
|
5492
|
+
const ref = nodeRefs[i];
|
|
5493
|
+
if (ref.base != null) return { base: ref.base };
|
|
5494
|
+
if (ref.nid === void 0 || ref.nid === null) continue;
|
|
5495
|
+
const ctx = new StepCtx(comp, nodeRefs, i, vid);
|
|
5496
|
+
const step = ctx.resolveNode()?.toPathStep(ctx) ?? null;
|
|
5497
|
+
if (step !== null) return { step };
|
|
5417
5498
|
}
|
|
5418
5499
|
return null;
|
|
5419
5500
|
}
|
|
5420
5501
|
var NO_EVENT_INFO = [null, null];
|
|
5421
5502
|
var BUBBLING_EVENTS = /* @__PURE__ */ new Set(["drop"]);
|
|
5503
|
+
var path = () => new PathBuilder();
|
|
5422
5504
|
var PathBuilder = class {
|
|
5423
5505
|
constructor() {
|
|
5424
5506
|
this.pathChanges = [];
|
|
5425
5507
|
}
|
|
5508
|
+
toPath() {
|
|
5509
|
+
return new Path(this.pathChanges);
|
|
5510
|
+
}
|
|
5426
5511
|
add(pathChange) {
|
|
5427
5512
|
this.pathChanges.push(pathChange);
|
|
5428
5513
|
return this;
|
|
@@ -5559,31 +5644,14 @@ function parseBool(s, px) {
|
|
|
5559
5644
|
const val = parseToken(tokens[0], px);
|
|
5560
5645
|
return val !== null && kindOf(val) & G_BOOL ? val : null;
|
|
5561
5646
|
}
|
|
5562
|
-
|
|
5563
|
-
|
|
5564
|
-
|
|
5565
|
-
|
|
5566
|
-
|
|
5567
|
-
|
|
5568
|
-
|
|
5569
|
-
|
|
5570
|
-
}
|
|
5571
|
-
function parseField(s, px) {
|
|
5572
|
-
return _parseSingle(s, px, G_FIELD);
|
|
5573
|
-
}
|
|
5574
|
-
function parseProvide(s, px) {
|
|
5575
|
-
return _parseSingle(s, px, G_PROVIDE);
|
|
5576
|
-
}
|
|
5577
|
-
function parseMacroAttr(s, px) {
|
|
5578
|
-
return _parseSingle(s, px, G_ALL);
|
|
5579
|
-
}
|
|
5580
|
-
function parseReceiveHandler(s, px) {
|
|
5581
|
-
return _parseHandler(s, px, "receive", true, true, false);
|
|
5582
|
-
}
|
|
5583
|
-
function parseAlterHandler(s, px) {
|
|
5584
|
-
const r = _parseHandler(s, px, "alter", false, false, true);
|
|
5585
|
-
return r === null ? null : r.handlerVal;
|
|
5586
|
-
}
|
|
5647
|
+
var parseText = (s, px) => _parseSingle(s, px, G_TEXT);
|
|
5648
|
+
var parseComponent = (s, px) => _parseSingle(s, px, G_COMPONENT);
|
|
5649
|
+
var parseSequence = (s, px) => _parseSingle(s, px, G_SEQUENCE);
|
|
5650
|
+
var parseField = (s, px) => _parseSingle(s, px, G_FIELD);
|
|
5651
|
+
var parseProvide = (s, px) => _parseSingle(s, px, G_PROVIDE);
|
|
5652
|
+
var parseMacroAttr = (s, px) => _parseSingle(s, px, G_ALL);
|
|
5653
|
+
var parseReceiveHandler = (s, px) => _parseHandler(s, px, "receive", true, true, false);
|
|
5654
|
+
var parseAlterHandler = (s, px) => _parseHandler(s, px, "alter", false, false, true)?.handlerVal ?? null;
|
|
5587
5655
|
function _parseHandler(s, px, namespace, allowArgs, report, allowMethod) {
|
|
5588
5656
|
const tokens = tokenizeValue(s.trim());
|
|
5589
5657
|
const headTok = tokens[0] ?? "";
|
|
@@ -6272,19 +6340,9 @@ function childOpts(vnode, ns, opts) {
|
|
|
6272
6340
|
const target = ns === SVG_NS && isForeignObject(vnode.tag) ? null : ns;
|
|
6273
6341
|
return target === (opts.namespace ?? null) ? opts : { ...opts, namespace: target };
|
|
6274
6342
|
}
|
|
6275
|
-
var NEVER_ASSIGN =
|
|
6276
|
-
"width"
|
|
6277
|
-
|
|
6278
|
-
"href",
|
|
6279
|
-
"list",
|
|
6280
|
-
"form",
|
|
6281
|
-
"tabIndex",
|
|
6282
|
-
"download",
|
|
6283
|
-
"rowSpan",
|
|
6284
|
-
"colSpan",
|
|
6285
|
-
"role",
|
|
6286
|
-
"popover"
|
|
6287
|
-
]);
|
|
6343
|
+
var NEVER_ASSIGN = new Set(
|
|
6344
|
+
"width height href list form tabIndex download rowSpan colSpan role popover".split(" ")
|
|
6345
|
+
);
|
|
6288
6346
|
var PROP_ATTR_NAME = { className: "class", htmlFor: "for" };
|
|
6289
6347
|
function applyProperties(node, props) {
|
|
6290
6348
|
const namespaced = isNamespaced(node);
|
|
@@ -6563,6 +6621,10 @@ function morphChildren(parentDom, oldChilds, newChilds, opts) {
|
|
|
6563
6621
|
if (!used2[i] && domNodes[i].parentNode === parentDom) parentDom.removeChild(domNodes[i]);
|
|
6564
6622
|
}
|
|
6565
6623
|
function render(vnode, container, options, prev) {
|
|
6624
|
+
if (vnode == null) {
|
|
6625
|
+
container.replaceChildren();
|
|
6626
|
+
return { vnode: null, dom: null };
|
|
6627
|
+
}
|
|
6566
6628
|
const isFragment = vnode instanceof VFragment;
|
|
6567
6629
|
if (prev && prev.vnode instanceof VFragment === isFragment) {
|
|
6568
6630
|
const oldDom = isFragment ? container : prev.dom;
|
|
@@ -6602,13 +6664,16 @@ function h(tagName, properties, children, namespace) {
|
|
|
6602
6664
|
}
|
|
6603
6665
|
|
|
6604
6666
|
// src/anode.js
|
|
6605
|
-
function
|
|
6606
|
-
|
|
6607
|
-
|
|
6608
|
-
|
|
6609
|
-
|
|
6610
|
-
|
|
6611
|
-
|
|
6667
|
+
function renderTarget(val, stack) {
|
|
6668
|
+
if (val instanceof DynVal) {
|
|
6669
|
+
const loc = stack.lookupDynamicLocated(val.name);
|
|
6670
|
+
if (loc?.path == null) return [loc?.value ?? null, stack.renderPath, null];
|
|
6671
|
+
return [loc.value, stack.renderPath.pushFrame(loc.path), loc.path];
|
|
6672
|
+
}
|
|
6673
|
+
const step = val.toPathItem?.() ?? null;
|
|
6674
|
+
if (step === null) return [val.eval(stack), stack.renderPath, null];
|
|
6675
|
+
const path2 = stack.renderPath.pushItem(step);
|
|
6676
|
+
return [val.eval(stack), path2, stack.pendingFrame ? path2.toTransactionPath() : null];
|
|
6612
6677
|
}
|
|
6613
6678
|
var BaseNode = class {
|
|
6614
6679
|
render(_stack, _rx) {
|
|
@@ -6930,33 +6995,31 @@ var RenderViewId = class extends ANode {
|
|
|
6930
6995
|
setDataAttr(_key, _val) {
|
|
6931
6996
|
}
|
|
6932
6997
|
};
|
|
6933
|
-
function dynRenderStep(comp, name, key) {
|
|
6934
|
-
const p = resolveDynProducer(comp, name);
|
|
6935
|
-
if (!p) return null;
|
|
6936
|
-
return key === void 0 ? new DynStep(p.producerCompId, p.producerSteps) : new DynEachStep(p.producerCompId, p.producerSteps, key);
|
|
6937
|
-
}
|
|
6938
6998
|
var RenderNode = class extends RenderViewId {
|
|
6939
6999
|
render(stack, rx) {
|
|
6940
|
-
const
|
|
6941
|
-
|
|
7000
|
+
const [value, renderPath, base] = renderTarget(this.val, stack);
|
|
7001
|
+
const newStack = stack.enter(value, {}, true, renderPath, false);
|
|
7002
|
+
return rx.renderIt(newStack, this, "", this.evalViewName(stack), base);
|
|
6942
7003
|
}
|
|
7004
|
+
// A `*name` target contributes no step: the site recorded the absolute base it
|
|
7005
|
+
// resumed at, and event reconstruction turns that into a continuation frame.
|
|
6943
7006
|
toPathStep(ctx) {
|
|
6944
|
-
if (this.val instanceof DynVal) return
|
|
7007
|
+
if (this.val instanceof DynVal) return null;
|
|
6945
7008
|
return super.toPathStep(ctx);
|
|
6946
7009
|
}
|
|
6947
7010
|
};
|
|
6948
7011
|
var RenderItNode = class extends RenderViewId {
|
|
6949
7012
|
render(stack, rx) {
|
|
6950
|
-
const
|
|
6951
|
-
|
|
7013
|
+
const base = stack.pendingFrame ? stack.renderPath.toTransactionPath() : null;
|
|
7014
|
+
const newStack = stack.enter(stack.it, {}, true, stack.renderPath, false);
|
|
7015
|
+
return rx.renderIt(newStack, this, "", this.evalViewName(stack), base);
|
|
6952
7016
|
}
|
|
6953
7017
|
toPathStep(ctx) {
|
|
6954
7018
|
const next = ctx.next();
|
|
6955
7019
|
if (next === null) return null;
|
|
6956
7020
|
const nextNode = next.resolveNode();
|
|
6957
7021
|
if (nextNode instanceof EachNode && next.hasKey) {
|
|
6958
|
-
if (nextNode.val instanceof DynVal)
|
|
6959
|
-
return dynRenderStep(ctx.comp, nextNode.val.name, next.key);
|
|
7022
|
+
if (nextNode.val instanceof DynVal) return null;
|
|
6960
7023
|
return new EachRenderItStep(nextNode.val.name, next.key);
|
|
6961
7024
|
}
|
|
6962
7025
|
return null;
|
|
@@ -7058,11 +7121,19 @@ var EachNode = class extends WrapperNode {
|
|
|
7058
7121
|
this.iterInfo = new IterInfo(val, null, null, null);
|
|
7059
7122
|
}
|
|
7060
7123
|
render(stack, rx) {
|
|
7061
|
-
return rx.renderEachWhen(stack, this
|
|
7124
|
+
return rx.renderEachWhen(stack, this);
|
|
7062
7125
|
}
|
|
7063
7126
|
toPathStep(ctx) {
|
|
7064
7127
|
return ctx.hasKey ? new EachBindStep(this.iterInfo, ctx.key) : null;
|
|
7065
7128
|
}
|
|
7129
|
+
// Where one item lives, for the render path. `@each` re-binds `it` to the item
|
|
7130
|
+
// whether or not the body is a component, so the position moves either way and
|
|
7131
|
+
// the step has to address it — `.rows` iterated at `key` IS `rows[key]`.
|
|
7132
|
+
// Null for a dynamic sequence: `*rows` carries its own absolute path and enters
|
|
7133
|
+
// a continuation frame instead (see Renderer.renderEachWhen).
|
|
7134
|
+
itemStep(key) {
|
|
7135
|
+
return this.val instanceof FieldVal ? new SeqStep(this.val.name, key) : null;
|
|
7136
|
+
}
|
|
7066
7137
|
static register = true;
|
|
7067
7138
|
};
|
|
7068
7139
|
var IterInfo = class {
|
|
@@ -7401,6 +7472,215 @@ function collectAppClassesInSet(app) {
|
|
|
7401
7472
|
return classes;
|
|
7402
7473
|
}
|
|
7403
7474
|
|
|
7475
|
+
// src/stack.js
|
|
7476
|
+
var STOP = /* @__PURE__ */ Symbol("STOP");
|
|
7477
|
+
var NEXT = /* @__PURE__ */ Symbol("NEXT");
|
|
7478
|
+
var DEFAULT_ROUTE = ["dyn", "lex"];
|
|
7479
|
+
function routeLookup(route, lex, dyn) {
|
|
7480
|
+
for (let i = 0; i < route.length; i++) {
|
|
7481
|
+
const leg = route[i];
|
|
7482
|
+
if (leg === "dyn") {
|
|
7483
|
+
const v = dyn();
|
|
7484
|
+
if (v != null) return v;
|
|
7485
|
+
} else if (leg === "lex") {
|
|
7486
|
+
const v = lex();
|
|
7487
|
+
if (v != null) return v;
|
|
7488
|
+
} else {
|
|
7489
|
+
console.warn("unknown lookup route leg", leg, '- expected "dyn" or "lex"');
|
|
7490
|
+
}
|
|
7491
|
+
}
|
|
7492
|
+
return null;
|
|
7493
|
+
}
|
|
7494
|
+
var isTypeName = (s) => {
|
|
7495
|
+
const c = s.charCodeAt(0);
|
|
7496
|
+
return c >= 65 && c <= 90;
|
|
7497
|
+
};
|
|
7498
|
+
function lookup(chain, name, dv = null) {
|
|
7499
|
+
let n = chain;
|
|
7500
|
+
while (n !== null) {
|
|
7501
|
+
const r = n[0].lookup(name);
|
|
7502
|
+
if (r === STOP) return dv;
|
|
7503
|
+
if (r !== NEXT) return r;
|
|
7504
|
+
n = n[1];
|
|
7505
|
+
}
|
|
7506
|
+
return dv;
|
|
7507
|
+
}
|
|
7508
|
+
var BindFrame = class {
|
|
7509
|
+
constructor(it, binds, isFrame) {
|
|
7510
|
+
this.it = it;
|
|
7511
|
+
this.binds = binds;
|
|
7512
|
+
this.isFrame = isFrame;
|
|
7513
|
+
}
|
|
7514
|
+
lookup(name) {
|
|
7515
|
+
const v = this.binds[name];
|
|
7516
|
+
return v === void 0 ? this.isFrame ? STOP : NEXT : v;
|
|
7517
|
+
}
|
|
7518
|
+
};
|
|
7519
|
+
var DynFrame = class {
|
|
7520
|
+
constructor(binds, types) {
|
|
7521
|
+
this.binds = binds;
|
|
7522
|
+
this.types = types;
|
|
7523
|
+
}
|
|
7524
|
+
lookup(name) {
|
|
7525
|
+
const v = (isTypeName(name) ? this.types : this.binds)[name];
|
|
7526
|
+
return v === void 0 ? NEXT : v;
|
|
7527
|
+
}
|
|
7528
|
+
};
|
|
7529
|
+
function computeViewsId(views) {
|
|
7530
|
+
let s = "";
|
|
7531
|
+
let n = views;
|
|
7532
|
+
while (n !== null) {
|
|
7533
|
+
s += n[0];
|
|
7534
|
+
n = n[1];
|
|
7535
|
+
}
|
|
7536
|
+
return s === "main" ? "" : s;
|
|
7537
|
+
}
|
|
7538
|
+
var Stack = class _Stack {
|
|
7539
|
+
constructor(fields) {
|
|
7540
|
+
Object.assign(this, fields);
|
|
7541
|
+
}
|
|
7542
|
+
_with(patch) {
|
|
7543
|
+
return new _Stack({ ...this, ...patch });
|
|
7544
|
+
}
|
|
7545
|
+
// Evaluate every provide the entered component publishes and push them as one
|
|
7546
|
+
// dynBinds frame, keyed by NAME. A value is published together with the absolute
|
|
7547
|
+
// path it lives at: the same declaration is read as `*name` AND resumed at by
|
|
7548
|
+
// `<x render="*name">`, so a consumer needs both halves. Types go in the same
|
|
7549
|
+
// frame's other map. No-op with no provides.
|
|
7550
|
+
_pushProvides() {
|
|
7551
|
+
const comp = this.comps.getCompFor(this.it);
|
|
7552
|
+
if (comp == null) return this;
|
|
7553
|
+
const { provide, provideType } = comp;
|
|
7554
|
+
const binds = {};
|
|
7555
|
+
const types = {};
|
|
7556
|
+
let has2 = false;
|
|
7557
|
+
const base = this._publishBase();
|
|
7558
|
+
for (const k in provide) {
|
|
7559
|
+
const step = provide[k].val.toPathItem?.() ?? null;
|
|
7560
|
+
if (step === null) continue;
|
|
7561
|
+
const value = provide[k].val.eval(this);
|
|
7562
|
+
binds[k] = { value, path: base === null ? null : base.concat([step]) };
|
|
7563
|
+
has2 = true;
|
|
7564
|
+
}
|
|
7565
|
+
for (const k in provideType) {
|
|
7566
|
+
types[k] = provideType[k];
|
|
7567
|
+
has2 = true;
|
|
7568
|
+
}
|
|
7569
|
+
if (!has2) return this;
|
|
7570
|
+
return this._with({ dynBinds: [new DynFrame(binds, types), this.dynBinds] });
|
|
7571
|
+
}
|
|
7572
|
+
// The absolute address of the component being entered, or null when this
|
|
7573
|
+
// position cannot be written down as one. Frame-only steps carry bindings and
|
|
7574
|
+
// address nothing, so they are compacted away first; what is left is checked
|
|
7575
|
+
// against the value actually being rendered, because a scope CAN move the
|
|
7576
|
+
// render position without contributing an addressing step (a plain `@each`
|
|
7577
|
+
// body re-binds `it` to the item while its rebuild step is an identity).
|
|
7578
|
+
//
|
|
7579
|
+
// A null base still publishes the VALUE — `*name` reads it fine — but there is
|
|
7580
|
+
// nowhere to resume, so `<x render="*name">` renders nothing rather than
|
|
7581
|
+
// editing whatever happens to live at the address we guessed.
|
|
7582
|
+
_publishBase() {
|
|
7583
|
+
const base = this.renderPath.toTransactionPath().compact();
|
|
7584
|
+
return base.lookup(this.root, NOT_FOUND) === this.it ? base : null;
|
|
7585
|
+
}
|
|
7586
|
+
static root(comps, it, ctx = null) {
|
|
7587
|
+
return new _Stack({
|
|
7588
|
+
comps,
|
|
7589
|
+
root: it,
|
|
7590
|
+
it,
|
|
7591
|
+
binds: [new BindFrame(it, {}, true), null],
|
|
7592
|
+
dynBinds: [new DynFrame({}, {}), null],
|
|
7593
|
+
views: ["main", null],
|
|
7594
|
+
viewsId: "",
|
|
7595
|
+
renderPath: new DispatchPath(),
|
|
7596
|
+
pendingFrame: false,
|
|
7597
|
+
ctx
|
|
7598
|
+
})._pushProvides();
|
|
7599
|
+
}
|
|
7600
|
+
// `renderPath` defaults to this stack's own: an ordinary scope does not move.
|
|
7601
|
+
// `pendingFrame` clears on a component frame (which emits the base) and is
|
|
7602
|
+
// inherited by transparent scopes, which have to carry it to the next boundary.
|
|
7603
|
+
enter(it, bindings = {}, isFrame = true, renderPath = this.renderPath, pendingFrame = null) {
|
|
7604
|
+
const stack = this._with({
|
|
7605
|
+
it,
|
|
7606
|
+
binds: [new BindFrame(it, bindings, isFrame), this.binds],
|
|
7607
|
+
renderPath,
|
|
7608
|
+
pendingFrame: pendingFrame ?? (isFrame ? false : this.pendingFrame)
|
|
7609
|
+
});
|
|
7610
|
+
return isFrame ? stack._pushProvides() : stack;
|
|
7611
|
+
}
|
|
7612
|
+
pushViewName(name) {
|
|
7613
|
+
const views = [name, this.views];
|
|
7614
|
+
return this._with({ views, viewsId: computeViewsId(views) });
|
|
7615
|
+
}
|
|
7616
|
+
// Published types are stable per scope and would only churn the render cache, so
|
|
7617
|
+
// the cache key covers values alone.
|
|
7618
|
+
_pushDynBindValuesToArray(arr, comp) {
|
|
7619
|
+
for (const k in comp.provide) arr.push(this.lookupDynamic(k));
|
|
7620
|
+
for (const k in comp.lookup) arr.push(this.lookupDynamic(k));
|
|
7621
|
+
}
|
|
7622
|
+
// `*name`: the nearest binding above (including this component's own provides,
|
|
7623
|
+
// pushed on entering it), else a path registered in the component's lexical
|
|
7624
|
+
// scope, else this component's declared default, else null.
|
|
7625
|
+
//
|
|
7626
|
+
// One chain walk and no producer resolution: a lookup names what it WANTS, so the
|
|
7627
|
+
// frame it wants is keyed by that name. The default belongs to the CONSUMER's
|
|
7628
|
+
// declaration and is evaluated against the consumer's stack, which is why it is
|
|
7629
|
+
// consulted only after the whole chain has missed.
|
|
7630
|
+
lookupDynamicLocated(name) {
|
|
7631
|
+
if (isTypeName(name)) return null;
|
|
7632
|
+
const v = lookup(this.dynBinds, name);
|
|
7633
|
+
if (v != null) return v;
|
|
7634
|
+
const comp = this.comps.getCompFor(this.it);
|
|
7635
|
+
if (comp == null) return null;
|
|
7636
|
+
const path2 = comp.scope?.lookupPath?.(name) ?? null;
|
|
7637
|
+
if (path2 !== null) {
|
|
7638
|
+
const value2 = path2.lookup(this.root, NOT_FOUND);
|
|
7639
|
+
if (value2 !== NOT_FOUND) return { value: value2, path: path2 };
|
|
7640
|
+
}
|
|
7641
|
+
const dval = comp.lookup[name]?.val ?? null;
|
|
7642
|
+
if (dval === null) return null;
|
|
7643
|
+
const step = dval.toPathItem?.() ?? null;
|
|
7644
|
+
const value = dval.eval(this);
|
|
7645
|
+
return step === null ? { value, path: null } : { value, path: this.renderPath.toTransactionPath().concat([step]) };
|
|
7646
|
+
}
|
|
7647
|
+
lookupDynamic(name) {
|
|
7648
|
+
if (isTypeName(name)) return lookup(this.dynBinds, name);
|
|
7649
|
+
return this.lookupDynamicLocated(name)?.value ?? null;
|
|
7650
|
+
}
|
|
7651
|
+
lookupBind(name) {
|
|
7652
|
+
return lookup(this.binds, name);
|
|
7653
|
+
}
|
|
7654
|
+
lookupFieldRaw(name) {
|
|
7655
|
+
return this.it[name] ?? null;
|
|
7656
|
+
}
|
|
7657
|
+
lookupMethod(name) {
|
|
7658
|
+
const fn = this.it[name];
|
|
7659
|
+
return fn instanceof Function ? fn.call(this.it) : null;
|
|
7660
|
+
}
|
|
7661
|
+
// The dispatched DOM event / drag info, read only by EventMemberVal's
|
|
7662
|
+
// `e.<member>` handler args. Null outside a live event transaction.
|
|
7663
|
+
lookupEvent() {
|
|
7664
|
+
return this.ctx?.event ?? null;
|
|
7665
|
+
}
|
|
7666
|
+
lookupDragInfo() {
|
|
7667
|
+
return this.ctx?.dragInfo ?? null;
|
|
7668
|
+
}
|
|
7669
|
+
getHandlerFor(name, key) {
|
|
7670
|
+
return this.comps.getHandlerFor(this.it, name, key);
|
|
7671
|
+
}
|
|
7672
|
+
lookupBestView(views, defaultViewName) {
|
|
7673
|
+
let n = this.views;
|
|
7674
|
+
while (n !== null) {
|
|
7675
|
+
const view = views[n[0]];
|
|
7676
|
+
if (view !== void 0) return view;
|
|
7677
|
+
n = n[1];
|
|
7678
|
+
}
|
|
7679
|
+
return views[defaultViewName];
|
|
7680
|
+
}
|
|
7681
|
+
};
|
|
7682
|
+
var NOT_FOUND = /* @__PURE__ */ Symbol("NOT_FOUND");
|
|
7683
|
+
|
|
7404
7684
|
// src/components.js
|
|
7405
7685
|
var COMPONENT = /* @__PURE__ */ Symbol.for("tutuca.component");
|
|
7406
7686
|
var Components = class {
|
|
@@ -7439,12 +7719,14 @@ var ComponentStack = class _ComponentStack {
|
|
|
7439
7719
|
this.byName = {};
|
|
7440
7720
|
this.intentsByName = {};
|
|
7441
7721
|
this.macros = {};
|
|
7722
|
+
this.paths = {};
|
|
7442
7723
|
}
|
|
7443
7724
|
enter() {
|
|
7444
7725
|
return new _ComponentStack(this.comps, this);
|
|
7445
7726
|
}
|
|
7446
7727
|
registerComponents(comps, opts) {
|
|
7447
|
-
const { aliases: aliases2 = {} } = opts ?? {};
|
|
7728
|
+
const { aliases: aliases2 = {}, paths } = opts ?? {};
|
|
7729
|
+
if (paths) this.registerPaths(paths);
|
|
7448
7730
|
for (let i = 0; i < comps.length; i++) {
|
|
7449
7731
|
const Comp = comps[i];
|
|
7450
7732
|
Comp[COMPONENT].scope = this.enter();
|
|
@@ -7458,6 +7740,27 @@ var ComponentStack = class _ComponentStack {
|
|
|
7458
7740
|
else console.warn("alias", alias, "to inexistent component", aliases2[alias]);
|
|
7459
7741
|
}
|
|
7460
7742
|
}
|
|
7743
|
+
// Register lowercase names as absolute paths from the app state root. A
|
|
7744
|
+
// descendant that declares one in its `lookup` reads and renders `*name` without
|
|
7745
|
+
// anything above it publishing one — which is what makes a session, a theme or a
|
|
7746
|
+
// host-owned value available in its natural registration scope, instead of forcing
|
|
7747
|
+
// an application root whose only job is to `provide` it. Register on a nested
|
|
7748
|
+
// scope to narrow a name; nearest registration wins.
|
|
7749
|
+
//
|
|
7750
|
+
// Uppercase names are ignored: a component TYPE is what `lookupComponent` already
|
|
7751
|
+
// answers, and a type has no path.
|
|
7752
|
+
registerPaths(paths) {
|
|
7753
|
+
for (const name in paths) {
|
|
7754
|
+
if (isTypeName(name)) {
|
|
7755
|
+
console.warn("registerPaths: a type name has no path", name);
|
|
7756
|
+
continue;
|
|
7757
|
+
}
|
|
7758
|
+
this.paths[name] = paths[name].toPath?.() ?? paths[name];
|
|
7759
|
+
}
|
|
7760
|
+
}
|
|
7761
|
+
lookupPath(name) {
|
|
7762
|
+
return this.paths[name] ?? this.parent?.lookupPath(name) ?? null;
|
|
7763
|
+
}
|
|
7461
7764
|
registerMacros(macros) {
|
|
7462
7765
|
for (const key in macros) {
|
|
7463
7766
|
const lower = key.toLowerCase();
|
|
@@ -7489,17 +7792,16 @@ var ComponentStack = class _ComponentStack {
|
|
|
7489
7792
|
lookupComponent(name) {
|
|
7490
7793
|
return this.byName[name] ?? this.parent?.lookupComponent(name) ?? null;
|
|
7491
7794
|
}
|
|
7492
|
-
//
|
|
7493
|
-
// names
|
|
7494
|
-
//
|
|
7495
|
-
//
|
|
7496
|
-
//
|
|
7497
|
-
|
|
7795
|
+
// Whether anything in this scope chain provides `name`. Existence only: a lookup
|
|
7796
|
+
// names what it WANTS and takes whoever is nearest above it at render time, so
|
|
7797
|
+
// there is no producer to identify — several components may publish one name and
|
|
7798
|
+
// the live render ancestry decides. Used by the linter to tell a lookup that can
|
|
7799
|
+
// be satisfied from one that never will be.
|
|
7800
|
+
hasProvider(name) {
|
|
7498
7801
|
for (const compName in this.byName) {
|
|
7499
|
-
|
|
7500
|
-
if (Comp.provide?.[name] !== void 0) return Comp;
|
|
7802
|
+
if (this.byName[compName].provide?.[name] !== void 0) return true;
|
|
7501
7803
|
}
|
|
7502
|
-
return this.parent?.
|
|
7804
|
+
return this.parent?.hasProvider(name) ?? false;
|
|
7503
7805
|
}
|
|
7504
7806
|
lookupMacro(name) {
|
|
7505
7807
|
return this.macros[name] ?? this.parent?.lookupMacro(name) ?? null;
|
|
@@ -7516,10 +7818,6 @@ var LookupInfo = class {
|
|
|
7516
7818
|
}
|
|
7517
7819
|
};
|
|
7518
7820
|
var isString = (v) => typeof v === "string";
|
|
7519
|
-
var isTypeName = (s) => {
|
|
7520
|
-
const c = s.charCodeAt(0);
|
|
7521
|
-
return c >= 65 && c <= 90;
|
|
7522
|
-
};
|
|
7523
7821
|
var _rawSpecKeys = "name view style commonStyle globalStyle receive intent alter views provide lookup fields methods statics";
|
|
7524
7822
|
var KNOWN_SPEC_KEYS = new Set(_rawSpecKeys.split(" "));
|
|
7525
7823
|
var _compId = 0;
|
|
@@ -9883,7 +10181,6 @@ var DYN_VAL_NOT_DEFINED = "DYN_VAL_NOT_DEFINED";
|
|
|
9883
10181
|
var DYN_ALIAS_NOT_REFERENCED = "DYN_ALIAS_NOT_REFERENCED";
|
|
9884
10182
|
var PROVIDE_NOT_ADDRESSABLE = "PROVIDE_NOT_ADDRESSABLE";
|
|
9885
10183
|
var PROVIDE_TYPE_BAD_SHAPE = "PROVIDE_TYPE_BAD_SHAPE";
|
|
9886
|
-
var PROVIDE_NAME_COLLISION = "PROVIDE_NAME_COLLISION";
|
|
9887
10184
|
var LOOKUP_BAD_SHAPE = "LOOKUP_BAD_SHAPE";
|
|
9888
10185
|
var LOOKUP_NO_PROVIDER = "LOOKUP_NO_PROVIDER";
|
|
9889
10186
|
var RENDER_IT_OUTSIDE_OF_LOOP = "RENDER_IT_OUTSIDE_OF_LOOP";
|
|
@@ -10006,7 +10303,6 @@ function checkComponent(Comp, lx = new LintContext(), { wellKnownExtras = EMPTY_
|
|
|
10006
10303
|
checkFieldMethodNameCollisions(lx, Comp);
|
|
10007
10304
|
checkProvidesAreAddressable(lx, Comp);
|
|
10008
10305
|
checkProvidedTypes(lx, Comp);
|
|
10009
|
-
checkProvideNameCollisions(lx, Comp);
|
|
10010
10306
|
checkLookupShapes(lx, Comp);
|
|
10011
10307
|
checkLookupTypesResolve(lx, Comp);
|
|
10012
10308
|
checkLookupsHaveProviders(lx, Comp);
|
|
@@ -10690,19 +10986,6 @@ function checkProvidedTypes(lx, Comp) {
|
|
|
10690
10986
|
if (raw !== "self") lx.error(PROVIDE_TYPE_BAD_SHAPE, { name, value: raw });
|
|
10691
10987
|
}
|
|
10692
10988
|
}
|
|
10693
|
-
function checkProvideNameCollisions(lx, Comp) {
|
|
10694
|
-
const scope = Comp.scope;
|
|
10695
|
-
if (!scope) return;
|
|
10696
|
-
for (const name in Comp.provide) {
|
|
10697
|
-
for (let s = scope; s; s = s.parent) {
|
|
10698
|
-
for (const otherName in s.byName) {
|
|
10699
|
-
const Other = s.byName[otherName];
|
|
10700
|
-
if (Other !== Comp && Other.provide?.[name] !== void 0)
|
|
10701
|
-
lx.error(PROVIDE_NAME_COLLISION, { name, other: Other.name });
|
|
10702
|
-
}
|
|
10703
|
-
}
|
|
10704
|
-
}
|
|
10705
|
-
}
|
|
10706
10989
|
var KNOWN_LOOKUP_KEYS = /* @__PURE__ */ new Set(["name", "default"]);
|
|
10707
10990
|
function checkLookupShapes(lx, Comp) {
|
|
10708
10991
|
const raw = Comp._rawLookup;
|
|
@@ -10744,7 +11027,7 @@ function checkLookupsHaveProviders(lx, Comp) {
|
|
|
10744
11027
|
if (!scope) return;
|
|
10745
11028
|
for (const name in Comp.lookup) {
|
|
10746
11029
|
if (isTypeName2(name)) continue;
|
|
10747
|
-
if (scope.
|
|
11030
|
+
if (scope.hasProvider?.(name) || scope.lookupPath?.(name)) continue;
|
|
10748
11031
|
const info = { name, hasDefault: Comp.lookup[name].val != null };
|
|
10749
11032
|
if (info.hasDefault) lx.hint(LOOKUP_NO_PROVIDER, info);
|
|
10750
11033
|
else lx.error(LOOKUP_NO_PROVIDER, info);
|
|
@@ -10866,9 +11149,22 @@ var CHECK_TYPE_LIST = Array.isArray;
|
|
|
10866
11149
|
var CHECK_TYPE_OBJECT = isPlainObject;
|
|
10867
11150
|
var CHECK_TYPE_MAP = (v) => v instanceof Map;
|
|
10868
11151
|
var CHECK_TYPE_SET = (v) => v instanceof Set;
|
|
11152
|
+
var COERCE_NONE = (_v) => null;
|
|
11153
|
+
var COERCE_BOOL = (v) => !!v;
|
|
11154
|
+
var COERCE_STRING = (v) => v?.toString?.() ?? "";
|
|
11155
|
+
var COERCE_INT = (v) => Number.isFinite(v) ? Math.trunc(v) : null;
|
|
11156
|
+
var COERCE_LIST = (v) => Array.isArray(v) ? [...v] : null;
|
|
11157
|
+
var COERCE_OBJECT = (v) => isPlainObject(v) ? { ...v } : null;
|
|
11158
|
+
var COERCE_MAP = (v) => {
|
|
11159
|
+
if (v instanceof Map) return new Map(v);
|
|
11160
|
+
if (Array.isArray(v) || isPlainObject(v))
|
|
11161
|
+
return new Map(Array.isArray(v) ? v : Object.entries(v));
|
|
11162
|
+
return null;
|
|
11163
|
+
};
|
|
11164
|
+
var COERCE_SET = (v) => v instanceof Set || Array.isArray(v) ? new Set(v) : null;
|
|
10869
11165
|
var FieldBool = class extends Field {
|
|
10870
11166
|
constructor(name, defaultValue = false) {
|
|
10871
|
-
super("bool", name, CHECK_TYPE_BOOL,
|
|
11167
|
+
super("bool", name, CHECK_TYPE_BOOL, COERCE_BOOL, defaultValue);
|
|
10872
11168
|
}
|
|
10873
11169
|
};
|
|
10874
11170
|
var FieldAny = class extends Field {
|
|
@@ -10878,23 +11174,17 @@ var FieldAny = class extends Field {
|
|
|
10878
11174
|
};
|
|
10879
11175
|
var FieldString = class extends Field {
|
|
10880
11176
|
constructor(name, defaultValue = "") {
|
|
10881
|
-
super("text", name, CHECK_TYPE_STRING,
|
|
11177
|
+
super("text", name, CHECK_TYPE_STRING, COERCE_STRING, defaultValue);
|
|
10882
11178
|
}
|
|
10883
11179
|
};
|
|
10884
11180
|
var FieldInt = class extends Field {
|
|
10885
11181
|
constructor(name, defaultValue = 0) {
|
|
10886
|
-
super(
|
|
10887
|
-
"int",
|
|
10888
|
-
name,
|
|
10889
|
-
CHECK_TYPE_INT,
|
|
10890
|
-
(v) => Number.isFinite(v) ? Math.trunc(v) : null,
|
|
10891
|
-
defaultValue
|
|
10892
|
-
);
|
|
11182
|
+
super("int", name, CHECK_TYPE_INT, COERCE_INT, defaultValue);
|
|
10893
11183
|
}
|
|
10894
11184
|
};
|
|
10895
11185
|
var FieldFloat = class extends Field {
|
|
10896
11186
|
constructor(name, defaultValue = 0) {
|
|
10897
|
-
super("float", name, CHECK_TYPE_FLOAT,
|
|
11187
|
+
super("float", name, CHECK_TYPE_FLOAT, COERCE_NONE, defaultValue);
|
|
10898
11188
|
}
|
|
10899
11189
|
};
|
|
10900
11190
|
var metaOf = (v) => v?.constructor?.[COMPONENT] ?? v?.constructor?.getMetaClass?.();
|
|
@@ -10907,45 +11197,22 @@ var FieldComp = class extends Field {
|
|
|
10907
11197
|
};
|
|
10908
11198
|
var FieldList = class extends Field {
|
|
10909
11199
|
constructor(name, defaultValue = []) {
|
|
10910
|
-
super("list", name, CHECK_TYPE_LIST,
|
|
11200
|
+
super("list", name, CHECK_TYPE_LIST, COERCE_LIST, defaultValue);
|
|
10911
11201
|
}
|
|
10912
11202
|
};
|
|
10913
11203
|
var FieldObject = class extends Field {
|
|
10914
11204
|
constructor(name, defaultValue = {}) {
|
|
10915
|
-
super(
|
|
10916
|
-
"object",
|
|
10917
|
-
name,
|
|
10918
|
-
CHECK_TYPE_OBJECT,
|
|
10919
|
-
(v) => isPlainObject(v) ? { ...v } : null,
|
|
10920
|
-
defaultValue
|
|
10921
|
-
);
|
|
11205
|
+
super("object", name, CHECK_TYPE_OBJECT, COERCE_OBJECT, defaultValue);
|
|
10922
11206
|
}
|
|
10923
11207
|
};
|
|
10924
11208
|
var FieldMap = class extends Field {
|
|
10925
11209
|
constructor(name, defaultValue = /* @__PURE__ */ new Map()) {
|
|
10926
|
-
super(
|
|
10927
|
-
"map",
|
|
10928
|
-
name,
|
|
10929
|
-
CHECK_TYPE_MAP,
|
|
10930
|
-
(v) => {
|
|
10931
|
-
if (v instanceof Map) return new Map(v);
|
|
10932
|
-
if (Array.isArray(v) || isPlainObject(v))
|
|
10933
|
-
return new Map(Array.isArray(v) ? v : Object.entries(v));
|
|
10934
|
-
return null;
|
|
10935
|
-
},
|
|
10936
|
-
defaultValue
|
|
10937
|
-
);
|
|
11210
|
+
super("map", name, CHECK_TYPE_MAP, COERCE_MAP, defaultValue);
|
|
10938
11211
|
}
|
|
10939
11212
|
};
|
|
10940
11213
|
var FieldSet = class extends Field {
|
|
10941
11214
|
constructor(name, defaultValue = /* @__PURE__ */ new Set()) {
|
|
10942
|
-
super(
|
|
10943
|
-
"set",
|
|
10944
|
-
name,
|
|
10945
|
-
CHECK_TYPE_SET,
|
|
10946
|
-
(v) => v instanceof Set || Array.isArray(v) ? new Set(v) : null,
|
|
10947
|
-
defaultValue
|
|
10948
|
-
);
|
|
11215
|
+
super("set", name, CHECK_TYPE_SET, COERCE_SET, defaultValue);
|
|
10949
11216
|
}
|
|
10950
11217
|
};
|
|
10951
11218
|
function mkCompField(field, scope, args) {
|
|
@@ -11043,8 +11310,7 @@ function classFromData(name, { fields = {}, methods, statics }) {
|
|
|
11043
11310
|
const value = fields[field];
|
|
11044
11311
|
const type3 = typeof value;
|
|
11045
11312
|
if (type3 === "string") b.addField(field, value, FieldString);
|
|
11046
|
-
else if (type3 === "number")
|
|
11047
|
-
b.addField(field, value, Number.isInteger(value) ? FieldInt : FieldFloat);
|
|
11313
|
+
else if (type3 === "number") b.addField(field, value, FieldFloat);
|
|
11048
11314
|
else if (type3 === "boolean") b.addField(field, value, FieldBool);
|
|
11049
11315
|
else if (Array.isArray(value)) b.addField(field, [...value], FieldList);
|
|
11050
11316
|
else if (value instanceof Set) b.addField(field, new Set(value), FieldSet);
|
|
@@ -11121,160 +11387,6 @@ Component.fromSpec = (opts) => {
|
|
|
11121
11387
|
};
|
|
11122
11388
|
var component = (opts) => Component.fromSpec(opts);
|
|
11123
11389
|
|
|
11124
|
-
// src/stack.js
|
|
11125
|
-
var STOP = /* @__PURE__ */ Symbol("STOP");
|
|
11126
|
-
var NEXT = /* @__PURE__ */ Symbol("NEXT");
|
|
11127
|
-
var DEFAULT_ROUTE = ["dyn", "lex"];
|
|
11128
|
-
function routeLookup(route, lex, dyn) {
|
|
11129
|
-
for (let i = 0; i < route.length; i++) {
|
|
11130
|
-
const leg = route[i];
|
|
11131
|
-
if (leg === "dyn") {
|
|
11132
|
-
const v = dyn();
|
|
11133
|
-
if (v != null) return v;
|
|
11134
|
-
} else if (leg === "lex") {
|
|
11135
|
-
const v = lex();
|
|
11136
|
-
if (v != null) return v;
|
|
11137
|
-
} else {
|
|
11138
|
-
console.warn("unknown lookup route leg", leg, '- expected "dyn" or "lex"');
|
|
11139
|
-
}
|
|
11140
|
-
}
|
|
11141
|
-
return null;
|
|
11142
|
-
}
|
|
11143
|
-
function lookup(chain, name, dv = null) {
|
|
11144
|
-
let n = chain;
|
|
11145
|
-
while (n !== null) {
|
|
11146
|
-
const r = n[0].lookup(name);
|
|
11147
|
-
if (r === STOP) return dv;
|
|
11148
|
-
if (r !== NEXT) return r;
|
|
11149
|
-
n = n[1];
|
|
11150
|
-
}
|
|
11151
|
-
return dv;
|
|
11152
|
-
}
|
|
11153
|
-
var BindFrame = class {
|
|
11154
|
-
constructor(it, binds, isFrame) {
|
|
11155
|
-
this.it = it;
|
|
11156
|
-
this.binds = binds;
|
|
11157
|
-
this.isFrame = isFrame;
|
|
11158
|
-
}
|
|
11159
|
-
lookup(name) {
|
|
11160
|
-
const v = this.binds[name];
|
|
11161
|
-
return v === void 0 ? this.isFrame ? STOP : NEXT : v;
|
|
11162
|
-
}
|
|
11163
|
-
};
|
|
11164
|
-
var ObjectFrame = class {
|
|
11165
|
-
constructor(binds) {
|
|
11166
|
-
this.binds = binds;
|
|
11167
|
-
}
|
|
11168
|
-
lookup(key) {
|
|
11169
|
-
const v = this.binds[key];
|
|
11170
|
-
return v === void 0 ? NEXT : v;
|
|
11171
|
-
}
|
|
11172
|
-
};
|
|
11173
|
-
function computeViewsId(views) {
|
|
11174
|
-
let s = "";
|
|
11175
|
-
let n = views;
|
|
11176
|
-
while (n !== null) {
|
|
11177
|
-
s += n[0];
|
|
11178
|
-
n = n[1];
|
|
11179
|
-
}
|
|
11180
|
-
return s === "main" ? "" : s;
|
|
11181
|
-
}
|
|
11182
|
-
var Stack = class _Stack {
|
|
11183
|
-
constructor(comps, it, binds, dynBinds, views, viewsId, ctx = null) {
|
|
11184
|
-
this.comps = comps;
|
|
11185
|
-
this.it = it;
|
|
11186
|
-
this.binds = binds;
|
|
11187
|
-
this.dynBinds = dynBinds;
|
|
11188
|
-
this.views = views;
|
|
11189
|
-
this.viewsId = viewsId;
|
|
11190
|
-
this.ctx = ctx;
|
|
11191
|
-
}
|
|
11192
|
-
// Evaluate every provide the entered component publishes and push them as one
|
|
11193
|
-
// dynBinds frame, keyed by NAME. Published types go in the same frame: a type name
|
|
11194
|
-
// starts A-Z and a value name does not, so the two namespaces cannot collide and
|
|
11195
|
-
// nearest-ancestor-wins falls out of frame order for both. No-op with no provides.
|
|
11196
|
-
_pushProvides() {
|
|
11197
|
-
const comp = this.comps.getCompFor(this.it);
|
|
11198
|
-
if (comp == null) return this;
|
|
11199
|
-
const { provide, provideType } = comp;
|
|
11200
|
-
const dynObj = {};
|
|
11201
|
-
let has2 = false;
|
|
11202
|
-
for (const k in provide) {
|
|
11203
|
-
dynObj[k] = provide[k].val.eval(this);
|
|
11204
|
-
has2 = true;
|
|
11205
|
-
}
|
|
11206
|
-
for (const k in provideType) {
|
|
11207
|
-
dynObj[k] = provideType[k];
|
|
11208
|
-
has2 = true;
|
|
11209
|
-
}
|
|
11210
|
-
if (!has2) return this;
|
|
11211
|
-
const newDynBinds = [new ObjectFrame(dynObj), this.dynBinds];
|
|
11212
|
-
const { comps, it, binds, views, viewsId, ctx } = this;
|
|
11213
|
-
return new _Stack(comps, it, binds, newDynBinds, views, viewsId, ctx);
|
|
11214
|
-
}
|
|
11215
|
-
static root(comps, it, ctx) {
|
|
11216
|
-
const binds = [new BindFrame(it, {}, true), null];
|
|
11217
|
-
const dynBinds = [new ObjectFrame({}), null];
|
|
11218
|
-
const views = ["main", null];
|
|
11219
|
-
return new _Stack(comps, it, binds, dynBinds, views, "", ctx)._pushProvides();
|
|
11220
|
-
}
|
|
11221
|
-
enter(it, bindings = {}, isFrame = true) {
|
|
11222
|
-
const { comps, binds, dynBinds, views, viewsId, ctx } = this;
|
|
11223
|
-
const newBinds = [new BindFrame(it, bindings, isFrame), binds];
|
|
11224
|
-
const stack = new _Stack(comps, it, newBinds, dynBinds, views, viewsId, ctx);
|
|
11225
|
-
return isFrame ? stack._pushProvides() : stack;
|
|
11226
|
-
}
|
|
11227
|
-
pushViewName(name) {
|
|
11228
|
-
const { comps, it, binds, dynBinds, views, ctx } = this;
|
|
11229
|
-
const newViews = [name, views];
|
|
11230
|
-
return new _Stack(comps, it, binds, dynBinds, newViews, computeViewsId(newViews), ctx);
|
|
11231
|
-
}
|
|
11232
|
-
// Published types are stable per scope and would only churn the render cache, so
|
|
11233
|
-
// the cache key covers values alone.
|
|
11234
|
-
_pushDynBindValuesToArray(arr, comp) {
|
|
11235
|
-
for (const k in comp.provide) arr.push(this.lookupDynamic(k));
|
|
11236
|
-
for (const k in comp.lookup) arr.push(this.lookupDynamic(k));
|
|
11237
|
-
}
|
|
11238
|
-
// `*name`: the nearest binding above (including this component's own provides,
|
|
11239
|
-
// pushed on entering it), else this component's declared default, else null.
|
|
11240
|
-
lookupDynamic(name) {
|
|
11241
|
-
const v = lookup(this.dynBinds, name);
|
|
11242
|
-
if (v != null) return v;
|
|
11243
|
-
const comp = this.comps.getCompFor(this.it);
|
|
11244
|
-
return comp?.lookup[name]?.val?.eval(this) ?? null;
|
|
11245
|
-
}
|
|
11246
|
-
lookupBind(name) {
|
|
11247
|
-
return lookup(this.binds, name);
|
|
11248
|
-
}
|
|
11249
|
-
lookupFieldRaw(name) {
|
|
11250
|
-
return this.it[name] ?? null;
|
|
11251
|
-
}
|
|
11252
|
-
lookupMethod(name) {
|
|
11253
|
-
const fn = this.it[name];
|
|
11254
|
-
return fn instanceof Function ? fn.call(this.it) : null;
|
|
11255
|
-
}
|
|
11256
|
-
// The dispatched DOM event / drag info, read only by EventMemberVal's
|
|
11257
|
-
// `e.<member>` handler args. Null outside a live event transaction.
|
|
11258
|
-
lookupEvent() {
|
|
11259
|
-
return this.ctx?.event ?? null;
|
|
11260
|
-
}
|
|
11261
|
-
lookupDragInfo() {
|
|
11262
|
-
return this.ctx?.dragInfo ?? null;
|
|
11263
|
-
}
|
|
11264
|
-
getHandlerFor(name, key) {
|
|
11265
|
-
return this.comps.getHandlerFor(this.it, name, key);
|
|
11266
|
-
}
|
|
11267
|
-
lookupBestView(views, defaultViewName) {
|
|
11268
|
-
let n = this.views;
|
|
11269
|
-
while (n !== null) {
|
|
11270
|
-
const view = views[n[0]];
|
|
11271
|
-
if (view !== void 0) return view;
|
|
11272
|
-
n = n[1];
|
|
11273
|
-
}
|
|
11274
|
-
return views[defaultViewName];
|
|
11275
|
-
}
|
|
11276
|
-
};
|
|
11277
|
-
|
|
11278
11390
|
// src/transactor.js
|
|
11279
11391
|
var State2 = class {
|
|
11280
11392
|
constructor(val) {
|
|
@@ -11350,9 +11462,9 @@ var Transactor = class {
|
|
|
11350
11462
|
// `.a[.selId]` render target reconstructed from a DOM event) against the root the
|
|
11351
11463
|
// handler read, so pathKeys carries concrete keys instead of dropping the dynamic
|
|
11352
11464
|
// step. No-op when nobody is observing.
|
|
11353
|
-
_emitRecord(root, { kind, name, args, path, targetPath, handler, handlerName, matched, before, after, parent }) {
|
|
11465
|
+
_emitRecord(root, { kind, name, args, path: path2, targetPath, handler, handlerName, matched, before, after, parent }) {
|
|
11354
11466
|
if (this._observers.length === 0) return;
|
|
11355
|
-
const pinned =
|
|
11467
|
+
const pinned = path2.pinKeys(root);
|
|
11356
11468
|
this._emit({
|
|
11357
11469
|
kind,
|
|
11358
11470
|
name,
|
|
@@ -11403,18 +11515,20 @@ var Transactor = class {
|
|
|
11403
11515
|
// intent's answerPath is: a reply must reach the sender that asked even if a key
|
|
11404
11516
|
// moved while the message was in flight. Null when nobody is waiting — a host
|
|
11405
11517
|
// sendAtRoot or a view's own `@on.*` — and ctx.sendReply refuses on that.
|
|
11406
|
-
pushSend(
|
|
11407
|
-
const t = new SendEvent(
|
|
11408
|
-
t.
|
|
11518
|
+
pushSend(path2, name, args = [], parent = null, origin = null, txnPath = null) {
|
|
11519
|
+
const t = new SendEvent(path2, this, name, args, parent);
|
|
11520
|
+
t.txnPath = txnPath;
|
|
11521
|
+
t.origin = origin;
|
|
11522
|
+
t.originPinned = origin === null ? null : origin.toTransactionPath().pinKeys(this.state.val);
|
|
11409
11523
|
this.pushTransaction(t);
|
|
11410
11524
|
return this._link(t, parent);
|
|
11411
11525
|
}
|
|
11412
11526
|
// Raise an intent: a job the sender did not address, walked along a route until
|
|
11413
11527
|
// something answers. `opts.route` is a list of legs (see DEFAULT_ROUTE) and
|
|
11414
11528
|
// `opts.livePath` opts out of pinning the answer's destination keys.
|
|
11415
|
-
pushIntent(
|
|
11529
|
+
pushIntent(path2, name, args = [], opts = {}, parent = null) {
|
|
11416
11530
|
const release = parent ? parent.completion.track() : null;
|
|
11417
|
-
const walk = new IntentWalk(this,
|
|
11531
|
+
const walk = new IntentWalk(this, path2, name, args, opts, parent, release);
|
|
11418
11532
|
walk.advance();
|
|
11419
11533
|
return walk;
|
|
11420
11534
|
}
|
|
@@ -11448,16 +11562,17 @@ var Transactor = class {
|
|
|
11448
11562
|
transaction._completion?.releaseSelf();
|
|
11449
11563
|
}
|
|
11450
11564
|
}
|
|
11451
|
-
transactInputNow(
|
|
11452
|
-
this.transact(new InputEvent(
|
|
11565
|
+
transactInputNow(path2, event, eventHandler, dragInfo) {
|
|
11566
|
+
this.transact(new InputEvent(path2, event, eventHandler, this, dragInfo));
|
|
11453
11567
|
}
|
|
11454
11568
|
};
|
|
11455
11569
|
function nullHandler() {
|
|
11456
11570
|
return this;
|
|
11457
11571
|
}
|
|
11458
11572
|
var Transaction = class {
|
|
11459
|
-
constructor(
|
|
11460
|
-
this.path =
|
|
11573
|
+
constructor(path2, transactor, parentTransaction = null) {
|
|
11574
|
+
this.path = path2;
|
|
11575
|
+
this.txnPath = null;
|
|
11461
11576
|
this.transactor = transactor;
|
|
11462
11577
|
this.parentTransaction = parentTransaction;
|
|
11463
11578
|
this._completion = null;
|
|
@@ -11506,9 +11621,11 @@ var Transaction = class {
|
|
|
11506
11621
|
getHandlerAndArgs(_root, _instance, _comps) {
|
|
11507
11622
|
return null;
|
|
11508
11623
|
}
|
|
11509
|
-
// The path used to apply the mutation
|
|
11510
|
-
//
|
|
11624
|
+
// The path used to apply the mutation: the ACTIVE frame of the dispatch path, so
|
|
11625
|
+
// an event inside a `<x render="*name">` subtree updates the value where it
|
|
11626
|
+
// really lives (the dispatch `this.path` keeps the visual callers, for bubbling).
|
|
11511
11627
|
getTransactionPath() {
|
|
11628
|
+
if (this.txnPath !== null) return this.txnPath;
|
|
11512
11629
|
return this.path.toTransactionPath().compact();
|
|
11513
11630
|
}
|
|
11514
11631
|
run(curRoot, comps) {
|
|
@@ -11526,15 +11643,16 @@ var Transaction = class {
|
|
|
11526
11643
|
}
|
|
11527
11644
|
};
|
|
11528
11645
|
var InputEvent = class extends Transaction {
|
|
11529
|
-
constructor(
|
|
11530
|
-
super(
|
|
11646
|
+
constructor(path2, e, handler, transactor, dragInfo) {
|
|
11647
|
+
super(path2, transactor);
|
|
11531
11648
|
this.e = e;
|
|
11532
11649
|
this.handler = handler;
|
|
11533
11650
|
this.dragInfo = dragInfo;
|
|
11534
11651
|
this._dispatchPath = null;
|
|
11535
11652
|
}
|
|
11536
|
-
// Frame steps removed,
|
|
11537
|
-
//
|
|
11653
|
+
// Frame-only steps removed, one step per crossed component kept — inside every
|
|
11654
|
+
// continuation frame independently, so bubbling it visits every component and
|
|
11655
|
+
// then returns to the caller that wrote the `*name`.
|
|
11538
11656
|
get dispatchPath() {
|
|
11539
11657
|
this._dispatchPath ??= this.path.compact();
|
|
11540
11658
|
return this._dispatchPath;
|
|
@@ -11569,11 +11687,11 @@ var InputEvent = class extends Transaction {
|
|
|
11569
11687
|
this.transactor.pushIntent(this.dispatchPath, name, args, rest, this);
|
|
11570
11688
|
}
|
|
11571
11689
|
getHandlerAndArgs(root, _instance, comps) {
|
|
11572
|
-
const stack = this.path.
|
|
11690
|
+
const stack = this.path.buildStack(Stack.root(comps, root, this));
|
|
11573
11691
|
const [handler, args] = this.handler.getHandlerAndArgs(stack, this);
|
|
11574
11692
|
this._handlerArgs = [...args];
|
|
11575
|
-
const
|
|
11576
|
-
args.push(new EventContext(
|
|
11693
|
+
const path2 = this.dispatchPath;
|
|
11694
|
+
args.push(new EventContext(path2, this.transactor, this));
|
|
11577
11695
|
return [handler, args];
|
|
11578
11696
|
}
|
|
11579
11697
|
// The dispatched DOM event, read only through `e.<member>` handler args
|
|
@@ -11584,11 +11702,11 @@ var InputEvent = class extends Transaction {
|
|
|
11584
11702
|
}
|
|
11585
11703
|
};
|
|
11586
11704
|
var NameArgsTransaction = class extends Transaction {
|
|
11587
|
-
constructor(
|
|
11588
|
-
super(
|
|
11705
|
+
constructor(path2, transactor, name, args, parentTransaction) {
|
|
11706
|
+
super(path2, transactor, parentTransaction);
|
|
11589
11707
|
this.name = name;
|
|
11590
11708
|
this.args = args;
|
|
11591
|
-
this.targetPath =
|
|
11709
|
+
this.targetPath = path2;
|
|
11592
11710
|
}
|
|
11593
11711
|
handlerProp = null;
|
|
11594
11712
|
// NameArgs verbs map their handler bucket straight to the observed kind:
|
|
@@ -11645,8 +11763,8 @@ var SendEvent = class extends NameArgsTransaction {
|
|
|
11645
11763
|
};
|
|
11646
11764
|
var IntentEvent = class extends NameArgsTransaction {
|
|
11647
11765
|
handlerProp = "intent";
|
|
11648
|
-
constructor(
|
|
11649
|
-
super(
|
|
11766
|
+
constructor(path2, transactor, walk) {
|
|
11767
|
+
super(path2, transactor, walk.name, walk.args, walk.parent);
|
|
11650
11768
|
this.walk = walk;
|
|
11651
11769
|
this.targetPath = walk.origin;
|
|
11652
11770
|
}
|
|
@@ -11673,17 +11791,17 @@ var PASS = /* @__PURE__ */ Symbol.for("tutuca.intent.pass");
|
|
|
11673
11791
|
var REFUSAL_RING_CAP = 200;
|
|
11674
11792
|
var INTENT_DEPTH = 64;
|
|
11675
11793
|
var IntentWalk = class {
|
|
11676
|
-
constructor(transactor,
|
|
11794
|
+
constructor(transactor, path2, name, args, opts, parent, release) {
|
|
11677
11795
|
this.transactor = transactor;
|
|
11678
11796
|
this.name = name;
|
|
11679
11797
|
this.args = args;
|
|
11680
11798
|
this.route = opts?.route ?? DEFAULT_ROUTE;
|
|
11681
11799
|
this.parent = parent;
|
|
11682
11800
|
this.release = release;
|
|
11683
|
-
this.origin =
|
|
11684
|
-
this.answerPath = opts?.livePath ? null :
|
|
11801
|
+
this.origin = path2;
|
|
11802
|
+
this.answerPath = opts?.livePath ? null : path2.toTransactionPath().pinKeys(transactor.state.val);
|
|
11685
11803
|
this.legIndex = 0;
|
|
11686
|
-
this.dynAt =
|
|
11804
|
+
this.dynAt = path2;
|
|
11687
11805
|
this.hops = 0;
|
|
11688
11806
|
this.ended = false;
|
|
11689
11807
|
}
|
|
@@ -11695,7 +11813,7 @@ var IntentWalk = class {
|
|
|
11695
11813
|
while (this.legIndex < this.route.length) {
|
|
11696
11814
|
const leg = this.route[this.legIndex];
|
|
11697
11815
|
if (leg === "dyn") {
|
|
11698
|
-
if (this.dynAt.
|
|
11816
|
+
if (!this.dynAt.canPop()) {
|
|
11699
11817
|
this.legIndex++;
|
|
11700
11818
|
continue;
|
|
11701
11819
|
}
|
|
@@ -11792,8 +11910,8 @@ var IntentWalk = class {
|
|
|
11792
11910
|
if (this.ended) return;
|
|
11793
11911
|
this.ended = true;
|
|
11794
11912
|
if (name === null) return this.release?.();
|
|
11795
|
-
const
|
|
11796
|
-
|
|
11913
|
+
const t = new SendEvent(this.origin, this.transactor, name, args, this.parent);
|
|
11914
|
+
t.txnPath = this.answerPath;
|
|
11797
11915
|
t._isAnswer = true;
|
|
11798
11916
|
this.transactor.pushTransaction(t);
|
|
11799
11917
|
if (this.release) t.completion.whenSubtreeSettled().then(this.release);
|
|
@@ -11859,8 +11977,8 @@ var Completion = class {
|
|
|
11859
11977
|
}
|
|
11860
11978
|
};
|
|
11861
11979
|
var Dispatcher = class {
|
|
11862
|
-
constructor(
|
|
11863
|
-
this.path =
|
|
11980
|
+
constructor(path2, transactor, parentTransaction, root = transactor.state.val) {
|
|
11981
|
+
this.path = path2;
|
|
11864
11982
|
this.transactor = transactor;
|
|
11865
11983
|
this.parent = parentTransaction;
|
|
11866
11984
|
this.root = root;
|
|
@@ -11888,7 +12006,9 @@ var Dispatcher = class {
|
|
|
11888
12006
|
// replayed; provides are pushed on every component frame either way, so a provide
|
|
11889
12007
|
// that reads a loop binding is the one case this cannot reproduce faithfully.
|
|
11890
12008
|
_stack() {
|
|
11891
|
-
this._stackMemo ??= this.path.
|
|
12009
|
+
this._stackMemo ??= this.path.buildStack(
|
|
12010
|
+
Stack.root(this.transactor.comps, this.root, this.parent)
|
|
12011
|
+
);
|
|
11892
12012
|
return this._stackMemo;
|
|
11893
12013
|
}
|
|
11894
12014
|
// Resolve a name the way the renderer would. `opts.route` takes the same legs in
|
|
@@ -11902,14 +12022,19 @@ var Dispatcher = class {
|
|
|
11902
12022
|
);
|
|
11903
12023
|
}
|
|
11904
12024
|
// The `lex` leg without a Stack: the scope of the component whose handler is
|
|
11905
|
-
// running, which is the leaf of this ctx's path.
|
|
12025
|
+
// running, which is the leaf of this ctx's path. A type name resolves to the
|
|
12026
|
+
// component registered under it; a value name to a path registered under it
|
|
12027
|
+
// (see ComponentStack.registerPaths), read against the current root.
|
|
11906
12028
|
_lookupLex(name) {
|
|
11907
12029
|
let Comp = null;
|
|
11908
12030
|
this.walkPath((c) => {
|
|
11909
12031
|
Comp = c;
|
|
11910
12032
|
return false;
|
|
11911
12033
|
});
|
|
11912
|
-
|
|
12034
|
+
const scope = Comp?.scope;
|
|
12035
|
+
if (scope == null) return null;
|
|
12036
|
+
if (isTypeName(name)) return scope.lookupComponent(name) ?? null;
|
|
12037
|
+
return scope.lookupPath(name)?.lookup(this.root) ?? null;
|
|
11913
12038
|
}
|
|
11914
12039
|
// A component lookup is a value lookup constrained to a component. The `lex` leg
|
|
11915
12040
|
// can only ever answer with one; the `dyn` leg reads a binding an ancestor
|
|
@@ -11931,8 +12056,8 @@ var Dispatcher = class {
|
|
|
11931
12056
|
send(name, args) {
|
|
11932
12057
|
return this.sendAtPath(this.path, name, args);
|
|
11933
12058
|
}
|
|
11934
|
-
sendAtPath(
|
|
11935
|
-
return this.transactor.pushSend(
|
|
12059
|
+
sendAtPath(path2, name, args) {
|
|
12060
|
+
return this.transactor.pushSend(path2, name, args, this.parent, this.path);
|
|
11936
12061
|
}
|
|
11937
12062
|
// An intent is ROUTED: it names a job and walks until something answers. The verb
|
|
11938
12063
|
// does not decide which scope answers — `opts.route` does, written here at the call
|
|
@@ -11940,8 +12065,8 @@ var Dispatcher = class {
|
|
|
11940
12065
|
intent(name, args, opts) {
|
|
11941
12066
|
return this.intentAtPath(this.path, name, args, opts);
|
|
11942
12067
|
}
|
|
11943
|
-
intentAtPath(
|
|
11944
|
-
return this.transactor.pushIntent(
|
|
12068
|
+
intentAtPath(path2, name, args, opts) {
|
|
12069
|
+
return this.transactor.pushIntent(path2, name, args, opts, this.parent);
|
|
11945
12070
|
}
|
|
11946
12071
|
};
|
|
11947
12072
|
var EventContext = class extends Dispatcher {
|
|
@@ -11970,7 +12095,14 @@ var EventContext = class extends Dispatcher {
|
|
|
11970
12095
|
this.transactor.refuse("NO_SENDER", { name });
|
|
11971
12096
|
return null;
|
|
11972
12097
|
}
|
|
11973
|
-
return this.
|
|
12098
|
+
return this.transactor.pushSend(
|
|
12099
|
+
origin,
|
|
12100
|
+
name,
|
|
12101
|
+
args,
|
|
12102
|
+
this.parent,
|
|
12103
|
+
this.path,
|
|
12104
|
+
this.parent.originPinned
|
|
12105
|
+
);
|
|
11974
12106
|
}
|
|
11975
12107
|
// End the walk answering nothing — "served, and no answer".
|
|
11976
12108
|
stop() {
|
|
@@ -12002,13 +12134,13 @@ var PathChanges = class extends PathBuilder {
|
|
|
12002
12134
|
}
|
|
12003
12135
|
};
|
|
12004
12136
|
function rootDispatcher(transactor) {
|
|
12005
|
-
return new Dispatcher(new
|
|
12137
|
+
return new Dispatcher(new DispatchPath(), transactor, null);
|
|
12006
12138
|
}
|
|
12007
12139
|
|
|
12008
12140
|
// tools/core/results.js
|
|
12009
12141
|
var ModuleInfo = class {
|
|
12010
|
-
constructor({ path = null, present = /* @__PURE__ */ new Set(), counts = {}, warnings = [] }) {
|
|
12011
|
-
this.path =
|
|
12142
|
+
constructor({ path: path2 = null, present = /* @__PURE__ */ new Set(), counts = {}, warnings = [] }) {
|
|
12143
|
+
this.path = path2;
|
|
12012
12144
|
this.present = present;
|
|
12013
12145
|
this.counts = counts;
|
|
12014
12146
|
this.warnings = warnings;
|
|
@@ -12118,8 +12250,8 @@ var DescribeResult = class {
|
|
|
12118
12250
|
}
|
|
12119
12251
|
};
|
|
12120
12252
|
var ModuleTestReport = class {
|
|
12121
|
-
constructor({ path = null, suites = [], counts = { pass: 0, fail: 0, skip: 0, total: 0 } }) {
|
|
12122
|
-
this.path =
|
|
12253
|
+
constructor({ path: path2 = null, suites = [], counts = { pass: 0, fail: 0, skip: 0, total: 0 } }) {
|
|
12254
|
+
this.path = path2;
|
|
12123
12255
|
this.suites = suites;
|
|
12124
12256
|
this.counts = counts;
|
|
12125
12257
|
}
|
|
@@ -12162,8 +12294,8 @@ var Test = class {
|
|
|
12162
12294
|
}
|
|
12163
12295
|
};
|
|
12164
12296
|
var ModuleTests = class {
|
|
12165
|
-
constructor({ path = null, suites = [] } = {}) {
|
|
12166
|
-
this.path =
|
|
12297
|
+
constructor({ path: path2 = null, suites = [] } = {}) {
|
|
12298
|
+
this.path = path2;
|
|
12167
12299
|
this.suites = suites;
|
|
12168
12300
|
}
|
|
12169
12301
|
};
|
|
@@ -12185,8 +12317,8 @@ function titleFromArg(arg) {
|
|
|
12185
12317
|
if (typeof arg === "function") return arg.name || "(anonymous)";
|
|
12186
12318
|
return String(arg);
|
|
12187
12319
|
}
|
|
12188
|
-
function makeCollector({ path = null, components = [] } = {}) {
|
|
12189
|
-
const moduleTests = new ModuleTests({ path, suites: [] });
|
|
12320
|
+
function makeCollector({ path: path2 = null, components = [] } = {}) {
|
|
12321
|
+
const moduleTests = new ModuleTests({ path: path2, suites: [] });
|
|
12190
12322
|
const stack = [];
|
|
12191
12323
|
function describe(...args) {
|
|
12192
12324
|
let head;
|
|
@@ -12287,7 +12419,7 @@ async function driveStack(stack, value, phase, opts = {}) {
|
|
|
12287
12419
|
val
|
|
12288
12420
|
);
|
|
12289
12421
|
});
|
|
12290
|
-
dispatchPhase(rootDispatcher(transactor), new
|
|
12422
|
+
dispatchPhase(rootDispatcher(transactor), new DispatchPath(), phase, value);
|
|
12291
12423
|
await transactor.settle();
|
|
12292
12424
|
return transactor.state.val;
|
|
12293
12425
|
}
|
|
@@ -12297,7 +12429,7 @@ async function drive(cfg, value, phase, opts = {}) {
|
|
|
12297
12429
|
async function runTests({
|
|
12298
12430
|
getTests,
|
|
12299
12431
|
components = [],
|
|
12300
|
-
path = null,
|
|
12432
|
+
path: path2 = null,
|
|
12301
12433
|
expect: expect2,
|
|
12302
12434
|
name = null,
|
|
12303
12435
|
grep = null,
|
|
@@ -12308,13 +12440,13 @@ async function runTests({
|
|
|
12308
12440
|
const counts = { pass: 0, fail: 0, skip: 0, total: 0 };
|
|
12309
12441
|
if (typeof getTests !== "function") {
|
|
12310
12442
|
return new TestReport({
|
|
12311
|
-
modules: [new ModuleTestReport({ path, suites: [], counts })]
|
|
12443
|
+
modules: [new ModuleTestReport({ path: path2, suites: [], counts })]
|
|
12312
12444
|
});
|
|
12313
12445
|
}
|
|
12314
12446
|
if (typeof expect2 !== "function") {
|
|
12315
12447
|
throw new Error("runTests: expect must be provided (e.g. chai's expect)");
|
|
12316
12448
|
}
|
|
12317
|
-
const { describe, test: test3, moduleTests } = makeCollector({ path, components });
|
|
12449
|
+
const { describe, test: test3, moduleTests } = makeCollector({ path: path2, components });
|
|
12318
12450
|
let _stack = null;
|
|
12319
12451
|
const getStack = () => _stack ??= buildStack({ components, macros, intentHandlers });
|
|
12320
12452
|
const driveLocal = (value, phase, opts = {}) => driveStack(getStack(), value, phase, opts);
|
|
@@ -12377,7 +12509,7 @@ async function runTests({
|
|
|
12377
12509
|
if (r !== null) suiteResults.push(r);
|
|
12378
12510
|
}
|
|
12379
12511
|
return new TestReport({
|
|
12380
|
-
modules: [new ModuleTestReport({ path, suites: suiteResults, counts })]
|
|
12512
|
+
modules: [new ModuleTestReport({ path: path2, suites: suiteResults, counts })]
|
|
12381
12513
|
});
|
|
12382
12514
|
}
|
|
12383
12515
|
|
|
@@ -12546,15 +12678,13 @@ function lintIdToMessage(id, info) {
|
|
|
12546
12678
|
case "DYN_ALIAS_NOT_REFERENCED":
|
|
12547
12679
|
return `Lookup '${info.name}' is defined but never used — remove it or reference it as '*${info.name}' in a view`;
|
|
12548
12680
|
case "PROVIDE_NOT_ADDRESSABLE":
|
|
12549
|
-
return `Provide '${info.name}' value '${info.value}' must be a field ('.f') or seq-access ('.s[.k]') — a
|
|
12681
|
+
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`;
|
|
12550
12682
|
case "LOOKUP_BAD_SHAPE":
|
|
12551
12683
|
return `Lookup '${info.name}' has an invalid shape: ${info.problem}`;
|
|
12552
12684
|
case "LOOKUP_NO_PROVIDER":
|
|
12553
|
-
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`;
|
|
12685
|
+
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`;
|
|
12554
12686
|
case "PROVIDE_TYPE_BAD_SHAPE":
|
|
12555
12687
|
return `Provide '${info.name}' starts uppercase, so it publishes a component type — its value must be 'self', not '${info.value}'`;
|
|
12556
|
-
case "PROVIDE_NAME_COLLISION":
|
|
12557
|
-
return `Provide '${info.name}' is also provided by '${info.other}' in the same scope — one name, one provider, so a lookup can find it`;
|
|
12558
12688
|
case "UNKNOWN_MACRO_ARG":
|
|
12559
12689
|
return `Argument '${info.name}' is not declared in macro '${info.macroName}'`;
|
|
12560
12690
|
case "UNKNOWN_DIRECTIVE":
|
|
@@ -12720,7 +12850,7 @@ var App = class {
|
|
|
12720
12850
|
const { type: type3 } = e;
|
|
12721
12851
|
const isDrag = type3 === "dragover" || type3 === "dragstart" || type3 === "dragend" || type3 === "drop";
|
|
12722
12852
|
const { rootNode: root, maxEventNodeDepth: maxDepth, comps, transactor } = this;
|
|
12723
|
-
const [
|
|
12853
|
+
const [path2, handlers] = DispatchPath.fromNodeAndEventName(
|
|
12724
12854
|
e.target,
|
|
12725
12855
|
type3,
|
|
12726
12856
|
root,
|
|
@@ -12728,9 +12858,9 @@ var App = class {
|
|
|
12728
12858
|
comps,
|
|
12729
12859
|
!isDrag
|
|
12730
12860
|
);
|
|
12731
|
-
if (isDrag) this._handleDragEvent(e, type3,
|
|
12732
|
-
if (
|
|
12733
|
-
for (const handler of handlers) transactor.transactInputNow(
|
|
12861
|
+
if (isDrag) this._handleDragEvent(e, type3, path2);
|
|
12862
|
+
if (path2 !== null && handlers !== null)
|
|
12863
|
+
for (const handler of handlers) transactor.transactInputNow(path2, e, handler, this.dragInfo);
|
|
12734
12864
|
}
|
|
12735
12865
|
_handleTouchEvent(e) {
|
|
12736
12866
|
const { type: type3 } = e;
|
|
@@ -12773,7 +12903,7 @@ var App = class {
|
|
|
12773
12903
|
this._touch = null;
|
|
12774
12904
|
}
|
|
12775
12905
|
}
|
|
12776
|
-
_handleDragEvent(e, type3,
|
|
12906
|
+
_handleDragEvent(e, type3, path2) {
|
|
12777
12907
|
if (type3 === "dragover") {
|
|
12778
12908
|
const dropTarget = getClosestDropTarget(e.target, this.rootNode, Infinity);
|
|
12779
12909
|
if (dropTarget !== null) {
|
|
@@ -12785,10 +12915,10 @@ var App = class {
|
|
|
12785
12915
|
} else if (type3 === "dragstart") {
|
|
12786
12916
|
e.target.dataset.dragging = 1;
|
|
12787
12917
|
const rootValue = this.state.val;
|
|
12788
|
-
const txnPath =
|
|
12918
|
+
const txnPath = path2.compact().toTransactionPath();
|
|
12789
12919
|
const value = txnPath.lookup(rootValue);
|
|
12790
12920
|
const dragType = e.target.dataset.dragtype ?? "?";
|
|
12791
|
-
const stack =
|
|
12921
|
+
const stack = path2.buildStack(this.makeStack(rootValue));
|
|
12792
12922
|
this.dragInfo = new DragInfo(stack, value, dragType, e.target);
|
|
12793
12923
|
} else if (type3 === "drop") {
|
|
12794
12924
|
e.preventDefault();
|
|
@@ -12863,7 +12993,7 @@ var App = class {
|
|
|
12863
12993
|
this.rootNode.removeEventListener(name, this, listenerOpts(name));
|
|
12864
12994
|
}
|
|
12865
12995
|
sendAtRoot(name, args) {
|
|
12866
|
-
this.transactor.pushSend(new
|
|
12996
|
+
this.transactor.pushSend(new DispatchPath(), name, args);
|
|
12867
12997
|
}
|
|
12868
12998
|
registerComponents(comps, opts) {
|
|
12869
12999
|
const scope = this.compStack.enter();
|
|
@@ -13003,7 +13133,20 @@ var WeakMapDomCache = class {
|
|
|
13003
13133
|
};
|
|
13004
13134
|
|
|
13005
13135
|
// src/renderer.js
|
|
13006
|
-
var DATASET_ATTRS = ["nid", "cid", "eid", "vid", "si", "sk"];
|
|
13136
|
+
var DATASET_ATTRS = ["nid", "cid", "eid", "vid", "si", "sk", "rp"];
|
|
13137
|
+
function stampRenderBase(vdom, text) {
|
|
13138
|
+
if (vdom instanceof VNode)
|
|
13139
|
+
return new VNode(
|
|
13140
|
+
vdom.tag,
|
|
13141
|
+
{ ...vdom.attrs, "data-rp": text },
|
|
13142
|
+
vdom.childs,
|
|
13143
|
+
vdom.key,
|
|
13144
|
+
vdom.namespace
|
|
13145
|
+
);
|
|
13146
|
+
if (vdom instanceof VFragment)
|
|
13147
|
+
return new VFragment(vdom.childs.map((c) => stampRenderBase(c, text)));
|
|
13148
|
+
return vdom;
|
|
13149
|
+
}
|
|
13007
13150
|
var Renderer = class {
|
|
13008
13151
|
constructor(comps) {
|
|
13009
13152
|
this.comps = comps;
|
|
@@ -13040,17 +13183,17 @@ var Renderer = class {
|
|
|
13040
13183
|
if (comp === null) return null;
|
|
13041
13184
|
return this._rValComp(stack, val, comp, comp.getView(viewName).anode, "ROOT", viewName);
|
|
13042
13185
|
}
|
|
13043
|
-
renderIt(stack, node, key, viewName) {
|
|
13186
|
+
renderIt(stack, node, key, viewName, base = null) {
|
|
13044
13187
|
const comp = this.comps.getCompFor(stack.it);
|
|
13045
|
-
return comp ? this._rValComp(stack, stack.it, comp, node, key, viewName) : null;
|
|
13188
|
+
return comp ? this._rValComp(stack, stack.it, comp, node, key, viewName, base) : null;
|
|
13046
13189
|
}
|
|
13047
13190
|
// `node` is the parse node of the render site (`<x render>` / `render-it` /
|
|
13048
13191
|
// `render-each`, or the view's root anode for the app root). It keys the
|
|
13049
13192
|
// cache as a globally-unique object: node ids alone are unique only within a
|
|
13050
13193
|
// single view, so the same value rendered by two components (e.g. through a
|
|
13051
13194
|
// shared dynamic-var sequence) would otherwise collide in the cache.
|
|
13052
|
-
_rValComp(stack, val, comp, node, key, viewName) {
|
|
13053
|
-
const cacheKey = `${viewName ?? ""}${stack.viewsId ?? ""}${key}`;
|
|
13195
|
+
_rValComp(stack, val, comp, node, key, viewName, base = null) {
|
|
13196
|
+
const cacheKey = `${viewName ?? ""}${stack.viewsId ?? ""}${key}${stack.renderPath.addressKey}`;
|
|
13054
13197
|
const cachePath = [node, val];
|
|
13055
13198
|
stack._pushDynBindValuesToArray(cachePath, comp);
|
|
13056
13199
|
const cachedNode = this.cache.get(cachePath, cacheKey);
|
|
@@ -13058,30 +13201,43 @@ var Renderer = class {
|
|
|
13058
13201
|
const view = viewName ? comp.getView(viewName) : stack.lookupBestView(comp.views, "main");
|
|
13059
13202
|
const body = this.renderView(view, stack);
|
|
13060
13203
|
if (body == null) return null;
|
|
13204
|
+
const baseJson = base === null ? null : pathToJson(base);
|
|
13061
13205
|
const meta = this._renderMetadata({
|
|
13062
13206
|
$: "Comp",
|
|
13063
13207
|
nid: node?.nodeId ?? null,
|
|
13064
13208
|
cid: comp.id,
|
|
13065
|
-
vid: view.name
|
|
13209
|
+
vid: view.name,
|
|
13210
|
+
...baseJson === null ? null : { base: baseJson }
|
|
13066
13211
|
});
|
|
13067
|
-
const dom = new VFragment([
|
|
13212
|
+
const dom = new VFragment([
|
|
13213
|
+
meta,
|
|
13214
|
+
baseJson === null ? body : stampRenderBase(body, JSON.stringify(baseJson))
|
|
13215
|
+
]);
|
|
13068
13216
|
this.cache.set(cachePath, cacheKey, dom);
|
|
13069
13217
|
return dom;
|
|
13070
13218
|
}
|
|
13071
13219
|
pushEachEntry(r, nid, attrName, key, dom) {
|
|
13072
13220
|
r.push(this._renderMetadata({ $: "Each", nid, [attrName]: key }), dom);
|
|
13073
13221
|
}
|
|
13074
|
-
renderEachWhen(stack,
|
|
13222
|
+
renderEachWhen(stack, each2) {
|
|
13223
|
+
const { iterInfo, node: view, nodeId: nid } = each2;
|
|
13075
13224
|
const { seq, filter, loopWith, enricher } = iterInfo.eval(stack);
|
|
13225
|
+
const seqPath = iterInfo.val instanceof DynVal ? stack.lookupDynamicLocated(iterInfo.val.name)?.path ?? null : null;
|
|
13076
13226
|
const r = [];
|
|
13077
13227
|
const it = stack.it;
|
|
13078
13228
|
const renderOne = (key, value, attrName, binds) => {
|
|
13229
|
+
const itemBase = seqPath === null ? null : keyedPath(seqPath, key);
|
|
13230
|
+
const itemStep = itemBase === null ? each2.itemStep(key) : null;
|
|
13231
|
+
const itemPath = itemBase !== null ? stack.renderPath.pushFrame(itemBase) : itemStep !== null ? stack.renderPath.pushItem(itemStep) : stack.renderPath;
|
|
13079
13232
|
const cachePath = enricher ? [view, it, value] : [view, value];
|
|
13080
|
-
const cacheKey = `${stack.viewsId ?? ""}${nid}${key}`;
|
|
13233
|
+
const cacheKey = `${stack.viewsId ?? ""}${nid}${key}${itemPath.addressKey}`;
|
|
13081
13234
|
const cachedNode = this.cache.get(cachePath, cacheKey);
|
|
13082
13235
|
if (cachedNode) this.pushEachEntry(r, nid, attrName, key, cachedNode);
|
|
13083
13236
|
else {
|
|
13084
|
-
const dom = this.renderView(
|
|
13237
|
+
const dom = this.renderView(
|
|
13238
|
+
view,
|
|
13239
|
+
stack.enter(value, binds, false, itemPath, itemBase !== null)
|
|
13240
|
+
);
|
|
13085
13241
|
if (dom != null) this.pushEachEntry(r, nid, attrName, key, dom);
|
|
13086
13242
|
this.cache.set(cachePath, cacheKey, dom);
|
|
13087
13243
|
}
|
|
@@ -13337,7 +13493,6 @@ export {
|
|
|
13337
13493
|
ModuleTests,
|
|
13338
13494
|
PASS,
|
|
13339
13495
|
PLACEHOLDERLESS_TEMPLATE_STRING,
|
|
13340
|
-
PROVIDE_NAME_COLLISION,
|
|
13341
13496
|
PROVIDE_NOT_ADDRESSABLE,
|
|
13342
13497
|
PROVIDE_TYPE_BAD_SHAPE,
|
|
13343
13498
|
ParseContext,
|
|
@@ -13378,6 +13533,7 @@ export {
|
|
|
13378
13533
|
lintIdToMessage,
|
|
13379
13534
|
macro,
|
|
13380
13535
|
makeCollector,
|
|
13536
|
+
path,
|
|
13381
13537
|
phaseOps,
|
|
13382
13538
|
reportTestReportToConsole,
|
|
13383
13539
|
resolveArgs,
|