Class PropertyPathMap<V>
Type Parameters
- V
Stored value type.
Implements
- Iterable<[readonly PropertyKey[], V]>
Constructors
constructor
-
new PropertyPathMap<V>(
entries?: Iterable<readonly [PropertyPath, V], any, any>,
options?: Constructor,
): PropertyPathMap<V>Creates a new property path map and optionally initializes it from PropertyPath / value pairs.
Later duplicate paths overwrite earlier values without changing the original insertion position. Resource limits are validated before initial entries are inserted and apply to every subsequent operation.
Type Parameters
- V
Stored value type.
Parameters
Optionalentries: Iterable<readonly [PropertyPath, V], any, any>Optional initial PropertyPath / value entries.
Optionaloptions: ConstructorDefensive storage and traversal limits.
Constructor-level defensive limits applied to storage and every iterator.
-
OptionalmaxEntries?: numberMaximum number of exact stored paths. Overwriting an existing path does not consume another entry.
-
OptionalmaxNodes?: numberMaximum number of allocated non-root trie nodes. Shared path prefixes consume one node per unique segment.
-
OptionalmaxPathDepth?: numberMaximum number of property-key segments in a stored or queried path.
-
OptionalmaxTraversalResults?: numberMaximum results produced by one iterator unless reduced per call. Reaching the limit truncates normally.
-
OptionalmaxTraversalVisits?: numberMaximum properties or trie nodes processed during iterator traversal unless reduced per call. Exceeding the limit throws a
RangeError.
-
Returns PropertyPathMap<V>
- V
Accessors
[toStringTag]
-
get "[toStringTag]"(): string
Provides the standard object tag used by
Object.prototype.toString.Returns string
nodeCount
-
get nodeCount(): number
Number of allocated non-root trie nodes.
This value is maintained incrementally and may be used to monitor current trie resource consumption.
Returns number
size
-
get size(): number
Number of exact property paths currently stored.
Returns number
Methods
[iterator]
-
Returns the default insertion-order iterator of
[path, value]pairs.Constructor-level traversal result and visit caps apply. Use entries when per-call limits are required.
Returns IterableIterator<[readonly PropertyKey[], V]>
clear
-
Removes every stored entry and releases the complete trie.
This operation is
O(1)with respect to explicit traversal; the prior structure becomes available for garbage collection once no active iterator or external references remain.Returns void
delete
-
Deletes the value stored at an exact property path.
Descendant entries do not count as a match. Deleting
['settings']does not remove['settings', 'theme'], and deleting a parentless path does not affect siblings.After removal, unused nodes are pruned from the terminal node toward the root. Pruning stops at the first node that still stores a value or has another child.
Parameters
- path: PropertyPath
Dotted or exact property-key path.
Returns boolean
truewhen an entry existed and was removed; otherwisefalse.Throws
If
pathis not a valid PropertyPath. - path: PropertyPath
entries
-
Returns an insertion-order iterator of
[path, value]pairs.Paths are canonical frozen arrays owned by this map.
maxDepthis measured from the trie root,maxResultstruncates the iterator normally, andmaxVisitsthrows when exceeded. Yielded entries retain insertion order.Parameters
Optionaloptions: IterationOptional insertion-order traversal limits.
Returns IterableIterator<[readonly PropertyKey[], V]>
Entry iterator.
forEach
-
forEach(
callback: (
value: V,
key: readonly PropertyKey[],
map: PropertyPathMap<V>,
) => void,
thisArg?: unknown,
): voidInvokes a callback once for every entry in insertion order.
The callback arguments follow
Map.prototype.forEach: value, key, then map. The key is the canonical readonly property-key array associated with the stored entry. Unlike the explicit iterator methods,forEachalways visits the complete map, which is already bounded by the configuredmaxEntriesstorage limit.Parameters
- callback: (value: V, key: readonly PropertyKey[], map: PropertyPathMap<V>) => void
Function invoked for each entry.
OptionalthisArg: unknownOptional callback
thisvalue.
Returns void
- callback: (value: V, key: readonly PropertyKey[], map: PropertyPathMap<V>) => void
get
-
Retrieves the value stored at an exact structural path.
undefinedmay mean either that the path is absent or thatundefinedis the stored value. Use has when that distinction matters.Parameters
- path: PropertyPath
Dotted or exact property-key path.
Returns V
Stored value or
undefinedwhen the exact path is absent.Throws
If
pathis not a valid PropertyPath. - path: PropertyPath
has
-
Determines whether a value is stored at an exact structural path.
Descendant paths do not cause a prefix to be reported as present.
Parameters
- path: PropertyPath
Dotted or exact property-key path.
Returns boolean
Whether the exact path stores a value.
Throws
If
pathis not a valid PropertyPath. - path: PropertyPath
keys
-
Returns an insertion-order iterator of canonical property-key paths.
maxDepthis measured from the trie root,maxResultstruncates normally, andmaxVisitsthrows when exceeded.Parameters
Optionaloptions: IterationOptional insertion-order traversal limits.
Returns IterableIterator<readonly PropertyKey[]>
Key iterator.
matchingEntries
-
matchingEntries(
data: unknown,
options: Match & { includePropertyValue: true },
): IterableIterator<[readonly PropertyKey[], V, unknown]>Yields stored entries whose complete paths are available in a candidate value.
Matching traverses the property-key trie directly instead of resolving every stored path independently. Once a candidate prefix is missing or cannot be traversed, every stored descendant below that prefix is rejected without additional property access. Shared prefixes are therefore checked and read at most once per matching operation.
Set
pathPrefixto begin matching at one absolute stored path and ignore every unrelated trie branch. The prefix itself is yielded when it stores an entry and exists in the candidate object. SetstopAtto match one absolute path normally while pruning every stored descendant beneath it. Returned paths always remain absolute.A terminal property is considered available when it exists, even when its value is
undefinedornull. By default, terminal-only properties are not read, avoiding unnecessary getter and proxygettrap invocation. SetincludePropertyValuetotrueto append the resolved candidate property value to each yielded tuple.Array matching follows the same rules as the package property-path utilities: numeric indexes must be numbers in the ECMAScript array-index range, while symbol properties remain valid. String array indexes such as
'0'are rejected. Ordinary objects retain normal JavaScript key coercion semantics.Circular candidate values are safe because traversal is bounded by the finite depth of the stored trie; no cycle tracking is required.
Matching uses depth-first trie order, with sibling branches following the order in which their first trie nodes were created. This order is deterministic for an unchanged map but is not the map's global insertion order.
maxDepthis relative topathPrefix, or to the trie root when no prefix is supplied.maxResultstruncates normally, whilemaxVisitsthrows before another candidate property or trie node is processed.Parameters
- data: unknown
Candidate object or function to inspect. Non-traversable values produce an empty iterator.
- options: Match & { includePropertyValue: true }
Matching options.
Returns IterableIterator<[readonly PropertyKey[], V, unknown]>
Iterator of canonical stored paths and their associated mapped values, optionally followed by the resolved candidate property value.
- data: unknown
-
matchingEntries(
data: unknown,
options?: Match & { includePropertyValue?: false },
): IterableIterator<[readonly PropertyKey[], V]>Yields stored entries whose complete paths are available in a candidate value.
Matching traverses the property-key trie directly instead of resolving every stored path independently. Once a candidate prefix is missing or cannot be traversed, every stored descendant below that prefix is rejected without additional property access. Shared prefixes are therefore checked and read at most once per matching operation.
Set
pathPrefixto begin matching at one absolute stored path and ignore every unrelated trie branch. The prefix itself is yielded when it stores an entry and exists in the candidate object. SetstopAtto match one absolute path normally while pruning every stored descendant beneath it. Returned paths always remain absolute.A terminal property is considered available when it exists, even when its value is
undefinedornull. By default, terminal-only properties are not read, avoiding unnecessary getter and proxygettrap invocation. SetincludePropertyValuetotrueto append the resolved candidate property value to each yielded tuple.Array matching follows the same rules as the package property-path utilities: numeric indexes must be numbers in the ECMAScript array-index range, while symbol properties remain valid. String array indexes such as
'0'are rejected. Ordinary objects retain normal JavaScript key coercion semantics.Circular candidate values are safe because traversal is bounded by the finite depth of the stored trie; no cycle tracking is required.
Matching uses depth-first trie order, with sibling branches following the order in which their first trie nodes were created. This order is deterministic for an unchanged map but is not the map's global insertion order.
maxDepthis relative topathPrefix, or to the trie root when no prefix is supplied.maxResultstruncates normally, whilemaxVisitsthrows before another candidate property or trie node is processed.Parameters
- data: unknown
Candidate object or function to inspect. Non-traversable values produce an empty iterator.
Optionaloptions: Match & { includePropertyValue?: false }Matching options.
Returns IterableIterator<[readonly PropertyKey[], V]>
Iterator of canonical stored paths and their associated mapped values, optionally followed by the resolved candidate property value.
- data: unknown
-
matchingEntries(
data: unknown,
options?: Match,
): IterableIterator<
[readonly PropertyKey[], V]
| [readonly PropertyKey[], V, unknown],
>Yields stored entries whose complete paths are available in a candidate value.
Matching traverses the property-key trie directly instead of resolving every stored path independently. Once a candidate prefix is missing or cannot be traversed, every stored descendant below that prefix is rejected without additional property access. Shared prefixes are therefore checked and read at most once per matching operation.
Set
pathPrefixto begin matching at one absolute stored path and ignore every unrelated trie branch. The prefix itself is yielded when it stores an entry and exists in the candidate object. SetstopAtto match one absolute path normally while pruning every stored descendant beneath it. Returned paths always remain absolute.A terminal property is considered available when it exists, even when its value is
undefinedornull. By default, terminal-only properties are not read, avoiding unnecessary getter and proxygettrap invocation. SetincludePropertyValuetotrueto append the resolved candidate property value to each yielded tuple.Array matching follows the same rules as the package property-path utilities: numeric indexes must be numbers in the ECMAScript array-index range, while symbol properties remain valid. String array indexes such as
'0'are rejected. Ordinary objects retain normal JavaScript key coercion semantics.Circular candidate values are safe because traversal is bounded by the finite depth of the stored trie; no cycle tracking is required.
Matching uses depth-first trie order, with sibling branches following the order in which their first trie nodes were created. This order is deterministic for an unchanged map but is not the map's global insertion order.
maxDepthis relative topathPrefix, or to the trie root when no prefix is supplied.maxResultstruncates normally, whilemaxVisitsthrows before another candidate property or trie node is processed.Parameters
- data: unknown
Candidate object or function to inspect. Non-traversable values produce an empty iterator.
Optionaloptions: MatchMatching options.
Returns IterableIterator<
[readonly PropertyKey[], V]
| [readonly PropertyKey[], V, unknown],
>Iterator of canonical stored paths and their associated mapped values, optionally followed by the resolved candidate property value.
- data: unknown
matchingKeys
-
Yields canonical stored paths whose complete paths are available in a candidate value.
This is a path-only projection of matchingEntries and uses the same trie-aware pruning, prefix / stop bounds, property semantics, and depth-first trie order. Candidate terminal values are never requested solely for this iterator; properties are read only when descendant traversal requires them.
Parameters
- data: unknown
Candidate object or function to inspect.
Optionaloptions: MatchKeysPath-only matching options.
Returns IterableIterator<readonly PropertyKey[]>
Iterator of matching canonical property-key paths.
- data: unknown
matchingValues
-
matchingValues(
data: unknown,
options: Match & { includePropertyValue: true },
): IterableIterator<[V, unknown]>Yields mapped values whose stored path paths are available in a candidate value.
By default, this returns only each value stored in the map. Set
includePropertyValuetotrueto return[mappedValue, propertyValue]tuples, wherepropertyValueis resolved from the candidate data object at the matching property path. Prefix and stop bounds follow the semantics documented by matchingEntries.Parameters
- data: unknown
Candidate object or function to inspect.
- options: Match & { includePropertyValue: true }
Matching options.
Returns IterableIterator<[V, unknown]>
Iterator of mapped values or mapped-value / candidate-property-value tuples.
- data: unknown
-
matchingValues(
data: unknown,
options?: Match & { includePropertyValue?: false },
): IterableIterator<V>Yields mapped values whose stored path paths are available in a candidate value.
By default, this returns only each value stored in the map. Set
includePropertyValuetotrueto return[mappedValue, propertyValue]tuples, wherepropertyValueis resolved from the candidate data object at the matching property path. Prefix and stop bounds follow the semantics documented by matchingEntries.Parameters
- data: unknown
Candidate object or function to inspect.
Optionaloptions: Match & { includePropertyValue?: false }Matching options.
Returns IterableIterator<V>
Iterator of mapped values or mapped-value / candidate-property-value tuples.
- data: unknown
-
Yields mapped values whose stored path paths are available in a candidate value.
By default, this returns only each value stored in the map. Set
includePropertyValuetotrueto return[mappedValue, propertyValue]tuples, wherepropertyValueis resolved from the candidate data object at the matching property path. Prefix and stop bounds follow the semantics documented by matchingEntries.Parameters
- data: unknown
Candidate object or function to inspect.
Optionaloptions: MatchMatching options.
Returns IterableIterator<V | [V, unknown]>
Iterator of mapped values or mapped-value / candidate-property-value tuples.
- data: unknown
set
-
Stores a value at an exact structural path.
Existing trie nodes are inspected first so path depth, entry count, and node count limits can be validated before any mutation occurs. Overwriting an existing path updates only its value, preserving size and insertion order. A new entry copies and freezes its normalized path once for stable iteration.
Parameters
- path: PropertyPath
Dotted or exact property-key path.
- value: V
Value to store.
undefinedis valid.
Returns this
This map.
Throws
If
pathis not a valid PropertyPath. - path: PropertyPath
subtreeEntries
-
Yields stored entries from one trie subtree without inspecting a candidate data object.
pathPrefixselects the absolute trie node where traversal begins. The prefix entry is included when the exact path stores a value, even when it has no descendants. A missing stored prefix produces an empty iterator.stopAtincludes its own entry when present and prunes all descendants beneath that node.Subtree traversal uses deterministic depth-first trie order rather than global insertion order. Returned canonical paths remain absolute and are reused from their stored entries.
maxDepthis relative topathPrefix, or to the trie root when no prefix is supplied.maxResultstruncates normally, whilemaxVisitsthrows.Parameters
Optionaloptions: SubtreeSubtree bounds.
Returns IterableIterator<[readonly PropertyKey[], V]>
Iterator of canonical stored paths and mapped values.
subtreeKeys
-
Yields canonical stored paths from one trie subtree.
This is a path-only projection of subtreeEntries. It performs no candidate object access and allocates no temporary entry tuples.
Parameters
Optionaloptions: SubtreeSubtree bounds.
Returns IterableIterator<readonly PropertyKey[]>
Iterator of canonical stored property-key paths.
subtreeValues
-
Yields mapped values from one trie subtree.
This is a value-only projection of subtreeEntries. It performs no candidate object access and allocates no temporary entry tuples.
Parameters
Optionaloptions: SubtreeSubtree bounds.
Returns IterableIterator<V>
Iterator of mapped values.
values
-
Returns an insertion-order iterator of stored values.
maxDepthis measured from the trie root,maxResultstruncates normally, andmaxVisitsthrows when exceeded.Parameters
Optionaloptions: IterationOptional insertion-order traversal limits.
Returns IterableIterator<V>
Value iterator.
Stores values by structural PropertyPath paths using a property-key trie.
PropertyPathMapcombines exact structural path storage with trie-aware object matching and bounded subtree traversal. In addition to normal map-style lookup, stored paths can be evaluated collectively against a candidate object, allowing the map to operate as a reusable index of properties, bindings, field definitions, validators, or other metadata associated with an object structure.Unlike
Map<readonly PropertyKey[], V>, lookup does not depend on property-key array identity. Equivalent paths resolve to the same entry even when a new property-key array is supplied:Example
Dotted strings and equivalent string-key arrays share the same trie path:
Example
Exact array property-key paths remain necessary for symbols, numeric keys, empty-string keys, and string keys containing literal periods.
Iterator families
The collection provides three complementary iterator families:
entries,keys, andvaluesiterate all stored entries in normal map insertion order.matchingEntries,matchingKeys, andmatchingValuesevaluate stored paths against a candidate object.subtreeEntries,subtreeKeys, andsubtreeValuestraverse a selected trie branch without inspecting an object.Every iterator supports bounded operation through depth, result, and visit limits. Matching and subtree iterators additionally support absolute
pathPrefixandstopAtbounds.Candidate-object matching
The matching iterators treat the stored trie as a reusable structural query over a candidate object:
Example
Matching traverses the property-key trie and candidate object together. Shared path prefixes are inspected only once for each matching operation. When a candidate prefix is missing or cannot be traversed, the complete stored subtree beneath that prefix is rejected without resolving each descendant path independently. This makes matching particularly useful when the map contains many paths with common prefixes.
matchingKeysyields only the available stored paths, whilematchingValuesyields only their mapped values.matchingEntriesyields both:By default, matching determines terminal property availability without reading the terminal value. This avoids invoking a terminal getter or proxy
gettrap merely to establish that a path exists.Set
includePropertyValueto include the resolved candidate value in the iterator result:Example
The overloads for
matchingEntriesandmatchingValuesreflect a literalincludePropertyValue: trueoption in the returned iterator type.Matching follows normal JavaScript property lookup by default. Set
hasOwnOnlyto require every matched segment to be an own property of the candidate value reached at that depth.Prefix and stop bounds
pathPrefixbegins matching or subtree traversal directly at one absolute stored trie path. Unrelated branches are never visited:Example
Returned paths remain absolute. The prefix itself is included when it stores a mapped value and satisfies the iterator operation.
stopAtincludes a selected path when it stores a value, but prunes every stored descendant beneath it:Example
When both options are supplied,
stopAtmust equal or descend frompathPrefix.maxDepthis measured relative topathPrefix, or relative to the trie root when no prefix is supplied.Candidate-independent subtree traversal
Subtree iterators traverse stored entries without accessing a candidate object:
Example
These iterators are useful for inspecting, processing, or removing logical groups of stored paths without scanning unrelated branches. They share the same
pathPrefix,stopAt,maxDepth,maxResults, andmaxVisitscontrols as matching traversal.Matching and subtree iterators use deterministic depth-first trie order rather than global insertion order.
Key semantics
Each path segment is stored in a native
Map<PropertyKey, ...>:Map/ SameValueZero semantics.0is not'0').Stored canonical paths are copied and frozen once when first inserted. Overwriting an existing entry retains its original insertion position and canonical path. Deleting and reinserting a path moves it to the end, matching normal
Mapinsertion-order behavior.Defensive limits
Every instance applies configurable limits to stored path depth, terminal entries, allocated trie nodes, yielded traversal results, and traversal visits. Storage limits are preflighted before mutation, so failed insertion cannot leave a partial trie branch. Per-call
maxDepth,maxResults, andmaxVisitsoptions may reduce, but never exceed, the constructor traversal caps.Reaching
maxResultsends an iterator normally after the configured number of results. ExceedingmaxVisitsthrows before another candidate property or trie node is processed during the iterative walk. Path normalization and fixed- depth trie scope lookup are bounded separately bymaxPathDepth. These limits do not measure the retained size of mapped values or individual property keys.Candidate-object matching may invoke getters and proxy traps when descendant traversal or an explicitly requested terminal property value requires a read. Exceptions from those operations are intentionally propagated.
Complexity
get,has, andsetareO(path length).deleteis alsoO(path length)and prunes unused trie nodes. Normal map iteration isO(entry count)and follows insertion order through a linked list of terminal entries.Trie-aware matching visits only reachable stored prefixes. An unavailable candidate prefix rejects every stored descendant beneath it with one candidate-property check. Matching entry and value iterators may optionally include the resolved candidate property value without performing a second path lookup.
pathPrefixbegins traversal directly at a selected stored trie node, whilestopAtprunes one descendant branch by node identity. Candidate-independent subtree iterators visit only terminal entries beneath the selected node.Mutation of the map while an iterator is active is intentionally unspecified.