This package is retired. The published package, documentation, examples, and changelog remain available.
Migrate to ast-compare
Maintenance has moved to ast-compare. Use it for new projects
and migrate existing calls after checking the behavior differences below.
Published ast-loose-compare versions remain available for applications that
need their existing behavior.
Both libraries check whether the second value is equal to, or a subset of,
the first. For whitespace-tolerant matching, replace looseCompare with
compare and enable hungryForWhitespace:
npm install ast-compare
import { compare } from "ast-compare";
const first = { tag: "a", content: [" ", "\n"], title: "Docs" };
const pattern = { tag: "a", content: { text: "\t" } };
compare(first, pattern, { hungryForWhitespace: true }); // true
Keep the argument order: the value being searched comes first, and the pattern
comes second. Whitespace matching is off by default in ast-compare; retain
the option when replacing loose comparisons. The other defaults provide
ordered subset matching, literal strings, and boolean results.
This is not a drop-in replacement. Run your application’s comparison tests, review array matches and missing-input handling, then remove the old dependency:
npm uninstall ast-loose-compare
Array matching changes
looseCompare compares array items at corresponding positions, starting at
index zero. compare accepts an ordered subsequence: it can skip items before
or between pattern matches. Except when both arrays contain only whitespace
and empty containers, every pattern item must match a different item.
import { compare } from "ast-compare";
const options = { hungryForWhitespace: true };
compare(["a", "b", "c"], ["b", "c"], options); // true; looseCompare returns false
compare(["a", "b", "c"], ["a", "c"], options); // true; looseCompare returns false
compare(["a", "b"], ["b", "a"], options); // false: order still matters
There is no option for the old positional-prefix behavior. Setting
matchStrictly: true also requires equal array lengths and equal object key
counts at every depth, except when both values qualify for whitespace
equivalence. It does not preserve the old subset semantics.
Review callers that depend on exact positions before migrating them.
Missing inputs and return values
looseCompare returns undefined when either top-level input is missing,
undefined, or null. compare distinguishes omitted arguments from
explicit values:
- Omitting either required argument throws a
TypeError. - Explicit
nullandundefinedare values: each matches itself, and they do not match each other. - Without verbose mode, a completed comparison always returns a boolean.
import { compare } from "ast-compare";
compare(null, null); // true
compare(undefined, undefined); // true
compare(null, undefined); // false
If your application uses nullish values to mean that no comparison should run,
handle that condition before calling compare. Do not rely on an undefined
return value to signal missing input.
Other behavior differences
The compare results in this table use hungryForWhitespace: true.
| First value | Second pattern | looseCompare | compare |
|---|---|---|---|
[" ", "different"] | |||
[" ", "different"] | ["\n", "expected"] | true | false |
1 | |||
1 | 1 | false | true |
true | |||
true | true | false | true |
{ a: 1 } | |||
{ a: 1 } | { b: undefined } | true | false |
{ a: " " } | |||
{ a: " " } | { b: "\n" } | false | true |
The first row is a bug in the old library: a whitespace match can return
success before checking the remaining array items. compare checks the full
pattern. It also handles equal primitive values and requires a pattern’s own
enumerable keys to exist in a meaningful object.
When both values contain only whitespace and empty containers, compare
treats them as equivalent even if their types, keys, or lengths differ.
Numbers, booleans, null, and undefined are meaningful values, not whitespace.
TypeScript migration
Import JsonValue, JsonObject, and JsonArray from ast-compare instead.
Its object and array types are readonly and permit explicit undefined
entries. Use ComparableValue when a top-level value can be undefined.
The old UnknownValueObj has no direct alias. AnyObject uses readonly keys
and unknown values instead of any; callers must narrow values before using
them. Prefer a specific application type when its shape is known.
import { compare } from "ast-compare";
import type { ComparableValue } from "ast-compare";
const first: ComparableValue = { content: [" "] };
const pattern: ComparableValue = { content: "\n" };
const matched: boolean = compare(first, pattern, { hungryForWhitespace: true });
Functions and other non-JSON objects are outside the supported input contract. Do not use their incidental runtime results as migration requirements.
Browser scripts
For direct browser use, replace the script filename and global as well as the function call:
<script src="https://cdn.jsdelivr.net/npm/ast-compare/dist/ast-compare.umd.js"></script>
<script>
const matched = astCompare.compare(
{ tag: "a", content: [" "] },
{ tag: "a", content: "\n" },
{ hungryForWhitespace: true },
);
// matched === true
</script>
The old script uses ast-loose-compare.umd.js and
astLooseCompare.looseCompare. Test the replacement with your own fixtures
before updating production pages. Existing old-package releases remain
available if you need to defer migration.
API — looseCompare()
This reference describes the legacy package. Its historical examples and changelog remain available.
import { looseCompare } from "ast-loose-compare";
looseCompare(bigObj, smallObj) returns a boolean, or undefined for a
nullish top-level input. It compares object subsets, positional array prefixes,
and strings, treating whitespace-only values as equivalent in many cases.
Its edge cases and known false positives are described above.
API — version
You can import version:
API — types
The legacy package exports JsonValue, JsonObject, JsonArray, and
UnknownValueObj. See TypeScript migration for the
replacement types and their differences.