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.
@@ -51,6 +51,7 @@ var Regor = (() => {
51
51
  onUnmounted: () => onUnmounted,
52
52
  pause: () => pause,
53
53
  persist: () => persist,
54
+ pval: () => pval,
54
55
  raw: () => raw,
55
56
  ref: () => ref,
56
57
  removeNode: () => removeNode,
@@ -381,6 +382,37 @@ var Regor = (() => {
381
382
  `${constructor} was not found in the context stack at occurrence ${occurrence}.`
382
383
  );
383
384
  }
385
+ /**
386
+ * Validates selected incoming props using assertion-style validators.
387
+ *
388
+ * Only keys listed in `schema` are checked. Validation throws immediately
389
+ * on the first invalid prop and does not mutate `head.props`.
390
+ *
391
+ * The schema is keyed from `head.props`, so editor completion can suggest
392
+ * known prop names while still allowing you to validate only a subset.
393
+ *
394
+ * Validators typically come from `pval`, but custom user validators are also
395
+ * supported.
396
+ *
397
+ * Example:
398
+ * ```ts
399
+ * head.validateProps({
400
+ * title: pval.isString,
401
+ * count: pval.optional(pval.isNumber),
402
+ * })
403
+ * ```
404
+ *
405
+ * @param schema - Validators to apply to selected incoming props.
406
+ */
407
+ validateProps(schema) {
408
+ const props = this.props;
409
+ for (const name in schema) {
410
+ const validator = schema[name];
411
+ if (!validator) continue;
412
+ const validateProp = validator;
413
+ validateProp(props[name], name, this);
414
+ }
415
+ }
384
416
  /**
385
417
  * Unmounts this component instance by removing nodes between `start` and `end`
386
418
  * and calling unmount lifecycle handlers for captured contexts.
@@ -529,10 +561,13 @@ var Regor = (() => {
529
561
  }
530
562
  __bindAll(element) {
531
563
  const isIfElement = element.hasAttribute(this.__if);
532
- const elements = findElements(element, this.__ifSelector);
533
- for (const el of elements) {
534
- this.__bind(el);
535
- }
564
+ if (isIfElement) this.__bind(element);
565
+ this.__binder.__componentBinder.__forEachBindableDescendant(
566
+ element,
567
+ (el) => {
568
+ if (el.hasAttribute(this.__if)) this.__bind(el);
569
+ }
570
+ );
536
571
  return isIfElement;
537
572
  }
538
573
  __isProcessedOrMark(el) {
@@ -1324,8 +1359,16 @@ var Regor = (() => {
1324
1359
  }
1325
1360
  return false;
1326
1361
  }
1362
+ __isNamedSlotTemplateShortcut(node) {
1363
+ if (!isTemplate(node)) return false;
1364
+ const attributeNames = node.getAttributeNames();
1365
+ if (node.hasAttribute("name")) return true;
1366
+ return attributeNames.some((x) => x.startsWith("#"));
1367
+ }
1368
+ __isDefaultSlotTemplateShortcut(node) {
1369
+ return isTemplate(node) && node.getAttributeNames().length === 0;
1370
+ }
1327
1371
  __unwrapComponents(element) {
1328
- var _a;
1329
1372
  const binder = this.__binder;
1330
1373
  const parser = binder.__parser;
1331
1374
  const registeredComponents = binder.__config.__components;
@@ -1334,16 +1377,9 @@ var Regor = (() => {
1334
1377
  return;
1335
1378
  }
1336
1379
  const contextComponents = parser.__getComponents();
1337
- const contextComponentSelectors = parser.__getComponentSelectors();
1338
- const registeredSelector = this.__getRegisteredComponentSelector(registeredComponents);
1339
- const selector = [
1340
- ...registeredSelector ? [registeredSelector] : [],
1341
- ...contextComponentSelectors,
1342
- ...contextComponentSelectors.map(hyphenate)
1343
- ].join(",");
1380
+ const selector = this.__getComponentSelector();
1344
1381
  if (isNullOrWhitespace(selector)) return;
1345
- const list = element.querySelectorAll(selector);
1346
- const components = ((_a = element.matches) == null ? void 0 : _a.call(element, selector)) ? [element, ...list] : list;
1382
+ const components = this.__collectTopLevelComponentHosts(element, selector);
1347
1383
  for (const component of components) {
1348
1384
  if (component.hasAttribute(binder.__pre)) continue;
1349
1385
  const parent = component.parentNode;
@@ -1417,7 +1453,7 @@ var Regor = (() => {
1417
1453
  };
1418
1454
  const capturedContext = [...parser.__capture()];
1419
1455
  const createComponentCtx = () => {
1420
- var _a2;
1456
+ var _a;
1421
1457
  const props = getProps(component, capturedContext);
1422
1458
  const head2 = new ComponentHead(
1423
1459
  props,
@@ -1427,8 +1463,8 @@ var Regor = (() => {
1427
1463
  endOfComponent
1428
1464
  );
1429
1465
  const componentCtx2 = useScope(() => {
1430
- var _a3;
1431
- return (_a3 = registeredComponent.context(head2)) != null ? _a3 : {};
1466
+ var _a2;
1467
+ return (_a2 = registeredComponent.context(head2)) != null ? _a2 : {};
1432
1468
  }).context;
1433
1469
  if (head2.autoProps) {
1434
1470
  for (const [key, propsValue] of Object.entries(props)) {
@@ -1452,7 +1488,7 @@ var Regor = (() => {
1452
1488
  }
1453
1489
  } else componentCtx2[key] = propsValue;
1454
1490
  }
1455
- (_a2 = head2.onAutoPropsAssigned) == null ? void 0 : _a2.call(head2);
1491
+ (_a = head2.onAutoPropsAssigned) == null ? void 0 : _a.call(head2);
1456
1492
  }
1457
1493
  return { componentCtx: componentCtx2, head: head2 };
1458
1494
  };
@@ -1461,6 +1497,7 @@ var Regor = (() => {
1461
1497
  const len = childNodes.length;
1462
1498
  const isEmptyComponent = component.childNodes.length === 0;
1463
1499
  const expandSlot = (slot) => {
1500
+ var _a;
1464
1501
  const parent2 = slot.parentElement;
1465
1502
  let name = slot.name;
1466
1503
  if (isNullOrWhitespace(name)) {
@@ -1490,9 +1527,12 @@ var Regor = (() => {
1490
1527
  `template[name='${name}'], template[\\#${name}]`
1491
1528
  );
1492
1529
  if (!compTemplate && name === "default") {
1493
- compTemplate = component.querySelector("template:not([name])");
1494
- if (compTemplate && compTemplate.getAttributeNames().filter((x) => x.startsWith("#")).length > 0)
1495
- compTemplate = null;
1530
+ const unnamedTemplates = component.querySelectorAll(
1531
+ "template:not([name])"
1532
+ );
1533
+ compTemplate = (_a = [...unnamedTemplates].find(
1534
+ (x) => this.__isDefaultSlotTemplateShortcut(x)
1535
+ )) != null ? _a : null;
1496
1536
  }
1497
1537
  const createSwitchContext = (childNodes2) => {
1498
1538
  if (!head.enableSwitch) return;
@@ -1528,7 +1568,7 @@ var Regor = (() => {
1528
1568
  return;
1529
1569
  }
1530
1570
  const childNodes2 = [...getChildNodes(component)].filter(
1531
- (x) => !isTemplate(x)
1571
+ (x) => !this.__isNamedSlotTemplateShortcut(x)
1532
1572
  );
1533
1573
  for (const slotChild of childNodes2) {
1534
1574
  parent2.insertBefore(slotChild, slot);
@@ -1614,6 +1654,65 @@ var Regor = (() => {
1614
1654
  parser.__scoped(capturedContext, bindComponent);
1615
1655
  }
1616
1656
  }
1657
+ __getComponentSelector() {
1658
+ const binder = this.__binder;
1659
+ const parser = binder.__parser;
1660
+ const registeredComponents = binder.__config.__components;
1661
+ const contextComponentSelectors = parser.__getComponentSelectors();
1662
+ const registeredSelector = this.__getRegisteredComponentSelector(registeredComponents);
1663
+ return [
1664
+ ...registeredSelector ? [registeredSelector] : [],
1665
+ ...contextComponentSelectors,
1666
+ ...contextComponentSelectors.map(hyphenate)
1667
+ ].join(",");
1668
+ }
1669
+ __collectTopLevelComponentHosts(root, selector) {
1670
+ var _a;
1671
+ const result = [];
1672
+ if (isNullOrWhitespace(selector)) return result;
1673
+ if ((_a = root.matches) == null ? void 0 : _a.call(root, selector)) return [root];
1674
+ const stack = this.__getChildElements(root).reverse();
1675
+ while (stack.length > 0) {
1676
+ const current = stack.pop();
1677
+ if (current.matches(selector)) {
1678
+ result.push(current);
1679
+ continue;
1680
+ }
1681
+ stack.push(...this.__getChildElements(current).reverse());
1682
+ }
1683
+ return result;
1684
+ }
1685
+ __forEachBindableDescendant(root, action) {
1686
+ const selector = this.__getComponentSelector();
1687
+ const stack = this.__getChildElements(root).reverse();
1688
+ while (stack.length > 0) {
1689
+ const current = stack.pop();
1690
+ action(current);
1691
+ if (!isNullOrWhitespace(selector) && current.matches(selector)) continue;
1692
+ stack.push(...this.__getChildElements(current).reverse());
1693
+ }
1694
+ }
1695
+ __getChildElements(root) {
1696
+ const children = root == null ? void 0 : root.children;
1697
+ if ((children == null ? void 0 : children.length) != null) {
1698
+ const result = [];
1699
+ for (let i = 0; i < children.length; ++i) {
1700
+ const child = children[i];
1701
+ if (isElement(child)) result.push(child);
1702
+ }
1703
+ return result;
1704
+ }
1705
+ const childNodes = root == null ? void 0 : root.childNodes;
1706
+ if ((childNodes == null ? void 0 : childNodes.length) != null) {
1707
+ const result = [];
1708
+ for (let i = 0; i < childNodes.length; ++i) {
1709
+ const child = childNodes[i];
1710
+ if (isElement(child)) result.push(child);
1711
+ }
1712
+ return result;
1713
+ }
1714
+ return [];
1715
+ }
1617
1716
  };
1618
1717
 
1619
1718
  // src/bind/DirectiveCollector.ts
@@ -1706,10 +1805,10 @@ var Regor = (() => {
1706
1805
  };
1707
1806
  processNode(element);
1708
1807
  if (!isRecursive || !element.firstElementChild) return map;
1709
- const nodes = element.querySelectorAll("*");
1710
- for (const node of nodes) {
1711
- processNode(node);
1712
- }
1808
+ this.__binder.__componentBinder.__forEachBindableDescendant(
1809
+ element,
1810
+ processNode
1811
+ );
1713
1812
  return map;
1714
1813
  }
1715
1814
  };
@@ -1727,17 +1826,19 @@ var Regor = (() => {
1727
1826
  constructor(binder) {
1728
1827
  __publicField(this, "__binder");
1729
1828
  __publicField(this, "__is");
1730
- __publicField(this, "__isSelector");
1731
1829
  this.__binder = binder;
1732
1830
  this.__is = binder.__config.__builtInNames.is;
1733
- this.__isSelector = toSelector(this.__is) + ", [is]";
1734
1831
  }
1735
1832
  __bindAll(element) {
1736
1833
  const isComponentElement = element.hasAttribute(this.__is);
1737
- const elements = findElements(element, this.__isSelector);
1738
- for (const el of elements) {
1739
- this.__bind(el);
1740
- }
1834
+ if (isComponentElement || element.hasAttribute("is"))
1835
+ this.__bind(element);
1836
+ this.__binder.__componentBinder.__forEachBindableDescendant(
1837
+ element,
1838
+ (el) => {
1839
+ if (el.hasAttribute(this.__is) || el.hasAttribute("is")) this.__bind(el);
1840
+ }
1841
+ );
1741
1842
  return isComponentElement;
1742
1843
  }
1743
1844
  __bind(el) {
@@ -2214,10 +2315,13 @@ var Regor = (() => {
2214
2315
  }
2215
2316
  __bindAll(element) {
2216
2317
  const isForElement = element.hasAttribute(this.__for);
2217
- const elements = findElements(element, this.__forSelector);
2218
- for (const el of elements) {
2219
- this.__bindFor(el);
2220
- }
2318
+ if (isForElement) this.__bindFor(element);
2319
+ this.__binder.__componentBinder.__forEachBindableDescendant(
2320
+ element,
2321
+ (el) => {
2322
+ if (el.hasAttribute(this.__for)) this.__bindFor(el);
2323
+ }
2324
+ );
2221
2325
  return isForElement;
2222
2326
  }
2223
2327
  __isProcessedOrMark(el) {
@@ -2894,11 +2998,11 @@ var Regor = (() => {
2894
2998
  }
2895
2999
  return;
2896
3000
  }
2897
- const isBoolean = key in booleanAttributes;
2898
- if (isNullOrUndefined(value) || isBoolean && !includeBooleanAttr(value)) {
3001
+ const isBoolean2 = key in booleanAttributes;
3002
+ if (isNullOrUndefined(value) || isBoolean2 && !includeBooleanAttr(value)) {
2899
3003
  el.removeAttribute(key);
2900
3004
  } else {
2901
- el.setAttribute(key, isBoolean ? "" : value);
3005
+ el.setAttribute(key, isBoolean2 ? "" : value);
2902
3006
  }
2903
3007
  };
2904
3008
 
@@ -3148,7 +3252,7 @@ var Regor = (() => {
3148
3252
  var handleInputAndTextArea = (el, flags, getModelRef, parsedValue) => {
3149
3253
  const isLazy = flags.lazy;
3150
3254
  const eventType = isLazy ? "change" : "input";
3151
- const isNumber = isNumberInput(el);
3255
+ const isNumber2 = isNumberInput(el);
3152
3256
  const trimmer = () => {
3153
3257
  if (!flags.trim && !getFlags(parsedValue()[1]).trim) return;
3154
3258
  el.value = el.value.trim();
@@ -3178,7 +3282,7 @@ var Regor = (() => {
3178
3282
  if (!target || target.composing) return;
3179
3283
  let value = target.value;
3180
3284
  const flags2 = getFlags(parsedValue()[1]);
3181
- if (isNumber || flags2.number || flags2.int) {
3285
+ if (isNumber2 || flags2.number || flags2.int) {
3182
3286
  if (flags2.int) {
3183
3287
  value = parseInt(value);
3184
3288
  } else {
@@ -4493,12 +4597,12 @@ var Regor = (() => {
4493
4597
  this.__gobbleSpaces();
4494
4598
  let ch = this.__code;
4495
4599
  while (ch === PERIOD_CODE || ch === OBRACK_CODE || ch === OPAREN_CODE || ch === QUMARK_CODE) {
4496
- let optional;
4600
+ let optional2;
4497
4601
  if (ch === QUMARK_CODE) {
4498
4602
  if (this.__expr.charCodeAt(this.__index + 1) !== PERIOD_CODE) {
4499
4603
  break;
4500
4604
  }
4501
- optional = true;
4605
+ optional2 = true;
4502
4606
  this.__index += 2;
4503
4607
  this.__gobbleSpaces();
4504
4608
  ch = this.__code;
@@ -4524,7 +4628,7 @@ var Regor = (() => {
4524
4628
  callee: node
4525
4629
  };
4526
4630
  } else {
4527
- if (optional) {
4631
+ if (optional2) {
4528
4632
  this.__index--;
4529
4633
  }
4530
4634
  this.__gobbleSpaces();
@@ -4535,7 +4639,7 @@ var Regor = (() => {
4535
4639
  property: this.__gobbleIdentifier()
4536
4640
  };
4537
4641
  }
4538
- if (optional) {
4642
+ if (optional2) {
4539
4643
  node.optional = true;
4540
4644
  }
4541
4645
  this.__gobbleSpaces();
@@ -6065,6 +6169,113 @@ var Regor = (() => {
6065
6169
  };
6066
6170
  };
6067
6171
 
6172
+ // src/app/propValidators.ts
6173
+ var fail = (name, message) => {
6174
+ throw new Error(`Invalid prop "${name}": ${message}.`);
6175
+ };
6176
+ var describeValue = (value) => {
6177
+ var _a;
6178
+ if (value === null) return "null";
6179
+ if (value === void 0) return "undefined";
6180
+ if (typeof value === "string") return "string";
6181
+ if (typeof value === "number") return "number";
6182
+ if (typeof value === "boolean") return "boolean";
6183
+ if (typeof value === "bigint") return "bigint";
6184
+ if (typeof value === "symbol") return "symbol";
6185
+ if (typeof value === "function") return "function";
6186
+ if (isArray(value)) return "array";
6187
+ if (value instanceof Date) return "Date";
6188
+ if (value instanceof RegExp) return "RegExp";
6189
+ if (value instanceof Map) return "Map";
6190
+ if (value instanceof Set) return "Set";
6191
+ const ctorName = (_a = value == null ? void 0 : value.constructor) == null ? void 0 : _a.name;
6192
+ return ctorName && ctorName !== "Object" ? ctorName : "object";
6193
+ };
6194
+ var formatLiteral = (value) => {
6195
+ if (typeof value === "string") return `"${value}"`;
6196
+ if (typeof value === "number" || typeof value === "boolean") {
6197
+ return String(value);
6198
+ }
6199
+ if (value === null) return "null";
6200
+ if (value === void 0) return "undefined";
6201
+ return describeValue(value);
6202
+ };
6203
+ var isString2 = (value, name) => {
6204
+ if (typeof value !== "string") fail(name, "expected string");
6205
+ };
6206
+ var isNumber = (value, name) => {
6207
+ if (typeof value !== "number") fail(name, "expected number");
6208
+ };
6209
+ var isBoolean = (value, name) => {
6210
+ if (typeof value !== "boolean") fail(name, "expected boolean");
6211
+ };
6212
+ var isClass = (ctor) => {
6213
+ return (value, name) => {
6214
+ if (!(value instanceof ctor)) {
6215
+ fail(name, `expected instance of ${ctor.name || "provided class"}`);
6216
+ }
6217
+ };
6218
+ };
6219
+ var optional = (validator) => {
6220
+ return (value, name, head) => {
6221
+ if (value === void 0) return;
6222
+ validator(value, name, head);
6223
+ };
6224
+ };
6225
+ var nullable = (validator) => {
6226
+ return (value, name, head) => {
6227
+ if (value === null) return;
6228
+ validator(value, name, head);
6229
+ };
6230
+ };
6231
+ var oneOf = (values) => {
6232
+ return (value, name) => {
6233
+ if (values.includes(value)) return;
6234
+ fail(
6235
+ name,
6236
+ `expected one of ${values.map((x) => formatLiteral(x)).join(", ")}`
6237
+ );
6238
+ };
6239
+ };
6240
+ var arrayOf = (validator) => {
6241
+ return (value, name, head) => {
6242
+ if (!isArray(value)) fail(name, "expected array");
6243
+ const items = value;
6244
+ for (let i = 0; i < items.length; ++i) {
6245
+ validator(items[i], `${name}[${i}]`, head);
6246
+ }
6247
+ };
6248
+ };
6249
+ var shape = (schema) => {
6250
+ return (value, name, head) => {
6251
+ if (!isObject(value)) fail(name, "expected object");
6252
+ const record = value;
6253
+ for (const key in schema) {
6254
+ const validator = schema[key];
6255
+ validator(record[key], `${name}.${key}`, head);
6256
+ }
6257
+ };
6258
+ };
6259
+ var refOf = (validator) => {
6260
+ return (value, name, head) => {
6261
+ if (!isRef(value)) fail(name, "expected ref");
6262
+ const refValue = value;
6263
+ validator(refValue(), `${name}.value`, head);
6264
+ };
6265
+ };
6266
+ var pval = {
6267
+ isString: isString2,
6268
+ isNumber,
6269
+ isBoolean,
6270
+ isClass,
6271
+ optional,
6272
+ nullable,
6273
+ oneOf,
6274
+ arrayOf,
6275
+ shape,
6276
+ refOf
6277
+ };
6278
+
6068
6279
  // src/composition/ContextRegistry.ts
6069
6280
  var ContextRegistry = class {
6070
6281
  constructor() {