tutuca 0.9.29 → 0.9.30

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 CHANGED
@@ -11,6 +11,9 @@ Zero-dependency batteries included SPA framework.
11
11
 
12
12
  ## Quick Start
13
13
 
14
+ For an interactive walk-through with editable examples, see the
15
+ [tutorial](https://marianoguerra.github.io/tutuca/tutorial.html).
16
+
14
17
  ### CDN (no install)
15
18
 
16
19
  ```html
@@ -2258,8 +2258,21 @@ function checkConsistentAttrs(lx, Comp, referencedAlters, referencedComputed) {
2258
2258
  for (const attr of view.ctx.attrs) {
2259
2259
  const { attrs, wrapperAttrs, textChild, isMacroCall } = attr;
2260
2260
  if (attrs?.constructor.name === "DynAttrs") {
2261
+ const seenNames = new Set;
2261
2262
  for (const attr2 of attrs.items) {
2262
- if (attr2?.constructor.name === "Attr") {
2263
+ const name = attr2?.name;
2264
+ if (name !== undefined && name !== "data-eid") {
2265
+ if (seenNames.has(name)) {
2266
+ lx.error(DUPLICATE_ATTR_DEFINITION, { name });
2267
+ } else {
2268
+ seenNames.add(name);
2269
+ }
2270
+ }
2271
+ if (attr2?.constructor.name === "IfAttr") {
2272
+ for (const subVal of [attr2.condVal, attr2.thenVal, attr2.elseVal]) {
2273
+ checkConsistentAttrVal(lx, subVal, fields, proto, computed, scope, alter, referencedAlters, referencedComputed, isMacroCall);
2274
+ }
2275
+ } else if (attr2?.val !== undefined) {
2263
2276
  checkConsistentAttrVal(lx, attr2.val, fields, proto, computed, scope, alter, referencedAlters, referencedComputed, isMacroCall);
2264
2277
  }
2265
2278
  }
@@ -2346,7 +2359,7 @@ class LintContext {
2346
2359
  this.reports.push({ id, info, level, context: { ...this.frame } });
2347
2360
  }
2348
2361
  }
2349
- var ALT_HANDLER_NOT_DEFINED = "ALT_HANDLER_NOT_DEFINED", ALT_HANDLER_NOT_REFERENCED = "ALT_HANDLER_NOT_REFERENCED", RENDER_IT_OUTSIDE_OF_LOOP = "RENDER_IT_OUTSIDE_OF_LOOP", UNKNOWN_EVENT_MODIFIER = "UNKNOWN_EVENT_MODIFIER", UNKNOWN_HANDLER_ARG_NAME = "UNKNOWN_HANDLER_ARG_NAME", INPUT_HANDLER_NOT_IMPLEMENTED = "INPUT_HANDLER_NOT_IMPLEMENTED", INPUT_HANDLER_NOT_REFERENCED = "INPUT_HANDLER_NOT_REFERENCED", INPUT_HANDLER_METHOD_NOT_IMPLEMENTED = "INPUT_HANDLER_METHOD_NOT_IMPLEMENTED", INPUT_HANDLER_FOR_INPUT_HANDLER_METHOD = "INPUT_HANDLER_FOR_INPUT_HANDLER_METHOD", INPUT_HANDLER_METHOD_FOR_INPUT_HANDLER = "INPUT_HANDLER_METHOD_FOR_INPUT_HANDLER", FIELD_VAL_NOT_DEFINED = "FIELD_VAL_NOT_DEFINED", COMPUTED_VAL_NOT_DEFINED = "COMPUTED_VAL_NOT_DEFINED", COMPUTED_NOT_REFERENCED = "COMPUTED_NOT_REFERENCED", UNKNOWN_REQUEST_NAME = "UNKNOWN_REQUEST_NAME", UNKNOWN_COMPONENT_NAME = "UNKNOWN_COMPONENT_NAME", UNKNOWN_MACRO_ARG = "UNKNOWN_MACRO_ARG", LEVEL_WARN = "warn", LEVEL_ERROR = "error", LEVEL_HINT = "hint", NO_WRAPPERS, KNOWN_HANDLER_NAMES, LintParseContext;
2362
+ var ALT_HANDLER_NOT_DEFINED = "ALT_HANDLER_NOT_DEFINED", ALT_HANDLER_NOT_REFERENCED = "ALT_HANDLER_NOT_REFERENCED", RENDER_IT_OUTSIDE_OF_LOOP = "RENDER_IT_OUTSIDE_OF_LOOP", UNKNOWN_EVENT_MODIFIER = "UNKNOWN_EVENT_MODIFIER", UNKNOWN_HANDLER_ARG_NAME = "UNKNOWN_HANDLER_ARG_NAME", INPUT_HANDLER_NOT_IMPLEMENTED = "INPUT_HANDLER_NOT_IMPLEMENTED", INPUT_HANDLER_NOT_REFERENCED = "INPUT_HANDLER_NOT_REFERENCED", INPUT_HANDLER_METHOD_NOT_IMPLEMENTED = "INPUT_HANDLER_METHOD_NOT_IMPLEMENTED", INPUT_HANDLER_FOR_INPUT_HANDLER_METHOD = "INPUT_HANDLER_FOR_INPUT_HANDLER_METHOD", INPUT_HANDLER_METHOD_FOR_INPUT_HANDLER = "INPUT_HANDLER_METHOD_FOR_INPUT_HANDLER", FIELD_VAL_NOT_DEFINED = "FIELD_VAL_NOT_DEFINED", COMPUTED_VAL_NOT_DEFINED = "COMPUTED_VAL_NOT_DEFINED", COMPUTED_NOT_REFERENCED = "COMPUTED_NOT_REFERENCED", DUPLICATE_ATTR_DEFINITION = "DUPLICATE_ATTR_DEFINITION", UNKNOWN_REQUEST_NAME = "UNKNOWN_REQUEST_NAME", UNKNOWN_COMPONENT_NAME = "UNKNOWN_COMPONENT_NAME", UNKNOWN_MACRO_ARG = "UNKNOWN_MACRO_ARG", LEVEL_WARN = "warn", LEVEL_ERROR = "error", LEVEL_HINT = "hint", NO_WRAPPERS, KNOWN_HANDLER_NAMES, LintParseContext;
2350
2363
  var init_lint_check = __esm(() => {
2351
2364
  init_anode();
2352
2365
  NO_WRAPPERS = {};
@@ -812,6 +812,7 @@ class Attr extends BaseAttr {
812
812
 
813
813
  class ConstAttr extends Attr {
814
814
  }
815
+
815
816
  class RawHtmlAttr extends Attr {
816
817
  constructor(val) {
817
818
  super("dangerouslySetInnerHTML", val ?? vp.nullConstVal);
@@ -1558,6 +1559,7 @@ var INPUT_HANDLER_METHOD_FOR_INPUT_HANDLER = "INPUT_HANDLER_METHOD_FOR_INPUT_HAN
1558
1559
  var FIELD_VAL_NOT_DEFINED = "FIELD_VAL_NOT_DEFINED";
1559
1560
  var COMPUTED_VAL_NOT_DEFINED = "COMPUTED_VAL_NOT_DEFINED";
1560
1561
  var COMPUTED_NOT_REFERENCED = "COMPUTED_NOT_REFERENCED";
1562
+ var DUPLICATE_ATTR_DEFINITION = "DUPLICATE_ATTR_DEFINITION";
1561
1563
  var UNKNOWN_REQUEST_NAME = "UNKNOWN_REQUEST_NAME";
1562
1564
  var UNKNOWN_COMPONENT_NAME = "UNKNOWN_COMPONENT_NAME";
1563
1565
  var UNKNOWN_MACRO_ARG = "UNKNOWN_MACRO_ARG";
@@ -1791,8 +1793,21 @@ function checkConsistentAttrs(lx, Comp, referencedAlters, referencedComputed) {
1791
1793
  for (const attr of view.ctx.attrs) {
1792
1794
  const { attrs, wrapperAttrs, textChild, isMacroCall } = attr;
1793
1795
  if (attrs?.constructor.name === "DynAttrs") {
1796
+ const seenNames = new Set;
1794
1797
  for (const attr2 of attrs.items) {
1795
- if (attr2?.constructor.name === "Attr") {
1798
+ const name = attr2?.name;
1799
+ if (name !== undefined && name !== "data-eid") {
1800
+ if (seenNames.has(name)) {
1801
+ lx.error(DUPLICATE_ATTR_DEFINITION, { name });
1802
+ } else {
1803
+ seenNames.add(name);
1804
+ }
1805
+ }
1806
+ if (attr2?.constructor.name === "IfAttr") {
1807
+ for (const subVal of [attr2.condVal, attr2.thenVal, attr2.elseVal]) {
1808
+ checkConsistentAttrVal(lx, subVal, fields, proto, computed, scope, alter, referencedAlters, referencedComputed, isMacroCall);
1809
+ }
1810
+ } else if (attr2?.val !== undefined) {
1796
1811
  checkConsistentAttrVal(lx, attr2.val, fields, proto, computed, scope, alter, referencedAlters, referencedComputed, isMacroCall);
1797
1812
  }
1798
1813
  }
@@ -1915,6 +1930,8 @@ function lintIdToMessage(id, info) {
1915
1930
  return `Computed property '$${info.name}' is not defined`;
1916
1931
  case "COMPUTED_NOT_REFERENCED":
1917
1932
  return `Computed property '$${info.name}' is defined but not referenced`;
1933
+ case "DUPLICATE_ATTR_DEFINITION":
1934
+ return `Attribute '${info.name}' is defined more than once`;
1918
1935
  case "UNKNOWN_REQUEST_NAME":
1919
1936
  return `Unknown request '!${info.name}'`;
1920
1937
  case "UNKNOWN_COMPONENT_NAME":
@@ -7738,12 +7755,6 @@ class Field {
7738
7755
  proto[`reset${uname}`] = function() {
7739
7756
  return this.set(name, that.defaultValue);
7740
7757
  };
7741
- proto[`is${uname}NotSet`] = function() {
7742
- return this.get(name) == null;
7743
- };
7744
- proto[`is${uname}Set`] = function() {
7745
- return this.get(name) != null;
7746
- };
7747
7758
  this.extendProtoForType(proto, uname);
7748
7759
  }
7749
7760
  }
@@ -7796,6 +7807,7 @@ class FieldBool extends Field {
7796
7807
  proto[`set${uname}`] = function(v) {
7797
7808
  return this.set(name, !!v);
7798
7809
  };
7810
+ extendProtoTruthy(proto, name, uname);
7799
7811
  }
7800
7812
  }
7801
7813
 
@@ -7808,6 +7820,10 @@ class FieldAny extends Field {
7808
7820
  const type = getTypeName(dv) ?? "any";
7809
7821
  return { type, defaultValue: dv?.toJS ? dv.toJS() : dv };
7810
7822
  }
7823
+ extendProtoForType(proto, uname) {
7824
+ extendProtoNullable(proto, this.name, uname);
7825
+ extendProtoTruthy(proto, this.name, uname);
7826
+ }
7811
7827
  }
7812
7828
  var stringCoercer = (v) => v?.toString?.() ?? "";
7813
7829
 
@@ -7825,6 +7841,9 @@ class FieldInt extends Field {
7825
7841
  constructor(name, defaultValue = 0) {
7826
7842
  super("int", name, CHECK_TYPE_INT, intCoercer, defaultValue);
7827
7843
  }
7844
+ extendProtoForType(proto, uname) {
7845
+ extendProtoTruthy(proto, this.name, uname);
7846
+ }
7828
7847
  }
7829
7848
  var floatCoercer = (_) => null;
7830
7849
 
@@ -7832,6 +7851,9 @@ class FieldFloat extends Field {
7832
7851
  constructor(name, defaultValue = 0) {
7833
7852
  super("float", name, CHECK_TYPE_FLOAT, floatCoercer, defaultValue);
7834
7853
  }
7854
+ extendProtoForType(proto, uname) {
7855
+ extendProtoTruthy(proto, this.name, uname);
7856
+ }
7835
7857
  }
7836
7858
  var getTypeName = (v) => v?.constructor?.getMetaClass?.()?.name;
7837
7859
 
@@ -7856,6 +7878,10 @@ class FieldComp extends Field {
7856
7878
  toDataDef() {
7857
7879
  return { component: this.typeName, args: this.args };
7858
7880
  }
7881
+ extendProtoForType(proto, uname) {
7882
+ extendProtoNullable(proto, this.name, uname);
7883
+ extendProtoTruthy(proto, this.name, uname);
7884
+ }
7859
7885
  }
7860
7886
  var NONE2 = Symbol("NONE");
7861
7887
  function extendProtoForKeyed(proto, name, uname) {
@@ -7927,6 +7953,25 @@ function extendProtoSized(proto, name, uname, defaultEmpty, propName = "size") {
7927
7953
  proto[`${name}Len`] = function() {
7928
7954
  return this.get(name, defaultEmpty)[propName];
7929
7955
  };
7956
+ proto[`is${uname}Truthy`] = function() {
7957
+ return this.get(name, defaultEmpty)[propName] > 0;
7958
+ };
7959
+ proto[`is${uname}Falsy`] = function() {
7960
+ return this.get(name, defaultEmpty)[propName] === 0;
7961
+ };
7962
+ }
7963
+ function extendProtoNullable(proto, name, uname) {
7964
+ proto[`is${uname}Null`] = function() {
7965
+ return this.get(name) == null;
7966
+ };
7967
+ }
7968
+ function extendProtoTruthy(proto, name, uname) {
7969
+ proto[`is${uname}Truthy`] = function() {
7970
+ return !!this.get(name);
7971
+ };
7972
+ proto[`is${uname}Falsy`] = function() {
7973
+ return !this.get(name);
7974
+ };
7930
7975
  }
7931
7976
  var EMPTY_SET2 = Set2();
7932
7977
  var isetCoercer = (v) => Array.isArray(v) ? Set2(v) : v instanceof Set ? Set2(v) : null;
@@ -8658,6 +8703,7 @@ export {
8658
8703
  INPUT_HANDLER_FOR_INPUT_HANDLER_METHOD,
8659
8704
  Map2 as IMap,
8660
8705
  FIELD_VAL_NOT_DEFINED,
8706
+ DUPLICATE_ATTR_DEFINITION,
8661
8707
  Collection,
8662
8708
  COMPUTED_VAL_NOT_DEFINED,
8663
8709
  COMPUTED_NOT_REFERENCED,