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
- }
2483
- }
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);
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);
@@ -3379,7 +3399,7 @@ class Renderer {
3379
3399
  _rValComp(stack, val, comp, node, key, viewName) {
3380
3400
  const cacheKey = `${viewName ?? stack.viewsId ?? ""}-${key}`;
3381
3401
  const cachePath = [node, val];
3382
- stack._pushDynBindValuesToArray(cachePath, comp.dynamic);
3402
+ stack._pushDynBindValuesToArray(cachePath, comp);
3383
3403
  const cachedNode = this.cache.get(cachePath, cacheKey);
3384
3404
  if (cachedNode)
3385
3405
  return cachedNode;
@@ -3820,10 +3840,11 @@ class ClassBuilder {
3820
3840
  this._statics = {
3821
3841
  make: function(inArgs = {}, opts = {}) {
3822
3842
  const args = {};
3843
+ const scope = opts.scope ?? this.scope;
3823
3844
  for (const key in inArgs) {
3824
3845
  const field = fields[key];
3825
3846
  if (compFields.has(key))
3826
- args[key] = mkCompField(field, opts.scope, inArgs[key]);
3847
+ args[key] = mkCompField(field, scope, inArgs[key]);
3827
3848
  else if (field === undefined)
3828
3849
  console.warn("extra argument to constructor:", name, key, inArgs);
3829
3850
  else
@@ -3831,7 +3852,7 @@ class ClassBuilder {
3831
3852
  }
3832
3853
  for (const key of compFields)
3833
3854
  if (args[key] === undefined)
3834
- args[key] = mkCompField(fields[key], opts.scope, inArgs[key]);
3855
+ args[key] = mkCompField(fields[key], scope, inArgs[key]);
3835
3856
  return this(args);
3836
3857
  }
3837
3858
  };
@@ -3918,7 +3939,8 @@ function classFromData(name, { fields = {}, methods, statics }) {
3918
3939
  b.statics(statics);
3919
3940
  return b.build();
3920
3941
  }
3921
- var component = (opts) => new Component(classFromData(opts.name, opts), opts);
3942
+ Component.fromSpec = (opts) => new Component(classFromData(opts.name, opts), opts);
3943
+ var component = (opts) => Component.fromSpec(opts);
3922
3944
 
3923
3945
  // index.js
3924
3946
  var css = String.raw;
package/dist/tutuca.js CHANGED
@@ -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);
@@ -7749,7 +7769,7 @@ class Renderer {
7749
7769
  _rValComp(stack, val, comp, node, key, viewName) {
7750
7770
  const cacheKey = `${viewName ?? stack.viewsId ?? ""}-${key}`;
7751
7771
  const cachePath = [node, val];
7752
- stack._pushDynBindValuesToArray(cachePath, comp.dynamic);
7772
+ stack._pushDynBindValuesToArray(cachePath, comp);
7753
7773
  const cachedNode = this.cache.get(cachePath, cacheKey);
7754
7774
  if (cachedNode)
7755
7775
  return cachedNode;
@@ -8133,10 +8153,11 @@ class ClassBuilder {
8133
8153
  this._statics = {
8134
8154
  make: function(inArgs = {}, opts = {}) {
8135
8155
  const args = {};
8156
+ const scope = opts.scope ?? this.scope;
8136
8157
  for (const key in inArgs) {
8137
8158
  const field = fields[key];
8138
8159
  if (compFields.has(key))
8139
- args[key] = mkCompField(field, opts.scope, inArgs[key]);
8160
+ args[key] = mkCompField(field, scope, inArgs[key]);
8140
8161
  else if (field === undefined)
8141
8162
  console.warn("extra argument to constructor:", name, key, inArgs);
8142
8163
  else
@@ -8144,7 +8165,7 @@ class ClassBuilder {
8144
8165
  }
8145
8166
  for (const key of compFields)
8146
8167
  if (args[key] === undefined)
8147
- args[key] = mkCompField(fields[key], opts.scope, inArgs[key]);
8168
+ args[key] = mkCompField(fields[key], scope, inArgs[key]);
8148
8169
  return this(args);
8149
8170
  }
8150
8171
  };
@@ -8231,7 +8252,8 @@ function classFromData(name, { fields = {}, methods, statics }) {
8231
8252
  b.statics(statics);
8232
8253
  return b.build();
8233
8254
  }
8234
- var component = (opts) => new Component(classFromData(opts.name, opts), opts);
8255
+ Component.fromSpec = (opts) => new Component(classFromData(opts.name, opts), opts);
8256
+ var component = (opts) => Component.fromSpec(opts);
8235
8257
 
8236
8258
  // index.js
8237
8259
  var css = String.raw;