No 3rd party dependencies. All dependencies and devDependencies, checked recursively, are Codsen packages.
Permalink to InstallationInstallation
Permalink to Quick TakeQuick Take
Permalink to ExamplesExamples
- Compare Arrays
- Compare Plain Objects
- Compare Strings
opts.arrayOrderopts.hungryForWhitespaceopts.matchStrictlyopts.useWildcardsopts.verboseWhenMismatches- Report deterministic work and elapsed time
- Report comparison progress
- Match each unordered array element only once
- Compare nested arrays without regard to order
- Match object keys using wildcards
Purpose
compare(firstValue, secondPattern) checks whether the second value is equal
to, or a subset of, the first. It is especially useful for comparing abstract
syntax trees (ASTs).
It compares parsed HTML and CSS trees or individual branches.
import { compare } from "ast-compare";
compare({ tag: "a", attrs: { href: "/" } }, { tag: "a" });
// true
compare({ tag: "a", attrs: { href: "/" } }, { tag: "a" }, {
matchStrictly: true,
});
// false: the first object has an extra key
Supported values are strings, numbers, booleans, null, plain objects, arrays,
and explicit undefined, including nested combinations of these values.
Migrating from ast-loose-compare
For whitespace-tolerant subset comparisons, enable hungryForWhitespace
when calling compare. Read the
migration guide before replacing
looseCompare: array matching, missing-input handling, and some primitive
results differ. The default options of compare remain unchanged.
compare()
The main function compare() is imported like this:
The function takes two values and an optional options object:
| Input argument | Type | Required | Description |
|---|---|---|---|
firstValueType: ComparableValue | |||
firstValue | ComparableValue | yes | The value that may contain the requested pattern. |
secondPatternType: ComparableValue | |||
secondPattern | ComparableValue | yes | The value that must equal, or be a subset of, the first value. |
optsType: Partial<Opts> or null | |||
opts | Partial<Opts> or null | no | Options. null has the same effect as omitting this argument. |
- A match returns
true. - A mismatch returns
falseby default. WithverboseWhenMismatches: true, it returns a string that describes the mismatch and its path. - Missing arguments and invalid options throw a
TypeErrororRangeErrorwith an identifier such as[THROW_ID_01].
The function does not mutate either input.
The options object has the following shape:
| Key | Type | Default | Description |
|---|---|---|---|
arrayOrderType: "ordered" or "any"Default: "ordered" | |||
arrayOrder | "ordered" or "any" | "ordered" | Match array patterns as an ordered subsequence, or match each pattern item at any unused position. |
hungryForWhitespaceType: booleanDefault: false | |||
hungryForWhitespace | boolean | false | Treat recursively whitespace-only strings and containers as equivalent empty values. |
matchStrictlyType: booleanDefault: false | |||
matchStrictly | boolean | false | Require arrays and objects to contain the same number of entries as their patterns. |
reportCompletionFuncType: function or nullDefault: null | |||
reportCompletionFunc | function or null | null | Receive completion statistics after a comparison. |
reportProgressFuncType: function or nullDefault: null | |||
reportProgressFunc | function or null | null | Receive monotonic progress percentages. |
reportProgressFuncFromType: numberDefault: 0 | |||
reportProgressFuncFrom | number | 0 | Set the start of the progress range. |
reportProgressFuncToType: numberDefault: 100 | |||
reportProgressFuncTo | number | 100 | Set the end of the progress range. |
verboseWhenMismatchesType: booleanDefault: false | |||
verboseWhenMismatches | boolean | false | Return an explanatory string instead of false when values do not match. |
useWildcardsType: booleanDefault: false | |||
useWildcards | boolean | false | Enable wildcard string patterns in values and object keys. |
The options object accepts only the keys listed in this table, with values of
the documented types. Omit an option to use its default; explicitly setting an
option to undefined is invalid. Progress range endpoints must be finite
numbers, and the start must not exceed the end.
The exported defaults object is a frozen, read-only snapshot. Attempting to
modify it cannot change later comparisons.
Object matching
The second object’s own enumerable string keys must exist in the first object, and their values must match. Inherited properties, non-enumerable properties, and symbol keys do not participate. Key order does not matter.
By default, the first object can contain extra keys. matchStrictly: true
requires equal key counts at every depth. An empty object pattern matches only
an empty object unless both values qualify for whitespace matching.
Array matching
With the default arrayOrder: "ordered", pattern items must appear in the first
array in the same order, but other items can occur between them. With
arrayOrder: "any", every pattern item must match a different item in the first
array; repeated or ambiguous items are matched one-to-one. These rules apply
at every depth.
compare(["a", "b", "c"], ["a", "c"]); // true
compare(["a", "b"], ["b", "a"]); // false
compare(["a", "b"], ["b", "a"], { arrayOrder: "any" }); // true
compare(["a", "b"], ["a", "a"], { arrayOrder: "any" }); // false
matchStrictly: true additionally requires equal array lengths at every depth.
With ordered matching, this means corresponding positions must match. Wildcard
keys and values keep their normal meaning in strict mode. Whitespace matching
can override the length and key-count requirements, as described next.
Whitespace matching
With hungryForWhitespace: true, any two recursively empty values match, even
when their types, shapes, lengths, or key counts differ. This also applies with
matchStrictly: true. Empty values are:
- strings containing only whitespace;
- arrays whose entries are all empty; and
- plain objects whose values are all empty.
Numbers, booleans, null, undefined, and sparse array holes are meaningful;
they are not whitespace. A whitespace-only pattern does not match meaningful
content merely because it appears inside an array or object. Sparse array holes
compare as undefined.
compare({ content: [" ", "\n"] }, [], {
hungryForWhitespace: true,
matchStrictly: true,
});
// true: both values are recursively empty
compare(["content"], [" "], { hungryForWhitespace: true }); // false
Wildcard matching
With useWildcards: true, * matches zero or more characters, including line
breaks. Escape it as \* to match a literal asterisk. A leading ! negates
the whole pattern. Matching is case-sensitive and anchored to the complete
string. The second value supplies the pattern; wildcard syntax in the first
value is ordinary text.
compare("heading", "head*", { useWildcards: true }); // true
compare("heading", "!head*", { useWildcards: true }); // false
compare("*", "\\*", { useWildcards: true }); // true: a literal asterisk
Wildcard object keys are fallbacks: an exact own enumerable key takes precedence when it exists. Each wildcard key must consume a different key in the first object, and the corresponding values must recursively match as well. An exact key that fails its value comparison does not fall back to other keys.
compare({ dataPrimary: 1, dataSecondary: 2 }, { "data*": 2 }, {
useWildcards: true,
});
// true: dataSecondary matches both the key pattern and the value
Progress and completion reports
reportProgressFunc receives the configured start value and end value for both
matches and mismatches. Longer comparisons also emit monotonic intermediate
values. These are estimates based on work performed, not exact percentages of
the total work. Short comparisons can emit only the endpoints; equal endpoints
produce one callback.
Use reportProgressFuncFrom and reportProgressFuncTo to compose this work into
a wider progress range. Callbacks run synchronously during compare().
reportCompletionFunc receives these statistics:
| Key | Description |
|---|---|
candidateComparisons | |
candidateComparisons | Candidate pairs checked during unordered array or wildcard matching. |
comparisons | |
comparisons | Nested value comparisons performed. |
matchingEdges | |
matchingEdges | Compatible candidate pairs found for injective matching. |
timeTakenInMilliseconds | |
timeTakenInMilliseconds | Best-effort elapsed time. |
The counters describe work performed by the implementation; their values can change when the comparison algorithm is optimized. Elapsed time is measured in milliseconds and can be zero for short comparisons or when the clock is unavailable.
Exceptions thrown by either reporting callback are ignored and do not change the comparison result.
defaults
You can import defaults:
It's a plain object:
The main function calculates the options to be used by merging the options you passed with these defaults.
version
You can import version:
Types
This package is written in TypeScript and exports the following types:
| Type | Description |
|---|---|
AnyObjectType: AnyObject | |
AnyObject | A read-only object with string keys and unknown values. |
BooleanOptsType: BooleanOpts | |
BooleanOpts | Options that make compare() return a boolean. |
ComparableValueType: ComparableValue | |
ComparableValue | A JsonValue or explicit undefined. |
CompletionStatsType: CompletionStats | |
CompletionStats | Counters and elapsed time passed to reportCompletionFunc. |
JsonArrayType: JsonArray | |
JsonArray | A read-only array of JsonValue or undefined entries. |
JsonObjectType: JsonObject | |
JsonObject | A read-only object whose values are JsonValue or undefined. |
JsonValueType: JsonValue | |
JsonValue | A nested string, number, boolean, null, JsonObject, or JsonArray. |
OptsType: Opts | |
Opts | The complete options object documented above. |
VerboseOptsType: VerboseOpts | |
VerboseOpts | Options with verboseWhenMismatches: true, making the return type true | string. |
import type {
AnyObject,
BooleanOpts,
ComparableValue,
CompletionStats,
JsonArray,
JsonObject,
JsonValue,
Opts,
VerboseOpts,
} from "ast-compare";
opts.verboseWhenMismatches
Use verboseWhenMismatches: true when you need to explain why a pattern did not
match. Every mismatch returns a string containing the failing path, the reason,
and correctly labelled first and second values. A successful comparison still
returns true.
The VerboseOpts overload exposes this as true | string; it does not return
false.
Differences from _.isMatch
Partial comparisons will match empty array and empty object source values against any array or object value, respectively.
_.isMatch matches an empty
array pattern to every array. That is often undesirable when comparing parsed
HTML or CSS trees. This library does not match an empty array or object pattern
to a non-empty value of the same type unless hungryForWhitespace is enabled
and both values are recursively whitespace-empty.
compare(["a", "b", "c"], []); // false
compare({ tag: "a" }, {}); // false