objectmodel 4.3.1 → 4.4.0
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/.eslintignore +8 -8
- package/.eslintrc.json +25 -25
- package/.travis.yml +2 -2
- package/LICENSE +22 -22
- package/README.md +67 -67
- package/build/add-banner.js +13 -13
- package/build/bundle-entry.dev.js +2 -2
- package/build/bundle-entry.js +11 -11
- package/dist/object-model.cjs +462 -469
- package/dist/object-model.js +462 -469
- package/dist/object-model.js.map +1 -1
- package/dist/object-model.min.js +2 -2
- package/dist/object-model.min.js.map +1 -1
- package/index.html +4 -4
- package/package.json +9 -3
- package/rollup.config.js +13 -13
- package/src/array-model.d.ts +16 -0
- package/src/array-model.js +68 -68
- package/src/devtool-formatter.js +198 -198
- package/src/function-model.d.ts +24 -0
- package/src/function-model.js +58 -65
- package/src/helpers.js +43 -43
- package/src/index.js +4 -4
- package/src/list-model.js +43 -43
- package/src/map-model.d.ts +18 -0
- package/src/map-model.js +48 -48
- package/src/object-model.d.ts +74 -0
- package/src/set-model.d.ts +16 -0
- package/src/set-model.js +41 -41
- package/test/array-model.spec.cjs +291 -291
- package/test/array-model.test-d.ts +24 -0
- package/test/basic-model.spec.cjs +263 -263
- package/test/basic-model.test-d.ts +30 -0
- package/test/bench/array.html +51 -51
- package/test/bench/bench-lib.js +49 -49
- package/test/bench/map-no-cast.html +53 -53
- package/test/bench/map-set.html +52 -52
- package/test/bench/map.html +51 -51
- package/test/bench/object-models.html +87 -87
- package/test/function-model.spec.cjs +161 -162
- package/test/function-model.test-d.ts +18 -0
- package/test/index.cjs +13 -13
- package/test/map-model.spec.cjs +224 -224
- package/test/map-model.test-d.ts +21 -0
- package/test/model.spec.cjs +30 -30
- package/test/object-model.spec.cjs +1345 -1346
- package/test/object-model.test-d.ts +53 -0
- package/test/set-model.spec.cjs +213 -213
- package/test/set-model.test-d.ts +17 -0
- package/test/umd.html +25 -25
- package/types/definitions.d.ts +43 -0
- package/types/helpers.d.ts +4 -0
- package/types/index.d.ts +6 -128
package/dist/object-model.cjs
CHANGED
|
@@ -1,48 +1,48 @@
|
|
|
1
|
-
// ObjectModel v4.
|
|
1
|
+
// ObjectModel v4.4.0 - http://objectmodel.js.org
|
|
2
2
|
// MIT License - Sylvain Pollet-Villard
|
|
3
|
-
const
|
|
4
|
-
ObjectProto = Object.prototype,
|
|
5
|
-
bettertypeof = x => ObjectProto.toString.call(x).match(/\s([a-zA-Z]+)/)[1],
|
|
6
|
-
getProto = Object.getPrototypeOf,
|
|
7
|
-
setProto = Object.setPrototypeOf,
|
|
8
|
-
|
|
9
|
-
has = (o, prop) => ObjectProto.hasOwnProperty.call(o, prop),
|
|
10
|
-
is = (Constructor, obj) => obj instanceof Constructor,
|
|
11
|
-
isFunction = f => typeof f === "function",
|
|
12
|
-
isObject = o => o && typeof o === "object",
|
|
13
|
-
isString = s => typeof s === "string",
|
|
14
|
-
isPlainObject = o => isObject(o) && getProto(o) === ObjectProto,
|
|
15
|
-
isIterable = x => x && isFunction(x[Symbol.iterator]),
|
|
16
|
-
|
|
17
|
-
proxify = (val, traps) => new Proxy(val, traps),
|
|
18
|
-
|
|
19
|
-
merge = (target, src = {}) => {
|
|
20
|
-
for (let key in src) {
|
|
21
|
-
if (isPlainObject(src[key])) {
|
|
22
|
-
const o = {};
|
|
23
|
-
merge(o, target[key]);
|
|
24
|
-
merge(o, src[key]);
|
|
25
|
-
target[key] = o;
|
|
26
|
-
} else {
|
|
27
|
-
target[key] = src[key];
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
return target
|
|
31
|
-
},
|
|
32
|
-
|
|
33
|
-
define = (obj, key, value, enumerable = false) => {
|
|
34
|
-
Object.defineProperty(obj, key, { value, enumerable, writable: true, configurable: true });
|
|
35
|
-
},
|
|
36
|
-
|
|
37
|
-
extend = (child, parent, props) => {
|
|
38
|
-
child.prototype = Object.assign(Object.create(parent.prototype, {
|
|
39
|
-
constructor: {
|
|
40
|
-
value: child,
|
|
41
|
-
writable: true,
|
|
42
|
-
configurable: true
|
|
43
|
-
}
|
|
44
|
-
}), props);
|
|
45
|
-
setProto(child, parent);
|
|
3
|
+
const
|
|
4
|
+
ObjectProto = Object.prototype,
|
|
5
|
+
bettertypeof = x => ObjectProto.toString.call(x).match(/\s([a-zA-Z]+)/)[1],
|
|
6
|
+
getProto = Object.getPrototypeOf,
|
|
7
|
+
setProto = Object.setPrototypeOf,
|
|
8
|
+
|
|
9
|
+
has = (o, prop) => ObjectProto.hasOwnProperty.call(o, prop),
|
|
10
|
+
is = (Constructor, obj) => obj instanceof Constructor,
|
|
11
|
+
isFunction = f => typeof f === "function",
|
|
12
|
+
isObject = o => o && typeof o === "object",
|
|
13
|
+
isString = s => typeof s === "string",
|
|
14
|
+
isPlainObject = o => isObject(o) && getProto(o) === ObjectProto,
|
|
15
|
+
isIterable = x => x && isFunction(x[Symbol.iterator]),
|
|
16
|
+
|
|
17
|
+
proxify = (val, traps) => new Proxy(val, traps),
|
|
18
|
+
|
|
19
|
+
merge = (target, src = {}) => {
|
|
20
|
+
for (let key in src) {
|
|
21
|
+
if (isPlainObject(src[key])) {
|
|
22
|
+
const o = {};
|
|
23
|
+
merge(o, target[key]);
|
|
24
|
+
merge(o, src[key]);
|
|
25
|
+
target[key] = o;
|
|
26
|
+
} else {
|
|
27
|
+
target[key] = src[key];
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return target
|
|
31
|
+
},
|
|
32
|
+
|
|
33
|
+
define = (obj, key, value, enumerable = false) => {
|
|
34
|
+
Object.defineProperty(obj, key, { value, enumerable, writable: true, configurable: true });
|
|
35
|
+
},
|
|
36
|
+
|
|
37
|
+
extend = (child, parent, props) => {
|
|
38
|
+
child.prototype = Object.assign(Object.create(parent.prototype, {
|
|
39
|
+
constructor: {
|
|
40
|
+
value: child,
|
|
41
|
+
writable: true,
|
|
42
|
+
configurable: true
|
|
43
|
+
}
|
|
44
|
+
}), props);
|
|
45
|
+
setProto(child, parent);
|
|
46
46
|
};
|
|
47
47
|
|
|
48
48
|
const
|
|
@@ -520,441 +520,434 @@ extend(Any.remaining, Any, {
|
|
|
520
520
|
});
|
|
521
521
|
Any[Symbol.iterator] = function* () { yield new Any.remaining(this.definition); };
|
|
522
522
|
|
|
523
|
-
const initListModel = (base, constructor, def, init, clone, mutators, otherTraps) => {
|
|
524
|
-
|
|
525
|
-
return initModel(def, constructor, base, init, model => Object.assign({
|
|
526
|
-
getPrototypeOf: () => model.prototype,
|
|
527
|
-
get(l, key) {
|
|
528
|
-
if (key === _original) return l
|
|
529
|
-
|
|
530
|
-
const val = l[key];
|
|
531
|
-
return isFunction(val) ? proxify(val, {
|
|
532
|
-
apply(fn, ctx, args) {
|
|
533
|
-
if (has(mutators, key)) {
|
|
534
|
-
// indexes of arguments to check def + cast
|
|
535
|
-
const [begin, end = args.length - 1, getArgDef] = mutators[key];
|
|
536
|
-
for (let i = begin; i <= end; i++) {
|
|
537
|
-
const argDef = getArgDef ? getArgDef(i) : model.definition;
|
|
538
|
-
args[i] = checkDefinition(
|
|
539
|
-
args[i],
|
|
540
|
-
argDef,
|
|
541
|
-
`${base.name}.${key} arguments[${i}]`,
|
|
542
|
-
model.errors,
|
|
543
|
-
[],
|
|
544
|
-
true
|
|
545
|
-
);
|
|
546
|
-
}
|
|
547
|
-
|
|
548
|
-
if (model.assertions.length > 0) {
|
|
549
|
-
const testingClone = clone(l);
|
|
550
|
-
fn.apply(testingClone, args);
|
|
551
|
-
checkAssertions(testingClone, model, `after ${key} mutation`);
|
|
552
|
-
}
|
|
553
|
-
|
|
554
|
-
unstackErrors(model);
|
|
555
|
-
}
|
|
556
|
-
|
|
557
|
-
return fn.apply(l, args)
|
|
558
|
-
}
|
|
559
|
-
}) : val
|
|
560
|
-
}
|
|
561
|
-
}, otherTraps))
|
|
523
|
+
const initListModel = (base, constructor, def, init, clone, mutators, otherTraps) => {
|
|
524
|
+
|
|
525
|
+
return initModel(def, constructor, base, init, model => Object.assign({
|
|
526
|
+
getPrototypeOf: () => model.prototype,
|
|
527
|
+
get(l, key) {
|
|
528
|
+
if (key === _original) return l
|
|
529
|
+
|
|
530
|
+
const val = l[key];
|
|
531
|
+
return isFunction(val) ? proxify(val, {
|
|
532
|
+
apply(fn, ctx, args) {
|
|
533
|
+
if (has(mutators, key)) {
|
|
534
|
+
// indexes of arguments to check def + cast
|
|
535
|
+
const [begin, end = args.length - 1, getArgDef] = mutators[key];
|
|
536
|
+
for (let i = begin; i <= end; i++) {
|
|
537
|
+
const argDef = getArgDef ? getArgDef(i) : model.definition;
|
|
538
|
+
args[i] = checkDefinition(
|
|
539
|
+
args[i],
|
|
540
|
+
argDef,
|
|
541
|
+
`${base.name}.${key} arguments[${i}]`,
|
|
542
|
+
model.errors,
|
|
543
|
+
[],
|
|
544
|
+
true
|
|
545
|
+
);
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
if (model.assertions.length > 0) {
|
|
549
|
+
const testingClone = clone(l);
|
|
550
|
+
fn.apply(testingClone, args);
|
|
551
|
+
checkAssertions(testingClone, model, `after ${key} mutation`);
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
unstackErrors(model);
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
return fn.apply(l, args)
|
|
558
|
+
}
|
|
559
|
+
}) : val
|
|
560
|
+
}
|
|
561
|
+
}, otherTraps))
|
|
562
562
|
};
|
|
563
563
|
|
|
564
|
-
function ArrayModel(initialDefinition) {
|
|
565
|
-
const model = initListModel(
|
|
566
|
-
Array,
|
|
567
|
-
ArrayModel,
|
|
568
|
-
initialDefinition,
|
|
569
|
-
a => Array.isArray(a) ? a.map(arg => cast(arg, model.definition)) : a,
|
|
570
|
-
a => [...a],
|
|
571
|
-
{
|
|
572
|
-
"copyWithin": [],
|
|
573
|
-
"fill": [0, 0],
|
|
574
|
-
"pop": [],
|
|
575
|
-
"push": [0],
|
|
576
|
-
"reverse": [],
|
|
577
|
-
"shift": [],
|
|
578
|
-
"sort": [],
|
|
579
|
-
"splice": [2],
|
|
580
|
-
"unshift": [0]
|
|
581
|
-
},
|
|
582
|
-
{
|
|
583
|
-
set(arr, key, val) {
|
|
584
|
-
return controlMutation(model, arr, key, val, (a, v) => a[key] = v, true)
|
|
585
|
-
},
|
|
586
|
-
|
|
587
|
-
deleteProperty(arr, key) {
|
|
588
|
-
return controlMutation(model, arr, key, undefined, a => delete a[key])
|
|
589
|
-
}
|
|
590
|
-
}
|
|
591
|
-
);
|
|
592
|
-
|
|
593
|
-
return model
|
|
594
|
-
}
|
|
595
|
-
|
|
596
|
-
extend(ArrayModel, Model, {
|
|
597
|
-
toString(stack) {
|
|
598
|
-
return "Array of " + formatDefinition(this.definition, stack)
|
|
599
|
-
},
|
|
600
|
-
|
|
601
|
-
[_check](arr, path, errors, stack) {
|
|
602
|
-
if (Array.isArray(arr))
|
|
603
|
-
(arr[_original] || arr).forEach((a, i) => checkDefinition(a, this.definition, `${path || "Array"}[${i}]`, errors, stack));
|
|
604
|
-
else stackError(errors, this, arr, path);
|
|
605
|
-
|
|
606
|
-
checkAssertions(arr, this, path, errors);
|
|
607
|
-
},
|
|
608
|
-
|
|
609
|
-
extend(...newParts) {
|
|
610
|
-
return extendModel(new ArrayModel(extendDefinition(this.definition, newParts)), this)
|
|
611
|
-
}
|
|
612
|
-
});
|
|
613
|
-
|
|
614
|
-
const controlMutation = (model, array, key, value, applyMutation, canBeExtended) => {
|
|
615
|
-
const path = `Array[${key}]`;
|
|
616
|
-
const isInDef = (+key >= 0 && (canBeExtended || key in array));
|
|
617
|
-
if (isInDef) value = checkDefinition(value, model.definition, path, model.errors, [], true);
|
|
618
|
-
|
|
619
|
-
const testArray = [...array];
|
|
620
|
-
applyMutation(testArray);
|
|
621
|
-
checkAssertions(testArray, model, path);
|
|
622
|
-
const isSuccess = !unstackErrors(model);
|
|
623
|
-
if (isSuccess) applyMutation(array, value);
|
|
624
|
-
return isSuccess
|
|
564
|
+
function ArrayModel(initialDefinition) {
|
|
565
|
+
const model = initListModel(
|
|
566
|
+
Array,
|
|
567
|
+
ArrayModel,
|
|
568
|
+
initialDefinition,
|
|
569
|
+
a => Array.isArray(a) ? a.map(arg => cast(arg, model.definition)) : a,
|
|
570
|
+
a => [...a],
|
|
571
|
+
{
|
|
572
|
+
"copyWithin": [],
|
|
573
|
+
"fill": [0, 0],
|
|
574
|
+
"pop": [],
|
|
575
|
+
"push": [0],
|
|
576
|
+
"reverse": [],
|
|
577
|
+
"shift": [],
|
|
578
|
+
"sort": [],
|
|
579
|
+
"splice": [2],
|
|
580
|
+
"unshift": [0]
|
|
581
|
+
},
|
|
582
|
+
{
|
|
583
|
+
set(arr, key, val) {
|
|
584
|
+
return controlMutation(model, arr, key, val, (a, v) => a[key] = v, true)
|
|
585
|
+
},
|
|
586
|
+
|
|
587
|
+
deleteProperty(arr, key) {
|
|
588
|
+
return controlMutation(model, arr, key, undefined, a => delete a[key])
|
|
589
|
+
}
|
|
590
|
+
}
|
|
591
|
+
);
|
|
592
|
+
|
|
593
|
+
return model
|
|
594
|
+
}
|
|
595
|
+
|
|
596
|
+
extend(ArrayModel, Model, {
|
|
597
|
+
toString(stack) {
|
|
598
|
+
return "Array of " + formatDefinition(this.definition, stack)
|
|
599
|
+
},
|
|
600
|
+
|
|
601
|
+
[_check](arr, path, errors, stack) {
|
|
602
|
+
if (Array.isArray(arr))
|
|
603
|
+
(arr[_original] || arr).forEach((a, i) => checkDefinition(a, this.definition, `${path || "Array"}[${i}]`, errors, stack));
|
|
604
|
+
else stackError(errors, this, arr, path);
|
|
605
|
+
|
|
606
|
+
checkAssertions(arr, this, path, errors);
|
|
607
|
+
},
|
|
608
|
+
|
|
609
|
+
extend(...newParts) {
|
|
610
|
+
return extendModel(new ArrayModel(extendDefinition(this.definition, newParts)), this)
|
|
611
|
+
}
|
|
612
|
+
});
|
|
613
|
+
|
|
614
|
+
const controlMutation = (model, array, key, value, applyMutation, canBeExtended) => {
|
|
615
|
+
const path = `Array[${key}]`;
|
|
616
|
+
const isInDef = (+key >= 0 && (canBeExtended || key in array));
|
|
617
|
+
if (isInDef) value = checkDefinition(value, model.definition, path, model.errors, [], true);
|
|
618
|
+
|
|
619
|
+
const testArray = [...array];
|
|
620
|
+
applyMutation(testArray);
|
|
621
|
+
checkAssertions(testArray, model, path);
|
|
622
|
+
const isSuccess = !unstackErrors(model);
|
|
623
|
+
if (isSuccess) applyMutation(array, value);
|
|
624
|
+
return isSuccess
|
|
625
625
|
};
|
|
626
626
|
|
|
627
|
-
function SetModel(initialDefinition) {
|
|
628
|
-
const model = initListModel(
|
|
629
|
-
Set,
|
|
630
|
-
SetModel,
|
|
631
|
-
initialDefinition,
|
|
632
|
-
it => isIterable(it) ? new Set([...it].map(val => cast(val, model.definition))) : it,
|
|
633
|
-
set => new Set(set),
|
|
634
|
-
{
|
|
635
|
-
"add": [0, 0],
|
|
636
|
-
"delete": [],
|
|
637
|
-
"clear": []
|
|
638
|
-
}
|
|
639
|
-
);
|
|
640
|
-
|
|
641
|
-
return model
|
|
642
|
-
}
|
|
643
|
-
|
|
644
|
-
extend(SetModel, Model, {
|
|
645
|
-
toString(stack) {
|
|
646
|
-
return "Set of " + formatDefinition(this.definition, stack)
|
|
647
|
-
},
|
|
648
|
-
|
|
649
|
-
[_check](set, path, errors, stack) {
|
|
650
|
-
if (is(Set, set)) {
|
|
651
|
-
for (let item of set.values()) {
|
|
652
|
-
checkDefinition(item, this.definition, `${path || "Set"} value`, errors, stack);
|
|
653
|
-
}
|
|
654
|
-
} else stackError(errors, this, set, path);
|
|
655
|
-
checkAssertions(set, this, path, errors);
|
|
656
|
-
},
|
|
657
|
-
|
|
658
|
-
extend(...newParts) {
|
|
659
|
-
return extendModel(new SetModel(extendDefinition(this.definition, newParts)), this)
|
|
660
|
-
}
|
|
627
|
+
function SetModel(initialDefinition) {
|
|
628
|
+
const model = initListModel(
|
|
629
|
+
Set,
|
|
630
|
+
SetModel,
|
|
631
|
+
initialDefinition,
|
|
632
|
+
it => isIterable(it) ? new Set([...it].map(val => cast(val, model.definition))) : it,
|
|
633
|
+
set => new Set(set),
|
|
634
|
+
{
|
|
635
|
+
"add": [0, 0],
|
|
636
|
+
"delete": [],
|
|
637
|
+
"clear": []
|
|
638
|
+
}
|
|
639
|
+
);
|
|
640
|
+
|
|
641
|
+
return model
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
extend(SetModel, Model, {
|
|
645
|
+
toString(stack) {
|
|
646
|
+
return "Set of " + formatDefinition(this.definition, stack)
|
|
647
|
+
},
|
|
648
|
+
|
|
649
|
+
[_check](set, path, errors, stack) {
|
|
650
|
+
if (is(Set, set)) {
|
|
651
|
+
for (let item of set.values()) {
|
|
652
|
+
checkDefinition(item, this.definition, `${path || "Set"} value`, errors, stack);
|
|
653
|
+
}
|
|
654
|
+
} else stackError(errors, this, set, path);
|
|
655
|
+
checkAssertions(set, this, path, errors);
|
|
656
|
+
},
|
|
657
|
+
|
|
658
|
+
extend(...newParts) {
|
|
659
|
+
return extendModel(new SetModel(extendDefinition(this.definition, newParts)), this)
|
|
660
|
+
}
|
|
661
661
|
});
|
|
662
662
|
|
|
663
|
-
function MapModel(initialKeyDefinition, initialValueDefinition) {
|
|
664
|
-
const getDef = i => i === 0 ? model.definition.key : model.definition.value;
|
|
665
|
-
const model = initListModel(
|
|
666
|
-
Map,
|
|
667
|
-
MapModel,
|
|
668
|
-
{ key: initialKeyDefinition, value: initialValueDefinition },
|
|
669
|
-
it => isIterable(it) ? new Map([...it].map(pair => pair.map((x, i) => cast(x, getDef(i))))) : it,
|
|
670
|
-
map => new Map(map),
|
|
671
|
-
{
|
|
672
|
-
"set": [0, 1, getDef],
|
|
673
|
-
"delete": [],
|
|
674
|
-
"clear": []
|
|
675
|
-
}
|
|
676
|
-
);
|
|
677
|
-
|
|
678
|
-
return model
|
|
679
|
-
}
|
|
680
|
-
|
|
681
|
-
extend(MapModel, Model, {
|
|
682
|
-
toString(stack) {
|
|
683
|
-
return `Map of ${formatDefinition(this.definition.key, stack)} : ${formatDefinition(this.definition.value, stack)}`
|
|
684
|
-
},
|
|
685
|
-
|
|
686
|
-
[_check](map, path, errors, stack) {
|
|
687
|
-
if (is(Map, map)) {
|
|
688
|
-
path = path || "Map";
|
|
689
|
-
for (let [key, value] of map) {
|
|
690
|
-
checkDefinition(key, this.definition.key, `${path} key`, errors, stack);
|
|
691
|
-
checkDefinition(value, this.definition.value, `${path}[${format$1(key)}]`, errors, stack);
|
|
692
|
-
}
|
|
693
|
-
} else stackError(errors, this, map, path);
|
|
694
|
-
|
|
695
|
-
checkAssertions(map, this, path, errors);
|
|
696
|
-
},
|
|
697
|
-
|
|
698
|
-
extend(keyParts, valueParts) {
|
|
699
|
-
return extendModel(new MapModel(
|
|
700
|
-
extendDefinition(this.definition.key, keyParts),
|
|
701
|
-
extendDefinition(this.definition.value, valueParts)
|
|
702
|
-
), this)
|
|
703
|
-
}
|
|
663
|
+
function MapModel(initialKeyDefinition, initialValueDefinition) {
|
|
664
|
+
const getDef = i => i === 0 ? model.definition.key : model.definition.value;
|
|
665
|
+
const model = initListModel(
|
|
666
|
+
Map,
|
|
667
|
+
MapModel,
|
|
668
|
+
{ key: initialKeyDefinition, value: initialValueDefinition },
|
|
669
|
+
it => isIterable(it) ? new Map([...it].map(pair => pair.map((x, i) => cast(x, getDef(i))))) : it,
|
|
670
|
+
map => new Map(map),
|
|
671
|
+
{
|
|
672
|
+
"set": [0, 1, getDef],
|
|
673
|
+
"delete": [],
|
|
674
|
+
"clear": []
|
|
675
|
+
}
|
|
676
|
+
);
|
|
677
|
+
|
|
678
|
+
return model
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
extend(MapModel, Model, {
|
|
682
|
+
toString(stack) {
|
|
683
|
+
return `Map of ${formatDefinition(this.definition.key, stack)} : ${formatDefinition(this.definition.value, stack)}`
|
|
684
|
+
},
|
|
685
|
+
|
|
686
|
+
[_check](map, path, errors, stack) {
|
|
687
|
+
if (is(Map, map)) {
|
|
688
|
+
path = path || "Map";
|
|
689
|
+
for (let [key, value] of map) {
|
|
690
|
+
checkDefinition(key, this.definition.key, `${path} key`, errors, stack);
|
|
691
|
+
checkDefinition(value, this.definition.value, `${path}[${format$1(key)}]`, errors, stack);
|
|
692
|
+
}
|
|
693
|
+
} else stackError(errors, this, map, path);
|
|
694
|
+
|
|
695
|
+
checkAssertions(map, this, path, errors);
|
|
696
|
+
},
|
|
697
|
+
|
|
698
|
+
extend(keyParts, valueParts) {
|
|
699
|
+
return extendModel(new MapModel(
|
|
700
|
+
extendDefinition(this.definition.key, keyParts),
|
|
701
|
+
extendDefinition(this.definition.value, valueParts)
|
|
702
|
+
), this)
|
|
703
|
+
}
|
|
704
704
|
});
|
|
705
705
|
|
|
706
|
-
function FunctionModel(...argsDef) {
|
|
707
|
-
return initModel({ arguments: argsDef }, FunctionModel, Function, null, model => ({
|
|
708
|
-
getPrototypeOf: () => model.prototype,
|
|
709
|
-
|
|
710
|
-
get(fn, key) {
|
|
711
|
-
return key === _original ? fn : fn[key]
|
|
712
|
-
},
|
|
713
|
-
|
|
714
|
-
apply(fn, ctx, args) {
|
|
715
|
-
const def = model.definition;
|
|
716
|
-
const remainingArgDef = def.arguments.find(argDef => is(Any.remaining, argDef));
|
|
717
|
-
const nbArgsToCheck = remainingArgDef ? Math.max(args.length, def.arguments.length - 1) : def.arguments.length;
|
|
718
|
-
|
|
719
|
-
for (let i = 0; i < nbArgsToCheck; i++) {
|
|
720
|
-
const argDef = remainingArgDef && i >= def.arguments.length - 1 ? remainingArgDef.definition : def.arguments[i];
|
|
721
|
-
args[i] = checkDefinition(args[i], argDef, `arguments[${i}]`, model.errors, [], true);
|
|
722
|
-
}
|
|
723
|
-
|
|
724
|
-
checkAssertions(args, model, "arguments");
|
|
725
|
-
|
|
726
|
-
let result;
|
|
727
|
-
if (!model.errors.length) {
|
|
728
|
-
result = Reflect.apply(fn, ctx, args);
|
|
729
|
-
if ("return" in def)
|
|
730
|
-
result = checkDefinition(result, def.return, "return value", model.errors, [], true);
|
|
731
|
-
}
|
|
732
|
-
unstackErrors(model);
|
|
733
|
-
return result
|
|
734
|
-
}
|
|
735
|
-
}))
|
|
736
|
-
}
|
|
737
|
-
|
|
738
|
-
extend(FunctionModel, Model, {
|
|
739
|
-
toString(stack = []) {
|
|
740
|
-
let out = `Function(${this.definition.arguments.map(
|
|
741
|
-
argDef => formatDefinition(argDef, [...stack])
|
|
742
|
-
).join(", ")})`;
|
|
743
|
-
|
|
744
|
-
if ("return" in this.definition) {
|
|
745
|
-
out += " => " + formatDefinition(this.definition.return, stack);
|
|
746
|
-
}
|
|
747
|
-
return out
|
|
748
|
-
},
|
|
749
|
-
|
|
750
|
-
return(def) {
|
|
751
|
-
this.definition.return = def;
|
|
752
|
-
return this
|
|
753
|
-
},
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
mixedReturns = extendDefinition(this.definition.return, newReturns);
|
|
759
|
-
return extendModel(new FunctionModel(...mixedArgs).return(mixedReturns), this)
|
|
760
|
-
},
|
|
761
|
-
|
|
762
|
-
[_check](f, path, errors) {
|
|
763
|
-
if (!isFunction(f)) stackError(errors, "Function", f, path);
|
|
764
|
-
}
|
|
706
|
+
function FunctionModel(...argsDef) {
|
|
707
|
+
return initModel({ arguments: argsDef }, FunctionModel, Function, null, model => ({
|
|
708
|
+
getPrototypeOf: () => model.prototype,
|
|
709
|
+
|
|
710
|
+
get(fn, key) {
|
|
711
|
+
return key === _original ? fn : fn[key]
|
|
712
|
+
},
|
|
713
|
+
|
|
714
|
+
apply(fn, ctx, args) {
|
|
715
|
+
const def = model.definition;
|
|
716
|
+
const remainingArgDef = def.arguments.find(argDef => is(Any.remaining, argDef));
|
|
717
|
+
const nbArgsToCheck = remainingArgDef ? Math.max(args.length, def.arguments.length - 1) : def.arguments.length;
|
|
718
|
+
|
|
719
|
+
for (let i = 0; i < nbArgsToCheck; i++) {
|
|
720
|
+
const argDef = remainingArgDef && i >= def.arguments.length - 1 ? remainingArgDef.definition : def.arguments[i];
|
|
721
|
+
args[i] = checkDefinition(args[i], argDef, `arguments[${i}]`, model.errors, [], true);
|
|
722
|
+
}
|
|
723
|
+
|
|
724
|
+
checkAssertions(args, model, "arguments");
|
|
725
|
+
|
|
726
|
+
let result;
|
|
727
|
+
if (!model.errors.length) {
|
|
728
|
+
result = Reflect.apply(fn, ctx, args);
|
|
729
|
+
if ("return" in def)
|
|
730
|
+
result = checkDefinition(result, def.return, "return value", model.errors, [], true);
|
|
731
|
+
}
|
|
732
|
+
unstackErrors(model);
|
|
733
|
+
return result
|
|
734
|
+
}
|
|
735
|
+
}))
|
|
736
|
+
}
|
|
737
|
+
|
|
738
|
+
extend(FunctionModel, Model, {
|
|
739
|
+
toString(stack = []) {
|
|
740
|
+
let out = `Function(${this.definition.arguments.map(
|
|
741
|
+
argDef => formatDefinition(argDef, [...stack])
|
|
742
|
+
).join(", ")})`;
|
|
743
|
+
|
|
744
|
+
if ("return" in this.definition) {
|
|
745
|
+
out += " => " + formatDefinition(this.definition.return, stack);
|
|
746
|
+
}
|
|
747
|
+
return out
|
|
748
|
+
},
|
|
749
|
+
|
|
750
|
+
return(def) {
|
|
751
|
+
this.definition.return = def;
|
|
752
|
+
return this
|
|
753
|
+
},
|
|
754
|
+
|
|
755
|
+
[_check](f, path, errors) {
|
|
756
|
+
if (!isFunction(f)) stackError(errors, "Function", f, path);
|
|
757
|
+
}
|
|
765
758
|
});
|
|
766
759
|
|
|
767
|
-
const styles = {
|
|
768
|
-
list: "list-style-type: none; padding: 0; margin: 0;",
|
|
769
|
-
listItem: "padding: 0 0 0 1em;",
|
|
770
|
-
model: "color: #3e999f;",
|
|
771
|
-
instance: "color: #718c00; font-style: italic",
|
|
772
|
-
function: "color: #4271AE",
|
|
773
|
-
string: "color: #C41A16",
|
|
774
|
-
number: "color: #1C00CF",
|
|
775
|
-
boolean: "color: #AA0D91",
|
|
776
|
-
property: "color: #8959a8",
|
|
777
|
-
private: "color: #C19ED8",
|
|
778
|
-
constant: "color: #8959a8; font-weight: bold",
|
|
779
|
-
privateConstant: "color: #C19ED8; font-weight: bold",
|
|
780
|
-
null: "color: #8e908c",
|
|
781
|
-
undeclared: "color: #C0C0C0;",
|
|
782
|
-
proto: "color: #B871BD; font-style: italic"
|
|
783
|
-
};
|
|
784
|
-
|
|
785
|
-
const getModel = (instance) => {
|
|
786
|
-
if (instance === undefined || instance === null)
|
|
787
|
-
return null
|
|
788
|
-
|
|
789
|
-
const proto = getProto(instance);
|
|
790
|
-
if (!proto || !proto.constructor || !is(Model, proto.constructor))
|
|
791
|
-
return null
|
|
792
|
-
|
|
793
|
-
return proto.constructor
|
|
794
|
-
};
|
|
795
|
-
|
|
796
|
-
const span = (style, ...children) => ["span", { style }, ...children];
|
|
797
|
-
|
|
798
|
-
const format = (x, config = {}) => {
|
|
799
|
-
if (x === null || x === undefined)
|
|
800
|
-
return span(styles.null, "" + x);
|
|
801
|
-
|
|
802
|
-
if (typeof x === "boolean")
|
|
803
|
-
return span(styles.boolean, x);
|
|
804
|
-
|
|
805
|
-
if (typeof x === "number")
|
|
806
|
-
return span(styles.number, x);
|
|
807
|
-
|
|
808
|
-
if (typeof x === "string")
|
|
809
|
-
return span(styles.string, `"${x}"`);
|
|
810
|
-
|
|
811
|
-
if (Array.isArray(x) && config.isModelDefinition) {
|
|
812
|
-
return span("", ...x.flatMap(part => [format(part, config), " or "]).slice(0, -1))
|
|
813
|
-
}
|
|
814
|
-
|
|
815
|
-
if (isPlainObject(x))
|
|
816
|
-
return formatObject(x, getModel(x), config)
|
|
817
|
-
|
|
818
|
-
if (isFunction(x) && !is(Model, x) && config.isModelDefinition)
|
|
819
|
-
return span(styles.function, x.name || x.toString());
|
|
820
|
-
|
|
821
|
-
return ["object", { object: x, config }]
|
|
822
|
-
};
|
|
823
|
-
|
|
824
|
-
const formatObject = (o, model, config) => span("",
|
|
825
|
-
"{",
|
|
826
|
-
["ol", { style: styles.list }, ...Object.keys(o).map(prop =>
|
|
827
|
-
["li", { style: styles.listItem }, span(styles.property, prop), ": ", format(o[prop], config)])
|
|
828
|
-
],
|
|
829
|
-
"}"
|
|
830
|
-
);
|
|
831
|
-
|
|
832
|
-
const formatModel = model => {
|
|
833
|
-
const
|
|
834
|
-
cfg = { isModelDefinition: true },
|
|
835
|
-
def = model.definition,
|
|
836
|
-
formatList = (list, map) => list.flatMap(e => [map(e), ", "]).slice(0, -1);
|
|
837
|
-
let parts = [];
|
|
838
|
-
|
|
839
|
-
if (is(BasicModel, model)) parts = [format(def, cfg)];
|
|
840
|
-
if (is(ArrayModel, model)) parts = ["Array of ", format(def, cfg)];
|
|
841
|
-
if (is(SetModel, model)) parts = ["Set of ", format(def, cfg)];
|
|
842
|
-
if (is(MapModel, model)) parts = ["Map of ", format(def.key, cfg), " : ", format(def.value, cfg)];
|
|
843
|
-
if (is(FunctionModel, model)) {
|
|
844
|
-
parts = ["Function(", ...formatList(def.arguments, arg => format(arg, cfg)), ")"];
|
|
845
|
-
if ("return" in def) parts.push(" => ", format(def.return, cfg));
|
|
846
|
-
}
|
|
847
|
-
|
|
848
|
-
if (model.assertions.length > 0) {
|
|
849
|
-
parts.push("\n(assertions: ", ...formatList(model.assertions, f => ["object", { object: f }]), ")");
|
|
850
|
-
}
|
|
851
|
-
|
|
852
|
-
return span(styles.model, ...parts)
|
|
853
|
-
};
|
|
854
|
-
|
|
855
|
-
const ModelFormatter = {
|
|
856
|
-
header(x, config = {}) {
|
|
857
|
-
if (x === Any)
|
|
858
|
-
return span(styles.model, "Any")
|
|
859
|
-
|
|
860
|
-
if (is(Any.remaining, x))
|
|
861
|
-
return span(styles.model, "...", format(x.definition, { isModelDefinition: true }))
|
|
862
|
-
|
|
863
|
-
if (is(ObjectModel, x))
|
|
864
|
-
return span(styles.model, x.name)
|
|
865
|
-
|
|
866
|
-
if (is(Model, x)) {
|
|
867
|
-
return formatModel(x)
|
|
868
|
-
}
|
|
869
|
-
|
|
870
|
-
if (config.isModelDefinition && isPlainObject(x))
|
|
871
|
-
return format(x, config)
|
|
872
|
-
|
|
873
|
-
return null;
|
|
874
|
-
},
|
|
875
|
-
hasBody(x) {
|
|
876
|
-
return is(ObjectModel, x)
|
|
877
|
-
},
|
|
878
|
-
body(model) {
|
|
879
|
-
return span("",
|
|
880
|
-
"{",
|
|
881
|
-
["ol", { style: styles.list }, ...Object.keys(model.definition).map(prop => {
|
|
882
|
-
const isPrivate = model.conventionForPrivate(prop);
|
|
883
|
-
const isConstant = model.conventionForConstant(prop);
|
|
884
|
-
const hasDefault = model.default && has(model.default, prop);
|
|
885
|
-
let style = styles.property;
|
|
886
|
-
|
|
887
|
-
if (isPrivate) {
|
|
888
|
-
style = isConstant ? styles.privateConstant : styles.private;
|
|
889
|
-
} else if (isConstant) {
|
|
890
|
-
style = styles.constant;
|
|
891
|
-
}
|
|
892
|
-
|
|
893
|
-
return ["li", { style: styles.listItem },
|
|
894
|
-
span(style, prop), ": ", format(model.definition[prop], { isModelDefinition: true }),
|
|
895
|
-
hasDefault ? span(styles.proto, " = ", format(model.default[prop])) : ""
|
|
896
|
-
]
|
|
897
|
-
})],
|
|
898
|
-
"}"
|
|
899
|
-
)
|
|
900
|
-
}
|
|
901
|
-
};
|
|
902
|
-
|
|
903
|
-
const ModelInstanceFormatter = {
|
|
904
|
-
header(x, config = {}) {
|
|
905
|
-
if (config.isInstanceProperty && isPlainObject(x)) {
|
|
906
|
-
return format(x, config)
|
|
907
|
-
}
|
|
908
|
-
|
|
909
|
-
const model = getModel(x);
|
|
910
|
-
if (is(Model, model)) {
|
|
911
|
-
const parts = is(ObjectModel, model) ? [model.name] : [["object", { object: x[_original] }], ` (${model.name})`];
|
|
912
|
-
return span(styles.instance, ...parts)
|
|
913
|
-
}
|
|
914
|
-
|
|
915
|
-
return null;
|
|
916
|
-
},
|
|
917
|
-
hasBody(x) {
|
|
918
|
-
return x && is(ObjectModel, getModel(x))
|
|
919
|
-
},
|
|
920
|
-
body(x) {
|
|
921
|
-
const model = getModel(x);
|
|
922
|
-
const o = x[_original] || x;
|
|
923
|
-
return span("",
|
|
924
|
-
"{",
|
|
925
|
-
[
|
|
926
|
-
"ol",
|
|
927
|
-
{ style: styles.list },
|
|
928
|
-
...Object.keys(o).map(prop => {
|
|
929
|
-
const isPrivate = model.conventionForPrivate(prop);
|
|
930
|
-
const isConstant = model.conventionForConstant(prop);
|
|
931
|
-
const isDeclared = prop in model.definition;
|
|
932
|
-
let style = styles.property;
|
|
933
|
-
|
|
934
|
-
if (!isDeclared) {
|
|
935
|
-
style = styles.undeclared;
|
|
936
|
-
} else if (isPrivate) {
|
|
937
|
-
style = isConstant ? styles.privateConstant : styles.private;
|
|
938
|
-
} else if (isConstant) {
|
|
939
|
-
style = styles.constant;
|
|
940
|
-
}
|
|
941
|
-
|
|
942
|
-
return ["li", { style: styles.listItem },
|
|
943
|
-
span(style, prop), ": ", format(o[prop], { isInstanceProperty: true })
|
|
944
|
-
]
|
|
945
|
-
}),
|
|
946
|
-
["li", { style: styles.listItem },
|
|
947
|
-
span(styles.proto, "__proto__", ": ", ["object", { object: getProto(x) }])
|
|
948
|
-
]
|
|
949
|
-
],
|
|
950
|
-
"}"
|
|
951
|
-
)
|
|
952
|
-
}
|
|
953
|
-
};
|
|
954
|
-
|
|
955
|
-
if (typeof window !== "undefined") {
|
|
956
|
-
window.devtoolsFormatters = (window.devtoolsFormatters || [])
|
|
957
|
-
.concat(ModelFormatter, ModelInstanceFormatter);
|
|
760
|
+
const styles = {
|
|
761
|
+
list: "list-style-type: none; padding: 0; margin: 0;",
|
|
762
|
+
listItem: "padding: 0 0 0 1em;",
|
|
763
|
+
model: "color: #3e999f;",
|
|
764
|
+
instance: "color: #718c00; font-style: italic",
|
|
765
|
+
function: "color: #4271AE",
|
|
766
|
+
string: "color: #C41A16",
|
|
767
|
+
number: "color: #1C00CF",
|
|
768
|
+
boolean: "color: #AA0D91",
|
|
769
|
+
property: "color: #8959a8",
|
|
770
|
+
private: "color: #C19ED8",
|
|
771
|
+
constant: "color: #8959a8; font-weight: bold",
|
|
772
|
+
privateConstant: "color: #C19ED8; font-weight: bold",
|
|
773
|
+
null: "color: #8e908c",
|
|
774
|
+
undeclared: "color: #C0C0C0;",
|
|
775
|
+
proto: "color: #B871BD; font-style: italic"
|
|
776
|
+
};
|
|
777
|
+
|
|
778
|
+
const getModel = (instance) => {
|
|
779
|
+
if (instance === undefined || instance === null)
|
|
780
|
+
return null
|
|
781
|
+
|
|
782
|
+
const proto = getProto(instance);
|
|
783
|
+
if (!proto || !proto.constructor || !is(Model, proto.constructor))
|
|
784
|
+
return null
|
|
785
|
+
|
|
786
|
+
return proto.constructor
|
|
787
|
+
};
|
|
788
|
+
|
|
789
|
+
const span = (style, ...children) => ["span", { style }, ...children];
|
|
790
|
+
|
|
791
|
+
const format = (x, config = {}) => {
|
|
792
|
+
if (x === null || x === undefined)
|
|
793
|
+
return span(styles.null, "" + x);
|
|
794
|
+
|
|
795
|
+
if (typeof x === "boolean")
|
|
796
|
+
return span(styles.boolean, x);
|
|
797
|
+
|
|
798
|
+
if (typeof x === "number")
|
|
799
|
+
return span(styles.number, x);
|
|
800
|
+
|
|
801
|
+
if (typeof x === "string")
|
|
802
|
+
return span(styles.string, `"${x}"`);
|
|
803
|
+
|
|
804
|
+
if (Array.isArray(x) && config.isModelDefinition) {
|
|
805
|
+
return span("", ...x.flatMap(part => [format(part, config), " or "]).slice(0, -1))
|
|
806
|
+
}
|
|
807
|
+
|
|
808
|
+
if (isPlainObject(x))
|
|
809
|
+
return formatObject(x, getModel(x), config)
|
|
810
|
+
|
|
811
|
+
if (isFunction(x) && !is(Model, x) && config.isModelDefinition)
|
|
812
|
+
return span(styles.function, x.name || x.toString());
|
|
813
|
+
|
|
814
|
+
return ["object", { object: x, config }]
|
|
815
|
+
};
|
|
816
|
+
|
|
817
|
+
const formatObject = (o, model, config) => span("",
|
|
818
|
+
"{",
|
|
819
|
+
["ol", { style: styles.list }, ...Object.keys(o).map(prop =>
|
|
820
|
+
["li", { style: styles.listItem }, span(styles.property, prop), ": ", format(o[prop], config)])
|
|
821
|
+
],
|
|
822
|
+
"}"
|
|
823
|
+
);
|
|
824
|
+
|
|
825
|
+
const formatModel = model => {
|
|
826
|
+
const
|
|
827
|
+
cfg = { isModelDefinition: true },
|
|
828
|
+
def = model.definition,
|
|
829
|
+
formatList = (list, map) => list.flatMap(e => [map(e), ", "]).slice(0, -1);
|
|
830
|
+
let parts = [];
|
|
831
|
+
|
|
832
|
+
if (is(BasicModel, model)) parts = [format(def, cfg)];
|
|
833
|
+
if (is(ArrayModel, model)) parts = ["Array of ", format(def, cfg)];
|
|
834
|
+
if (is(SetModel, model)) parts = ["Set of ", format(def, cfg)];
|
|
835
|
+
if (is(MapModel, model)) parts = ["Map of ", format(def.key, cfg), " : ", format(def.value, cfg)];
|
|
836
|
+
if (is(FunctionModel, model)) {
|
|
837
|
+
parts = ["Function(", ...formatList(def.arguments, arg => format(arg, cfg)), ")"];
|
|
838
|
+
if ("return" in def) parts.push(" => ", format(def.return, cfg));
|
|
839
|
+
}
|
|
840
|
+
|
|
841
|
+
if (model.assertions.length > 0) {
|
|
842
|
+
parts.push("\n(assertions: ", ...formatList(model.assertions, f => ["object", { object: f }]), ")");
|
|
843
|
+
}
|
|
844
|
+
|
|
845
|
+
return span(styles.model, ...parts)
|
|
846
|
+
};
|
|
847
|
+
|
|
848
|
+
const ModelFormatter = {
|
|
849
|
+
header(x, config = {}) {
|
|
850
|
+
if (x === Any)
|
|
851
|
+
return span(styles.model, "Any")
|
|
852
|
+
|
|
853
|
+
if (is(Any.remaining, x))
|
|
854
|
+
return span(styles.model, "...", format(x.definition, { isModelDefinition: true }))
|
|
855
|
+
|
|
856
|
+
if (is(ObjectModel, x))
|
|
857
|
+
return span(styles.model, x.name)
|
|
858
|
+
|
|
859
|
+
if (is(Model, x)) {
|
|
860
|
+
return formatModel(x)
|
|
861
|
+
}
|
|
862
|
+
|
|
863
|
+
if (config.isModelDefinition && isPlainObject(x))
|
|
864
|
+
return format(x, config)
|
|
865
|
+
|
|
866
|
+
return null;
|
|
867
|
+
},
|
|
868
|
+
hasBody(x) {
|
|
869
|
+
return is(ObjectModel, x)
|
|
870
|
+
},
|
|
871
|
+
body(model) {
|
|
872
|
+
return span("",
|
|
873
|
+
"{",
|
|
874
|
+
["ol", { style: styles.list }, ...Object.keys(model.definition).map(prop => {
|
|
875
|
+
const isPrivate = model.conventionForPrivate(prop);
|
|
876
|
+
const isConstant = model.conventionForConstant(prop);
|
|
877
|
+
const hasDefault = model.default && has(model.default, prop);
|
|
878
|
+
let style = styles.property;
|
|
879
|
+
|
|
880
|
+
if (isPrivate) {
|
|
881
|
+
style = isConstant ? styles.privateConstant : styles.private;
|
|
882
|
+
} else if (isConstant) {
|
|
883
|
+
style = styles.constant;
|
|
884
|
+
}
|
|
885
|
+
|
|
886
|
+
return ["li", { style: styles.listItem },
|
|
887
|
+
span(style, prop), ": ", format(model.definition[prop], { isModelDefinition: true }),
|
|
888
|
+
hasDefault ? span(styles.proto, " = ", format(model.default[prop])) : ""
|
|
889
|
+
]
|
|
890
|
+
})],
|
|
891
|
+
"}"
|
|
892
|
+
)
|
|
893
|
+
}
|
|
894
|
+
};
|
|
895
|
+
|
|
896
|
+
const ModelInstanceFormatter = {
|
|
897
|
+
header(x, config = {}) {
|
|
898
|
+
if (config.isInstanceProperty && isPlainObject(x)) {
|
|
899
|
+
return format(x, config)
|
|
900
|
+
}
|
|
901
|
+
|
|
902
|
+
const model = getModel(x);
|
|
903
|
+
if (is(Model, model)) {
|
|
904
|
+
const parts = is(ObjectModel, model) ? [model.name] : [["object", { object: x[_original] }], ` (${model.name})`];
|
|
905
|
+
return span(styles.instance, ...parts)
|
|
906
|
+
}
|
|
907
|
+
|
|
908
|
+
return null;
|
|
909
|
+
},
|
|
910
|
+
hasBody(x) {
|
|
911
|
+
return x && is(ObjectModel, getModel(x))
|
|
912
|
+
},
|
|
913
|
+
body(x) {
|
|
914
|
+
const model = getModel(x);
|
|
915
|
+
const o = x[_original] || x;
|
|
916
|
+
return span("",
|
|
917
|
+
"{",
|
|
918
|
+
[
|
|
919
|
+
"ol",
|
|
920
|
+
{ style: styles.list },
|
|
921
|
+
...Object.keys(o).map(prop => {
|
|
922
|
+
const isPrivate = model.conventionForPrivate(prop);
|
|
923
|
+
const isConstant = model.conventionForConstant(prop);
|
|
924
|
+
const isDeclared = prop in model.definition;
|
|
925
|
+
let style = styles.property;
|
|
926
|
+
|
|
927
|
+
if (!isDeclared) {
|
|
928
|
+
style = styles.undeclared;
|
|
929
|
+
} else if (isPrivate) {
|
|
930
|
+
style = isConstant ? styles.privateConstant : styles.private;
|
|
931
|
+
} else if (isConstant) {
|
|
932
|
+
style = styles.constant;
|
|
933
|
+
}
|
|
934
|
+
|
|
935
|
+
return ["li", { style: styles.listItem },
|
|
936
|
+
span(style, prop), ": ", format(o[prop], { isInstanceProperty: true })
|
|
937
|
+
]
|
|
938
|
+
}),
|
|
939
|
+
["li", { style: styles.listItem },
|
|
940
|
+
span(styles.proto, "__proto__", ": ", ["object", { object: getProto(x) }])
|
|
941
|
+
]
|
|
942
|
+
],
|
|
943
|
+
"}"
|
|
944
|
+
)
|
|
945
|
+
}
|
|
946
|
+
};
|
|
947
|
+
|
|
948
|
+
if (typeof window !== "undefined") {
|
|
949
|
+
window.devtoolsFormatters = (window.devtoolsFormatters || [])
|
|
950
|
+
.concat(ModelFormatter, ModelInstanceFormatter);
|
|
958
951
|
}
|
|
959
952
|
|
|
960
953
|
;
|