tutuca 0.9.77 → 0.9.79

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.
@@ -474,6 +474,7 @@ var G_BOOL = K_FIELD | K_METHOD | K_BIND | K_DYN | K_CONST;
474
474
  var G_TEXT = G_BOOL | K_STRTPL;
475
475
  var G_COMPONENT = K_FIELD | K_SEQ | K_DYN;
476
476
  var G_SEQUENCE = K_FIELD | K_DYN;
477
+ var G_PROVIDE = K_FIELD | K_SEQ;
477
478
  var G_FIELD = K_FIELD | K_METHOD | K_CONST | K_STR | K_SEQ;
478
479
  var G_VALUE = K_FIELD | K_METHOD | K_BIND | K_DYN | K_NAME | K_TYPE | K_REQUEST | K_CONST;
479
480
  var G_PRED_ARG = G_BOOL | K_STR;
@@ -592,6 +593,9 @@ class ValParser {
592
593
  parseField(s, px) {
593
594
  return this._parseSingle(s, px, G_FIELD);
594
595
  }
596
+ parseProvide(s, px) {
597
+ return this._parseSingle(s, px, G_PROVIDE);
598
+ }
595
599
  parseHandlerArg(s, px) {
596
600
  return this._parseSingle(s, px, G_HANDLER_ARG);
597
601
  }
@@ -1578,21 +1582,22 @@ function h(tagName, properties, children, namespace) {
1578
1582
  }
1579
1583
 
1580
1584
  // src/anode.js
1581
- function resolveDynProducer(comp, dynName) {
1582
- const dyn = comp?.dynamic?.[dynName];
1583
- if (dyn == null)
1584
- return null;
1585
- let producerComp, producerDyn;
1586
- if (dyn.compName != null) {
1587
- producerComp = comp.scope?.lookupComponent(dyn.compName);
1588
- producerDyn = producerComp?.dynamic?.[dyn.dynName];
1585
+ function resolveDynProducer(comp, name) {
1586
+ let producerComp, producerProvide;
1587
+ const lk = comp?.lookup?.[name];
1588
+ if (lk != null) {
1589
+ producerComp = comp.scope?.lookupComponent(lk.compName);
1590
+ producerProvide = producerComp?.provide?.[lk.provideName];
1589
1591
  } else {
1592
+ const p = comp?.provide?.[name];
1593
+ if (p == null)
1594
+ return null;
1590
1595
  producerComp = comp;
1591
- producerDyn = dyn;
1596
+ producerProvide = p;
1592
1597
  }
1593
- if (producerComp == null || producerDyn == null)
1598
+ if (producerComp == null || producerProvide == null)
1594
1599
  return null;
1595
- const pi = producerDyn.val?.toPathItem?.() ?? null;
1600
+ const pi = producerProvide.val?.toPathItem?.() ?? null;
1596
1601
  return { producerCompId: producerComp.id, producerSteps: pi ? [pi] : [] };
1597
1602
  }
1598
1603
 
@@ -2335,9 +2340,6 @@ class Components {
2335
2340
  getCompFor(v) {
2336
2341
  return v?.[this.getComponentSymbol]?.() ?? null;
2337
2342
  }
2338
- getOnEnterFor(v) {
2339
- return this.getCompFor(v)?.on.stackEnter ?? defaultOnStackEnter;
2340
- }
2341
2343
  getHandlerFor(v, name, key) {
2342
2344
  return this.getCompFor(v)?.[key][name] ?? null;
2343
2345
  }
@@ -2369,6 +2371,7 @@ class ComponentStack {
2369
2371
  for (let i = 0;i < comps.length; i++) {
2370
2372
  const comp = comps[i];
2371
2373
  comp.scope = this.enter();
2374
+ comp.Class.scope = comp.scope;
2372
2375
  this.comps.registerComponent(comp);
2373
2376
  this.byName[comp.name] = comp;
2374
2377
  }
@@ -2406,36 +2409,30 @@ class ComponentStack {
2406
2409
  }
2407
2410
  }
2408
2411
 
2409
- class Dynamic {
2412
+ class ProvideInfo {
2410
2413
  constructor(name, val, symbol) {
2411
2414
  this.name = name;
2412
2415
  this.val = val;
2413
2416
  this.symbol = symbol;
2414
2417
  }
2415
- getSymbol(_stack) {
2416
- return this.symbol;
2417
- }
2418
- evalAndBind(stack, binds) {
2419
- binds[this.getSymbol(stack)] = this.val.eval(stack);
2420
- }
2421
2418
  }
2422
2419
 
2423
- class DynamicAlias extends Dynamic {
2424
- constructor(name, val, compName, dynName) {
2425
- super(name, val, null);
2420
+ class LookupInfo {
2421
+ constructor(name, compName, provideName, val) {
2422
+ this.name = name;
2426
2423
  this.compName = compName;
2427
- this.dynName = dynName;
2428
- }
2429
- _resolveSymbol(stack) {
2430
- return stack.lookupType(this.compName)?.dynamic[this.dynName]?.symbol ?? null;
2424
+ this.provideName = provideName;
2425
+ this.val = val;
2426
+ this._sym = undefined;
2431
2427
  }
2432
- getSymbol(stack) {
2433
- this.symbol ??= this._resolveSymbol(stack);
2434
- return this.symbol;
2428
+ getProducerSymbol(stack) {
2429
+ if (this._sym === undefined)
2430
+ this._sym = stack.lookupType(this.compName)?.provide?.[this.provideName]?.symbol ?? null;
2431
+ return this._sym;
2435
2432
  }
2436
2433
  }
2437
2434
  var isString = (v) => typeof v === "string";
2438
- var _rawSpecKeys = "name view style commonStyle globalStyle input receive bubble response alter on views dynamic fields methods statics";
2435
+ var _rawSpecKeys = "name view style commonStyle globalStyle input receive bubble response alter views provide lookup fields methods statics";
2439
2436
  var KNOWN_SPEC_KEYS = new Set(_rawSpecKeys.split(" "));
2440
2437
  var _compId = 0;
2441
2438
 
@@ -2452,35 +2449,47 @@ class Component {
2452
2449
  this.bubble = o.bubble ?? {};
2453
2450
  this.response = o.response ?? {};
2454
2451
  this.alter = o.alter ?? {};
2455
- this.on = { stackEnter: o.on?.stackEnter ?? defaultOnStackEnter };
2456
2452
  for (const name in o.views ?? {}) {
2457
2453
  const v = o.views[name];
2458
2454
  const { view, style } = isString(v) ? { view: v } : v;
2459
2455
  this.views[name] = new View(name, view, style);
2460
2456
  }
2461
- this._rawDynamic = o.dynamic ?? {};
2462
- this.dynamic = {};
2457
+ this._rawProvide = o.provide ?? {};
2458
+ this._rawLookup = o.lookup ?? {};
2459
+ this.provide = {};
2460
+ this.lookup = {};
2463
2461
  this.scope = null;
2462
+ this.spec = o;
2464
2463
  this.extra = {};
2465
2464
  for (const key of Object.keys(o))
2466
2465
  if (!KNOWN_SPEC_KEYS.has(key))
2467
2466
  this.extra[key] = o[key];
2468
2467
  }
2468
+ clone() {
2469
+ return Component.fromSpec(this.spec);
2470
+ }
2469
2471
  compile(ParseContext2) {
2470
2472
  for (const name in this.views)
2471
2473
  this.views[name].compile(new ParseContext2, this.scope, this.id);
2472
- for (const key in this._rawDynamic) {
2473
- const dinfo = this._rawDynamic[key];
2474
- if (isString(dinfo)) {
2475
- const val = vp.parseField(dinfo, this.views.main.ctx);
2476
- this.dynamic[key] = new Dynamic(key, val, Symbol(key));
2477
- } else if (isString(dinfo?.default) && isString(dinfo?.for)) {
2478
- const val = vp.parseField(dinfo.default, this.views.main.ctx);
2479
- const [compName, dynName] = dinfo.for.split(".");
2480
- if (isString(compName) && isString(dynName))
2481
- this.dynamic[key] = new DynamicAlias(key, val, compName, dynName);
2482
- }
2474
+ const ctx = this.views.main.ctx;
2475
+ for (const key in this._rawProvide) {
2476
+ const val = vp.parseProvide(this._rawProvide[key], ctx);
2477
+ if (val)
2478
+ this.provide[key] = new ProvideInfo(key, val, Symbol(key));
2479
+ }
2480
+ for (const key in this._rawLookup) {
2481
+ const linfo = this._rawLookup[key];
2482
+ const forStr = isString(linfo) ? linfo : isString(linfo?.for) ? linfo.for : null;
2483
+ const [compName, provideName] = forStr === null ? [] : forStr.split(".");
2484
+ if (!isString(compName) || !isString(provideName))
2485
+ continue;
2486
+ const defStr = isString(linfo?.default) ? linfo.default : null;
2487
+ const val = defStr === null ? null : vp.parseField(defStr, ctx);
2488
+ this.lookup[key] = new LookupInfo(key, compName, provideName, val);
2483
2489
  }
2490
+ for (const key in this.lookup)
2491
+ if (this.provide[key] !== undefined)
2492
+ console.warn("name declared in both provide and lookup", this.name, key);
2484
2493
  }
2485
2494
  make(args, opts) {
2486
2495
  return this.Class.make(args, opts ?? { scope: this.scope });
@@ -2508,9 +2517,6 @@ class Component {
2508
2517
  `);
2509
2518
  }
2510
2519
  }
2511
- function defaultOnStackEnter() {
2512
- return null;
2513
- }
2514
2520
 
2515
2521
  // src/stack.js
2516
2522
  var STOP = Symbol("STOP");
@@ -2569,47 +2575,61 @@ class Stack {
2569
2575
  this.viewsId = viewsId;
2570
2576
  this.ctx = ctx;
2571
2577
  }
2572
- _enrichOnEnter() {
2573
- return this.withDynamicBinds(this.comps.getOnEnterFor(this.it).call(this.it));
2578
+ _pushProvides() {
2579
+ const provide = this.comps.getCompFor(this.it)?.provide;
2580
+ if (provide == null)
2581
+ return this;
2582
+ const dynObj = {};
2583
+ let has = false;
2584
+ for (const k in provide) {
2585
+ dynObj[provide[k].symbol] = provide[k].val.eval(this);
2586
+ has = true;
2587
+ }
2588
+ if (!has)
2589
+ return this;
2590
+ const newDynBinds = [new ObjectFrame(dynObj), this.dynBinds];
2591
+ const { comps, it, binds, views, viewsId, ctx } = this;
2592
+ return new Stack(comps, it, binds, newDynBinds, views, viewsId, ctx);
2574
2593
  }
2575
2594
  static root(comps, it, ctx) {
2576
2595
  const binds = [new BindFrame(it, { it }, true), null];
2577
2596
  const dynBinds = [new ObjectFrame({}), null];
2578
2597
  const views = ["main", null];
2579
- return new Stack(comps, it, binds, dynBinds, views, "", ctx)._enrichOnEnter();
2598
+ return new Stack(comps, it, binds, dynBinds, views, "", ctx)._pushProvides();
2580
2599
  }
2581
2600
  enter(it, bindings = {}, isFrame = true) {
2582
2601
  const { comps, binds, dynBinds, views, viewsId, ctx } = this;
2583
2602
  const newBinds = [new BindFrame(it, bindings, isFrame), binds];
2584
2603
  const stack = new Stack(comps, it, newBinds, dynBinds, views, viewsId, ctx);
2585
- return isFrame ? stack._enrichOnEnter() : stack;
2604
+ return isFrame ? stack._pushProvides() : stack;
2586
2605
  }
2587
2606
  pushViewName(name) {
2588
2607
  const { comps, it, binds, dynBinds, views, ctx } = this;
2589
2608
  const newViews = [name, views];
2590
2609
  return new Stack(comps, it, binds, dynBinds, newViews, computeViewsId(newViews), ctx);
2591
2610
  }
2592
- withDynamicBinds(dynamics) {
2593
- if (dynamics == null || dynamics.length === 0)
2594
- return this;
2595
- const dynObj = {};
2596
- const comp = this.comps.getCompFor(this.it);
2597
- for (const dynName of dynamics)
2598
- comp.dynamic[dynName].evalAndBind(this, dynObj);
2599
- const newDynBinds = [new ObjectFrame(dynObj), this.dynBinds];
2600
- const { comps, it, binds, views, viewsId, ctx } = this;
2601
- return new Stack(comps, it, binds, newDynBinds, views, viewsId, ctx);
2611
+ _pushDynBindValuesToArray(arr, comp) {
2612
+ for (const k in comp.provide)
2613
+ arr.push(this._lookupProvide(comp.provide[k]));
2614
+ for (const k in comp.lookup)
2615
+ arr.push(this._lookupAlias(comp.lookup[k]));
2602
2616
  }
2603
- _pushDynBindValuesToArray(arr, dyns) {
2604
- for (const k in dyns)
2605
- arr.push(this._lookupDynamicWithDynVal(dyns[k]));
2617
+ _lookupProvide(p) {
2618
+ return lookup(this.dynBinds, p.symbol) ?? p.val.eval(this) ?? null;
2606
2619
  }
2607
- _lookupDynamicWithDynVal(d) {
2608
- return lookup(this.dynBinds, d.getSymbol(this)) ?? d.val?.eval(this) ?? null;
2620
+ _lookupAlias(lk) {
2621
+ const sym = lk.getProducerSymbol(this);
2622
+ return (sym != null ? lookup(this.dynBinds, sym) : null) ?? lk.val?.eval(this) ?? null;
2609
2623
  }
2610
2624
  lookupDynamic(name) {
2611
- const d = this.comps.getCompFor(this.it)?.dynamic[name];
2612
- return d ? this._lookupDynamicWithDynVal(d) : null;
2625
+ const comp = this.comps.getCompFor(this.it);
2626
+ if (comp == null)
2627
+ return null;
2628
+ const lk = comp.lookup[name];
2629
+ if (lk !== undefined)
2630
+ return this._lookupAlias(lk);
2631
+ const p = comp.provide[name];
2632
+ return p !== undefined ? this._lookupProvide(p) : null;
2613
2633
  }
2614
2634
  lookupBind(name) {
2615
2635
  return lookup(this.binds, name);
@@ -3602,10 +3622,11 @@ class ClassBuilder {
3602
3622
  this._statics = {
3603
3623
  make: function(inArgs = {}, opts = {}) {
3604
3624
  const args = {};
3625
+ const scope = opts.scope ?? this.scope;
3605
3626
  for (const key in inArgs) {
3606
3627
  const field = fields[key];
3607
3628
  if (compFields.has(key))
3608
- args[key] = mkCompField(field, opts.scope, inArgs[key]);
3629
+ args[key] = mkCompField(field, scope, inArgs[key]);
3609
3630
  else if (field === undefined)
3610
3631
  console.warn("extra argument to constructor:", name, key, inArgs);
3611
3632
  else
@@ -3613,7 +3634,7 @@ class ClassBuilder {
3613
3634
  }
3614
3635
  for (const key of compFields)
3615
3636
  if (args[key] === undefined)
3616
- args[key] = mkCompField(fields[key], opts.scope, inArgs[key]);
3637
+ args[key] = mkCompField(fields[key], scope, inArgs[key]);
3617
3638
  return this(args);
3618
3639
  }
3619
3640
  };
@@ -3700,7 +3721,8 @@ function classFromData(name, { fields = {}, methods, statics }) {
3700
3721
  b.statics(statics);
3701
3722
  return b.build();
3702
3723
  }
3703
- var component = (opts) => new Component(classFromData(opts.name, opts), opts);
3724
+ Component.fromSpec = (opts) => new Component(classFromData(opts.name, opts), opts);
3725
+ var component = (opts) => Component.fromSpec(opts);
3704
3726
 
3705
3727
  // src/renderer.js
3706
3728
  import { isIndexed, isKeyed } from "immutable";
@@ -3822,7 +3844,7 @@ class Renderer {
3822
3844
  _rValComp(stack, val, comp, node, key, viewName) {
3823
3845
  const cacheKey = `${viewName ?? stack.viewsId ?? ""}-${key}`;
3824
3846
  const cachePath = [node, val];
3825
- stack._pushDynBindValuesToArray(cachePath, comp.dynamic);
3847
+ stack._pushDynBindValuesToArray(cachePath, comp);
3826
3848
  const cachedNode = this.cache.get(cachePath, cacheKey);
3827
3849
  if (cachedNode)
3828
3850
  return cachedNode;
@@ -4847,6 +4847,7 @@ var G_BOOL = K_FIELD | K_METHOD | K_BIND | K_DYN | K_CONST;
4847
4847
  var G_TEXT = G_BOOL | K_STRTPL;
4848
4848
  var G_COMPONENT = K_FIELD | K_SEQ | K_DYN;
4849
4849
  var G_SEQUENCE = K_FIELD | K_DYN;
4850
+ var G_PROVIDE = K_FIELD | K_SEQ;
4850
4851
  var G_FIELD = K_FIELD | K_METHOD | K_CONST | K_STR | K_SEQ;
4851
4852
  var G_VALUE = K_FIELD | K_METHOD | K_BIND | K_DYN | K_NAME | K_TYPE | K_REQUEST | K_CONST;
4852
4853
  var G_PRED_ARG = G_BOOL | K_STR;
@@ -4965,6 +4966,9 @@ class ValParser {
4965
4966
  parseField(s, px) {
4966
4967
  return this._parseSingle(s, px, G_FIELD);
4967
4968
  }
4969
+ parseProvide(s, px) {
4970
+ return this._parseSingle(s, px, G_PROVIDE);
4971
+ }
4968
4972
  parseHandlerArg(s, px) {
4969
4973
  return this._parseSingle(s, px, G_HANDLER_ARG);
4970
4974
  }
@@ -5951,21 +5955,22 @@ function h(tagName, properties, children, namespace) {
5951
5955
  }
5952
5956
 
5953
5957
  // src/anode.js
5954
- function resolveDynProducer(comp, dynName) {
5955
- const dyn = comp?.dynamic?.[dynName];
5956
- if (dyn == null)
5957
- return null;
5958
- let producerComp, producerDyn;
5959
- if (dyn.compName != null) {
5960
- producerComp = comp.scope?.lookupComponent(dyn.compName);
5961
- producerDyn = producerComp?.dynamic?.[dyn.dynName];
5958
+ function resolveDynProducer(comp, name) {
5959
+ let producerComp, producerProvide;
5960
+ const lk = comp?.lookup?.[name];
5961
+ if (lk != null) {
5962
+ producerComp = comp.scope?.lookupComponent(lk.compName);
5963
+ producerProvide = producerComp?.provide?.[lk.provideName];
5962
5964
  } else {
5965
+ const p = comp?.provide?.[name];
5966
+ if (p == null)
5967
+ return null;
5963
5968
  producerComp = comp;
5964
- producerDyn = dyn;
5969
+ producerProvide = p;
5965
5970
  }
5966
- if (producerComp == null || producerDyn == null)
5971
+ if (producerComp == null || producerProvide == null)
5967
5972
  return null;
5968
- const pi = producerDyn.val?.toPathItem?.() ?? null;
5973
+ const pi = producerProvide.val?.toPathItem?.() ?? null;
5969
5974
  return { producerCompId: producerComp.id, producerSteps: pi ? [pi] : [] };
5970
5975
  }
5971
5976
 
@@ -6708,9 +6713,6 @@ class Components {
6708
6713
  getCompFor(v) {
6709
6714
  return v?.[this.getComponentSymbol]?.() ?? null;
6710
6715
  }
6711
- getOnEnterFor(v) {
6712
- return this.getCompFor(v)?.on.stackEnter ?? defaultOnStackEnter;
6713
- }
6714
6716
  getHandlerFor(v, name, key) {
6715
6717
  return this.getCompFor(v)?.[key][name] ?? null;
6716
6718
  }
@@ -6742,6 +6744,7 @@ class ComponentStack {
6742
6744
  for (let i = 0;i < comps.length; i++) {
6743
6745
  const comp = comps[i];
6744
6746
  comp.scope = this.enter();
6747
+ comp.Class.scope = comp.scope;
6745
6748
  this.comps.registerComponent(comp);
6746
6749
  this.byName[comp.name] = comp;
6747
6750
  }
@@ -6779,36 +6782,30 @@ class ComponentStack {
6779
6782
  }
6780
6783
  }
6781
6784
 
6782
- class Dynamic {
6785
+ class ProvideInfo {
6783
6786
  constructor(name, val, symbol) {
6784
6787
  this.name = name;
6785
6788
  this.val = val;
6786
6789
  this.symbol = symbol;
6787
6790
  }
6788
- getSymbol(_stack) {
6789
- return this.symbol;
6790
- }
6791
- evalAndBind(stack, binds) {
6792
- binds[this.getSymbol(stack)] = this.val.eval(stack);
6793
- }
6794
6791
  }
6795
6792
 
6796
- class DynamicAlias extends Dynamic {
6797
- constructor(name, val, compName, dynName) {
6798
- super(name, val, null);
6793
+ class LookupInfo {
6794
+ constructor(name, compName, provideName, val) {
6795
+ this.name = name;
6799
6796
  this.compName = compName;
6800
- this.dynName = dynName;
6801
- }
6802
- _resolveSymbol(stack) {
6803
- return stack.lookupType(this.compName)?.dynamic[this.dynName]?.symbol ?? null;
6797
+ this.provideName = provideName;
6798
+ this.val = val;
6799
+ this._sym = undefined;
6804
6800
  }
6805
- getSymbol(stack) {
6806
- this.symbol ??= this._resolveSymbol(stack);
6807
- return this.symbol;
6801
+ getProducerSymbol(stack) {
6802
+ if (this._sym === undefined)
6803
+ this._sym = stack.lookupType(this.compName)?.provide?.[this.provideName]?.symbol ?? null;
6804
+ return this._sym;
6808
6805
  }
6809
6806
  }
6810
6807
  var isString = (v) => typeof v === "string";
6811
- var _rawSpecKeys = "name view style commonStyle globalStyle input receive bubble response alter on views dynamic fields methods statics";
6808
+ var _rawSpecKeys = "name view style commonStyle globalStyle input receive bubble response alter views provide lookup fields methods statics";
6812
6809
  var KNOWN_SPEC_KEYS = new Set(_rawSpecKeys.split(" "));
6813
6810
  var _compId = 0;
6814
6811
 
@@ -6825,35 +6822,47 @@ class Component {
6825
6822
  this.bubble = o.bubble ?? {};
6826
6823
  this.response = o.response ?? {};
6827
6824
  this.alter = o.alter ?? {};
6828
- this.on = { stackEnter: o.on?.stackEnter ?? defaultOnStackEnter };
6829
6825
  for (const name in o.views ?? {}) {
6830
6826
  const v = o.views[name];
6831
6827
  const { view, style } = isString(v) ? { view: v } : v;
6832
6828
  this.views[name] = new View(name, view, style);
6833
6829
  }
6834
- this._rawDynamic = o.dynamic ?? {};
6835
- this.dynamic = {};
6830
+ this._rawProvide = o.provide ?? {};
6831
+ this._rawLookup = o.lookup ?? {};
6832
+ this.provide = {};
6833
+ this.lookup = {};
6836
6834
  this.scope = null;
6835
+ this.spec = o;
6837
6836
  this.extra = {};
6838
6837
  for (const key of Object.keys(o))
6839
6838
  if (!KNOWN_SPEC_KEYS.has(key))
6840
6839
  this.extra[key] = o[key];
6841
6840
  }
6841
+ clone() {
6842
+ return Component.fromSpec(this.spec);
6843
+ }
6842
6844
  compile(ParseContext2) {
6843
6845
  for (const name in this.views)
6844
6846
  this.views[name].compile(new ParseContext2, this.scope, this.id);
6845
- for (const key in this._rawDynamic) {
6846
- const dinfo = this._rawDynamic[key];
6847
- if (isString(dinfo)) {
6848
- const val = vp.parseField(dinfo, this.views.main.ctx);
6849
- this.dynamic[key] = new Dynamic(key, val, Symbol(key));
6850
- } else if (isString(dinfo?.default) && isString(dinfo?.for)) {
6851
- const val = vp.parseField(dinfo.default, this.views.main.ctx);
6852
- const [compName, dynName] = dinfo.for.split(".");
6853
- if (isString(compName) && isString(dynName))
6854
- this.dynamic[key] = new DynamicAlias(key, val, compName, dynName);
6855
- }
6847
+ const ctx = this.views.main.ctx;
6848
+ for (const key in this._rawProvide) {
6849
+ const val = vp.parseProvide(this._rawProvide[key], ctx);
6850
+ if (val)
6851
+ this.provide[key] = new ProvideInfo(key, val, Symbol(key));
6852
+ }
6853
+ for (const key in this._rawLookup) {
6854
+ const linfo = this._rawLookup[key];
6855
+ const forStr = isString(linfo) ? linfo : isString(linfo?.for) ? linfo.for : null;
6856
+ const [compName, provideName] = forStr === null ? [] : forStr.split(".");
6857
+ if (!isString(compName) || !isString(provideName))
6858
+ continue;
6859
+ const defStr = isString(linfo?.default) ? linfo.default : null;
6860
+ const val = defStr === null ? null : vp.parseField(defStr, ctx);
6861
+ this.lookup[key] = new LookupInfo(key, compName, provideName, val);
6856
6862
  }
6863
+ for (const key in this.lookup)
6864
+ if (this.provide[key] !== undefined)
6865
+ console.warn("name declared in both provide and lookup", this.name, key);
6857
6866
  }
6858
6867
  make(args, opts) {
6859
6868
  return this.Class.make(args, opts ?? { scope: this.scope });
@@ -6881,9 +6890,6 @@ class Component {
6881
6890
  `);
6882
6891
  }
6883
6892
  }
6884
- function defaultOnStackEnter() {
6885
- return null;
6886
- }
6887
6893
 
6888
6894
  // src/stack.js
6889
6895
  var STOP = Symbol("STOP");
@@ -6942,47 +6948,61 @@ class Stack2 {
6942
6948
  this.viewsId = viewsId;
6943
6949
  this.ctx = ctx;
6944
6950
  }
6945
- _enrichOnEnter() {
6946
- return this.withDynamicBinds(this.comps.getOnEnterFor(this.it).call(this.it));
6951
+ _pushProvides() {
6952
+ const provide = this.comps.getCompFor(this.it)?.provide;
6953
+ if (provide == null)
6954
+ return this;
6955
+ const dynObj = {};
6956
+ let has2 = false;
6957
+ for (const k in provide) {
6958
+ dynObj[provide[k].symbol] = provide[k].val.eval(this);
6959
+ has2 = true;
6960
+ }
6961
+ if (!has2)
6962
+ return this;
6963
+ const newDynBinds = [new ObjectFrame(dynObj), this.dynBinds];
6964
+ const { comps, it, binds, views, viewsId, ctx } = this;
6965
+ return new Stack2(comps, it, binds, newDynBinds, views, viewsId, ctx);
6947
6966
  }
6948
6967
  static root(comps, it, ctx) {
6949
6968
  const binds = [new BindFrame(it, { it }, true), null];
6950
6969
  const dynBinds = [new ObjectFrame({}), null];
6951
6970
  const views = ["main", null];
6952
- return new Stack2(comps, it, binds, dynBinds, views, "", ctx)._enrichOnEnter();
6971
+ return new Stack2(comps, it, binds, dynBinds, views, "", ctx)._pushProvides();
6953
6972
  }
6954
6973
  enter(it, bindings = {}, isFrame = true) {
6955
6974
  const { comps, binds, dynBinds, views, viewsId, ctx } = this;
6956
6975
  const newBinds = [new BindFrame(it, bindings, isFrame), binds];
6957
6976
  const stack = new Stack2(comps, it, newBinds, dynBinds, views, viewsId, ctx);
6958
- return isFrame ? stack._enrichOnEnter() : stack;
6977
+ return isFrame ? stack._pushProvides() : stack;
6959
6978
  }
6960
6979
  pushViewName(name) {
6961
6980
  const { comps, it, binds, dynBinds, views, ctx } = this;
6962
6981
  const newViews = [name, views];
6963
6982
  return new Stack2(comps, it, binds, dynBinds, newViews, computeViewsId(newViews), ctx);
6964
6983
  }
6965
- withDynamicBinds(dynamics) {
6966
- if (dynamics == null || dynamics.length === 0)
6967
- return this;
6968
- const dynObj = {};
6969
- const comp = this.comps.getCompFor(this.it);
6970
- for (const dynName of dynamics)
6971
- comp.dynamic[dynName].evalAndBind(this, dynObj);
6972
- const newDynBinds = [new ObjectFrame(dynObj), this.dynBinds];
6973
- const { comps, it, binds, views, viewsId, ctx } = this;
6974
- return new Stack2(comps, it, binds, newDynBinds, views, viewsId, ctx);
6984
+ _pushDynBindValuesToArray(arr, comp) {
6985
+ for (const k in comp.provide)
6986
+ arr.push(this._lookupProvide(comp.provide[k]));
6987
+ for (const k in comp.lookup)
6988
+ arr.push(this._lookupAlias(comp.lookup[k]));
6975
6989
  }
6976
- _pushDynBindValuesToArray(arr, dyns) {
6977
- for (const k in dyns)
6978
- arr.push(this._lookupDynamicWithDynVal(dyns[k]));
6990
+ _lookupProvide(p) {
6991
+ return lookup(this.dynBinds, p.symbol) ?? p.val.eval(this) ?? null;
6979
6992
  }
6980
- _lookupDynamicWithDynVal(d) {
6981
- return lookup(this.dynBinds, d.getSymbol(this)) ?? d.val?.eval(this) ?? null;
6993
+ _lookupAlias(lk) {
6994
+ const sym = lk.getProducerSymbol(this);
6995
+ return (sym != null ? lookup(this.dynBinds, sym) : null) ?? lk.val?.eval(this) ?? null;
6982
6996
  }
6983
6997
  lookupDynamic(name) {
6984
- const d = this.comps.getCompFor(this.it)?.dynamic[name];
6985
- return d ? this._lookupDynamicWithDynVal(d) : null;
6998
+ const comp = this.comps.getCompFor(this.it);
6999
+ if (comp == null)
7000
+ return null;
7001
+ const lk = comp.lookup[name];
7002
+ if (lk !== undefined)
7003
+ return this._lookupAlias(lk);
7004
+ const p = comp.provide[name];
7005
+ return p !== undefined ? this._lookupProvide(p) : null;
6986
7006
  }
6987
7007
  lookupBind(name) {
6988
7008
  return lookup(this.binds, name);
@@ -7971,10 +7991,11 @@ class ClassBuilder {
7971
7991
  this._statics = {
7972
7992
  make: function(inArgs = {}, opts = {}) {
7973
7993
  const args = {};
7994
+ const scope = opts.scope ?? this.scope;
7974
7995
  for (const key in inArgs) {
7975
7996
  const field = fields[key];
7976
7997
  if (compFields.has(key))
7977
- args[key] = mkCompField(field, opts.scope, inArgs[key]);
7998
+ args[key] = mkCompField(field, scope, inArgs[key]);
7978
7999
  else if (field === undefined)
7979
8000
  console.warn("extra argument to constructor:", name, key, inArgs);
7980
8001
  else
@@ -7982,7 +8003,7 @@ class ClassBuilder {
7982
8003
  }
7983
8004
  for (const key of compFields)
7984
8005
  if (args[key] === undefined)
7985
- args[key] = mkCompField(fields[key], opts.scope, inArgs[key]);
8006
+ args[key] = mkCompField(fields[key], scope, inArgs[key]);
7986
8007
  return this(args);
7987
8008
  }
7988
8009
  };
@@ -8069,7 +8090,8 @@ function classFromData(name, { fields = {}, methods, statics }) {
8069
8090
  b.statics(statics);
8070
8091
  return b.build();
8071
8092
  }
8072
- var component = (opts) => new Component(classFromData(opts.name, opts), opts);
8093
+ Component.fromSpec = (opts) => new Component(classFromData(opts.name, opts), opts);
8094
+ var component = (opts) => Component.fromSpec(opts);
8073
8095
 
8074
8096
  // src/cache.js
8075
8097
  class NullDomCache {
@@ -8188,7 +8210,7 @@ class Renderer {
8188
8210
  _rValComp(stack, val, comp, node, key, viewName) {
8189
8211
  const cacheKey = `${viewName ?? stack.viewsId ?? ""}-${key}`;
8190
8212
  const cachePath = [node, val];
8191
- stack._pushDynBindValuesToArray(cachePath, comp.dynamic);
8213
+ stack._pushDynBindValuesToArray(cachePath, comp);
8192
8214
  const cachedNode = this.cache.get(cachePath, cacheKey);
8193
8215
  if (cachedNode)
8194
8216
  return cachedNode;