@fp-ts/data
Advanced tools
Comparing version 0.0.19 to 0.0.20
/** | ||
* @since 1.0.0 | ||
*/ | ||
export declare const considerByRef: <A extends object>(self: A) => A; | ||
/** | ||
* @since 1.0.0 | ||
*/ | ||
export declare const addTagToPreCheck: <K extends string>(self: K) => void; | ||
/** | ||
* @since 1.0.0 | ||
*/ | ||
export declare const considerProtoByRef: <A extends object>(self: A) => A; | ||
/** | ||
* @since 1.0.0 | ||
* @category symbols | ||
@@ -4,0 +16,0 @@ */ |
263
Equal.js
@@ -6,2 +6,3 @@ "use strict"; | ||
}); | ||
exports.considerProtoByRef = exports.considerByRef = exports.addTagToPreCheck = void 0; | ||
exports.equals = equals; | ||
@@ -17,8 +18,49 @@ exports.symbolHash = exports.symbolEqual = exports.hashRandom = exports.hashOptimize = exports.hashCombine = exports.hash = void 0; | ||
*/ | ||
const hashCache = /*#__PURE__*/new WeakMap(); | ||
const byRefCache = /*#__PURE__*/new WeakSet(); | ||
const globals = /*#__PURE__*/Reflect.ownKeys(globalThis).flatMap(k => typeof globalThis[k] === "function" && k !== "Array" && k !== "Object" && "prototype" in globalThis[k] ? [globalThis[k]["prototype"]] : []); | ||
const byRefProtoCache = /*#__PURE__*/new WeakSet(globals); | ||
const circularCache = /*#__PURE__*/new WeakMap(); | ||
const shortCircuitTags = ["_tag"]; | ||
const shortCircuitTagsSet = /*#__PURE__*/new Set(shortCircuitTags); | ||
/** | ||
* @since 1.0.0 | ||
*/ | ||
const considerByRef = self => { | ||
byRefCache.add(self); | ||
return self; | ||
}; | ||
/** | ||
* @since 1.0.0 | ||
*/ | ||
exports.considerByRef = considerByRef; | ||
const addTagToPreCheck = self => { | ||
if (!shortCircuitTagsSet.has(self)) { | ||
shortCircuitTags.push(self); | ||
shortCircuitTagsSet.add(self); | ||
} | ||
}; | ||
/** | ||
* @since 1.0.0 | ||
*/ | ||
exports.addTagToPreCheck = addTagToPreCheck; | ||
const considerProtoByRef = self => { | ||
byRefProtoCache.add(self); | ||
return self; | ||
}; | ||
/** | ||
* @since 1.0.0 | ||
* @category symbols | ||
*/ | ||
const symbolHash = /*#__PURE__*/Symbol.for("@fp-ts/data/DeepEqual/hash"); | ||
exports.considerProtoByRef = considerProtoByRef; | ||
const symbolHash = /*#__PURE__*/Symbol.for("@fp-ts/data/Equal/hash"); | ||
/** | ||
@@ -30,3 +72,3 @@ * @since 1.0.0 | ||
exports.symbolHash = symbolHash; | ||
const symbolEqual = /*#__PURE__*/Symbol.for("@fp-ts/data/DeepEqual/equal"); | ||
const symbolEqual = /*#__PURE__*/Symbol.for("@fp-ts/data/Equal/equal"); | ||
exports.symbolEqual = symbolEqual; | ||
@@ -59,8 +101,8 @@ | ||
const hashRandom = self => { | ||
if (!CACHE.has(self)) { | ||
if (!hashCache.has(self)) { | ||
const h = hashOptimize(pcgr.number()); | ||
CACHE.set(self, h); | ||
hashCache.set(self, h); | ||
} | ||
return CACHE.get(self); | ||
return hashCache.get(self); | ||
}; | ||
@@ -93,44 +135,85 @@ /** | ||
function compareObject(self, that) { | ||
const selfProto = Object.getPrototypeOf(self); | ||
const thatProto = Object.getPrototypeOf(self); | ||
const selfCircular = circularCache.get(self); | ||
let added = false; | ||
if (selfProto !== thatProto) { | ||
return false; | ||
} | ||
if (selfCircular) { | ||
if (selfCircular.has(that)) { | ||
return true; | ||
} | ||
if (selfProto !== Object.prototype) { | ||
return self === that; | ||
selfCircular.add(that); | ||
} else { | ||
circularCache.set(self, new WeakSet([that])); | ||
added = true; | ||
} | ||
if ("_tag" in self) { | ||
if ("_tag" in that) { | ||
if (self["_tag"] !== that["_tag"]) { | ||
return false; | ||
try { | ||
for (let i = 0; i < shortCircuitTags.length; i++) { | ||
const tag = shortCircuitTags[i]; | ||
if (tag in self) { | ||
if (tag in that) { | ||
if (!equals(self[tag], that[tag])) { | ||
return false; | ||
} | ||
} else { | ||
return false; | ||
} | ||
} | ||
} else { | ||
} | ||
const keysA = Object.getOwnPropertyNames(self); | ||
const keysB = Object.getOwnPropertyNames(that); | ||
if (keysA.length !== keysB.length) { | ||
return false; | ||
} | ||
} | ||
const keysA = Object.keys(self).sort(); | ||
const keysB = Object.keys(that).sort(); | ||
const keysBSet = new Set(Object.getOwnPropertyNames(that)); | ||
if (keysA.length !== keysB.length) { | ||
return false; | ||
} | ||
for (const ka of keysA) { | ||
if (!shortCircuitTagsSet.has(ka)) { | ||
if (!keysBSet.has(ka)) { | ||
return false; | ||
} | ||
if (!equals(keysA, keysB)) { | ||
return false; | ||
} | ||
const va = self[ka]; | ||
const vb = that[ka]; | ||
for (const ka of keysA) { | ||
const va = self[ka]; | ||
const vb = that[ka]; | ||
if (!equals(va, vb)) { | ||
return false; | ||
} | ||
} | ||
} | ||
if (!equals(va, vb)) { | ||
const symbolsA = Object.getOwnPropertySymbols(self); | ||
const symbolsB = Object.getOwnPropertySymbols(that); | ||
if (symbolsA.length !== symbolsB.length) { | ||
return false; | ||
} | ||
const symbolsBSet = new Set(symbolsB); | ||
for (const ka of symbolsA) { | ||
if (!symbolsBSet.has(ka)) { | ||
return false; | ||
} | ||
const va = self[ka]; | ||
const vb = that[ka]; | ||
if (!equals(va, vb)) { | ||
return false; | ||
} | ||
} | ||
return true; | ||
} finally { | ||
if (added) { | ||
circularCache.delete(self); | ||
} else { | ||
circularCache.get(self)?.delete(that); | ||
} | ||
} | ||
return true; | ||
} | ||
@@ -140,12 +223,11 @@ | ||
"object": (self, that) => { | ||
if (self == null || that == null || typeof that !== "object") { | ||
return self === that; | ||
if (self == null || that == null || typeof that !== "object" || byRefCache.has(self) || byRefCache.has(that)) { | ||
return false; | ||
} | ||
if (Array.isArray(self)) { | ||
if (Array.isArray(that)) { | ||
return self.length === that.length && self.every((v, i) => equals(v, that[i])); | ||
} else { | ||
return false; | ||
} | ||
const selfProto = Object.getPrototypeOf(self); | ||
const thatProto = Object.getPrototypeOf(that); | ||
if (byRefProtoCache.has(selfProto) || byRefProtoCache.has(thatProto)) { | ||
return false; | ||
} | ||
@@ -168,2 +250,10 @@ | ||
if (selfProto !== thatProto) { | ||
return false; | ||
} | ||
if (selfProto === Array.prototype) { | ||
return self.length === that.length && self.every((v, i) => equals(v, that[i])); | ||
} | ||
return compareObject(self, that); | ||
@@ -223,6 +313,4 @@ }, | ||
const CACHE = /*#__PURE__*/new WeakMap(); | ||
function hashStructure(o) { | ||
CACHE.set(o, hashNumber(pcgr.number())); | ||
hashCache.set(o, hashNumber(pcgr.number())); | ||
const keys = Object.keys(o); | ||
@@ -248,6 +336,10 @@ let h = 12289; | ||
const hashProtoMap = /*#__PURE__*/new Map([[Array.prototype, hashArray], [Object.prototype, hashStructure]]); | ||
function hashObject(value) { | ||
if (hashCache.has(value)) return hashCache.get(value); | ||
function hashObject(value) { | ||
if (CACHE.has(value)) return CACHE.get(value); | ||
if (byRefCache.has(value)) { | ||
hashCache.set(value, hashRandom(value)); | ||
return hashCache.get(value); | ||
} | ||
let h; | ||
@@ -258,6 +350,10 @@ | ||
} else { | ||
h = (hashProtoMap.get(Object.getPrototypeOf(value)) ?? hashProtoMap.get(Object.prototype))(value); | ||
if (Object.getPrototypeOf(value) === Array.prototype) { | ||
h = hashArray(value); | ||
} else { | ||
h = hashStructure(value); | ||
} | ||
} | ||
CACHE.set(value, h); | ||
hashCache.set(value, h); | ||
return h; | ||
@@ -267,38 +363,57 @@ } | ||
function hashGeneric(self) { | ||
if (typeof self === "number") { | ||
return hashNumber(self); | ||
} | ||
switch (typeof self) { | ||
case "number": | ||
{ | ||
return hashNumber(self); | ||
} | ||
if (typeof self === "string") { | ||
return hashString(self); | ||
} | ||
case "bigint": | ||
{ | ||
return hashString(self.toString(10)); | ||
} | ||
if (typeof self === "symbol") { | ||
return hashString(String(self)); | ||
} | ||
case "boolean": | ||
{ | ||
return hashString(String(self)); | ||
} | ||
if (typeof self === "bigint") { | ||
return hashString(self.toString(10)); | ||
} | ||
case "symbol": | ||
{ | ||
return hashString(String(self)); | ||
} | ||
if (typeof self === "undefined") { | ||
return hashString("undefined"); | ||
} | ||
case "string": | ||
{ | ||
return hashString(self); | ||
} | ||
if (typeof self === "object") { | ||
if (self == null) { | ||
return hashString("null"); | ||
} | ||
case "undefined": | ||
{ | ||
return hashString("undefined"); | ||
} | ||
return hashObject(self); | ||
} | ||
case "object": | ||
{ | ||
if (self == null) { | ||
return hashString("null"); | ||
} | ||
if (typeof self === "function") { | ||
if (CACHE.has(self)) { | ||
CACHE.set(self, isDeepEqual(self) ? self[symbolHash]() : hashNumber(pcgr.number())); | ||
} | ||
return hashObject(self); | ||
} | ||
return CACHE.get(self); | ||
case "function": | ||
{ | ||
if (!hashCache.has(self)) { | ||
hashCache.set(self, isDeepEqual(self) ? self[symbolHash]() : hashNumber(pcgr.number())); | ||
} | ||
return hashCache.get(self); | ||
} | ||
default: | ||
{ | ||
throw new Error("Bug in Equal.hashGeneric"); | ||
} | ||
} | ||
} | ||
//# sourceMappingURL=Equal.js.map |
@@ -109,3 +109,3 @@ "use strict"; | ||
for (const k of this.unsafeMap.keys()) { | ||
if (!that.unsafeMap.has(k) || this.unsafeMap.get(k) !== that.unsafeMap.get(k)) { | ||
if (!that.unsafeMap.has(k) || !Equal.equals(this.unsafeMap.get(k), that.unsafeMap.get(k))) { | ||
return false; | ||
@@ -112,0 +112,0 @@ } |
@@ -12,2 +12,4 @@ "use strict"; | ||
var Equal = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("@fp-ts/data/Equal")); | ||
var _Context = /*#__PURE__*/require("@fp-ts/data/internal/Context"); | ||
@@ -123,3 +125,3 @@ | ||
if (old !== newService) { | ||
if (!Equal.equals(old, newService)) { | ||
patch = combine(new UpdateService(tag, () => newService))(patch); | ||
@@ -126,0 +128,0 @@ } |
{ | ||
"name": "@fp-ts/data", | ||
"version": "0.0.19", | ||
"version": "0.0.20", | ||
"license": "MIT", | ||
@@ -5,0 +5,0 @@ "repository": { |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
2170609
41849