regor 1.4.4 → 1.4.6

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.
@@ -48,6 +48,7 @@ __export(index_exports, {
48
48
  onUnmounted: () => onUnmounted,
49
49
  pause: () => pause,
50
50
  persist: () => persist,
51
+ pval: () => pval,
51
52
  raw: () => raw,
52
53
  ref: () => ref,
53
54
  removeNode: () => removeNode,
@@ -377,6 +378,37 @@ var ComponentHead = class {
377
378
  `${constructor} was not found in the context stack at occurrence ${occurrence}.`
378
379
  );
379
380
  }
381
+ /**
382
+ * Validates selected incoming props using assertion-style validators.
383
+ *
384
+ * Only keys listed in `schema` are checked. Validation throws immediately
385
+ * on the first invalid prop and does not mutate `head.props`.
386
+ *
387
+ * The schema is keyed from `head.props`, so editor completion can suggest
388
+ * known prop names while still allowing you to validate only a subset.
389
+ *
390
+ * Validators typically come from `pval`, but custom user validators are also
391
+ * supported.
392
+ *
393
+ * Example:
394
+ * ```ts
395
+ * head.validateProps({
396
+ * title: pval.isString,
397
+ * count: pval.optional(pval.isNumber),
398
+ * })
399
+ * ```
400
+ *
401
+ * @param schema - Validators to apply to selected incoming props.
402
+ */
403
+ validateProps(schema) {
404
+ const props = this.props;
405
+ for (const name in schema) {
406
+ const validator = schema[name];
407
+ if (!validator) continue;
408
+ const validateProp = validator;
409
+ validateProp(props[name], name, this);
410
+ }
411
+ }
380
412
  /**
381
413
  * Unmounts this component instance by removing nodes between `start` and `end`
382
414
  * and calling unmount lifecycle handlers for captured contexts.
@@ -525,10 +557,13 @@ var IfBinder = class {
525
557
  }
526
558
  __bindAll(element) {
527
559
  const isIfElement = element.hasAttribute(this.__if);
528
- const elements = findElements(element, this.__ifSelector);
529
- for (const el of elements) {
530
- this.__bind(el);
531
- }
560
+ if (isIfElement) this.__bind(element);
561
+ this.__binder.__componentBinder.__forEachBindableDescendant(
562
+ element,
563
+ (el) => {
564
+ if (el.hasAttribute(this.__if)) this.__bind(el);
565
+ }
566
+ );
532
567
  return isIfElement;
533
568
  }
534
569
  __isProcessedOrMark(el) {
@@ -1314,6 +1349,15 @@ var ComponentBinder = class {
1314
1349
  }
1315
1350
  return false;
1316
1351
  }
1352
+ __isNamedSlotTemplateShortcut(node) {
1353
+ if (!isTemplate(node)) return false;
1354
+ const attributeNames = node.getAttributeNames();
1355
+ if (node.hasAttribute("name")) return true;
1356
+ return attributeNames.some((x) => x.startsWith("#"));
1357
+ }
1358
+ __isDefaultSlotTemplateShortcut(node) {
1359
+ return isTemplate(node) && node.getAttributeNames().length === 0;
1360
+ }
1317
1361
  __unwrapComponents(element) {
1318
1362
  const binder = this.__binder;
1319
1363
  const parser = binder.__parser;
@@ -1323,16 +1367,9 @@ var ComponentBinder = class {
1323
1367
  return;
1324
1368
  }
1325
1369
  const contextComponents = parser.__getComponents();
1326
- const contextComponentSelectors = parser.__getComponentSelectors();
1327
- const registeredSelector = this.__getRegisteredComponentSelector(registeredComponents);
1328
- const selector = [
1329
- ...registeredSelector ? [registeredSelector] : [],
1330
- ...contextComponentSelectors,
1331
- ...contextComponentSelectors.map(hyphenate)
1332
- ].join(",");
1370
+ const selector = this.__getComponentSelector();
1333
1371
  if (isNullOrWhitespace(selector)) return;
1334
- const list = element.querySelectorAll(selector);
1335
- const components = element.matches?.(selector) ? [element, ...list] : list;
1372
+ const components = this.__collectTopLevelComponentHosts(element, selector);
1336
1373
  for (const component of components) {
1337
1374
  if (component.hasAttribute(binder.__pre)) continue;
1338
1375
  const parent = component.parentNode;
@@ -1477,9 +1514,12 @@ var ComponentBinder = class {
1477
1514
  `template[name='${name}'], template[\\#${name}]`
1478
1515
  );
1479
1516
  if (!compTemplate && name === "default") {
1480
- compTemplate = component.querySelector("template:not([name])");
1481
- if (compTemplate && compTemplate.getAttributeNames().filter((x) => x.startsWith("#")).length > 0)
1482
- compTemplate = null;
1517
+ const unnamedTemplates = component.querySelectorAll(
1518
+ "template:not([name])"
1519
+ );
1520
+ compTemplate = [...unnamedTemplates].find(
1521
+ (x) => this.__isDefaultSlotTemplateShortcut(x)
1522
+ ) ?? null;
1483
1523
  }
1484
1524
  const createSwitchContext = (childNodes2) => {
1485
1525
  if (!head.enableSwitch) return;
@@ -1515,7 +1555,7 @@ var ComponentBinder = class {
1515
1555
  return;
1516
1556
  }
1517
1557
  const childNodes2 = [...getChildNodes(component)].filter(
1518
- (x) => !isTemplate(x)
1558
+ (x) => !this.__isNamedSlotTemplateShortcut(x)
1519
1559
  );
1520
1560
  for (const slotChild of childNodes2) {
1521
1561
  parent2.insertBefore(slotChild, slot);
@@ -1601,6 +1641,64 @@ var ComponentBinder = class {
1601
1641
  parser.__scoped(capturedContext, bindComponent);
1602
1642
  }
1603
1643
  }
1644
+ __getComponentSelector() {
1645
+ const binder = this.__binder;
1646
+ const parser = binder.__parser;
1647
+ const registeredComponents = binder.__config.__components;
1648
+ const contextComponentSelectors = parser.__getComponentSelectors();
1649
+ const registeredSelector = this.__getRegisteredComponentSelector(registeredComponents);
1650
+ return [
1651
+ ...registeredSelector ? [registeredSelector] : [],
1652
+ ...contextComponentSelectors,
1653
+ ...contextComponentSelectors.map(hyphenate)
1654
+ ].join(",");
1655
+ }
1656
+ __collectTopLevelComponentHosts(root, selector) {
1657
+ const result = [];
1658
+ if (isNullOrWhitespace(selector)) return result;
1659
+ if (root.matches?.(selector)) return [root];
1660
+ const stack = this.__getChildElements(root).reverse();
1661
+ while (stack.length > 0) {
1662
+ const current = stack.pop();
1663
+ if (current.matches(selector)) {
1664
+ result.push(current);
1665
+ continue;
1666
+ }
1667
+ stack.push(...this.__getChildElements(current).reverse());
1668
+ }
1669
+ return result;
1670
+ }
1671
+ __forEachBindableDescendant(root, action) {
1672
+ const selector = this.__getComponentSelector();
1673
+ const stack = this.__getChildElements(root).reverse();
1674
+ while (stack.length > 0) {
1675
+ const current = stack.pop();
1676
+ action(current);
1677
+ if (!isNullOrWhitespace(selector) && current.matches(selector)) continue;
1678
+ stack.push(...this.__getChildElements(current).reverse());
1679
+ }
1680
+ }
1681
+ __getChildElements(root) {
1682
+ const children = root?.children;
1683
+ if (children?.length != null) {
1684
+ const result = [];
1685
+ for (let i = 0; i < children.length; ++i) {
1686
+ const child = children[i];
1687
+ if (isElement(child)) result.push(child);
1688
+ }
1689
+ return result;
1690
+ }
1691
+ const childNodes = root?.childNodes;
1692
+ if (childNodes?.length != null) {
1693
+ const result = [];
1694
+ for (let i = 0; i < childNodes.length; ++i) {
1695
+ const child = childNodes[i];
1696
+ if (isElement(child)) result.push(child);
1697
+ }
1698
+ return result;
1699
+ }
1700
+ return [];
1701
+ }
1604
1702
  };
1605
1703
 
1606
1704
  // src/bind/DirectiveCollector.ts
@@ -1690,10 +1788,10 @@ var DirectiveCollector = class {
1690
1788
  };
1691
1789
  processNode(element);
1692
1790
  if (!isRecursive || !element.firstElementChild) return map;
1693
- const nodes = element.querySelectorAll("*");
1694
- for (const node of nodes) {
1695
- processNode(node);
1696
- }
1791
+ this.__binder.__componentBinder.__forEachBindableDescendant(
1792
+ element,
1793
+ processNode
1794
+ );
1697
1795
  return map;
1698
1796
  }
1699
1797
  };
@@ -1710,18 +1808,20 @@ var mount2 = (nodes, parent) => {
1710
1808
  var DynamicBinder = class {
1711
1809
  __binder;
1712
1810
  __is;
1713
- __isSelector;
1714
1811
  constructor(binder) {
1715
1812
  this.__binder = binder;
1716
1813
  this.__is = binder.__config.__builtInNames.is;
1717
- this.__isSelector = toSelector(this.__is) + ", [is]";
1718
1814
  }
1719
1815
  __bindAll(element) {
1720
1816
  const isComponentElement = element.hasAttribute(this.__is);
1721
- const elements = findElements(element, this.__isSelector);
1722
- for (const el of elements) {
1723
- this.__bind(el);
1724
- }
1817
+ if (isComponentElement || element.hasAttribute("is"))
1818
+ this.__bind(element);
1819
+ this.__binder.__componentBinder.__forEachBindableDescendant(
1820
+ element,
1821
+ (el) => {
1822
+ if (el.hasAttribute(this.__is) || el.hasAttribute("is")) this.__bind(el);
1823
+ }
1824
+ );
1725
1825
  return isComponentElement;
1726
1826
  }
1727
1827
  __bind(el) {
@@ -2193,10 +2293,13 @@ var ForBinder = class _ForBinder {
2193
2293
  }
2194
2294
  __bindAll(element) {
2195
2295
  const isForElement = element.hasAttribute(this.__for);
2196
- const elements = findElements(element, this.__forSelector);
2197
- for (const el of elements) {
2198
- this.__bindFor(el);
2199
- }
2296
+ if (isForElement) this.__bindFor(element);
2297
+ this.__binder.__componentBinder.__forEachBindableDescendant(
2298
+ element,
2299
+ (el) => {
2300
+ if (el.hasAttribute(this.__for)) this.__bindFor(el);
2301
+ }
2302
+ );
2200
2303
  return isForElement;
2201
2304
  }
2202
2305
  __isProcessedOrMark(el) {
@@ -2862,11 +2965,11 @@ var patchAttribute = (el, key, value, previousKey) => {
2862
2965
  }
2863
2966
  return;
2864
2967
  }
2865
- const isBoolean = key in booleanAttributes;
2866
- if (isNullOrUndefined(value) || isBoolean && !includeBooleanAttr(value)) {
2968
+ const isBoolean2 = key in booleanAttributes;
2969
+ if (isNullOrUndefined(value) || isBoolean2 && !includeBooleanAttr(value)) {
2867
2970
  el.removeAttribute(key);
2868
2971
  } else {
2869
- el.setAttribute(key, isBoolean ? "" : value);
2972
+ el.setAttribute(key, isBoolean2 ? "" : value);
2870
2973
  }
2871
2974
  };
2872
2975
 
@@ -3116,7 +3219,7 @@ var decimalSeparators = /[.,' ·٫]/;
3116
3219
  var handleInputAndTextArea = (el, flags, getModelRef, parsedValue) => {
3117
3220
  const isLazy = flags.lazy;
3118
3221
  const eventType = isLazy ? "change" : "input";
3119
- const isNumber = isNumberInput(el);
3222
+ const isNumber2 = isNumberInput(el);
3120
3223
  const trimmer = () => {
3121
3224
  if (!flags.trim && !getFlags(parsedValue()[1]).trim) return;
3122
3225
  el.value = el.value.trim();
@@ -3146,7 +3249,7 @@ var handleInputAndTextArea = (el, flags, getModelRef, parsedValue) => {
3146
3249
  if (!target || target.composing) return;
3147
3250
  let value = target.value;
3148
3251
  const flags2 = getFlags(parsedValue()[1]);
3149
- if (isNumber || flags2.number || flags2.int) {
3252
+ if (isNumber2 || flags2.number || flags2.int) {
3150
3253
  if (flags2.int) {
3151
3254
  value = parseInt(value);
3152
3255
  } else {
@@ -4451,12 +4554,12 @@ var Jsep = class {
4451
4554
  this.__gobbleSpaces();
4452
4555
  let ch = this.__code;
4453
4556
  while (ch === PERIOD_CODE || ch === OBRACK_CODE || ch === OPAREN_CODE || ch === QUMARK_CODE) {
4454
- let optional;
4557
+ let optional2;
4455
4558
  if (ch === QUMARK_CODE) {
4456
4559
  if (this.__expr.charCodeAt(this.__index + 1) !== PERIOD_CODE) {
4457
4560
  break;
4458
4561
  }
4459
- optional = true;
4562
+ optional2 = true;
4460
4563
  this.__index += 2;
4461
4564
  this.__gobbleSpaces();
4462
4565
  ch = this.__code;
@@ -4482,7 +4585,7 @@ var Jsep = class {
4482
4585
  callee: node
4483
4586
  };
4484
4587
  } else {
4485
- if (optional) {
4588
+ if (optional2) {
4486
4589
  this.__index--;
4487
4590
  }
4488
4591
  this.__gobbleSpaces();
@@ -4493,7 +4596,7 @@ var Jsep = class {
4493
4596
  property: this.__gobbleIdentifier()
4494
4597
  };
4495
4598
  }
4496
- if (optional) {
4599
+ if (optional2) {
4497
4600
  node.optional = true;
4498
4601
  }
4499
4602
  this.__gobbleSpaces();
@@ -6011,6 +6114,112 @@ var defineComponent = (template, options = {}) => {
6011
6114
  };
6012
6115
  };
6013
6116
 
6117
+ // src/app/propValidators.ts
6118
+ var fail = (name, message) => {
6119
+ throw new Error(`Invalid prop "${name}": ${message}.`);
6120
+ };
6121
+ var describeValue = (value) => {
6122
+ if (value === null) return "null";
6123
+ if (value === void 0) return "undefined";
6124
+ if (typeof value === "string") return "string";
6125
+ if (typeof value === "number") return "number";
6126
+ if (typeof value === "boolean") return "boolean";
6127
+ if (typeof value === "bigint") return "bigint";
6128
+ if (typeof value === "symbol") return "symbol";
6129
+ if (typeof value === "function") return "function";
6130
+ if (isArray(value)) return "array";
6131
+ if (value instanceof Date) return "Date";
6132
+ if (value instanceof RegExp) return "RegExp";
6133
+ if (value instanceof Map) return "Map";
6134
+ if (value instanceof Set) return "Set";
6135
+ const ctorName = value?.constructor?.name;
6136
+ return ctorName && ctorName !== "Object" ? ctorName : "object";
6137
+ };
6138
+ var formatLiteral = (value) => {
6139
+ if (typeof value === "string") return `"${value}"`;
6140
+ if (typeof value === "number" || typeof value === "boolean") {
6141
+ return String(value);
6142
+ }
6143
+ if (value === null) return "null";
6144
+ if (value === void 0) return "undefined";
6145
+ return describeValue(value);
6146
+ };
6147
+ var isString2 = (value, name) => {
6148
+ if (typeof value !== "string") fail(name, "expected string");
6149
+ };
6150
+ var isNumber = (value, name) => {
6151
+ if (typeof value !== "number") fail(name, "expected number");
6152
+ };
6153
+ var isBoolean = (value, name) => {
6154
+ if (typeof value !== "boolean") fail(name, "expected boolean");
6155
+ };
6156
+ var isClass = (ctor) => {
6157
+ return (value, name) => {
6158
+ if (!(value instanceof ctor)) {
6159
+ fail(name, `expected instance of ${ctor.name || "provided class"}`);
6160
+ }
6161
+ };
6162
+ };
6163
+ var optional = (validator) => {
6164
+ return (value, name, head) => {
6165
+ if (value === void 0) return;
6166
+ validator(value, name, head);
6167
+ };
6168
+ };
6169
+ var nullable = (validator) => {
6170
+ return (value, name, head) => {
6171
+ if (value === null) return;
6172
+ validator(value, name, head);
6173
+ };
6174
+ };
6175
+ var oneOf = (values) => {
6176
+ return (value, name) => {
6177
+ if (values.includes(value)) return;
6178
+ fail(
6179
+ name,
6180
+ `expected one of ${values.map((x) => formatLiteral(x)).join(", ")}`
6181
+ );
6182
+ };
6183
+ };
6184
+ var arrayOf = (validator) => {
6185
+ return (value, name, head) => {
6186
+ if (!isArray(value)) fail(name, "expected array");
6187
+ const items = value;
6188
+ for (let i = 0; i < items.length; ++i) {
6189
+ validator(items[i], `${name}[${i}]`, head);
6190
+ }
6191
+ };
6192
+ };
6193
+ var shape = (schema) => {
6194
+ return (value, name, head) => {
6195
+ if (!isObject(value)) fail(name, "expected object");
6196
+ const record = value;
6197
+ for (const key in schema) {
6198
+ const validator = schema[key];
6199
+ validator(record[key], `${name}.${key}`, head);
6200
+ }
6201
+ };
6202
+ };
6203
+ var refOf = (validator) => {
6204
+ return (value, name, head) => {
6205
+ if (!isRef(value)) fail(name, "expected ref");
6206
+ const refValue = value;
6207
+ validator(refValue(), `${name}.value`, head);
6208
+ };
6209
+ };
6210
+ var pval = {
6211
+ isString: isString2,
6212
+ isNumber,
6213
+ isBoolean,
6214
+ isClass,
6215
+ optional,
6216
+ nullable,
6217
+ oneOf,
6218
+ arrayOf,
6219
+ shape,
6220
+ refOf
6221
+ };
6222
+
6014
6223
  // src/composition/ContextRegistry.ts
6015
6224
  var ContextRegistry = class {
6016
6225
  byConstructor = /* @__PURE__ */ new Map();