tutuca 0.9.92 → 0.9.94
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 +310 -60
- package/dist/tutuca-dev.ext.js +1431 -1196
- package/dist/tutuca-dev.js +1431 -1196
- package/dist/tutuca-dev.min.js +3 -2
- package/dist/tutuca-extra.ext.js +186 -52
- package/dist/tutuca-extra.js +187 -53
- package/dist/tutuca-extra.min.js +1 -1
- package/dist/tutuca-storybook.js +69 -11
- package/dist/tutuca.ext.js +186 -52
- package/dist/tutuca.js +187 -53
- package/dist/tutuca.min.js +1 -1
- package/package.json +2 -1
- package/skill/tutuca/core.md +26 -0
- package/skill/tutuca/storybook.md +46 -0
- package/skill/tutuca/testing.md +33 -0
- package/skill/tutuca-source/tutuca.ext.js +186 -52
package/dist/tutuca.js
CHANGED
|
@@ -7290,36 +7290,81 @@ class Transactor {
|
|
|
7290
7290
|
this.transactions = [];
|
|
7291
7291
|
this.state = new State(rootValue);
|
|
7292
7292
|
this.onTransactionPushed = () => {};
|
|
7293
|
+
this._inflight = new Set;
|
|
7293
7294
|
}
|
|
7294
7295
|
pushTransaction(t) {
|
|
7295
7296
|
this.transactions.push(t);
|
|
7296
7297
|
this.onTransactionPushed(t);
|
|
7297
7298
|
}
|
|
7299
|
+
_link(child, parent) {
|
|
7300
|
+
if (parent) {
|
|
7301
|
+
const release = parent.completion.track();
|
|
7302
|
+
child.completion.whenSubtreeSettled().then(release);
|
|
7303
|
+
}
|
|
7304
|
+
return child;
|
|
7305
|
+
}
|
|
7298
7306
|
pushSend(path, name, args = [], opts = {}, parent = null) {
|
|
7299
|
-
|
|
7307
|
+
const t = new SendEvent(path, this, name, args, parent, opts);
|
|
7308
|
+
this.pushTransaction(t);
|
|
7309
|
+
return this._link(t, parent);
|
|
7310
|
+
}
|
|
7311
|
+
pushInput(path, name, args = [], opts = {}, parent = null) {
|
|
7312
|
+
const t = new InputDispatchEvent(path, this, name, args, parent, opts);
|
|
7313
|
+
this.pushTransaction(t);
|
|
7314
|
+
return this._link(t, parent);
|
|
7300
7315
|
}
|
|
7301
7316
|
pushBubble(path, name, args = [], opts = {}, parent = null, targetPath = null) {
|
|
7302
7317
|
const newOpts = opts.skipSelf ? { ...opts, skipSelf: false } : opts;
|
|
7303
|
-
|
|
7304
|
-
|
|
7305
|
-
|
|
7306
|
-
|
|
7307
|
-
|
|
7308
|
-
const
|
|
7309
|
-
const
|
|
7310
|
-
|
|
7311
|
-
|
|
7312
|
-
|
|
7313
|
-
|
|
7314
|
-
|
|
7315
|
-
|
|
7316
|
-
this.
|
|
7318
|
+
const t = new BubbleEvent(path, this, name, args, parent, newOpts, targetPath);
|
|
7319
|
+
this.pushTransaction(t);
|
|
7320
|
+
return this._link(t, parent);
|
|
7321
|
+
}
|
|
7322
|
+
pushRequest(path, name, args = [], opts = {}, parent = null) {
|
|
7323
|
+
const release = parent ? parent.completion.track() : null;
|
|
7324
|
+
const p = this._runRequest(path, name, args, opts, parent, release);
|
|
7325
|
+
this._inflight.add(p);
|
|
7326
|
+
p.finally(() => this._inflight.delete(p));
|
|
7327
|
+
return p;
|
|
7328
|
+
}
|
|
7329
|
+
async settle(maxTurns = 1e4) {
|
|
7330
|
+
while ((this.hasPendingTransactions || this._inflight.size) && maxTurns-- > 0) {
|
|
7331
|
+
while (this.hasPendingTransactions)
|
|
7332
|
+
this.transactNext();
|
|
7333
|
+
if (this._inflight.size)
|
|
7334
|
+
await Promise.allSettled([...this._inflight]);
|
|
7335
|
+
}
|
|
7336
|
+
}
|
|
7337
|
+
async _runRequest(path, name, args = [], opts = {}, parent = null, release = null) {
|
|
7338
|
+
let released = false;
|
|
7339
|
+
const transfer = (t) => {
|
|
7340
|
+
if (release) {
|
|
7341
|
+
released = true;
|
|
7342
|
+
t.completion.whenSubtreeSettled().then(release);
|
|
7343
|
+
}
|
|
7317
7344
|
};
|
|
7318
7345
|
try {
|
|
7319
|
-
const
|
|
7320
|
-
|
|
7321
|
-
|
|
7322
|
-
|
|
7346
|
+
const curRoot = this.state.val;
|
|
7347
|
+
const txnPath = path.toTransactionPath();
|
|
7348
|
+
const curLeaf = txnPath.lookup(curRoot);
|
|
7349
|
+
const handler = this.comps.getRequestFor(curLeaf, name) ?? mkReq404(name);
|
|
7350
|
+
const reqCtx = new RequestContext(path, this, parent, curRoot);
|
|
7351
|
+
const resHandlerName = opts?.onResName ?? name;
|
|
7352
|
+
const resPath = opts?.livePath ? null : txnPath.pinKeys(curRoot);
|
|
7353
|
+
const push = (specificName, baseName, singleArg, result, error) => {
|
|
7354
|
+
const resArgs = specificName ? [singleArg] : [result, error];
|
|
7355
|
+
const t = new ResponseEvent(path, this, specificName ?? baseName, resArgs, parent, resPath);
|
|
7356
|
+
transfer(t);
|
|
7357
|
+
this.pushTransaction(t);
|
|
7358
|
+
};
|
|
7359
|
+
try {
|
|
7360
|
+
const result = await handler.fn.apply(null, [...args, reqCtx]);
|
|
7361
|
+
push(opts?.onOkName, resHandlerName, result, result, null);
|
|
7362
|
+
} catch (error) {
|
|
7363
|
+
push(opts?.onErrorName, resHandlerName, error, null, error);
|
|
7364
|
+
}
|
|
7365
|
+
} finally {
|
|
7366
|
+
if (release && !released)
|
|
7367
|
+
release();
|
|
7323
7368
|
}
|
|
7324
7369
|
}
|
|
7325
7370
|
get hasPendingTransactions() {
|
|
@@ -7330,13 +7375,18 @@ class Transactor {
|
|
|
7330
7375
|
this.transact(this.transactions.shift());
|
|
7331
7376
|
}
|
|
7332
7377
|
transact(transaction) {
|
|
7333
|
-
|
|
7334
|
-
|
|
7335
|
-
|
|
7336
|
-
|
|
7337
|
-
|
|
7338
|
-
|
|
7339
|
-
|
|
7378
|
+
try {
|
|
7379
|
+
const curState = this.state.val;
|
|
7380
|
+
const newState = transaction.run(curState, this.comps);
|
|
7381
|
+
if (newState !== undefined) {
|
|
7382
|
+
this.state.set(newState, { transaction });
|
|
7383
|
+
transaction.afterTransaction();
|
|
7384
|
+
} else
|
|
7385
|
+
console.warn("undefined new state", { curState, transaction });
|
|
7386
|
+
} finally {
|
|
7387
|
+
transaction._completion?.ensureSelfSettled();
|
|
7388
|
+
transaction._completion?.releaseSelf();
|
|
7389
|
+
}
|
|
7340
7390
|
}
|
|
7341
7391
|
transactInputNow(path, event, eventHandler, dragInfo) {
|
|
7342
7392
|
this.transact(new InputEvent(path, event, eventHandler, this, dragInfo));
|
|
@@ -7357,18 +7407,17 @@ class Transaction {
|
|
|
7357
7407
|
this.path = path;
|
|
7358
7408
|
this.transactor = transactor;
|
|
7359
7409
|
this.parentTransaction = parentTransaction;
|
|
7360
|
-
this.
|
|
7410
|
+
this._completion = null;
|
|
7361
7411
|
}
|
|
7362
|
-
get
|
|
7363
|
-
this.
|
|
7364
|
-
return this.
|
|
7412
|
+
get completion() {
|
|
7413
|
+
this._completion ??= new Completion;
|
|
7414
|
+
return this._completion;
|
|
7365
7415
|
}
|
|
7366
|
-
|
|
7367
|
-
return this.
|
|
7416
|
+
whenSettled() {
|
|
7417
|
+
return this.completion.whenSettled();
|
|
7368
7418
|
}
|
|
7369
|
-
|
|
7370
|
-
this.
|
|
7371
|
-
parentTransaction.task.addDep(this.task);
|
|
7419
|
+
whenSubtreeSettled() {
|
|
7420
|
+
return this.completion.whenSubtreeSettled();
|
|
7372
7421
|
}
|
|
7373
7422
|
run(rootValue, comps) {
|
|
7374
7423
|
return this.updateRootValue(rootValue, comps);
|
|
@@ -7394,7 +7443,7 @@ class Transaction {
|
|
|
7394
7443
|
const txnPath = this.getTransactionPath();
|
|
7395
7444
|
const curLeaf = txnPath.lookup(curRoot);
|
|
7396
7445
|
const newLeaf = this.callHandler(curRoot, curLeaf, comps);
|
|
7397
|
-
this.
|
|
7446
|
+
this._completion?.markSelfSettled({ value: newLeaf, old: curLeaf });
|
|
7398
7447
|
return curLeaf !== newLeaf ? txnPath.setValue(curRoot, newLeaf) : curRoot;
|
|
7399
7448
|
}
|
|
7400
7449
|
lookupName(_name) {
|
|
@@ -7531,29 +7580,69 @@ class BubbleEvent extends SendEvent {
|
|
|
7531
7580
|
}
|
|
7532
7581
|
}
|
|
7533
7582
|
|
|
7534
|
-
class
|
|
7583
|
+
class InputDispatchEvent extends NameArgsTransaction {
|
|
7584
|
+
handlerProp = "input";
|
|
7585
|
+
}
|
|
7586
|
+
|
|
7587
|
+
class Completion {
|
|
7535
7588
|
constructor() {
|
|
7536
|
-
this.
|
|
7537
|
-
this.
|
|
7538
|
-
this.
|
|
7539
|
-
|
|
7540
|
-
|
|
7589
|
+
this.val = undefined;
|
|
7590
|
+
this.selfSettled = false;
|
|
7591
|
+
this.subtreeSettled = false;
|
|
7592
|
+
this.pending = 1;
|
|
7593
|
+
this._selfResolve = null;
|
|
7594
|
+
this._selfPromise = null;
|
|
7595
|
+
this._subtreeResolve = null;
|
|
7596
|
+
this._subtreePromise = null;
|
|
7597
|
+
this._selfReleased = false;
|
|
7598
|
+
}
|
|
7599
|
+
whenSettled() {
|
|
7600
|
+
if (this.selfSettled)
|
|
7601
|
+
return Promise.resolve(this.val);
|
|
7602
|
+
this._selfPromise ??= new Promise((res) => {
|
|
7603
|
+
this._selfResolve = res;
|
|
7541
7604
|
});
|
|
7542
|
-
this.
|
|
7605
|
+
return this._selfPromise;
|
|
7543
7606
|
}
|
|
7544
|
-
|
|
7545
|
-
|
|
7546
|
-
|
|
7547
|
-
|
|
7607
|
+
whenSubtreeSettled() {
|
|
7608
|
+
if (this.subtreeSettled)
|
|
7609
|
+
return Promise.resolve(this.val);
|
|
7610
|
+
this._subtreePromise ??= new Promise((res) => {
|
|
7611
|
+
this._subtreeResolve = res;
|
|
7612
|
+
});
|
|
7613
|
+
return this._subtreePromise;
|
|
7548
7614
|
}
|
|
7549
|
-
|
|
7615
|
+
markSelfSettled(val) {
|
|
7616
|
+
if (this.selfSettled)
|
|
7617
|
+
return;
|
|
7618
|
+
this.selfSettled = true;
|
|
7550
7619
|
this.val = val;
|
|
7551
|
-
this.
|
|
7620
|
+
this._selfResolve?.(val);
|
|
7621
|
+
}
|
|
7622
|
+
ensureSelfSettled() {
|
|
7623
|
+
if (!this.selfSettled)
|
|
7624
|
+
this.markSelfSettled(this.val);
|
|
7625
|
+
}
|
|
7626
|
+
track() {
|
|
7627
|
+
this.pending++;
|
|
7628
|
+
let done = false;
|
|
7629
|
+
return () => {
|
|
7630
|
+
if (done)
|
|
7631
|
+
return;
|
|
7632
|
+
done = true;
|
|
7633
|
+
this._release();
|
|
7634
|
+
};
|
|
7552
7635
|
}
|
|
7553
|
-
|
|
7554
|
-
if (this.
|
|
7555
|
-
|
|
7556
|
-
|
|
7636
|
+
releaseSelf() {
|
|
7637
|
+
if (this._selfReleased)
|
|
7638
|
+
return;
|
|
7639
|
+
this._selfReleased = true;
|
|
7640
|
+
this._release();
|
|
7641
|
+
}
|
|
7642
|
+
_release() {
|
|
7643
|
+
if (--this.pending === 0) {
|
|
7644
|
+
this.subtreeSettled = true;
|
|
7645
|
+
this._subtreeResolve?.(this.val);
|
|
7557
7646
|
}
|
|
7558
7647
|
}
|
|
7559
7648
|
}
|
|
@@ -7592,6 +7681,9 @@ class Dispatcher {
|
|
|
7592
7681
|
requestAtPath(path, name, args, opts) {
|
|
7593
7682
|
return this.transactor.pushRequest(path, name, args, opts, this.parent);
|
|
7594
7683
|
}
|
|
7684
|
+
inputAtPath(path, name, args, opts) {
|
|
7685
|
+
return this.transactor.pushInput(path, name, args, opts, this.parent);
|
|
7686
|
+
}
|
|
7595
7687
|
lookupTypeFor(name, inst) {
|
|
7596
7688
|
return this.transactor.comps.getCompFor(inst).scope.lookupComponent(name);
|
|
7597
7689
|
}
|
|
@@ -7890,6 +7982,45 @@ class DragInfo {
|
|
|
7890
7982
|
return this.stack.lookupBind(name);
|
|
7891
7983
|
}
|
|
7892
7984
|
}
|
|
7985
|
+
// src/on.js
|
|
7986
|
+
var OP_KINDS = ["send", "bubble", "request", "input"];
|
|
7987
|
+
function phaseOps(phase) {
|
|
7988
|
+
const ops = [];
|
|
7989
|
+
for (const type of OP_KINDS)
|
|
7990
|
+
for (const a of phase[type] ?? [])
|
|
7991
|
+
ops.push({ type, ...a });
|
|
7992
|
+
for (const a of phase.do ?? [])
|
|
7993
|
+
ops.push(a);
|
|
7994
|
+
return ops;
|
|
7995
|
+
}
|
|
7996
|
+
function resolveArgs(args, self) {
|
|
7997
|
+
return typeof args === "function" ? args(self) ?? [] : args ?? [];
|
|
7998
|
+
}
|
|
7999
|
+
function dispatchPhase(dispatcher, targetPath, phase, self) {
|
|
8000
|
+
if (!phase)
|
|
8001
|
+
return;
|
|
8002
|
+
for (const op of phaseOps(phase)) {
|
|
8003
|
+
const args = resolveArgs(op.args, self);
|
|
8004
|
+
switch (op.type) {
|
|
8005
|
+
case "send":
|
|
8006
|
+
dispatcher.sendAtPath(targetPath, op.name, args, op.opts);
|
|
8007
|
+
break;
|
|
8008
|
+
case "bubble":
|
|
8009
|
+
dispatcher.sendAtPath(targetPath, op.name, args, {
|
|
8010
|
+
skipSelf: true,
|
|
8011
|
+
bubbles: true,
|
|
8012
|
+
...op.opts
|
|
8013
|
+
});
|
|
8014
|
+
break;
|
|
8015
|
+
case "request":
|
|
8016
|
+
dispatcher.requestAtPath(targetPath, op.name, args, op.opts);
|
|
8017
|
+
break;
|
|
8018
|
+
case "input":
|
|
8019
|
+
dispatcher.inputAtPath(targetPath, op.name, args, op.opts);
|
|
8020
|
+
break;
|
|
8021
|
+
}
|
|
8022
|
+
}
|
|
8023
|
+
}
|
|
7893
8024
|
// src/oo.js
|
|
7894
8025
|
var BAD_VALUE = Symbol("BadValue");
|
|
7895
8026
|
var nullCoercer = (v) => v;
|
|
@@ -8302,8 +8433,10 @@ export {
|
|
|
8302
8433
|
test,
|
|
8303
8434
|
setIn$1 as setIn,
|
|
8304
8435
|
set,
|
|
8436
|
+
resolveArgs,
|
|
8305
8437
|
removeIn,
|
|
8306
8438
|
remove,
|
|
8439
|
+
phaseOps,
|
|
8307
8440
|
mergeWith$1 as mergeWith,
|
|
8308
8441
|
mergeDeepWith$1 as mergeDeepWith,
|
|
8309
8442
|
mergeDeep$1 as mergeDeep,
|
|
@@ -8336,6 +8469,7 @@ export {
|
|
|
8336
8469
|
getIn$1 as getIn,
|
|
8337
8470
|
get,
|
|
8338
8471
|
fromJS,
|
|
8472
|
+
dispatchPhase,
|
|
8339
8473
|
css,
|
|
8340
8474
|
component,
|
|
8341
8475
|
collectIterBindings,
|