tutuca 0.9.41 → 0.9.43
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/README.md +10 -2
- package/dist/tutuca-cli.js +61 -51
- package/dist/tutuca-dev.js +41 -40
- package/dist/tutuca-dev.min.js +3 -3
- package/dist/tutuca-extra.js +41 -40
- package/dist/tutuca-extra.min.js +3 -3
- package/dist/tutuca.js +41 -40
- package/dist/tutuca.min.js +3 -3
- package/package.json +1 -1
- package/skill/SKILL.md +46 -0
- package/skill/advanced.md +146 -0
- package/skill/cli.md +117 -0
- package/skill/core.md +766 -0
- package/skill/tutuca/SKILL.md +2 -2
- package/skill/tutuca/advanced.md +1 -1
- package/skill/tutuca/cli.md +2 -0
- package/skill/tutuca/core.md +84 -31
package/README.md
CHANGED
|
@@ -27,7 +27,7 @@ For an interactive walk-through with editable examples, see the
|
|
|
27
27
|
<body>
|
|
28
28
|
<div id="app"></div>
|
|
29
29
|
<script type="module">
|
|
30
|
-
import { component, html, tutuca } from "https://
|
|
30
|
+
import { component, html, tutuca } from "https://cdn.jsdelivr.net/npm/tutuca/+esm";
|
|
31
31
|
|
|
32
32
|
const Counter = component({
|
|
33
33
|
name: "Counter",
|
|
@@ -94,7 +94,7 @@ tutuca help [command]
|
|
|
94
94
|
| `docs [name]` | Component API docs — all, or one by name |
|
|
95
95
|
| `lint [name]` | Run lint checks — all, or one by name (exit 2 on errors) |
|
|
96
96
|
| `render [name] [--title t] [--view v]` | Render examples to HTML |
|
|
97
|
-
| `install-skill [--user] [--force]` | Install
|
|
97
|
+
| `install-skill [--user\|--project] [--margaui-skill\|--immutable-skill\|--all] [--dot-agents] [--force]` | Install bundled Claude Code skills (no module path needed) |
|
|
98
98
|
|
|
99
99
|
Global flags: `-f, --format <cli\|md\|json\|html>`, `-o, --output <file>`, `--pretty`, `-h, --help`.
|
|
100
100
|
|
|
@@ -154,6 +154,14 @@ npx tutuca install-skill
|
|
|
154
154
|
# or user-scoped: writes ~/.claude/skills/tutuca/
|
|
155
155
|
npx tutuca install-skill --user
|
|
156
156
|
|
|
157
|
+
# pick a different bundled skill, or install all three
|
|
158
|
+
npx tutuca install-skill --margaui-skill
|
|
159
|
+
npx tutuca install-skill --immutable-skill
|
|
160
|
+
npx tutuca install-skill --all
|
|
161
|
+
|
|
162
|
+
# install into ./.agents/skills/ instead of ./.claude/skills/
|
|
163
|
+
npx tutuca install-skill --dot-agents
|
|
164
|
+
|
|
157
165
|
# overwrite an existing install
|
|
158
166
|
npx tutuca install-skill --force
|
|
159
167
|
```
|
package/dist/tutuca-cli.js
CHANGED
|
@@ -478,7 +478,7 @@ class Step {
|
|
|
478
478
|
setValue(root, _v) {
|
|
479
479
|
return root;
|
|
480
480
|
}
|
|
481
|
-
|
|
481
|
+
updateBinds(_v, _o) {}
|
|
482
482
|
isFrame = true;
|
|
483
483
|
}
|
|
484
484
|
|
|
@@ -526,7 +526,7 @@ class Path {
|
|
|
526
526
|
console.warn(`bad PathItem`, { root, curVal, step, path: this });
|
|
527
527
|
return null;
|
|
528
528
|
}
|
|
529
|
-
step.
|
|
529
|
+
step.updateBinds(curVal, stack.binds[0].binds);
|
|
530
530
|
stack = stack.enter(curVal, {}, step.isFrame);
|
|
531
531
|
}
|
|
532
532
|
return stack;
|
|
@@ -641,7 +641,7 @@ var init_path = __esm(() => {
|
|
|
641
641
|
withKey(key) {
|
|
642
642
|
return new BindStep({ ...this.binds, key });
|
|
643
643
|
}
|
|
644
|
-
|
|
644
|
+
updateBinds(_v, o) {
|
|
645
645
|
Object.assign(o, this.binds);
|
|
646
646
|
}
|
|
647
647
|
isFrame = false;
|
|
@@ -677,7 +677,7 @@ var init_path = __esm(() => {
|
|
|
677
677
|
setValue(root, v) {
|
|
678
678
|
return root.set(this.field, root.get(this.field).set(this.key, v));
|
|
679
679
|
}
|
|
680
|
-
|
|
680
|
+
updateBinds(_v, o) {
|
|
681
681
|
o.key = this.key;
|
|
682
682
|
}
|
|
683
683
|
};
|
|
@@ -702,7 +702,7 @@ var init_path = __esm(() => {
|
|
|
702
702
|
const key = root?.get(this.keyField, NONE);
|
|
703
703
|
return seq === NONE || key === NONE ? root : root.set(this.seqField, seq.set(key, v));
|
|
704
704
|
}
|
|
705
|
-
|
|
705
|
+
updateBinds(v, o) {
|
|
706
706
|
o.key = v?.get(this.keyField, null);
|
|
707
707
|
}
|
|
708
708
|
};
|
|
@@ -1912,8 +1912,8 @@ var init_anode = __esm(() => {
|
|
|
1912
1912
|
};
|
|
1913
1913
|
ScopeNode = class ScopeNode extends WrapperNode {
|
|
1914
1914
|
render(stack, rx) {
|
|
1915
|
-
const
|
|
1916
|
-
return this.node.render(stack.enter(stack.it,
|
|
1915
|
+
const binds = this.val.eval(stack)?.call(stack.it) ?? {};
|
|
1916
|
+
return this.node.render(stack.enter(stack.it, binds, false), rx);
|
|
1917
1917
|
}
|
|
1918
1918
|
toPathItem() {
|
|
1919
1919
|
return new BindStep({});
|
|
@@ -4783,23 +4783,23 @@ function lookup(chain, name, dv = null) {
|
|
|
4783
4783
|
}
|
|
4784
4784
|
|
|
4785
4785
|
class BindFrame {
|
|
4786
|
-
constructor(it,
|
|
4786
|
+
constructor(it, binds, isFrame) {
|
|
4787
4787
|
this.it = it;
|
|
4788
|
-
this.
|
|
4788
|
+
this.binds = binds;
|
|
4789
4789
|
this.isFrame = isFrame;
|
|
4790
4790
|
}
|
|
4791
4791
|
lookup(name) {
|
|
4792
|
-
const v = this.
|
|
4792
|
+
const v = this.binds[name];
|
|
4793
4793
|
return v === undefined ? this.isFrame ? STOP : NEXT : v;
|
|
4794
4794
|
}
|
|
4795
4795
|
}
|
|
4796
4796
|
|
|
4797
4797
|
class ObjectFrame {
|
|
4798
|
-
constructor(
|
|
4799
|
-
this.
|
|
4798
|
+
constructor(binds) {
|
|
4799
|
+
this.binds = binds;
|
|
4800
4800
|
}
|
|
4801
4801
|
lookup(key) {
|
|
4802
|
-
const v = this.
|
|
4802
|
+
const v = this.binds[key];
|
|
4803
4803
|
return v === undefined ? NEXT : v;
|
|
4804
4804
|
}
|
|
4805
4805
|
}
|
|
@@ -4824,11 +4824,12 @@ class Stack {
|
|
|
4824
4824
|
this.ctx = ctx;
|
|
4825
4825
|
}
|
|
4826
4826
|
_enrichOnEnter() {
|
|
4827
|
-
return this.
|
|
4827
|
+
return this.withDynamicBinds(this.comps.getOnEnterFor(this.it).call(this.it));
|
|
4828
4828
|
}
|
|
4829
4829
|
upToFrameBinds() {
|
|
4830
4830
|
const { comps, binds, dynBinds, views, viewsId, ctx } = this;
|
|
4831
|
-
|
|
4831
|
+
const [head, tail] = binds;
|
|
4832
|
+
return head.isFrame ? this : new Stack(comps, tail[0].it, tail, dynBinds, views, viewsId, ctx);
|
|
4832
4833
|
}
|
|
4833
4834
|
static root(comps, it, ctx) {
|
|
4834
4835
|
const binds = [new BindFrame(it, { it }, true), null];
|
|
@@ -4847,7 +4848,7 @@ class Stack {
|
|
|
4847
4848
|
const newViews = [name, views];
|
|
4848
4849
|
return new Stack(comps, it, binds, dynBinds, newViews, computeViewsId(newViews), ctx);
|
|
4849
4850
|
}
|
|
4850
|
-
|
|
4851
|
+
withDynamicBinds(dynamics) {
|
|
4851
4852
|
if (dynamics == null || dynamics.length === 0)
|
|
4852
4853
|
return this;
|
|
4853
4854
|
const dynObj = {};
|
|
@@ -4938,14 +4939,13 @@ class Transactor {
|
|
|
4938
4939
|
pushTransaction(t) {
|
|
4939
4940
|
this.transactions.push(t);
|
|
4940
4941
|
this.onTransactionPushed(t);
|
|
4941
|
-
return t;
|
|
4942
4942
|
}
|
|
4943
|
-
|
|
4944
|
-
|
|
4943
|
+
pushSend(path, name, args = [], opts = {}, parent = null) {
|
|
4944
|
+
this.pushTransaction(new SendEvent(path, this, name, args, parent, opts));
|
|
4945
4945
|
}
|
|
4946
4946
|
pushBubble(path, name, args = [], opts = {}, parent = null) {
|
|
4947
4947
|
const newOpts = opts.skipSelf ? { ...opts, skipSelf: false } : opts;
|
|
4948
|
-
|
|
4948
|
+
this.pushTransaction(new BubbleEvent(path, this, name, args, parent, newOpts));
|
|
4949
4949
|
}
|
|
4950
4950
|
async pushRequest(path, name, args = [], opts = {}, parent = null) {
|
|
4951
4951
|
const curRoot = this.state.val;
|
|
@@ -4955,13 +4955,13 @@ class Transactor {
|
|
|
4955
4955
|
const push = (specificName, baseName, singleArg, result, error) => {
|
|
4956
4956
|
const resArgs = specificName ? [singleArg] : [result, error];
|
|
4957
4957
|
const t = new ResponseEvent(path, this, specificName ?? baseName, resArgs, parent);
|
|
4958
|
-
|
|
4958
|
+
this.pushTransaction(t);
|
|
4959
4959
|
};
|
|
4960
4960
|
try {
|
|
4961
4961
|
const result = await handler.fn.apply(null, args);
|
|
4962
|
-
|
|
4962
|
+
push(opts?.onOkName, resHandlerName, result, result, null);
|
|
4963
4963
|
} catch (error) {
|
|
4964
|
-
|
|
4964
|
+
push(opts?.onErrorName, resHandlerName, error, null, error);
|
|
4965
4965
|
}
|
|
4966
4966
|
}
|
|
4967
4967
|
get hasPendingTransactions() {
|
|
@@ -5081,14 +5081,14 @@ class Dispatcher {
|
|
|
5081
5081
|
get at() {
|
|
5082
5082
|
return new PathChanges(this);
|
|
5083
5083
|
}
|
|
5084
|
-
|
|
5085
|
-
return this.
|
|
5084
|
+
send(name, args, opts) {
|
|
5085
|
+
return this.sendAtPath(this.path, name, args, opts);
|
|
5086
5086
|
}
|
|
5087
5087
|
bubble(name, args, opts) {
|
|
5088
|
-
return this.
|
|
5088
|
+
return this.send(name, args, { skipSelf: true, bubbles: true, ...opts });
|
|
5089
5089
|
}
|
|
5090
|
-
|
|
5091
|
-
return this.transactor.
|
|
5090
|
+
sendAtPath(path, name, args, opts) {
|
|
5091
|
+
return this.transactor.pushSend(path, name, args, opts, this.parent);
|
|
5092
5092
|
}
|
|
5093
5093
|
request(name, args, opts) {
|
|
5094
5094
|
return this.requestAtPath(this.path, name, args, opts);
|
|
@@ -5100,7 +5100,7 @@ class Dispatcher {
|
|
|
5100
5100
|
return this.transactor.comps.getCompFor(inst).scope.lookupComponent(name);
|
|
5101
5101
|
}
|
|
5102
5102
|
}
|
|
5103
|
-
var isMac2, toNullIfNaN = (v) => Number.isNaN(v) ? null : v, InputEvent, NameArgsTransaction, ResponseEvent,
|
|
5103
|
+
var isMac2, toNullIfNaN = (v) => Number.isNaN(v) ? null : v, InputEvent, NameArgsTransaction, ResponseEvent, SendEvent, BubbleEvent, EventContext, PathChanges;
|
|
5104
5104
|
var init_transactor = __esm(() => {
|
|
5105
5105
|
init_path();
|
|
5106
5106
|
init_stack();
|
|
@@ -5125,6 +5125,7 @@ var init_transactor = __esm(() => {
|
|
|
5125
5125
|
args[i] = args[i].toHandlerArg(dispatcher);
|
|
5126
5126
|
}
|
|
5127
5127
|
}
|
|
5128
|
+
args.push(new EventContext(this.path, this.transactor, this));
|
|
5128
5129
|
return [handler, args];
|
|
5129
5130
|
}
|
|
5130
5131
|
lookupName(name) {
|
|
@@ -5188,8 +5189,8 @@ var init_transactor = __esm(() => {
|
|
|
5188
5189
|
ResponseEvent = class ResponseEvent extends NameArgsTransaction {
|
|
5189
5190
|
handlerProp = "response";
|
|
5190
5191
|
};
|
|
5191
|
-
|
|
5192
|
-
handlerProp = "
|
|
5192
|
+
SendEvent = class SendEvent extends NameArgsTransaction {
|
|
5193
|
+
handlerProp = "receive";
|
|
5193
5194
|
run(rootVal, comps) {
|
|
5194
5195
|
return this.opts.skipSelf ? rootVal : this.updateRootValue(rootVal, comps);
|
|
5195
5196
|
}
|
|
@@ -5199,7 +5200,7 @@ var init_transactor = __esm(() => {
|
|
|
5199
5200
|
this.transactor.pushBubble(path.popStep(), name, args, opts, this);
|
|
5200
5201
|
}
|
|
5201
5202
|
};
|
|
5202
|
-
BubbleEvent = class BubbleEvent extends
|
|
5203
|
+
BubbleEvent = class BubbleEvent extends SendEvent {
|
|
5203
5204
|
handlerProp = "bubble";
|
|
5204
5205
|
stopPropagation() {
|
|
5205
5206
|
this.opts.bubbles = false;
|
|
@@ -5215,11 +5216,11 @@ var init_transactor = __esm(() => {
|
|
|
5215
5216
|
super();
|
|
5216
5217
|
this.dispatcher = dispatcher;
|
|
5217
5218
|
}
|
|
5218
|
-
|
|
5219
|
-
return this.dispatcher.
|
|
5219
|
+
send(name, args, opts) {
|
|
5220
|
+
return this.dispatcher.sendAtPath(this.buildPath(), name, args, opts);
|
|
5220
5221
|
}
|
|
5221
5222
|
bubble(name, args, opts) {
|
|
5222
|
-
return this.
|
|
5223
|
+
return this.send(name, args, { skipSelf: true, bubbles: true, ...opts });
|
|
5223
5224
|
}
|
|
5224
5225
|
buildPath() {
|
|
5225
5226
|
return this.dispatcher.path.concat(this.pathChanges);
|
|
@@ -5713,8 +5714,8 @@ class App {
|
|
|
5713
5714
|
for (const name of this._eventNames)
|
|
5714
5715
|
this.rootNode.removeEventListener(name, this, listenerOpts(name));
|
|
5715
5716
|
}
|
|
5716
|
-
|
|
5717
|
-
|
|
5717
|
+
dispatchSendAtRoot(name, args, opts) {
|
|
5718
|
+
this.transactor.pushSend(new Path([]), name, args, opts);
|
|
5718
5719
|
}
|
|
5719
5720
|
registerComponents(comps, aliases) {
|
|
5720
5721
|
const scope = this.compStack.enter();
|
|
@@ -10175,15 +10176,15 @@ class Renderer {
|
|
|
10175
10176
|
this.getSeqInfo(seq)(seq, (key, value, attrName) => {
|
|
10176
10177
|
if (filter.call(it, key, value, iterData)) {
|
|
10177
10178
|
const cachePath = enricher ? [it, value] : [value];
|
|
10178
|
-
const
|
|
10179
|
+
const binds = { key, value };
|
|
10179
10180
|
const cacheKey = `${nid}-${key}`;
|
|
10180
10181
|
if (enricher)
|
|
10181
|
-
enricher.call(it,
|
|
10182
|
+
enricher.call(it, binds, key, value, iterData);
|
|
10182
10183
|
const cachedNode = this.cache.get(cachePath, cacheKey);
|
|
10183
10184
|
if (cachedNode)
|
|
10184
10185
|
this.pushEachEntry(r, nid, attrName, key, cachedNode);
|
|
10185
10186
|
else {
|
|
10186
|
-
const dom = this.renderView(view, stack.enter(value,
|
|
10187
|
+
const dom = this.renderView(view, stack.enter(value, binds, false));
|
|
10187
10188
|
this.pushEachEntry(r, nid, attrName, key, dom);
|
|
10188
10189
|
this.cache.set(cachePath, cacheKey, dom);
|
|
10189
10190
|
}
|
|
@@ -10392,9 +10393,10 @@ function findSkillsRoot() {
|
|
|
10392
10393
|
}
|
|
10393
10394
|
return null;
|
|
10394
10395
|
}
|
|
10395
|
-
function targetDir(scope, name) {
|
|
10396
|
+
function targetDir(scope, name, dotAgents) {
|
|
10396
10397
|
const base = scope === "user" ? homedir() : process.cwd();
|
|
10397
|
-
|
|
10398
|
+
const dir = dotAgents ? ".agents/skills" : ".claude/skills";
|
|
10399
|
+
return resolve(base, dir, name);
|
|
10398
10400
|
}
|
|
10399
10401
|
function targetHasSkillFiles(dir) {
|
|
10400
10402
|
if (!existsSync(dir))
|
|
@@ -10407,14 +10409,14 @@ function targetHasSkillFiles(dir) {
|
|
|
10407
10409
|
}
|
|
10408
10410
|
return false;
|
|
10409
10411
|
}
|
|
10410
|
-
function installSkill(skill, root, scope, force) {
|
|
10412
|
+
function installSkill(skill, root, scope, force, dotAgents) {
|
|
10411
10413
|
const src = resolve(root, skill.srcSubdir);
|
|
10412
10414
|
if (!existsSync(resolve(src, "SKILL.md"))) {
|
|
10413
10415
|
process.stderr.write(`tutuca: missing skill assets for ${skill.name} at ${src}
|
|
10414
10416
|
`);
|
|
10415
10417
|
process.exit(1);
|
|
10416
10418
|
}
|
|
10417
|
-
const target = targetDir(scope, skill.name);
|
|
10419
|
+
const target = targetDir(scope, skill.name, dotAgents);
|
|
10418
10420
|
if (targetHasSkillFiles(target) && !force) {
|
|
10419
10421
|
process.stderr.write(`tutuca: ${target} already contains skill files. Re-run with --force to overwrite.
|
|
10420
10422
|
`);
|
|
@@ -10422,7 +10424,8 @@ function installSkill(skill, root, scope, force) {
|
|
|
10422
10424
|
}
|
|
10423
10425
|
mkdirSync(target, { recursive: true });
|
|
10424
10426
|
cpSync(src, target, { recursive: true });
|
|
10425
|
-
const
|
|
10427
|
+
const baseDir = dotAgents ? ".agents/skills" : ".claude/skills";
|
|
10428
|
+
const rel = scope === "project" ? `${baseDir}/${skill.name}` : target;
|
|
10426
10429
|
process.stdout.write(`installed ${skill.name} skill → ${rel}
|
|
10427
10430
|
`);
|
|
10428
10431
|
}
|
|
@@ -10435,13 +10438,14 @@ async function run(argv) {
|
|
|
10435
10438
|
"margaui-skill": { type: "boolean", default: false },
|
|
10436
10439
|
"immutable-skill": { type: "boolean", default: false },
|
|
10437
10440
|
all: { type: "boolean", default: false },
|
|
10441
|
+
"dot-agents": { type: "boolean", default: false },
|
|
10438
10442
|
force: { type: "boolean", short: "f", default: false },
|
|
10439
10443
|
help: { type: "boolean", short: "h", default: false }
|
|
10440
10444
|
},
|
|
10441
10445
|
allowPositionals: false
|
|
10442
10446
|
});
|
|
10443
10447
|
if (parsed.values.help) {
|
|
10444
|
-
process.stdout.write(`tutuca install-skill [--user | --project] [--margaui-skill | --immutable-skill | --all] [--force]
|
|
10448
|
+
process.stdout.write(`tutuca install-skill [--user | --project] [--margaui-skill | --immutable-skill | --all] [--dot-agents] [--force]
|
|
10445
10449
|
` + `
|
|
10446
10450
|
` + ` Installs Claude Code skill assets into .claude/skills/<name>/.
|
|
10447
10451
|
` + ` Defaults to --project (cwd); --user installs at ~/.claude/skills/.
|
|
@@ -10452,6 +10456,7 @@ async function run(argv) {
|
|
|
10452
10456
|
` + ` --immutable-skill install the immutable-js skill instead
|
|
10453
10457
|
` + ` --all install every bundled skill (tutuca + margaui + immutable-js)
|
|
10454
10458
|
` + `
|
|
10459
|
+
` + ` --dot-agents installs into .agents/skills/ instead of .claude/skills/.
|
|
10455
10460
|
` + ` --force overwrites existing files.
|
|
10456
10461
|
`);
|
|
10457
10462
|
return;
|
|
@@ -10482,7 +10487,7 @@ async function run(argv) {
|
|
|
10482
10487
|
selected = selFlag ? [selFlag] : SKILLS.filter((s) => s.name === "tutuca");
|
|
10483
10488
|
}
|
|
10484
10489
|
for (const skill of selected) {
|
|
10485
|
-
installSkill(skill, root, scope, parsed.values.force);
|
|
10490
|
+
installSkill(skill, root, scope, parsed.values.force, parsed.values["dot-agents"]);
|
|
10486
10491
|
}
|
|
10487
10492
|
process.stdout.write(`Open a Claude Code session in this directory to use it.
|
|
10488
10493
|
`);
|
|
@@ -10579,10 +10584,15 @@ COMMANDS (no module required)
|
|
|
10579
10584
|
Without [command]: prints this full reference.
|
|
10580
10585
|
With [command]: prints that command's one-line description.
|
|
10581
10586
|
|
|
10582
|
-
install-skill [--user | --project] [--force]
|
|
10583
|
-
Copy
|
|
10584
|
-
|
|
10585
|
-
|
|
10587
|
+
install-skill [--user | --project] [--margaui-skill | --immutable-skill | --all] [--dot-agents] [--force]
|
|
10588
|
+
Copy bundled Claude Code skill assets into .claude/skills/<name>/.
|
|
10589
|
+
Scope: --project (cwd, default) or --user (~/.claude/skills/).
|
|
10590
|
+
Selection (default is the tutuca skill):
|
|
10591
|
+
--margaui-skill install the margaui skill instead
|
|
10592
|
+
--immutable-skill install the immutable-js skill instead
|
|
10593
|
+
--all install every bundled skill
|
|
10594
|
+
--dot-agents installs into .agents/skills/ instead of .claude/skills/.
|
|
10595
|
+
--force overwrites existing files.
|
|
10586
10596
|
|
|
10587
10597
|
GLOBAL FLAGS
|
|
10588
10598
|
-f, --format <cli|md|json|html>
|
package/dist/tutuca-dev.js
CHANGED
|
@@ -6,7 +6,7 @@ class Step {
|
|
|
6
6
|
setValue(root, _v) {
|
|
7
7
|
return root;
|
|
8
8
|
}
|
|
9
|
-
|
|
9
|
+
updateBinds(_v, _o) {}
|
|
10
10
|
isFrame = true;
|
|
11
11
|
}
|
|
12
12
|
|
|
@@ -27,7 +27,7 @@ class BindStep extends Step {
|
|
|
27
27
|
withKey(key) {
|
|
28
28
|
return new BindStep({ ...this.binds, key });
|
|
29
29
|
}
|
|
30
|
-
|
|
30
|
+
updateBinds(_v, o) {
|
|
31
31
|
Object.assign(o, this.binds);
|
|
32
32
|
}
|
|
33
33
|
isFrame = false;
|
|
@@ -65,7 +65,7 @@ class FieldSeqStep extends Step {
|
|
|
65
65
|
setValue(root, v) {
|
|
66
66
|
return root.set(this.field, root.get(this.field).set(this.key, v));
|
|
67
67
|
}
|
|
68
|
-
|
|
68
|
+
updateBinds(_v, o) {
|
|
69
69
|
o.key = this.key;
|
|
70
70
|
}
|
|
71
71
|
}
|
|
@@ -93,7 +93,7 @@ class SeqAccessStep extends Step {
|
|
|
93
93
|
const key = root?.get(this.keyField, NONE);
|
|
94
94
|
return seq === NONE || key === NONE ? root : root.set(this.seqField, seq.set(key, v));
|
|
95
95
|
}
|
|
96
|
-
|
|
96
|
+
updateBinds(v, o) {
|
|
97
97
|
o.key = v?.get(this.keyField, null);
|
|
98
98
|
}
|
|
99
99
|
}
|
|
@@ -142,7 +142,7 @@ class Path {
|
|
|
142
142
|
console.warn(`bad PathItem`, { root, curVal, step, path: this });
|
|
143
143
|
return null;
|
|
144
144
|
}
|
|
145
|
-
step.
|
|
145
|
+
step.updateBinds(curVal, stack.binds[0].binds);
|
|
146
146
|
stack = stack.enter(curVal, {}, step.isFrame);
|
|
147
147
|
}
|
|
148
148
|
return stack;
|
|
@@ -1328,8 +1328,8 @@ class SlotNode extends WrapperNode {
|
|
|
1328
1328
|
|
|
1329
1329
|
class ScopeNode extends WrapperNode {
|
|
1330
1330
|
render(stack, rx) {
|
|
1331
|
-
const
|
|
1332
|
-
return this.node.render(stack.enter(stack.it,
|
|
1331
|
+
const binds = this.val.eval(stack)?.call(stack.it) ?? {};
|
|
1332
|
+
return this.node.render(stack.enter(stack.it, binds, false), rx);
|
|
1333
1333
|
}
|
|
1334
1334
|
toPathItem() {
|
|
1335
1335
|
return new BindStep({});
|
|
@@ -4631,7 +4631,7 @@ class Component {
|
|
|
4631
4631
|
this.commonStyle = o.commonStyle ?? "";
|
|
4632
4632
|
this.globalStyle = o.globalStyle ?? "";
|
|
4633
4633
|
this.input = o.input ?? {};
|
|
4634
|
-
this.
|
|
4634
|
+
this.receive = o.receive ?? {};
|
|
4635
4635
|
this.bubble = o.bubble ?? {};
|
|
4636
4636
|
this.response = o.response ?? {};
|
|
4637
4637
|
this.alter = o.alter ?? {};
|
|
@@ -4709,23 +4709,23 @@ function lookup(chain, name, dv = null) {
|
|
|
4709
4709
|
}
|
|
4710
4710
|
|
|
4711
4711
|
class BindFrame {
|
|
4712
|
-
constructor(it,
|
|
4712
|
+
constructor(it, binds, isFrame) {
|
|
4713
4713
|
this.it = it;
|
|
4714
|
-
this.
|
|
4714
|
+
this.binds = binds;
|
|
4715
4715
|
this.isFrame = isFrame;
|
|
4716
4716
|
}
|
|
4717
4717
|
lookup(name) {
|
|
4718
|
-
const v = this.
|
|
4718
|
+
const v = this.binds[name];
|
|
4719
4719
|
return v === undefined ? this.isFrame ? STOP : NEXT : v;
|
|
4720
4720
|
}
|
|
4721
4721
|
}
|
|
4722
4722
|
|
|
4723
4723
|
class ObjectFrame {
|
|
4724
|
-
constructor(
|
|
4725
|
-
this.
|
|
4724
|
+
constructor(binds) {
|
|
4725
|
+
this.binds = binds;
|
|
4726
4726
|
}
|
|
4727
4727
|
lookup(key) {
|
|
4728
|
-
const v = this.
|
|
4728
|
+
const v = this.binds[key];
|
|
4729
4729
|
return v === undefined ? NEXT : v;
|
|
4730
4730
|
}
|
|
4731
4731
|
}
|
|
@@ -4750,11 +4750,12 @@ class Stack {
|
|
|
4750
4750
|
this.ctx = ctx;
|
|
4751
4751
|
}
|
|
4752
4752
|
_enrichOnEnter() {
|
|
4753
|
-
return this.
|
|
4753
|
+
return this.withDynamicBinds(this.comps.getOnEnterFor(this.it).call(this.it));
|
|
4754
4754
|
}
|
|
4755
4755
|
upToFrameBinds() {
|
|
4756
4756
|
const { comps, binds, dynBinds, views, viewsId, ctx } = this;
|
|
4757
|
-
|
|
4757
|
+
const [head, tail] = binds;
|
|
4758
|
+
return head.isFrame ? this : new Stack(comps, tail[0].it, tail, dynBinds, views, viewsId, ctx);
|
|
4758
4759
|
}
|
|
4759
4760
|
static root(comps, it, ctx) {
|
|
4760
4761
|
const binds = [new BindFrame(it, { it }, true), null];
|
|
@@ -4773,7 +4774,7 @@ class Stack {
|
|
|
4773
4774
|
const newViews = [name, views];
|
|
4774
4775
|
return new Stack(comps, it, binds, dynBinds, newViews, computeViewsId(newViews), ctx);
|
|
4775
4776
|
}
|
|
4776
|
-
|
|
4777
|
+
withDynamicBinds(dynamics) {
|
|
4777
4778
|
if (dynamics == null || dynamics.length === 0)
|
|
4778
4779
|
return this;
|
|
4779
4780
|
const dynObj = {};
|
|
@@ -4859,14 +4860,13 @@ class Transactor {
|
|
|
4859
4860
|
pushTransaction(t) {
|
|
4860
4861
|
this.transactions.push(t);
|
|
4861
4862
|
this.onTransactionPushed(t);
|
|
4862
|
-
return t;
|
|
4863
4863
|
}
|
|
4864
|
-
|
|
4865
|
-
|
|
4864
|
+
pushSend(path, name, args = [], opts = {}, parent = null) {
|
|
4865
|
+
this.pushTransaction(new SendEvent(path, this, name, args, parent, opts));
|
|
4866
4866
|
}
|
|
4867
4867
|
pushBubble(path, name, args = [], opts = {}, parent = null) {
|
|
4868
4868
|
const newOpts = opts.skipSelf ? { ...opts, skipSelf: false } : opts;
|
|
4869
|
-
|
|
4869
|
+
this.pushTransaction(new BubbleEvent(path, this, name, args, parent, newOpts));
|
|
4870
4870
|
}
|
|
4871
4871
|
async pushRequest(path, name, args = [], opts = {}, parent = null) {
|
|
4872
4872
|
const curRoot = this.state.val;
|
|
@@ -4876,13 +4876,13 @@ class Transactor {
|
|
|
4876
4876
|
const push = (specificName, baseName, singleArg, result, error) => {
|
|
4877
4877
|
const resArgs = specificName ? [singleArg] : [result, error];
|
|
4878
4878
|
const t = new ResponseEvent(path, this, specificName ?? baseName, resArgs, parent);
|
|
4879
|
-
|
|
4879
|
+
this.pushTransaction(t);
|
|
4880
4880
|
};
|
|
4881
4881
|
try {
|
|
4882
4882
|
const result = await handler.fn.apply(null, args);
|
|
4883
|
-
|
|
4883
|
+
push(opts?.onOkName, resHandlerName, result, result, null);
|
|
4884
4884
|
} catch (error) {
|
|
4885
|
-
|
|
4885
|
+
push(opts?.onErrorName, resHandlerName, error, null, error);
|
|
4886
4886
|
}
|
|
4887
4887
|
}
|
|
4888
4888
|
get hasPendingTransactions() {
|
|
@@ -4987,6 +4987,7 @@ class InputEvent extends Transaction {
|
|
|
4987
4987
|
args[i] = args[i].toHandlerArg(dispatcher);
|
|
4988
4988
|
}
|
|
4989
4989
|
}
|
|
4990
|
+
args.push(new EventContext(this.path, this.transactor, this));
|
|
4990
4991
|
return [handler, args];
|
|
4991
4992
|
}
|
|
4992
4993
|
lookupName(name) {
|
|
@@ -5053,8 +5054,8 @@ class ResponseEvent extends NameArgsTransaction {
|
|
|
5053
5054
|
handlerProp = "response";
|
|
5054
5055
|
}
|
|
5055
5056
|
|
|
5056
|
-
class
|
|
5057
|
-
handlerProp = "
|
|
5057
|
+
class SendEvent extends NameArgsTransaction {
|
|
5058
|
+
handlerProp = "receive";
|
|
5058
5059
|
run(rootVal, comps) {
|
|
5059
5060
|
return this.opts.skipSelf ? rootVal : this.updateRootValue(rootVal, comps);
|
|
5060
5061
|
}
|
|
@@ -5065,7 +5066,7 @@ class LogicEvent extends NameArgsTransaction {
|
|
|
5065
5066
|
}
|
|
5066
5067
|
}
|
|
5067
5068
|
|
|
5068
|
-
class BubbleEvent extends
|
|
5069
|
+
class BubbleEvent extends SendEvent {
|
|
5069
5070
|
handlerProp = "bubble";
|
|
5070
5071
|
stopPropagation() {
|
|
5071
5072
|
this.opts.bubbles = false;
|
|
@@ -5109,14 +5110,14 @@ class Dispatcher {
|
|
|
5109
5110
|
get at() {
|
|
5110
5111
|
return new PathChanges(this);
|
|
5111
5112
|
}
|
|
5112
|
-
|
|
5113
|
-
return this.
|
|
5113
|
+
send(name, args, opts) {
|
|
5114
|
+
return this.sendAtPath(this.path, name, args, opts);
|
|
5114
5115
|
}
|
|
5115
5116
|
bubble(name, args, opts) {
|
|
5116
|
-
return this.
|
|
5117
|
+
return this.send(name, args, { skipSelf: true, bubbles: true, ...opts });
|
|
5117
5118
|
}
|
|
5118
|
-
|
|
5119
|
-
return this.transactor.
|
|
5119
|
+
sendAtPath(path, name, args, opts) {
|
|
5120
|
+
return this.transactor.pushSend(path, name, args, opts, this.parent);
|
|
5120
5121
|
}
|
|
5121
5122
|
request(name, args, opts) {
|
|
5122
5123
|
return this.requestAtPath(this.path, name, args, opts);
|
|
@@ -5140,11 +5141,11 @@ class PathChanges extends PathBuilder {
|
|
|
5140
5141
|
super();
|
|
5141
5142
|
this.dispatcher = dispatcher;
|
|
5142
5143
|
}
|
|
5143
|
-
|
|
5144
|
-
return this.dispatcher.
|
|
5144
|
+
send(name, args, opts) {
|
|
5145
|
+
return this.dispatcher.sendAtPath(this.buildPath(), name, args, opts);
|
|
5145
5146
|
}
|
|
5146
5147
|
bubble(name, args, opts) {
|
|
5147
|
-
return this.
|
|
5148
|
+
return this.send(name, args, { skipSelf: true, bubbles: true, ...opts });
|
|
5148
5149
|
}
|
|
5149
5150
|
buildPath() {
|
|
5150
5151
|
return this.dispatcher.path.concat(this.pathChanges);
|
|
@@ -5643,8 +5644,8 @@ class App {
|
|
|
5643
5644
|
for (const name of this._eventNames)
|
|
5644
5645
|
this.rootNode.removeEventListener(name, this, listenerOpts(name));
|
|
5645
5646
|
}
|
|
5646
|
-
|
|
5647
|
-
|
|
5647
|
+
dispatchSendAtRoot(name, args, opts) {
|
|
5648
|
+
this.transactor.pushSend(new Path([]), name, args, opts);
|
|
5648
5649
|
}
|
|
5649
5650
|
registerComponents(comps, aliases) {
|
|
5650
5651
|
const scope = this.compStack.enter();
|
|
@@ -10684,15 +10685,15 @@ class Renderer {
|
|
|
10684
10685
|
this.getSeqInfo(seq)(seq, (key, value, attrName) => {
|
|
10685
10686
|
if (filter.call(it, key, value, iterData)) {
|
|
10686
10687
|
const cachePath = enricher ? [it, value] : [value];
|
|
10687
|
-
const
|
|
10688
|
+
const binds = { key, value };
|
|
10688
10689
|
const cacheKey = `${nid}-${key}`;
|
|
10689
10690
|
if (enricher)
|
|
10690
|
-
enricher.call(it,
|
|
10691
|
+
enricher.call(it, binds, key, value, iterData);
|
|
10691
10692
|
const cachedNode = this.cache.get(cachePath, cacheKey);
|
|
10692
10693
|
if (cachedNode)
|
|
10693
10694
|
this.pushEachEntry(r, nid, attrName, key, cachedNode);
|
|
10694
10695
|
else {
|
|
10695
|
-
const dom = this.renderView(view, stack.enter(value,
|
|
10696
|
+
const dom = this.renderView(view, stack.enter(value, binds, false));
|
|
10696
10697
|
this.pushEachEntry(r, nid, attrName, key, dom);
|
|
10697
10698
|
this.cache.set(cachePath, cacheKey, dom);
|
|
10698
10699
|
}
|