regor 1.4.5 → 1.4.7
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 +151 -0
- package/dist/regor.d.ts +120 -11
- package/dist/regor.es2015.cjs.js +258 -48
- package/dist/regor.es2015.cjs.prod.js +3 -3
- package/dist/regor.es2015.esm.js +258 -48
- package/dist/regor.es2015.esm.prod.js +3 -3
- package/dist/regor.es2015.iife.js +258 -48
- package/dist/regor.es2015.iife.prod.js +3 -3
- package/dist/regor.es2019.cjs.js +258 -48
- package/dist/regor.es2019.cjs.prod.js +3 -3
- package/dist/regor.es2019.esm.js +258 -48
- package/dist/regor.es2019.esm.prod.js +3 -3
- package/dist/regor.es2019.iife.js +258 -48
- package/dist/regor.es2019.iife.prod.js +3 -3
- package/dist/regor.es2022.cjs.js +256 -48
- package/dist/regor.es2022.cjs.prod.js +3 -3
- package/dist/regor.es2022.esm.js +256 -48
- package/dist/regor.es2022.esm.prod.js +3 -3
- package/dist/regor.es2022.iife.js +256 -48
- package/dist/regor.es2022.iife.prod.js +3 -3
- package/package.json +1 -1
|
@@ -49,6 +49,7 @@ var Regor = (() => {
|
|
|
49
49
|
onUnmounted: () => onUnmounted,
|
|
50
50
|
pause: () => pause,
|
|
51
51
|
persist: () => persist,
|
|
52
|
+
pval: () => pval,
|
|
52
53
|
raw: () => raw,
|
|
53
54
|
ref: () => ref,
|
|
54
55
|
removeNode: () => removeNode,
|
|
@@ -205,7 +206,180 @@ var Regor = (() => {
|
|
|
205
206
|
context.unmounted?.();
|
|
206
207
|
};
|
|
207
208
|
|
|
209
|
+
// src/log/warnings.ts
|
|
210
|
+
var warnings = {
|
|
211
|
+
[8 /* ModelRequiresRef */]: (el) => `Model binding requires a ref at ${el.outerHTML}`,
|
|
212
|
+
[7 /* ModelNotSupportOnElement */]: (el) => `Model binding is not supported on ${el.tagName} element at ${el.outerHTML}`,
|
|
213
|
+
[0 /* MissingBindingExpression */]: (name, el) => `${name} binding expression is missing at ${el.outerHTML}`,
|
|
214
|
+
[1 /* InvalidForExpression */]: (name, forPath, el) => `invalid ${name} expression: ${forPath} at ${el.outerHTML}`,
|
|
215
|
+
[2 /* BindingRequiresObjectExpressions */]: (name, el) => `${name} requires object expression at ${el.outerHTML}`,
|
|
216
|
+
[3 /* KeyIsEmpty */]: (name, el) => `${name} binder: key is empty on ${el.outerHTML}.`,
|
|
217
|
+
[4 /* PropertyAssignmentFailed */]: (key, tag, value, e) => ({
|
|
218
|
+
msg: `Failed setting prop "${key}" on <${tag.toLowerCase()}>: value ${value} is invalid.`,
|
|
219
|
+
args: [e]
|
|
220
|
+
}),
|
|
221
|
+
[5 /* MissingEventType */]: (name, el) => `${name} binding missing event type at ${el.outerHTML}`,
|
|
222
|
+
[6 /* ErrorLog */]: (msg, e) => ({ msg, args: [e] })
|
|
223
|
+
};
|
|
224
|
+
var warning = (type, ...args) => {
|
|
225
|
+
const msg = warnings[type];
|
|
226
|
+
const item = isFunction(msg) ? msg.call(warnings, ...args) : msg;
|
|
227
|
+
const handler = warningHandler.warning;
|
|
228
|
+
if (!handler) return;
|
|
229
|
+
if (isString(item)) handler(item);
|
|
230
|
+
else handler(item, ...item.args);
|
|
231
|
+
};
|
|
232
|
+
var warningHandler = {
|
|
233
|
+
warning: console.warn
|
|
234
|
+
};
|
|
235
|
+
|
|
236
|
+
// src/reactivity/refSymbols.ts
|
|
237
|
+
var refSymbol = Symbol("ref");
|
|
238
|
+
var srefSymbol = Symbol("sref");
|
|
239
|
+
var rawSymbol = Symbol("raw");
|
|
240
|
+
|
|
241
|
+
// src/reactivity/isRef.ts
|
|
242
|
+
var isRef = (value) => {
|
|
243
|
+
return value != null && value[srefSymbol] === 1;
|
|
244
|
+
};
|
|
245
|
+
|
|
246
|
+
// src/app/propValidators.ts
|
|
247
|
+
var PropValidationError = class extends Error {
|
|
248
|
+
propPath;
|
|
249
|
+
detail;
|
|
250
|
+
constructor(propPath, detail) {
|
|
251
|
+
super(detail);
|
|
252
|
+
this.name = "PropValidationError";
|
|
253
|
+
this.propPath = propPath;
|
|
254
|
+
this.detail = detail;
|
|
255
|
+
}
|
|
256
|
+
};
|
|
257
|
+
var fail = (name, message) => {
|
|
258
|
+
throw new PropValidationError(name, `${message}.`);
|
|
259
|
+
};
|
|
260
|
+
var describeValue = (value) => {
|
|
261
|
+
if (value === null) return "null";
|
|
262
|
+
if (value === void 0) return "undefined";
|
|
263
|
+
if (typeof value === "string") return "string";
|
|
264
|
+
if (typeof value === "number") return "number";
|
|
265
|
+
if (typeof value === "boolean") return "boolean";
|
|
266
|
+
if (typeof value === "bigint") return "bigint";
|
|
267
|
+
if (typeof value === "symbol") return "symbol";
|
|
268
|
+
if (typeof value === "function") return "function";
|
|
269
|
+
if (isArray(value)) return "array";
|
|
270
|
+
if (value instanceof Date) return "Date";
|
|
271
|
+
if (value instanceof RegExp) return "RegExp";
|
|
272
|
+
if (value instanceof Map) return "Map";
|
|
273
|
+
if (value instanceof Set) return "Set";
|
|
274
|
+
const ctorName = value?.constructor?.name;
|
|
275
|
+
return ctorName && ctorName !== "Object" ? ctorName : "object";
|
|
276
|
+
};
|
|
277
|
+
var formatLiteral = (value) => {
|
|
278
|
+
if (typeof value === "string") return `"${value}"`;
|
|
279
|
+
if (typeof value === "number" || typeof value === "boolean") {
|
|
280
|
+
return String(value);
|
|
281
|
+
}
|
|
282
|
+
if (value === null) return "null";
|
|
283
|
+
if (value === void 0) return "undefined";
|
|
284
|
+
return describeValue(value);
|
|
285
|
+
};
|
|
286
|
+
var isString2 = (value, name) => {
|
|
287
|
+
if (typeof value !== "string") fail(name, "expected string");
|
|
288
|
+
};
|
|
289
|
+
var isNumber = (value, name) => {
|
|
290
|
+
if (typeof value !== "number") fail(name, "expected number");
|
|
291
|
+
};
|
|
292
|
+
var isBoolean = (value, name) => {
|
|
293
|
+
if (typeof value !== "boolean") fail(name, "expected boolean");
|
|
294
|
+
};
|
|
295
|
+
var isClass = (ctor) => {
|
|
296
|
+
return (value, name) => {
|
|
297
|
+
if (!(value instanceof ctor)) {
|
|
298
|
+
fail(name, `expected instance of ${ctor.name || "provided class"}`);
|
|
299
|
+
}
|
|
300
|
+
};
|
|
301
|
+
};
|
|
302
|
+
var optional = (validator) => {
|
|
303
|
+
return (value, name, head) => {
|
|
304
|
+
if (value === void 0) return;
|
|
305
|
+
validator(value, name, head);
|
|
306
|
+
};
|
|
307
|
+
};
|
|
308
|
+
var nullable = (validator) => {
|
|
309
|
+
return (value, name, head) => {
|
|
310
|
+
if (value === null) return;
|
|
311
|
+
validator(value, name, head);
|
|
312
|
+
};
|
|
313
|
+
};
|
|
314
|
+
var oneOf = (values) => {
|
|
315
|
+
return (value, name) => {
|
|
316
|
+
if (values.includes(value)) return;
|
|
317
|
+
fail(
|
|
318
|
+
name,
|
|
319
|
+
`expected one of ${values.map((x) => formatLiteral(x)).join(", ")}`
|
|
320
|
+
);
|
|
321
|
+
};
|
|
322
|
+
};
|
|
323
|
+
var arrayOf = (validator) => {
|
|
324
|
+
return (value, name, head) => {
|
|
325
|
+
if (!isArray(value)) fail(name, "expected array");
|
|
326
|
+
const items = value;
|
|
327
|
+
for (let i = 0; i < items.length; ++i) {
|
|
328
|
+
validator(items[i], `${name}[${i}]`, head);
|
|
329
|
+
}
|
|
330
|
+
};
|
|
331
|
+
};
|
|
332
|
+
var shape = (schema) => {
|
|
333
|
+
return (value, name, head) => {
|
|
334
|
+
if (!isObject(value)) fail(name, "expected object");
|
|
335
|
+
const record = value;
|
|
336
|
+
for (const key in schema) {
|
|
337
|
+
const validator = schema[key];
|
|
338
|
+
validator(record[key], `${name}.${key}`, head);
|
|
339
|
+
}
|
|
340
|
+
};
|
|
341
|
+
};
|
|
342
|
+
var refOf = (validator) => {
|
|
343
|
+
return (value, name, head) => {
|
|
344
|
+
if (!isRef(value)) fail(name, "expected ref");
|
|
345
|
+
const refValue = value;
|
|
346
|
+
validator(refValue(), `${name}.value`, head);
|
|
347
|
+
};
|
|
348
|
+
};
|
|
349
|
+
var pval = {
|
|
350
|
+
fail,
|
|
351
|
+
isString: isString2,
|
|
352
|
+
isNumber,
|
|
353
|
+
isBoolean,
|
|
354
|
+
isClass,
|
|
355
|
+
optional,
|
|
356
|
+
nullable,
|
|
357
|
+
oneOf,
|
|
358
|
+
arrayOf,
|
|
359
|
+
shape,
|
|
360
|
+
refOf
|
|
361
|
+
};
|
|
362
|
+
|
|
208
363
|
// src/app/ComponentHead.ts
|
|
364
|
+
var formatComponentValidationError = (element, propName, error) => {
|
|
365
|
+
const tagName = element.tagName?.toLowerCase?.() || "unknown";
|
|
366
|
+
const finalPropName = error instanceof PropValidationError ? error.propPath : propName;
|
|
367
|
+
const detail = error instanceof PropValidationError ? error.detail : error instanceof Error ? error.message : String(error);
|
|
368
|
+
if (error instanceof Error) {
|
|
369
|
+
return new Error(
|
|
370
|
+
`Invalid prop "${finalPropName}" on <${tagName}>: ${detail}`,
|
|
371
|
+
{
|
|
372
|
+
cause: error
|
|
373
|
+
}
|
|
374
|
+
);
|
|
375
|
+
}
|
|
376
|
+
return new Error(
|
|
377
|
+
`Invalid prop "${finalPropName}" on <${tagName}>: ${detail}`,
|
|
378
|
+
{
|
|
379
|
+
cause: error
|
|
380
|
+
}
|
|
381
|
+
);
|
|
382
|
+
};
|
|
209
383
|
var ComponentHead = class {
|
|
210
384
|
/**
|
|
211
385
|
* Values provided by parent for this component instance.
|
|
@@ -293,12 +467,18 @@ var Regor = (() => {
|
|
|
293
467
|
* @internal
|
|
294
468
|
*/
|
|
295
469
|
__element;
|
|
296
|
-
|
|
470
|
+
/**
|
|
471
|
+
* Runtime behavior used when `validateProps(...)` encounters invalid input.
|
|
472
|
+
* Defaults to `'throw'`.
|
|
473
|
+
*/
|
|
474
|
+
__propValidationMode;
|
|
475
|
+
constructor(props, element, ctx, start, end, propValidationMode) {
|
|
297
476
|
this.props = props;
|
|
298
477
|
this.__element = element;
|
|
299
478
|
this.ctx = ctx;
|
|
300
479
|
this.start = start;
|
|
301
480
|
this.end = end;
|
|
481
|
+
this.__propValidationMode = propValidationMode;
|
|
302
482
|
}
|
|
303
483
|
/**
|
|
304
484
|
* Emits a custom DOM event from the component host element.
|
|
@@ -377,6 +557,61 @@ var Regor = (() => {
|
|
|
377
557
|
`${constructor} was not found in the context stack at occurrence ${occurrence}.`
|
|
378
558
|
);
|
|
379
559
|
}
|
|
560
|
+
/**
|
|
561
|
+
* Validates selected incoming props using assertion-style validators.
|
|
562
|
+
*
|
|
563
|
+
* Only keys listed in `schema` are checked. Validation throws immediately
|
|
564
|
+
* on the first invalid prop and does not mutate `head.props`.
|
|
565
|
+
*
|
|
566
|
+
* The schema is keyed from `head.props`, so editor completion can suggest
|
|
567
|
+
* known prop names while still allowing you to validate only a subset.
|
|
568
|
+
*
|
|
569
|
+
* Validators typically come from `pval`, but custom user validators are also
|
|
570
|
+
* supported. Custom validators may throw their own `Error`, though `pval.fail(...)`
|
|
571
|
+
* is recommended so nested validators can preserve the exact failing prop path.
|
|
572
|
+
*
|
|
573
|
+
* Example:
|
|
574
|
+
* ```ts
|
|
575
|
+
* head.validateProps({
|
|
576
|
+
* title: pval.isString,
|
|
577
|
+
* count: pval.optional(pval.isNumber),
|
|
578
|
+
* })
|
|
579
|
+
* ```
|
|
580
|
+
*
|
|
581
|
+
* Example with a custom validator:
|
|
582
|
+
* ```ts
|
|
583
|
+
* const isNonEmptyString: PropValidator<string> = (value, name) => {
|
|
584
|
+
* if (typeof value !== 'string' || value.trim() === '') {
|
|
585
|
+
* pval.fail(name, 'expected non-empty string')
|
|
586
|
+
* }
|
|
587
|
+
* }
|
|
588
|
+
* ```
|
|
589
|
+
*
|
|
590
|
+
* @param schema - Validators to apply to selected incoming props.
|
|
591
|
+
*/
|
|
592
|
+
validateProps(schema) {
|
|
593
|
+
if (this.__propValidationMode === "off") return;
|
|
594
|
+
const props = this.props;
|
|
595
|
+
for (const name in schema) {
|
|
596
|
+
const validator = schema[name];
|
|
597
|
+
if (!validator) continue;
|
|
598
|
+
const validateProp = validator;
|
|
599
|
+
try {
|
|
600
|
+
validateProp(props[name], name, this);
|
|
601
|
+
} catch (error) {
|
|
602
|
+
const enrichedError = formatComponentValidationError(
|
|
603
|
+
this.__element,
|
|
604
|
+
name,
|
|
605
|
+
error
|
|
606
|
+
);
|
|
607
|
+
if (this.__propValidationMode === "warn") {
|
|
608
|
+
warningHandler.warning(enrichedError.message, enrichedError);
|
|
609
|
+
continue;
|
|
610
|
+
}
|
|
611
|
+
throw enrichedError;
|
|
612
|
+
}
|
|
613
|
+
}
|
|
614
|
+
}
|
|
380
615
|
/**
|
|
381
616
|
* Unmounts this component instance by removing nodes between `start` and `end`
|
|
382
617
|
* and calling unmount lifecycle handlers for captured contexts.
|
|
@@ -410,33 +645,6 @@ var Regor = (() => {
|
|
|
410
645
|
getBindData(node).unbinders.push(unbinder);
|
|
411
646
|
};
|
|
412
647
|
|
|
413
|
-
// src/log/warnings.ts
|
|
414
|
-
var warnings = {
|
|
415
|
-
[8 /* ModelRequiresRef */]: (el) => `Model binding requires a ref at ${el.outerHTML}`,
|
|
416
|
-
[7 /* ModelNotSupportOnElement */]: (el) => `Model binding is not supported on ${el.tagName} element at ${el.outerHTML}`,
|
|
417
|
-
[0 /* MissingBindingExpression */]: (name, el) => `${name} binding expression is missing at ${el.outerHTML}`,
|
|
418
|
-
[1 /* InvalidForExpression */]: (name, forPath, el) => `invalid ${name} expression: ${forPath} at ${el.outerHTML}`,
|
|
419
|
-
[2 /* BindingRequiresObjectExpressions */]: (name, el) => `${name} requires object expression at ${el.outerHTML}`,
|
|
420
|
-
[3 /* KeyIsEmpty */]: (name, el) => `${name} binder: key is empty on ${el.outerHTML}.`,
|
|
421
|
-
[4 /* PropertyAssignmentFailed */]: (key, tag, value, e) => ({
|
|
422
|
-
msg: `Failed setting prop "${key}" on <${tag.toLowerCase()}>: value ${value} is invalid.`,
|
|
423
|
-
args: [e]
|
|
424
|
-
}),
|
|
425
|
-
[5 /* MissingEventType */]: (name, el) => `${name} binding missing event type at ${el.outerHTML}`,
|
|
426
|
-
[6 /* ErrorLog */]: (msg, e) => ({ msg, args: [e] })
|
|
427
|
-
};
|
|
428
|
-
var warning = (type, ...args) => {
|
|
429
|
-
const msg = warnings[type];
|
|
430
|
-
const item = isFunction(msg) ? msg.call(warnings, ...args) : msg;
|
|
431
|
-
const handler = warningHandler.warning;
|
|
432
|
-
if (!handler) return;
|
|
433
|
-
if (isString(item)) handler(item);
|
|
434
|
-
else handler(item, ...item.args);
|
|
435
|
-
};
|
|
436
|
-
var warningHandler = {
|
|
437
|
-
warning: console.warn
|
|
438
|
-
};
|
|
439
|
-
|
|
440
648
|
// src/bind/switch.ts
|
|
441
649
|
var switches = {};
|
|
442
650
|
var switchCounter = {};
|
|
@@ -840,16 +1048,6 @@ var Regor = (() => {
|
|
|
840
1048
|
return scopeSymbol2 in value;
|
|
841
1049
|
};
|
|
842
1050
|
|
|
843
|
-
// src/reactivity/refSymbols.ts
|
|
844
|
-
var refSymbol = Symbol("ref");
|
|
845
|
-
var srefSymbol = Symbol("sref");
|
|
846
|
-
var rawSymbol = Symbol("raw");
|
|
847
|
-
|
|
848
|
-
// src/reactivity/isRef.ts
|
|
849
|
-
var isRef = (value) => {
|
|
850
|
-
return value != null && value[srefSymbol] === 1;
|
|
851
|
-
};
|
|
852
|
-
|
|
853
1051
|
// src/directives/context.ts
|
|
854
1052
|
var contextDirective = {
|
|
855
1053
|
collectRefObj: true,
|
|
@@ -1417,7 +1615,8 @@ var Regor = (() => {
|
|
|
1417
1615
|
component,
|
|
1418
1616
|
capturedContext,
|
|
1419
1617
|
startOfComponent,
|
|
1420
|
-
endOfComponent
|
|
1618
|
+
endOfComponent,
|
|
1619
|
+
binder.__config.propValidationMode
|
|
1421
1620
|
);
|
|
1422
1621
|
const componentCtx2 = useScope(() => {
|
|
1423
1622
|
return registeredComponent.context(head2) ?? {};
|
|
@@ -2933,11 +3132,11 @@ var Regor = (() => {
|
|
|
2933
3132
|
}
|
|
2934
3133
|
return;
|
|
2935
3134
|
}
|
|
2936
|
-
const
|
|
2937
|
-
if (isNullOrUndefined(value) ||
|
|
3135
|
+
const isBoolean2 = key in booleanAttributes;
|
|
3136
|
+
if (isNullOrUndefined(value) || isBoolean2 && !includeBooleanAttr(value)) {
|
|
2938
3137
|
el.removeAttribute(key);
|
|
2939
3138
|
} else {
|
|
2940
|
-
el.setAttribute(key,
|
|
3139
|
+
el.setAttribute(key, isBoolean2 ? "" : value);
|
|
2941
3140
|
}
|
|
2942
3141
|
};
|
|
2943
3142
|
|
|
@@ -3187,7 +3386,7 @@ var Regor = (() => {
|
|
|
3187
3386
|
var handleInputAndTextArea = (el, flags, getModelRef, parsedValue) => {
|
|
3188
3387
|
const isLazy = flags.lazy;
|
|
3189
3388
|
const eventType = isLazy ? "change" : "input";
|
|
3190
|
-
const
|
|
3389
|
+
const isNumber2 = isNumberInput(el);
|
|
3191
3390
|
const trimmer = () => {
|
|
3192
3391
|
if (!flags.trim && !getFlags(parsedValue()[1]).trim) return;
|
|
3193
3392
|
el.value = el.value.trim();
|
|
@@ -3217,7 +3416,7 @@ var Regor = (() => {
|
|
|
3217
3416
|
if (!target || target.composing) return;
|
|
3218
3417
|
let value = target.value;
|
|
3219
3418
|
const flags2 = getFlags(parsedValue()[1]);
|
|
3220
|
-
if (
|
|
3419
|
+
if (isNumber2 || flags2.number || flags2.int) {
|
|
3221
3420
|
if (flags2.int) {
|
|
3222
3421
|
value = parseInt(value);
|
|
3223
3422
|
} else {
|
|
@@ -3831,6 +4030,15 @@ var Regor = (() => {
|
|
|
3831
4030
|
forGrowThreshold = 10;
|
|
3832
4031
|
globalContext;
|
|
3833
4032
|
useInterpolation = true;
|
|
4033
|
+
/**
|
|
4034
|
+
* Controls how `head.validateProps(...)` behaves when a validator fails.
|
|
4035
|
+
*
|
|
4036
|
+
* - `'throw'` (default): rethrows the validation error immediately.
|
|
4037
|
+
* - `'warn'`: forwards the validation error to `warningHandler.warning(...)`
|
|
4038
|
+
* and continues.
|
|
4039
|
+
* - `'off'`: skips runtime prop validation entirely.
|
|
4040
|
+
*/
|
|
4041
|
+
propValidationMode = "throw";
|
|
3834
4042
|
constructor(globalContext) {
|
|
3835
4043
|
this.setDirectives("r-");
|
|
3836
4044
|
if (globalContext) {
|
|
@@ -4522,12 +4730,12 @@ var Regor = (() => {
|
|
|
4522
4730
|
this.__gobbleSpaces();
|
|
4523
4731
|
let ch = this.__code;
|
|
4524
4732
|
while (ch === PERIOD_CODE || ch === OBRACK_CODE || ch === OPAREN_CODE || ch === QUMARK_CODE) {
|
|
4525
|
-
let
|
|
4733
|
+
let optional2;
|
|
4526
4734
|
if (ch === QUMARK_CODE) {
|
|
4527
4735
|
if (this.__expr.charCodeAt(this.__index + 1) !== PERIOD_CODE) {
|
|
4528
4736
|
break;
|
|
4529
4737
|
}
|
|
4530
|
-
|
|
4738
|
+
optional2 = true;
|
|
4531
4739
|
this.__index += 2;
|
|
4532
4740
|
this.__gobbleSpaces();
|
|
4533
4741
|
ch = this.__code;
|
|
@@ -4553,7 +4761,7 @@ var Regor = (() => {
|
|
|
4553
4761
|
callee: node
|
|
4554
4762
|
};
|
|
4555
4763
|
} else {
|
|
4556
|
-
if (
|
|
4764
|
+
if (optional2) {
|
|
4557
4765
|
this.__index--;
|
|
4558
4766
|
}
|
|
4559
4767
|
this.__gobbleSpaces();
|
|
@@ -4564,7 +4772,7 @@ var Regor = (() => {
|
|
|
4564
4772
|
property: this.__gobbleIdentifier()
|
|
4565
4773
|
};
|
|
4566
4774
|
}
|
|
4567
|
-
if (
|
|
4775
|
+
if (optional2) {
|
|
4568
4776
|
node.optional = true;
|
|
4569
4777
|
}
|
|
4570
4778
|
this.__gobbleSpaces();
|