@yarnpkg/json-proxy
Advanced tools
Comparing version 2.0.0-rc.6 to 2.0.0-rc.7
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { | ||
value: true | ||
}); | ||
Object.defineProperty(exports, "makeTracker", { | ||
enumerable: true, | ||
get: function () { | ||
return _makeTracker.makeTracker; | ||
} | ||
}); | ||
Object.defineProperty(exports, "Tracker", { | ||
enumerable: true, | ||
get: function () { | ||
return _makeTracker.Tracker; | ||
} | ||
}); | ||
Object.defineProperty(exports, "makeUpdater", { | ||
enumerable: true, | ||
get: function () { | ||
return _makeUpdater.makeUpdater; | ||
} | ||
}); | ||
Object.defineProperty(exports, "updateAndSave", { | ||
enumerable: true, | ||
get: function () { | ||
return _makeUpdater.updateAndSave; | ||
} | ||
}); | ||
var _makeTracker = require("./makeTracker"); | ||
var _makeUpdater = require("./makeUpdater"); | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var makeTracker_1 = require("./makeTracker"); | ||
exports.makeTracker = makeTracker_1.makeTracker; | ||
var makeUpdater_1 = require("./makeUpdater"); | ||
exports.makeUpdater = makeUpdater_1.makeUpdater; | ||
exports.updateAndSave = makeUpdater_1.updateAndSave; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { | ||
value: true | ||
}); | ||
exports.makeTracker = makeTracker; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const VERSION = Symbol(`Version`); | ||
function cloneObject(obj) { | ||
// Preserving the prototype is out of scope for this library; don't try to | ||
// implement it, I won't merge it | ||
return Object.assign(Object.create(null), obj); | ||
// Preserving the prototype is out of scope for this library; don't try to | ||
// implement it, I won't merge it | ||
return Object.assign(Object.create(null), obj); | ||
} | ||
function cloneValue(value) { | ||
if (typeof value === `object` && value !== null) { | ||
if (Array.isArray(value)) { | ||
return value.slice(); | ||
} else if (value instanceof Set) { | ||
return new Set(value); | ||
} else if (value instanceof Map) { | ||
return new Map(value); | ||
} else { | ||
return cloneObject(value); | ||
if (typeof value === `object` && value !== null) { | ||
if (Array.isArray(value)) { | ||
return value.slice(); | ||
} | ||
else if (value instanceof Set) { | ||
return new Set(value); | ||
} | ||
else if (value instanceof Map) { | ||
return new Map(value); | ||
} | ||
else { | ||
return cloneObject(value); | ||
} | ||
} | ||
} else { | ||
return value; | ||
} | ||
else { | ||
return value; | ||
} | ||
} | ||
function cloneValueChecked(value, version) { | ||
if (typeof value === `object` && value !== null) { | ||
if (value[VERSION] === version) return value; | ||
const clone = cloneValue(value); | ||
clone[VERSION] = version; | ||
return clone; | ||
} else { | ||
return cloneValue(value); | ||
} | ||
if (typeof value === `object` && value !== null) { | ||
if (value[VERSION] === version) | ||
return value; | ||
const clone = cloneValue(value); | ||
clone[VERSION] = version; | ||
return clone; | ||
} | ||
else { | ||
return cloneValue(value); | ||
} | ||
} | ||
function cloneValueDeep(value, filter) { | ||
if (typeof value === `object` && value !== null) { | ||
if (Array.isArray(value)) { | ||
return value.map(subValue => { | ||
return cloneValueDeep(subValue, filter); | ||
}); | ||
} else if (value instanceof Set) { | ||
const clone = new Set(); | ||
for (const subValue of value.values()) clone.add(cloneValueDeep(subValue, filter)); | ||
return clone; | ||
} else if (value instanceof Map) { | ||
const clone = new Map(); | ||
for (const [key, subValue] of value) clone.set(key, cloneValueDeep(subValue, filter)); | ||
return clone; | ||
} else { | ||
const clone = cloneObject(value); | ||
for (const key of Object.keys(clone)) { | ||
if (filter !== true && !filter[key]) continue; | ||
const nextFilter = filter !== true ? filter[key] : true; // @ts-ignore | ||
clone[key] = cloneValueDeep(clone[key], nextFilter); | ||
} | ||
return clone; | ||
if (typeof value === `object` && value !== null) { | ||
if (Array.isArray(value)) { | ||
return value.map(subValue => { | ||
return cloneValueDeep(subValue, filter); | ||
}); | ||
} | ||
else if (value instanceof Set) { | ||
const clone = new Set(); | ||
for (const subValue of value.values()) | ||
clone.add(cloneValueDeep(subValue, filter)); | ||
return clone; | ||
} | ||
else if (value instanceof Map) { | ||
const clone = new Map(); | ||
for (const [key, subValue] of value) | ||
clone.set(key, cloneValueDeep(subValue, filter)); | ||
return clone; | ||
} | ||
else { | ||
const clone = cloneObject(value); | ||
for (const key of Object.keys(clone)) { | ||
if (filter !== true && !filter[key]) | ||
continue; | ||
const nextFilter = filter !== true | ||
? filter[key] | ||
: true; | ||
// @ts-ignore | ||
clone[key] = cloneValueDeep(clone[key], nextFilter); | ||
} | ||
return clone; | ||
} | ||
} | ||
} else { | ||
return value; | ||
} | ||
else { | ||
return value; | ||
} | ||
} | ||
function compareValuesDeep(a, b) { | ||
if (a === b) { | ||
return true; | ||
} else if (a == null !== (b == null)) { | ||
return false; | ||
} else if (Array.isArray(a)) { | ||
if (!Array.isArray(b)) return false; | ||
if (a.length !== b.length) return false; | ||
for (let t = 0, T = a.length; t < T; ++t) if (!compareValuesDeep(a[t], b[t])) return false; | ||
return true; | ||
} else if (a instanceof Set) { | ||
if (!(b instanceof Set)) return false; | ||
if (a.size !== b.size) return false; | ||
for (const key of a.entries()) if (!b.has(key)) return false; | ||
return true; | ||
} else if (a instanceof Map) { | ||
if (!(b instanceof Map)) return false; | ||
if (a.size !== b.size) return false; | ||
for (const [key, value] of a.entries()) if (!compareValuesDeep(value, b.get(key))) return false; | ||
return true; | ||
} else if (a.constructor === Object) { | ||
if (b.constructor !== Object) return false; | ||
const aKeys = Object.keys(a); | ||
const bKeys = Object.keys(b); | ||
if (aKeys.length !== bKeys.length) return false; | ||
for (let t = 0, T = aKeys.length; t < T; ++t) if (aKeys[t] !== bKeys[t]) return false; | ||
for (let t = 0, T = aKeys.length; t < T; ++t) if (!compareValuesDeep(a[aKeys[t]], b[bKeys[t]])) return false; | ||
return true; | ||
} else { | ||
return false; | ||
} | ||
if (a === b) { | ||
return true; | ||
} | ||
else if ((a == null) !== (b == null)) { | ||
return false; | ||
} | ||
else if (Array.isArray(a)) { | ||
if (!Array.isArray(b)) | ||
return false; | ||
if (a.length !== b.length) | ||
return false; | ||
for (let t = 0, T = a.length; t < T; ++t) | ||
if (!compareValuesDeep(a[t], b[t])) | ||
return false; | ||
return true; | ||
} | ||
else if (a instanceof Set) { | ||
if (!(b instanceof Set)) | ||
return false; | ||
if (a.size !== b.size) | ||
return false; | ||
for (const key of a.entries()) | ||
if (!b.has(key)) | ||
return false; | ||
return true; | ||
} | ||
else if (a instanceof Map) { | ||
if (!(b instanceof Map)) | ||
return false; | ||
if (a.size !== b.size) | ||
return false; | ||
for (const [key, value] of a.entries()) | ||
if (!compareValuesDeep(value, b.get(key))) | ||
return false; | ||
return true; | ||
} | ||
else if (a.constructor === Object) { | ||
if (b.constructor !== Object) | ||
return false; | ||
const aKeys = Object.keys(a); | ||
const bKeys = Object.keys(b); | ||
if (aKeys.length !== bKeys.length) | ||
return false; | ||
for (let t = 0, T = aKeys.length; t < T; ++t) | ||
if (aKeys[t] !== bKeys[t]) | ||
return false; | ||
for (let t = 0, T = aKeys.length; t < T; ++t) | ||
if (!compareValuesDeep(a[aKeys[t]], b[bKeys[t]])) | ||
return false; | ||
return true; | ||
} | ||
else { | ||
return false; | ||
} | ||
} | ||
const proxyHandlerSet = (version, filter, ensureCloning) => ({ | ||
get(source, prop) { | ||
switch (prop) { | ||
case `clear`: | ||
return () => { | ||
const clonedParent = ensureCloning(); | ||
clonedParent.clear(); | ||
source.clear(); | ||
}; | ||
case `delete`: | ||
return key => { | ||
const clonedParent = ensureCloning(); | ||
clonedParent.delete(key); | ||
source.delete(key); | ||
}; | ||
case `add`: | ||
return key => { | ||
const clonedParent = ensureCloning(); | ||
clonedParent.add(key); | ||
source.add(key); | ||
}; | ||
// @ts-ignore | ||
default: | ||
return source[prop]; | ||
} | ||
} | ||
get(source, prop) { | ||
switch (prop) { | ||
case `clear`: return () => { | ||
const clonedParent = ensureCloning(); | ||
clonedParent.clear(); | ||
source.clear(); | ||
}; | ||
case `delete`: return (key) => { | ||
const clonedParent = ensureCloning(); | ||
clonedParent.delete(key); | ||
source.delete(key); | ||
}; | ||
case `add`: return (key) => { | ||
const clonedParent = ensureCloning(); | ||
clonedParent.add(key); | ||
source.add(key); | ||
}; | ||
// @ts-ignore | ||
default: return source[prop]; | ||
} | ||
}, | ||
}); | ||
const proxyHandlerMap = (version, filter, ensureCloning) => ({ | ||
get(source, prop) { | ||
switch (prop) { | ||
case `clear`: | ||
return () => { | ||
const clonedParent = ensureCloning(); | ||
clonedParent.clear(); | ||
source.clear(); | ||
}; | ||
case `delete`: | ||
return key => { | ||
const clonedParent = ensureCloning(); | ||
clonedParent.delete(key); | ||
source.delete(key); | ||
}; | ||
case `set`: | ||
return (key, value) => { | ||
const clonedParent = ensureCloning(); | ||
clonedParent.set(key, value); | ||
source.set(key, value); | ||
}; | ||
case `get`: | ||
return key => { | ||
const value = source.get(key); | ||
return makeValueObservable(value, version, filter, () => { | ||
get(source, prop) { | ||
switch (prop) { | ||
case `clear`: return () => { | ||
const clonedParent = ensureCloning(); | ||
clonedParent.clear(); | ||
source.clear(); | ||
}; | ||
case `delete`: return (key) => { | ||
const clonedParent = ensureCloning(); | ||
clonedParent.delete(key); | ||
source.delete(key); | ||
}; | ||
case `set`: return (key, value) => { | ||
const clonedParent = ensureCloning(); | ||
clonedParent.set(key, value); | ||
source.set(key, value); | ||
}; | ||
case `get`: return (key) => { | ||
const value = source.get(key); | ||
return makeValueObservable(value, version, filter, () => { | ||
const clonedParent = ensureCloning(); | ||
const immutableValue = clonedParent.get(key); | ||
const clonedValue = cloneValueChecked(immutableValue, version); | ||
clonedParent.set(key, clonedValue); | ||
return clonedParent; | ||
}); | ||
}; | ||
// @ts-ignore | ||
default: return source[prop]; | ||
} | ||
}, | ||
}); | ||
const proxyHandlerObject = (version, filter, ensureCloning) => ({ | ||
get(source, prop) { | ||
// @ts-ignore | ||
const value = source[prop]; | ||
// Typescript doesn't allow symbol in its index types | ||
if (typeof prop === `symbol`) | ||
return value; | ||
if (filter !== true && !filter[prop]) | ||
return value; | ||
const nextFilter = filter !== true | ||
? filter[prop] | ||
: true; | ||
return makeValueObservable(value, version, nextFilter, () => { | ||
const clonedParent = ensureCloning(); | ||
const immutableValue = clonedParent.get(key); | ||
// @ts-ignore | ||
const immutableValue = clonedParent[prop]; | ||
const clonedValue = cloneValueChecked(immutableValue, version); | ||
clonedParent.set(key, clonedValue); | ||
return clonedParent; | ||
}); | ||
}; | ||
// @ts-ignore | ||
default: | ||
return source[prop]; | ||
} | ||
} | ||
// @ts-ignore | ||
clonedParent[prop] = clonedValue; | ||
return clonedValue; | ||
}); | ||
}, | ||
set(source, prop, value) { | ||
// @ts-ignore | ||
const currentValue = source[prop]; | ||
if (!compareValuesDeep(currentValue, value)) { | ||
// We ensure that our parent is cloned, then assign the new value into it | ||
const clonedParent = ensureCloning(); | ||
// @ts-ignore | ||
clonedParent[prop] = cloneValueDeep(value, filter); | ||
} | ||
// @ts-ignore | ||
source[prop] = value; | ||
return true; | ||
}, | ||
}); | ||
const proxyHandlerObject = (version, filter, ensureCloning) => ({ | ||
get(source, prop) { | ||
// @ts-ignore | ||
const value = source[prop]; // Typescript doesn't allow symbol in its index types | ||
if (typeof prop === `symbol`) return value; | ||
if (filter !== true && !filter[prop]) return value; | ||
const nextFilter = filter !== true ? filter[prop] : true; | ||
return makeValueObservable(value, version, nextFilter, () => { | ||
const clonedParent = ensureCloning(); // @ts-ignore | ||
const immutableValue = clonedParent[prop]; | ||
const clonedValue = cloneValueChecked(immutableValue, version); // @ts-ignore | ||
clonedParent[prop] = clonedValue; | ||
return clonedValue; | ||
}); | ||
}, | ||
set(source, prop, value) { | ||
// @ts-ignore | ||
const currentValue = source[prop]; | ||
if (!compareValuesDeep(currentValue, value)) { | ||
// We ensure that our parent is cloned, then assign the new value into it | ||
const clonedParent = ensureCloning(); // @ts-ignore | ||
clonedParent[prop] = cloneValueDeep(value, filter); | ||
} // @ts-ignore | ||
source[prop] = value; | ||
return true; | ||
} | ||
}); | ||
function makeValueObservable(value, version, filter, ensureCloning) { | ||
if (typeof value === `object` && value !== null) { | ||
if (value instanceof Set) { | ||
return new Proxy(value, proxyHandlerSet(version, filter, ensureCloning)); | ||
} else if (value instanceof Map) { | ||
return new Proxy(value, proxyHandlerMap(version, filter, ensureCloning)); | ||
} else { | ||
return new Proxy(value, proxyHandlerObject(version, filter, ensureCloning)); | ||
if (typeof value === `object` && value !== null) { | ||
if (value instanceof Set) { | ||
return new Proxy(value, proxyHandlerSet(version, filter, ensureCloning)); | ||
} | ||
else if (value instanceof Map) { | ||
return new Proxy(value, proxyHandlerMap(version, filter, ensureCloning)); | ||
} | ||
else { | ||
return new Proxy(value, proxyHandlerObject(version, filter, ensureCloning)); | ||
} | ||
} | ||
} else { | ||
return value; | ||
} | ||
else { | ||
return value; | ||
} | ||
} | ||
function makeTracker(value, filter = true) { | ||
const tracker = { | ||
immutable: cloneValueDeep(value, filter), | ||
open(cb) { | ||
// A value guaranteed to be different from everything except itself | ||
const version = {}; | ||
cb(makeValueObservable(value, version, filter, () => { | ||
tracker.immutable = cloneValueChecked(tracker.immutable, version); | ||
return tracker.immutable; | ||
})); | ||
return tracker.immutable; | ||
} | ||
}; | ||
return tracker; | ||
} | ||
const tracker = { | ||
immutable: cloneValueDeep(value, filter), | ||
open(cb) { | ||
// A value guaranteed to be different from everything except itself | ||
const version = {}; | ||
cb(makeValueObservable(value, version, filter, () => { | ||
tracker.immutable = cloneValueChecked(tracker.immutable, version); | ||
return tracker.immutable; | ||
})); | ||
return tracker.immutable; | ||
}, | ||
}; | ||
return tracker; | ||
} | ||
exports.makeTracker = makeTracker; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { | ||
value: true | ||
}); | ||
exports.makeUpdater = makeUpdater; | ||
exports.updateAndSave = updateAndSave; | ||
var _fslib = require("@yarnpkg/fslib"); | ||
var _makeTracker = require("./makeTracker"); | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const fslib_1 = require("@yarnpkg/fslib"); | ||
const makeTracker_1 = require("./makeTracker"); | ||
async function makeUpdater(filename) { | ||
let indent = ` `; | ||
let obj; | ||
if (_fslib.xfs.existsSync(filename)) { | ||
const content = await _fslib.xfs.readFilePromise(filename, `utf8`); | ||
const indentMatch = content.match(/^[ \t]+/m); | ||
if (indentMatch) indent = indentMatch[0]; | ||
obj = JSON.parse(content || `{}`); | ||
} | ||
if (!obj) obj = {}; | ||
const tracker = (0, _makeTracker.makeTracker)(obj); | ||
const initial = tracker.immutable; | ||
return { | ||
open(cb) { | ||
tracker.open(cb); | ||
}, | ||
async save() { | ||
if (tracker.immutable === initial) return; | ||
const data = `${JSON.stringify(tracker.immutable, null, indent)}\n`; | ||
await _fslib.xfs.writeFilePromise(filename, data); | ||
let indent = ` `; | ||
let obj; | ||
if (fslib_1.xfs.existsSync(filename)) { | ||
const content = await fslib_1.xfs.readFilePromise(filename, `utf8`); | ||
const indentMatch = content.match(/^[ \t]+/m); | ||
if (indentMatch) | ||
indent = indentMatch[0]; | ||
obj = JSON.parse(content || `{}`); | ||
} | ||
}; | ||
if (!obj) | ||
obj = {}; | ||
const tracker = makeTracker_1.makeTracker(obj); | ||
const initial = tracker.immutable; | ||
return { | ||
open(cb) { | ||
tracker.open(cb); | ||
}, | ||
async save() { | ||
if (tracker.immutable === initial) | ||
return; | ||
const data = `${JSON.stringify(tracker.immutable, null, indent)}\n`; | ||
await fslib_1.xfs.writeFilePromise(filename, data); | ||
}, | ||
}; | ||
} | ||
exports.makeUpdater = makeUpdater; | ||
async function updateAndSave(filename, cb) { | ||
const updater = await makeUpdater(filename); | ||
updater.open(cb); | ||
await updater.save(); | ||
} | ||
const updater = await makeUpdater(filename); | ||
updater.open(cb); | ||
await updater.save(); | ||
} | ||
exports.updateAndSave = updateAndSave; |
{ | ||
"name": "@yarnpkg/json-proxy", | ||
"version": "2.0.0-rc.6", | ||
"version": "2.0.0-rc.7", | ||
"main": "./lib/index.js", | ||
"dependencies": { | ||
"@yarnpkg/fslib": "^2.0.0-rc.12" | ||
"@yarnpkg/fslib": "^2.0.0-rc.15" | ||
}, | ||
@@ -8,0 +8,0 @@ "scripts": { |
11259
7
319
Updated@yarnpkg/fslib@^2.0.0-rc.15