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.
@@ -315,6 +315,37 @@ var ComponentHead = class {
315
315
  `${constructor} was not found in the context stack at occurrence ${occurrence}.`
316
316
  );
317
317
  }
318
+ /**
319
+ * Validates selected incoming props using assertion-style validators.
320
+ *
321
+ * Only keys listed in `schema` are checked. Validation throws immediately
322
+ * on the first invalid prop and does not mutate `head.props`.
323
+ *
324
+ * The schema is keyed from `head.props`, so editor completion can suggest
325
+ * known prop names while still allowing you to validate only a subset.
326
+ *
327
+ * Validators typically come from `pval`, but custom user validators are also
328
+ * supported.
329
+ *
330
+ * Example:
331
+ * ```ts
332
+ * head.validateProps({
333
+ * title: pval.isString,
334
+ * count: pval.optional(pval.isNumber),
335
+ * })
336
+ * ```
337
+ *
338
+ * @param schema - Validators to apply to selected incoming props.
339
+ */
340
+ validateProps(schema) {
341
+ const props = this.props;
342
+ for (const name in schema) {
343
+ const validator = schema[name];
344
+ if (!validator) continue;
345
+ const validateProp = validator;
346
+ validateProp(props[name], name, this);
347
+ }
348
+ }
318
349
  /**
319
350
  * Unmounts this component instance by removing nodes between `start` and `end`
320
351
  * and calling unmount lifecycle handlers for captured contexts.
@@ -463,10 +494,13 @@ var IfBinder = class {
463
494
  }
464
495
  __bindAll(element) {
465
496
  const isIfElement = element.hasAttribute(this.__if);
466
- const elements = findElements(element, this.__ifSelector);
467
- for (const el of elements) {
468
- this.__bind(el);
469
- }
497
+ if (isIfElement) this.__bind(element);
498
+ this.__binder.__componentBinder.__forEachBindableDescendant(
499
+ element,
500
+ (el) => {
501
+ if (el.hasAttribute(this.__if)) this.__bind(el);
502
+ }
503
+ );
470
504
  return isIfElement;
471
505
  }
472
506
  __isProcessedOrMark(el) {
@@ -1258,8 +1292,16 @@ var ComponentBinder = class {
1258
1292
  }
1259
1293
  return false;
1260
1294
  }
1295
+ __isNamedSlotTemplateShortcut(node) {
1296
+ if (!isTemplate(node)) return false;
1297
+ const attributeNames = node.getAttributeNames();
1298
+ if (node.hasAttribute("name")) return true;
1299
+ return attributeNames.some((x) => x.startsWith("#"));
1300
+ }
1301
+ __isDefaultSlotTemplateShortcut(node) {
1302
+ return isTemplate(node) && node.getAttributeNames().length === 0;
1303
+ }
1261
1304
  __unwrapComponents(element) {
1262
- var _a;
1263
1305
  const binder = this.__binder;
1264
1306
  const parser = binder.__parser;
1265
1307
  const registeredComponents = binder.__config.__components;
@@ -1268,16 +1310,9 @@ var ComponentBinder = class {
1268
1310
  return;
1269
1311
  }
1270
1312
  const contextComponents = parser.__getComponents();
1271
- const contextComponentSelectors = parser.__getComponentSelectors();
1272
- const registeredSelector = this.__getRegisteredComponentSelector(registeredComponents);
1273
- const selector = [
1274
- ...registeredSelector ? [registeredSelector] : [],
1275
- ...contextComponentSelectors,
1276
- ...contextComponentSelectors.map(hyphenate)
1277
- ].join(",");
1313
+ const selector = this.__getComponentSelector();
1278
1314
  if (isNullOrWhitespace(selector)) return;
1279
- const list = element.querySelectorAll(selector);
1280
- const components = ((_a = element.matches) == null ? void 0 : _a.call(element, selector)) ? [element, ...list] : list;
1315
+ const components = this.__collectTopLevelComponentHosts(element, selector);
1281
1316
  for (const component of components) {
1282
1317
  if (component.hasAttribute(binder.__pre)) continue;
1283
1318
  const parent = component.parentNode;
@@ -1351,7 +1386,7 @@ var ComponentBinder = class {
1351
1386
  };
1352
1387
  const capturedContext = [...parser.__capture()];
1353
1388
  const createComponentCtx = () => {
1354
- var _a2;
1389
+ var _a;
1355
1390
  const props = getProps(component, capturedContext);
1356
1391
  const head2 = new ComponentHead(
1357
1392
  props,
@@ -1361,8 +1396,8 @@ var ComponentBinder = class {
1361
1396
  endOfComponent
1362
1397
  );
1363
1398
  const componentCtx2 = useScope(() => {
1364
- var _a3;
1365
- return (_a3 = registeredComponent.context(head2)) != null ? _a3 : {};
1399
+ var _a2;
1400
+ return (_a2 = registeredComponent.context(head2)) != null ? _a2 : {};
1366
1401
  }).context;
1367
1402
  if (head2.autoProps) {
1368
1403
  for (const [key, propsValue] of Object.entries(props)) {
@@ -1386,7 +1421,7 @@ var ComponentBinder = class {
1386
1421
  }
1387
1422
  } else componentCtx2[key] = propsValue;
1388
1423
  }
1389
- (_a2 = head2.onAutoPropsAssigned) == null ? void 0 : _a2.call(head2);
1424
+ (_a = head2.onAutoPropsAssigned) == null ? void 0 : _a.call(head2);
1390
1425
  }
1391
1426
  return { componentCtx: componentCtx2, head: head2 };
1392
1427
  };
@@ -1395,6 +1430,7 @@ var ComponentBinder = class {
1395
1430
  const len = childNodes.length;
1396
1431
  const isEmptyComponent = component.childNodes.length === 0;
1397
1432
  const expandSlot = (slot) => {
1433
+ var _a;
1398
1434
  const parent2 = slot.parentElement;
1399
1435
  let name = slot.name;
1400
1436
  if (isNullOrWhitespace(name)) {
@@ -1424,9 +1460,12 @@ var ComponentBinder = class {
1424
1460
  `template[name='${name}'], template[\\#${name}]`
1425
1461
  );
1426
1462
  if (!compTemplate && name === "default") {
1427
- compTemplate = component.querySelector("template:not([name])");
1428
- if (compTemplate && compTemplate.getAttributeNames().filter((x) => x.startsWith("#")).length > 0)
1429
- compTemplate = null;
1463
+ const unnamedTemplates = component.querySelectorAll(
1464
+ "template:not([name])"
1465
+ );
1466
+ compTemplate = (_a = [...unnamedTemplates].find(
1467
+ (x) => this.__isDefaultSlotTemplateShortcut(x)
1468
+ )) != null ? _a : null;
1430
1469
  }
1431
1470
  const createSwitchContext = (childNodes2) => {
1432
1471
  if (!head.enableSwitch) return;
@@ -1462,7 +1501,7 @@ var ComponentBinder = class {
1462
1501
  return;
1463
1502
  }
1464
1503
  const childNodes2 = [...getChildNodes(component)].filter(
1465
- (x) => !isTemplate(x)
1504
+ (x) => !this.__isNamedSlotTemplateShortcut(x)
1466
1505
  );
1467
1506
  for (const slotChild of childNodes2) {
1468
1507
  parent2.insertBefore(slotChild, slot);
@@ -1548,6 +1587,65 @@ var ComponentBinder = class {
1548
1587
  parser.__scoped(capturedContext, bindComponent);
1549
1588
  }
1550
1589
  }
1590
+ __getComponentSelector() {
1591
+ const binder = this.__binder;
1592
+ const parser = binder.__parser;
1593
+ const registeredComponents = binder.__config.__components;
1594
+ const contextComponentSelectors = parser.__getComponentSelectors();
1595
+ const registeredSelector = this.__getRegisteredComponentSelector(registeredComponents);
1596
+ return [
1597
+ ...registeredSelector ? [registeredSelector] : [],
1598
+ ...contextComponentSelectors,
1599
+ ...contextComponentSelectors.map(hyphenate)
1600
+ ].join(",");
1601
+ }
1602
+ __collectTopLevelComponentHosts(root, selector) {
1603
+ var _a;
1604
+ const result = [];
1605
+ if (isNullOrWhitespace(selector)) return result;
1606
+ if ((_a = root.matches) == null ? void 0 : _a.call(root, selector)) return [root];
1607
+ const stack = this.__getChildElements(root).reverse();
1608
+ while (stack.length > 0) {
1609
+ const current = stack.pop();
1610
+ if (current.matches(selector)) {
1611
+ result.push(current);
1612
+ continue;
1613
+ }
1614
+ stack.push(...this.__getChildElements(current).reverse());
1615
+ }
1616
+ return result;
1617
+ }
1618
+ __forEachBindableDescendant(root, action) {
1619
+ const selector = this.__getComponentSelector();
1620
+ const stack = this.__getChildElements(root).reverse();
1621
+ while (stack.length > 0) {
1622
+ const current = stack.pop();
1623
+ action(current);
1624
+ if (!isNullOrWhitespace(selector) && current.matches(selector)) continue;
1625
+ stack.push(...this.__getChildElements(current).reverse());
1626
+ }
1627
+ }
1628
+ __getChildElements(root) {
1629
+ const children = root == null ? void 0 : root.children;
1630
+ if ((children == null ? void 0 : children.length) != null) {
1631
+ const result = [];
1632
+ for (let i = 0; i < children.length; ++i) {
1633
+ const child = children[i];
1634
+ if (isElement(child)) result.push(child);
1635
+ }
1636
+ return result;
1637
+ }
1638
+ const childNodes = root == null ? void 0 : root.childNodes;
1639
+ if ((childNodes == null ? void 0 : childNodes.length) != null) {
1640
+ const result = [];
1641
+ for (let i = 0; i < childNodes.length; ++i) {
1642
+ const child = childNodes[i];
1643
+ if (isElement(child)) result.push(child);
1644
+ }
1645
+ return result;
1646
+ }
1647
+ return [];
1648
+ }
1551
1649
  };
1552
1650
 
1553
1651
  // src/bind/DirectiveCollector.ts
@@ -1640,10 +1738,10 @@ var DirectiveCollector = class {
1640
1738
  };
1641
1739
  processNode(element);
1642
1740
  if (!isRecursive || !element.firstElementChild) return map;
1643
- const nodes = element.querySelectorAll("*");
1644
- for (const node of nodes) {
1645
- processNode(node);
1646
- }
1741
+ this.__binder.__componentBinder.__forEachBindableDescendant(
1742
+ element,
1743
+ processNode
1744
+ );
1647
1745
  return map;
1648
1746
  }
1649
1747
  };
@@ -1661,17 +1759,19 @@ var DynamicBinder = class {
1661
1759
  constructor(binder) {
1662
1760
  __publicField(this, "__binder");
1663
1761
  __publicField(this, "__is");
1664
- __publicField(this, "__isSelector");
1665
1762
  this.__binder = binder;
1666
1763
  this.__is = binder.__config.__builtInNames.is;
1667
- this.__isSelector = toSelector(this.__is) + ", [is]";
1668
1764
  }
1669
1765
  __bindAll(element) {
1670
1766
  const isComponentElement = element.hasAttribute(this.__is);
1671
- const elements = findElements(element, this.__isSelector);
1672
- for (const el of elements) {
1673
- this.__bind(el);
1674
- }
1767
+ if (isComponentElement || element.hasAttribute("is"))
1768
+ this.__bind(element);
1769
+ this.__binder.__componentBinder.__forEachBindableDescendant(
1770
+ element,
1771
+ (el) => {
1772
+ if (el.hasAttribute(this.__is) || el.hasAttribute("is")) this.__bind(el);
1773
+ }
1774
+ );
1675
1775
  return isComponentElement;
1676
1776
  }
1677
1777
  __bind(el) {
@@ -2148,10 +2248,13 @@ var _ForBinder = class _ForBinder {
2148
2248
  }
2149
2249
  __bindAll(element) {
2150
2250
  const isForElement = element.hasAttribute(this.__for);
2151
- const elements = findElements(element, this.__forSelector);
2152
- for (const el of elements) {
2153
- this.__bindFor(el);
2154
- }
2251
+ if (isForElement) this.__bindFor(element);
2252
+ this.__binder.__componentBinder.__forEachBindableDescendant(
2253
+ element,
2254
+ (el) => {
2255
+ if (el.hasAttribute(this.__for)) this.__bindFor(el);
2256
+ }
2257
+ );
2155
2258
  return isForElement;
2156
2259
  }
2157
2260
  __isProcessedOrMark(el) {
@@ -2828,11 +2931,11 @@ var patchAttribute = (el, key, value, previousKey) => {
2828
2931
  }
2829
2932
  return;
2830
2933
  }
2831
- const isBoolean = key in booleanAttributes;
2832
- if (isNullOrUndefined(value) || isBoolean && !includeBooleanAttr(value)) {
2934
+ const isBoolean2 = key in booleanAttributes;
2935
+ if (isNullOrUndefined(value) || isBoolean2 && !includeBooleanAttr(value)) {
2833
2936
  el.removeAttribute(key);
2834
2937
  } else {
2835
- el.setAttribute(key, isBoolean ? "" : value);
2938
+ el.setAttribute(key, isBoolean2 ? "" : value);
2836
2939
  }
2837
2940
  };
2838
2941
 
@@ -3082,7 +3185,7 @@ var decimalSeparators = /[.,' ·٫]/;
3082
3185
  var handleInputAndTextArea = (el, flags, getModelRef, parsedValue) => {
3083
3186
  const isLazy = flags.lazy;
3084
3187
  const eventType = isLazy ? "change" : "input";
3085
- const isNumber = isNumberInput(el);
3188
+ const isNumber2 = isNumberInput(el);
3086
3189
  const trimmer = () => {
3087
3190
  if (!flags.trim && !getFlags(parsedValue()[1]).trim) return;
3088
3191
  el.value = el.value.trim();
@@ -3112,7 +3215,7 @@ var handleInputAndTextArea = (el, flags, getModelRef, parsedValue) => {
3112
3215
  if (!target || target.composing) return;
3113
3216
  let value = target.value;
3114
3217
  const flags2 = getFlags(parsedValue()[1]);
3115
- if (isNumber || flags2.number || flags2.int) {
3218
+ if (isNumber2 || flags2.number || flags2.int) {
3116
3219
  if (flags2.int) {
3117
3220
  value = parseInt(value);
3118
3221
  } else {
@@ -4427,12 +4530,12 @@ var Jsep = class {
4427
4530
  this.__gobbleSpaces();
4428
4531
  let ch = this.__code;
4429
4532
  while (ch === PERIOD_CODE || ch === OBRACK_CODE || ch === OPAREN_CODE || ch === QUMARK_CODE) {
4430
- let optional;
4533
+ let optional2;
4431
4534
  if (ch === QUMARK_CODE) {
4432
4535
  if (this.__expr.charCodeAt(this.__index + 1) !== PERIOD_CODE) {
4433
4536
  break;
4434
4537
  }
4435
- optional = true;
4538
+ optional2 = true;
4436
4539
  this.__index += 2;
4437
4540
  this.__gobbleSpaces();
4438
4541
  ch = this.__code;
@@ -4458,7 +4561,7 @@ var Jsep = class {
4458
4561
  callee: node
4459
4562
  };
4460
4563
  } else {
4461
- if (optional) {
4564
+ if (optional2) {
4462
4565
  this.__index--;
4463
4566
  }
4464
4567
  this.__gobbleSpaces();
@@ -4469,7 +4572,7 @@ var Jsep = class {
4469
4572
  property: this.__gobbleIdentifier()
4470
4573
  };
4471
4574
  }
4472
- if (optional) {
4575
+ if (optional2) {
4473
4576
  node.optional = true;
4474
4577
  }
4475
4578
  this.__gobbleSpaces();
@@ -5999,6 +6102,113 @@ var defineComponent = (template, options = {}) => {
5999
6102
  };
6000
6103
  };
6001
6104
 
6105
+ // src/app/propValidators.ts
6106
+ var fail = (name, message) => {
6107
+ throw new Error(`Invalid prop "${name}": ${message}.`);
6108
+ };
6109
+ var describeValue = (value) => {
6110
+ var _a;
6111
+ if (value === null) return "null";
6112
+ if (value === void 0) return "undefined";
6113
+ if (typeof value === "string") return "string";
6114
+ if (typeof value === "number") return "number";
6115
+ if (typeof value === "boolean") return "boolean";
6116
+ if (typeof value === "bigint") return "bigint";
6117
+ if (typeof value === "symbol") return "symbol";
6118
+ if (typeof value === "function") return "function";
6119
+ if (isArray(value)) return "array";
6120
+ if (value instanceof Date) return "Date";
6121
+ if (value instanceof RegExp) return "RegExp";
6122
+ if (value instanceof Map) return "Map";
6123
+ if (value instanceof Set) return "Set";
6124
+ const ctorName = (_a = value == null ? void 0 : value.constructor) == null ? void 0 : _a.name;
6125
+ return ctorName && ctorName !== "Object" ? ctorName : "object";
6126
+ };
6127
+ var formatLiteral = (value) => {
6128
+ if (typeof value === "string") return `"${value}"`;
6129
+ if (typeof value === "number" || typeof value === "boolean") {
6130
+ return String(value);
6131
+ }
6132
+ if (value === null) return "null";
6133
+ if (value === void 0) return "undefined";
6134
+ return describeValue(value);
6135
+ };
6136
+ var isString2 = (value, name) => {
6137
+ if (typeof value !== "string") fail(name, "expected string");
6138
+ };
6139
+ var isNumber = (value, name) => {
6140
+ if (typeof value !== "number") fail(name, "expected number");
6141
+ };
6142
+ var isBoolean = (value, name) => {
6143
+ if (typeof value !== "boolean") fail(name, "expected boolean");
6144
+ };
6145
+ var isClass = (ctor) => {
6146
+ return (value, name) => {
6147
+ if (!(value instanceof ctor)) {
6148
+ fail(name, `expected instance of ${ctor.name || "provided class"}`);
6149
+ }
6150
+ };
6151
+ };
6152
+ var optional = (validator) => {
6153
+ return (value, name, head) => {
6154
+ if (value === void 0) return;
6155
+ validator(value, name, head);
6156
+ };
6157
+ };
6158
+ var nullable = (validator) => {
6159
+ return (value, name, head) => {
6160
+ if (value === null) return;
6161
+ validator(value, name, head);
6162
+ };
6163
+ };
6164
+ var oneOf = (values) => {
6165
+ return (value, name) => {
6166
+ if (values.includes(value)) return;
6167
+ fail(
6168
+ name,
6169
+ `expected one of ${values.map((x) => formatLiteral(x)).join(", ")}`
6170
+ );
6171
+ };
6172
+ };
6173
+ var arrayOf = (validator) => {
6174
+ return (value, name, head) => {
6175
+ if (!isArray(value)) fail(name, "expected array");
6176
+ const items = value;
6177
+ for (let i = 0; i < items.length; ++i) {
6178
+ validator(items[i], `${name}[${i}]`, head);
6179
+ }
6180
+ };
6181
+ };
6182
+ var shape = (schema) => {
6183
+ return (value, name, head) => {
6184
+ if (!isObject(value)) fail(name, "expected object");
6185
+ const record = value;
6186
+ for (const key in schema) {
6187
+ const validator = schema[key];
6188
+ validator(record[key], `${name}.${key}`, head);
6189
+ }
6190
+ };
6191
+ };
6192
+ var refOf = (validator) => {
6193
+ return (value, name, head) => {
6194
+ if (!isRef(value)) fail(name, "expected ref");
6195
+ const refValue = value;
6196
+ validator(refValue(), `${name}.value`, head);
6197
+ };
6198
+ };
6199
+ var pval = {
6200
+ isString: isString2,
6201
+ isNumber,
6202
+ isBoolean,
6203
+ isClass,
6204
+ optional,
6205
+ nullable,
6206
+ oneOf,
6207
+ arrayOf,
6208
+ shape,
6209
+ refOf
6210
+ };
6211
+
6002
6212
  // src/composition/ContextRegistry.ts
6003
6213
  var ContextRegistry = class {
6004
6214
  constructor() {
@@ -6350,6 +6560,7 @@ export {
6350
6560
  onUnmounted,
6351
6561
  pause,
6352
6562
  persist,
6563
+ pval,
6353
6564
  raw,
6354
6565
  ref,
6355
6566
  removeNode,