MCPcopy Create free account
hub / github.com/Effect-TS/effect / isTree

Function isTree

packages/effect/src/SchemaAST.ts:4193–4251  ·  view source on GitHub ↗
(u: unknown, isLeaf: (u: unknown) => boolean)

Source from the content-addressed store, hash-verified

4191}
4192
4193function isTree(u: unknown, isLeaf: (u: unknown) => boolean): boolean {
4194 const cache = new WeakMap<object, boolean>()
4195 const stack: Array<TreeFrame> = []
4196 outer: while (true) {
4197 if (typeof u !== "object" || u === null) {
4198 if (!isLeaf(u)) {
4199 return false
4200 }
4201 } else {
4202 const value = u
4203 const cached = cache.get(value)
4204 // `false` marks a node on the current path, while `true` marks a fully
4205 // validated node that can be safely reused by a DAG.
4206 if (cached === false) {
4207 return false
4208 }
4209 if (cached === undefined) {
4210 const isArray = Array.isArray(value)
4211 if (!isArray) {
4212 const prototype = Object.getPrototypeOf(value)
4213 // A plain object from another realm has a different Object.prototype,
4214 // but that prototype still has a null prototype.
4215 if (
4216 prototype !== null &&
4217 prototype !== Object.prototype &&
4218 Object.getPrototypeOf(prototype) !== null
4219 ) {
4220 return false
4221 }
4222 }
4223 cache.set(value, false)
4224 stack.push({
4225 value,
4226 keys: isArray ? value.length : Object.keys(value),
4227 index: 0
4228 })
4229 }
4230 }
4231
4232 while (stack.length > 0) {
4233 const frame = stack[stack.length - 1]
4234 const keys = frame.keys
4235 if (typeof keys === "number") {
4236 if (frame.index < keys) {
4237 // A sparse slot is read as `undefined`; the leaf predicate determines
4238 // whether that is valid for the current tree.
4239 u = (frame.value as ReadonlyArray<unknown>)[frame.index++]
4240 continue outer
4241 }
4242 } else if (frame.index < keys.length) {
4243 u = (frame.value as Record<string, unknown>)[keys[frame.index++]]
4244 continue outer
4245 }
4246 cache.set(frame.value, true)
4247 stack.pop()
4248 }
4249 return true
4250 }

Callers 2

isJsonFunction · 0.85
isStringTreeFunction · 0.85

Calls 3

pushMethod · 0.80
getMethod · 0.65
setMethod · 0.65

Tested by

no test coverage detected