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.
@@ -353,6 +353,37 @@ var ComponentHead = class {
353
353
  `${constructor} was not found in the context stack at occurrence ${occurrence}.`
354
354
  );
355
355
  }
356
+ /**
357
+ * Validates selected incoming props using assertion-style validators.
358
+ *
359
+ * Only keys listed in `schema` are checked. Validation throws immediately
360
+ * on the first invalid prop and does not mutate `head.props`.
361
+ *
362
+ * The schema is keyed from `head.props`, so editor completion can suggest
363
+ * known prop names while still allowing you to validate only a subset.
364
+ *
365
+ * Validators typically come from `pval`, but custom user validators are also
366
+ * supported.
367
+ *
368
+ * Example:
369
+ * ```ts
370
+ * head.validateProps({
371
+ * title: pval.isString,
372
+ * count: pval.optional(pval.isNumber),
373
+ * })
374
+ * ```
375
+ *
376
+ * @param schema - Validators to apply to selected incoming props.
377
+ */
378
+ validateProps(schema) {
379
+ const props = this.props;
380
+ for (const name in schema) {
381
+ const validator = schema[name];
382
+ if (!validator) continue;
383
+ const validateProp = validator;
384
+ validateProp(props[name], name, this);
385
+ }
386
+ }
356
387
  /**
357
388
  * Unmounts this component instance by removing nodes between `start` and `end`
358
389
  * and calling unmount lifecycle handlers for captured contexts.
@@ -501,10 +532,13 @@ var IfBinder = class {
501
532
  }
502
533
  __bindAll(element) {
503
534
  const isIfElement = element.hasAttribute(this.__if);
504
- const elements = findElements(element, this.__ifSelector);
505
- for (const el of elements) {
506
- this.__bind(el);
507
- }
535
+ if (isIfElement) this.__bind(element);
536
+ this.__binder.__componentBinder.__forEachBindableDescendant(
537
+ element,
538
+ (el) => {
539
+ if (el.hasAttribute(this.__if)) this.__bind(el);
540
+ }
541
+ );
508
542
  return isIfElement;
509
543
  }
510
544
  __isProcessedOrMark(el) {
@@ -1296,8 +1330,16 @@ var ComponentBinder = class {
1296
1330
  }
1297
1331
  return false;
1298
1332
  }
1333
+ __isNamedSlotTemplateShortcut(node) {
1334
+ if (!isTemplate(node)) return false;
1335
+ const attributeNames = node.getAttributeNames();
1336
+ if (node.hasAttribute("name")) return true;
1337
+ return attributeNames.some((x) => x.startsWith("#"));
1338
+ }
1339
+ __isDefaultSlotTemplateShortcut(node) {
1340
+ return isTemplate(node) && node.getAttributeNames().length === 0;
1341
+ }
1299
1342
  __unwrapComponents(element) {
1300
- var _a;
1301
1343
  const binder = this.__binder;
1302
1344
  const parser = binder.__parser;
1303
1345
  const registeredComponents = binder.__config.__components;
@@ -1306,16 +1348,9 @@ var ComponentBinder = class {
1306
1348
  return;
1307
1349
  }
1308
1350
  const contextComponents = parser.__getComponents();
1309
- const contextComponentSelectors = parser.__getComponentSelectors();
1310
- const registeredSelector = this.__getRegisteredComponentSelector(registeredComponents);
1311
- const selector = [
1312
- ...registeredSelector ? [registeredSelector] : [],
1313
- ...contextComponentSelectors,
1314
- ...contextComponentSelectors.map(hyphenate)
1315
- ].join(",");
1351
+ const selector = this.__getComponentSelector();
1316
1352
  if (isNullOrWhitespace(selector)) return;
1317
- const list = element.querySelectorAll(selector);
1318
- const components = ((_a = element.matches) == null ? void 0 : _a.call(element, selector)) ? [element, ...list] : list;
1353
+ const components = this.__collectTopLevelComponentHosts(element, selector);
1319
1354
  for (const component of components) {
1320
1355
  if (component.hasAttribute(binder.__pre)) continue;
1321
1356
  const parent = component.parentNode;
@@ -1389,7 +1424,7 @@ var ComponentBinder = class {
1389
1424
  };
1390
1425
  const capturedContext = [...parser.__capture()];
1391
1426
  const createComponentCtx = () => {
1392
- var _a2;
1427
+ var _a;
1393
1428
  const props = getProps(component, capturedContext);
1394
1429
  const head2 = new ComponentHead(
1395
1430
  props,
@@ -1399,8 +1434,8 @@ var ComponentBinder = class {
1399
1434
  endOfComponent
1400
1435
  );
1401
1436
  const componentCtx2 = useScope(() => {
1402
- var _a3;
1403
- return (_a3 = registeredComponent.context(head2)) != null ? _a3 : {};
1437
+ var _a2;
1438
+ return (_a2 = registeredComponent.context(head2)) != null ? _a2 : {};
1404
1439
  }).context;
1405
1440
  if (head2.autoProps) {
1406
1441
  for (const [key, propsValue] of Object.entries(props)) {
@@ -1424,7 +1459,7 @@ var ComponentBinder = class {
1424
1459
  }
1425
1460
  } else componentCtx2[key] = propsValue;
1426
1461
  }
1427
- (_a2 = head2.onAutoPropsAssigned) == null ? void 0 : _a2.call(head2);
1462
+ (_a = head2.onAutoPropsAssigned) == null ? void 0 : _a.call(head2);
1428
1463
  }
1429
1464
  return { componentCtx: componentCtx2, head: head2 };
1430
1465
  };
@@ -1433,6 +1468,7 @@ var ComponentBinder = class {
1433
1468
  const len = childNodes.length;
1434
1469
  const isEmptyComponent = component.childNodes.length === 0;
1435
1470
  const expandSlot = (slot) => {
1471
+ var _a;
1436
1472
  const parent2 = slot.parentElement;
1437
1473
  let name = slot.name;
1438
1474
  if (isNullOrWhitespace(name)) {
@@ -1462,9 +1498,12 @@ var ComponentBinder = class {
1462
1498
  `template[name='${name}'], template[\\#${name}]`
1463
1499
  );
1464
1500
  if (!compTemplate && name === "default") {
1465
- compTemplate = component.querySelector("template:not([name])");
1466
- if (compTemplate && compTemplate.getAttributeNames().filter((x) => x.startsWith("#")).length > 0)
1467
- compTemplate = null;
1501
+ const unnamedTemplates = component.querySelectorAll(
1502
+ "template:not([name])"
1503
+ );
1504
+ compTemplate = (_a = [...unnamedTemplates].find(
1505
+ (x) => this.__isDefaultSlotTemplateShortcut(x)
1506
+ )) != null ? _a : null;
1468
1507
  }
1469
1508
  const createSwitchContext = (childNodes2) => {
1470
1509
  if (!head.enableSwitch) return;
@@ -1500,7 +1539,7 @@ var ComponentBinder = class {
1500
1539
  return;
1501
1540
  }
1502
1541
  const childNodes2 = [...getChildNodes(component)].filter(
1503
- (x) => !isTemplate(x)
1542
+ (x) => !this.__isNamedSlotTemplateShortcut(x)
1504
1543
  );
1505
1544
  for (const slotChild of childNodes2) {
1506
1545
  parent2.insertBefore(slotChild, slot);
@@ -1586,6 +1625,65 @@ var ComponentBinder = class {
1586
1625
  parser.__scoped(capturedContext, bindComponent);
1587
1626
  }
1588
1627
  }
1628
+ __getComponentSelector() {
1629
+ const binder = this.__binder;
1630
+ const parser = binder.__parser;
1631
+ const registeredComponents = binder.__config.__components;
1632
+ const contextComponentSelectors = parser.__getComponentSelectors();
1633
+ const registeredSelector = this.__getRegisteredComponentSelector(registeredComponents);
1634
+ return [
1635
+ ...registeredSelector ? [registeredSelector] : [],
1636
+ ...contextComponentSelectors,
1637
+ ...contextComponentSelectors.map(hyphenate)
1638
+ ].join(",");
1639
+ }
1640
+ __collectTopLevelComponentHosts(root, selector) {
1641
+ var _a;
1642
+ const result = [];
1643
+ if (isNullOrWhitespace(selector)) return result;
1644
+ if ((_a = root.matches) == null ? void 0 : _a.call(root, selector)) return [root];
1645
+ const stack = this.__getChildElements(root).reverse();
1646
+ while (stack.length > 0) {
1647
+ const current = stack.pop();
1648
+ if (current.matches(selector)) {
1649
+ result.push(current);
1650
+ continue;
1651
+ }
1652
+ stack.push(...this.__getChildElements(current).reverse());
1653
+ }
1654
+ return result;
1655
+ }
1656
+ __forEachBindableDescendant(root, action) {
1657
+ const selector = this.__getComponentSelector();
1658
+ const stack = this.__getChildElements(root).reverse();
1659
+ while (stack.length > 0) {
1660
+ const current = stack.pop();
1661
+ action(current);
1662
+ if (!isNullOrWhitespace(selector) && current.matches(selector)) continue;
1663
+ stack.push(...this.__getChildElements(current).reverse());
1664
+ }
1665
+ }
1666
+ __getChildElements(root) {
1667
+ const children = root == null ? void 0 : root.children;
1668
+ if ((children == null ? void 0 : children.length) != null) {
1669
+ const result = [];
1670
+ for (let i = 0; i < children.length; ++i) {
1671
+ const child = children[i];
1672
+ if (isElement(child)) result.push(child);
1673
+ }
1674
+ return result;
1675
+ }
1676
+ const childNodes = root == null ? void 0 : root.childNodes;
1677
+ if ((childNodes == null ? void 0 : childNodes.length) != null) {
1678
+ const result = [];
1679
+ for (let i = 0; i < childNodes.length; ++i) {
1680
+ const child = childNodes[i];
1681
+ if (isElement(child)) result.push(child);
1682
+ }
1683
+ return result;
1684
+ }
1685
+ return [];
1686
+ }
1589
1687
  };
1590
1688
 
1591
1689
  // src/bind/DirectiveCollector.ts
@@ -1678,10 +1776,10 @@ var DirectiveCollector = class {
1678
1776
  };
1679
1777
  processNode(element);
1680
1778
  if (!isRecursive || !element.firstElementChild) return map;
1681
- const nodes = element.querySelectorAll("*");
1682
- for (const node of nodes) {
1683
- processNode(node);
1684
- }
1779
+ this.__binder.__componentBinder.__forEachBindableDescendant(
1780
+ element,
1781
+ processNode
1782
+ );
1685
1783
  return map;
1686
1784
  }
1687
1785
  };
@@ -1699,17 +1797,19 @@ var DynamicBinder = class {
1699
1797
  constructor(binder) {
1700
1798
  __publicField(this, "__binder");
1701
1799
  __publicField(this, "__is");
1702
- __publicField(this, "__isSelector");
1703
1800
  this.__binder = binder;
1704
1801
  this.__is = binder.__config.__builtInNames.is;
1705
- this.__isSelector = toSelector(this.__is) + ", [is]";
1706
1802
  }
1707
1803
  __bindAll(element) {
1708
1804
  const isComponentElement = element.hasAttribute(this.__is);
1709
- const elements = findElements(element, this.__isSelector);
1710
- for (const el of elements) {
1711
- this.__bind(el);
1712
- }
1805
+ if (isComponentElement || element.hasAttribute("is"))
1806
+ this.__bind(element);
1807
+ this.__binder.__componentBinder.__forEachBindableDescendant(
1808
+ element,
1809
+ (el) => {
1810
+ if (el.hasAttribute(this.__is) || el.hasAttribute("is")) this.__bind(el);
1811
+ }
1812
+ );
1713
1813
  return isComponentElement;
1714
1814
  }
1715
1815
  __bind(el) {
@@ -2186,10 +2286,13 @@ var _ForBinder = class _ForBinder {
2186
2286
  }
2187
2287
  __bindAll(element) {
2188
2288
  const isForElement = element.hasAttribute(this.__for);
2189
- const elements = findElements(element, this.__forSelector);
2190
- for (const el of elements) {
2191
- this.__bindFor(el);
2192
- }
2289
+ if (isForElement) this.__bindFor(element);
2290
+ this.__binder.__componentBinder.__forEachBindableDescendant(
2291
+ element,
2292
+ (el) => {
2293
+ if (el.hasAttribute(this.__for)) this.__bindFor(el);
2294
+ }
2295
+ );
2193
2296
  return isForElement;
2194
2297
  }
2195
2298
  __isProcessedOrMark(el) {
@@ -2866,11 +2969,11 @@ var patchAttribute = (el, key, value, previousKey) => {
2866
2969
  }
2867
2970
  return;
2868
2971
  }
2869
- const isBoolean = key in booleanAttributes;
2870
- if (isNullOrUndefined(value) || isBoolean && !includeBooleanAttr(value)) {
2972
+ const isBoolean2 = key in booleanAttributes;
2973
+ if (isNullOrUndefined(value) || isBoolean2 && !includeBooleanAttr(value)) {
2871
2974
  el.removeAttribute(key);
2872
2975
  } else {
2873
- el.setAttribute(key, isBoolean ? "" : value);
2976
+ el.setAttribute(key, isBoolean2 ? "" : value);
2874
2977
  }
2875
2978
  };
2876
2979
 
@@ -3120,7 +3223,7 @@ var decimalSeparators = /[.,' ·٫]/;
3120
3223
  var handleInputAndTextArea = (el, flags, getModelRef, parsedValue) => {
3121
3224
  const isLazy = flags.lazy;
3122
3225
  const eventType = isLazy ? "change" : "input";
3123
- const isNumber = isNumberInput(el);
3226
+ const isNumber2 = isNumberInput(el);
3124
3227
  const trimmer = () => {
3125
3228
  if (!flags.trim && !getFlags(parsedValue()[1]).trim) return;
3126
3229
  el.value = el.value.trim();
@@ -3150,7 +3253,7 @@ var handleInputAndTextArea = (el, flags, getModelRef, parsedValue) => {
3150
3253
  if (!target || target.composing) return;
3151
3254
  let value = target.value;
3152
3255
  const flags2 = getFlags(parsedValue()[1]);
3153
- if (isNumber || flags2.number || flags2.int) {
3256
+ if (isNumber2 || flags2.number || flags2.int) {
3154
3257
  if (flags2.int) {
3155
3258
  value = parseInt(value);
3156
3259
  } else {
@@ -4465,12 +4568,12 @@ var Jsep = class {
4465
4568
  this.__gobbleSpaces();
4466
4569
  let ch = this.__code;
4467
4570
  while (ch === PERIOD_CODE || ch === OBRACK_CODE || ch === OPAREN_CODE || ch === QUMARK_CODE) {
4468
- let optional;
4571
+ let optional2;
4469
4572
  if (ch === QUMARK_CODE) {
4470
4573
  if (this.__expr.charCodeAt(this.__index + 1) !== PERIOD_CODE) {
4471
4574
  break;
4472
4575
  }
4473
- optional = true;
4576
+ optional2 = true;
4474
4577
  this.__index += 2;
4475
4578
  this.__gobbleSpaces();
4476
4579
  ch = this.__code;
@@ -4496,7 +4599,7 @@ var Jsep = class {
4496
4599
  callee: node
4497
4600
  };
4498
4601
  } else {
4499
- if (optional) {
4602
+ if (optional2) {
4500
4603
  this.__index--;
4501
4604
  }
4502
4605
  this.__gobbleSpaces();
@@ -4507,7 +4610,7 @@ var Jsep = class {
4507
4610
  property: this.__gobbleIdentifier()
4508
4611
  };
4509
4612
  }
4510
- if (optional) {
4613
+ if (optional2) {
4511
4614
  node.optional = true;
4512
4615
  }
4513
4616
  this.__gobbleSpaces();
@@ -6037,6 +6140,113 @@ var defineComponent = (template, options = {}) => {
6037
6140
  };
6038
6141
  };
6039
6142
 
6143
+ // src/app/propValidators.ts
6144
+ var fail = (name, message) => {
6145
+ throw new Error(`Invalid prop "${name}": ${message}.`);
6146
+ };
6147
+ var describeValue = (value) => {
6148
+ var _a;
6149
+ if (value === null) return "null";
6150
+ if (value === void 0) return "undefined";
6151
+ if (typeof value === "string") return "string";
6152
+ if (typeof value === "number") return "number";
6153
+ if (typeof value === "boolean") return "boolean";
6154
+ if (typeof value === "bigint") return "bigint";
6155
+ if (typeof value === "symbol") return "symbol";
6156
+ if (typeof value === "function") return "function";
6157
+ if (isArray(value)) return "array";
6158
+ if (value instanceof Date) return "Date";
6159
+ if (value instanceof RegExp) return "RegExp";
6160
+ if (value instanceof Map) return "Map";
6161
+ if (value instanceof Set) return "Set";
6162
+ const ctorName = (_a = value == null ? void 0 : value.constructor) == null ? void 0 : _a.name;
6163
+ return ctorName && ctorName !== "Object" ? ctorName : "object";
6164
+ };
6165
+ var formatLiteral = (value) => {
6166
+ if (typeof value === "string") return `"${value}"`;
6167
+ if (typeof value === "number" || typeof value === "boolean") {
6168
+ return String(value);
6169
+ }
6170
+ if (value === null) return "null";
6171
+ if (value === void 0) return "undefined";
6172
+ return describeValue(value);
6173
+ };
6174
+ var isString2 = (value, name) => {
6175
+ if (typeof value !== "string") fail(name, "expected string");
6176
+ };
6177
+ var isNumber = (value, name) => {
6178
+ if (typeof value !== "number") fail(name, "expected number");
6179
+ };
6180
+ var isBoolean = (value, name) => {
6181
+ if (typeof value !== "boolean") fail(name, "expected boolean");
6182
+ };
6183
+ var isClass = (ctor) => {
6184
+ return (value, name) => {
6185
+ if (!(value instanceof ctor)) {
6186
+ fail(name, `expected instance of ${ctor.name || "provided class"}`);
6187
+ }
6188
+ };
6189
+ };
6190
+ var optional = (validator) => {
6191
+ return (value, name, head) => {
6192
+ if (value === void 0) return;
6193
+ validator(value, name, head);
6194
+ };
6195
+ };
6196
+ var nullable = (validator) => {
6197
+ return (value, name, head) => {
6198
+ if (value === null) return;
6199
+ validator(value, name, head);
6200
+ };
6201
+ };
6202
+ var oneOf = (values) => {
6203
+ return (value, name) => {
6204
+ if (values.includes(value)) return;
6205
+ fail(
6206
+ name,
6207
+ `expected one of ${values.map((x) => formatLiteral(x)).join(", ")}`
6208
+ );
6209
+ };
6210
+ };
6211
+ var arrayOf = (validator) => {
6212
+ return (value, name, head) => {
6213
+ if (!isArray(value)) fail(name, "expected array");
6214
+ const items = value;
6215
+ for (let i = 0; i < items.length; ++i) {
6216
+ validator(items[i], `${name}[${i}]`, head);
6217
+ }
6218
+ };
6219
+ };
6220
+ var shape = (schema) => {
6221
+ return (value, name, head) => {
6222
+ if (!isObject(value)) fail(name, "expected object");
6223
+ const record = value;
6224
+ for (const key in schema) {
6225
+ const validator = schema[key];
6226
+ validator(record[key], `${name}.${key}`, head);
6227
+ }
6228
+ };
6229
+ };
6230
+ var refOf = (validator) => {
6231
+ return (value, name, head) => {
6232
+ if (!isRef(value)) fail(name, "expected ref");
6233
+ const refValue = value;
6234
+ validator(refValue(), `${name}.value`, head);
6235
+ };
6236
+ };
6237
+ var pval = {
6238
+ isString: isString2,
6239
+ isNumber,
6240
+ isBoolean,
6241
+ isClass,
6242
+ optional,
6243
+ nullable,
6244
+ oneOf,
6245
+ arrayOf,
6246
+ shape,
6247
+ refOf
6248
+ };
6249
+
6040
6250
  // src/composition/ContextRegistry.ts
6041
6251
  var ContextRegistry = class {
6042
6252
  constructor() {
@@ -6388,6 +6598,7 @@ export {
6388
6598
  onUnmounted,
6389
6599
  pause,
6390
6600
  persist,
6601
+ pval,
6391
6602
  raw,
6392
6603
  ref,
6393
6604
  removeNode,