New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

fastener

Package Overview
Dependencies
Maintainers
1
Versions
11
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

fastener - npm Package Compare versions

Comparing version 0.1.0 to 0.2.0

.nyc_output/48433.json

168

lib/fastener.js

@@ -6,6 +6,4 @@ "use strict";

});
exports.fromZipper = exports.toZipper = exports.right = exports.left = exports.downLast = exports.downHead = exports.downTo = exports.up = exports.modify = exports.set = exports.get = undefined;
exports.everywhere = exports.transformMove = exports.queryMove = exports.fromZipper = exports.toZipper = exports.last = exports.head = exports.right = exports.left = exports.downLast = exports.downHead = exports.keyOf = exports.downTo = exports.up = exports.modify = exports.set = exports.get = undefined;
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj; };
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };

@@ -19,4 +17,8 @@

function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; }
function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
var empty = [];
var pass = function pass(x, f) {

@@ -43,55 +45,35 @@ return f(x);

var up = exports.up = function up(z) {
return z.up(z);
};
var downTo = exports.downTo = R.curry(function (k, _ref) {
var upLeft = _ref.left;
var up = exports.up = function up(_ref) {
var left = _ref.left;
var focus = _ref.focus;
var upRight = _ref.right;
var right = _ref.right;
var keys = _ref.keys;
var _up = _ref.up;
if (keys) {
return _extends({ focus: R.zipObj(keys, [].concat(_toConsumableArray(left), [focus], _toConsumableArray(R.reverse(right)))) }, _up);
} else if (_up) {
return _extends({ focus: [].concat(_toConsumableArray(left), [focus], _toConsumableArray(R.reverse(right))) }, _up);
} else {
return undefined;
}
};
var downIndex = function downIndex(values, i, rest) {
return 0 <= i && i < values.length ? _extends({ left: values.slice(0, i),
focus: values[i],
right: values.slice(i + 1).reverse()
}, rest) : undefined;
};
var downTo = exports.downTo = R.curry(function (k, _ref2) {
var focus = _ref2.focus;
var up = _objectWithoutProperties(_ref2, ["focus"]);
if (isObject(focus)) {
var _ret = function () {
var keys = R.keys(focus);
var values = R.values(focus);
var i = keys.findIndex(R.equals(k));
return {
v: {
left: values.slice(0, i),
focus: values[i],
right: values.slice(i + 1),
up: function up(_ref2) {
var left = _ref2.left;
var focus = _ref2.focus;
var right = _ref2.right;
return {
left: upLeft,
focus: R.zipObj(keys, [].concat(_toConsumableArray(left), [focus], _toConsumableArray(right))),
right: upRight,
up: _up
};
}
}
};
}();
if ((typeof _ret === "undefined" ? "undefined" : _typeof(_ret)) === "object") return _ret.v;
var keys = R.keys(focus);
return downIndex(R.values(focus), keys.findIndex(R.equals(k)), { keys: keys, up: up });
} else if (isArray(focus)) {
return {
left: focus.slice(0, k),
focus: focus[k],
right: focus.slice(k + 1),
up: function up(_ref3) {
var left = _ref3.left;
var focus = _ref3.focus;
var right = _ref3.right;
return {
left: upLeft,
focus: [].concat(_toConsumableArray(left), [focus], _toConsumableArray(right)),
right: upRight,
up: _up
};
}
};
return downIndex(focus, k, { up: up });
} else {

@@ -102,2 +84,9 @@ return undefined;

var keyOf = exports.keyOf = function keyOf(_ref3) {
var left = _ref3.left;
var keys = _ref3.keys;
var up = _ref3.up;
return keys ? keys[left.length] : up ? left.length : undefined;
};
var downMost = function downMost(head) {

@@ -122,2 +111,6 @@ return function (z) {

// FYI: The left and right ops are not accidentally O(n). I'm just lazy. :)
var shift = function shift(f, c, t, k) {
return f.length === 0 ? undefined : k(R.dropLast(1, f), R.last(f), R.append(c, t));
};
var left = exports.left = function left(_ref4) {

@@ -127,8 +120,8 @@ var _left = _ref4.left;

var right = _ref4.right;
var up = _ref4.up;
return _left.length === 0 ? undefined : {
left: R.dropLast(1, _left),
focus: R.last(_left),
right: R.prepend(focus, right),
up: up };
var rest = _objectWithoutProperties(_ref4, ["left", "focus", "right"]);
return shift(_left, focus, right, function (l, f, r) {
return _extends({ left: l, focus: f, right: r }, rest);
});
};

@@ -140,14 +133,23 @@

var _right = _ref5.right;
var up = _ref5.up;
return _right.length === 0 ? undefined : {
left: R.append(focus, left),
focus: R.head(_right),
right: R.drop(1, _right),
up: up };
var rest = _objectWithoutProperties(_ref5, ["left", "focus", "right"]);
return shift(_right, focus, left, function (r, f, l) {
return _extends({ left: l, focus: f, right: r }, rest);
});
};
var head = exports.head = function head(z) {
return pass(up(z), function (z) {
return z && downHead(z);
});
};
var last = exports.last = function last(z) {
return pass(up(z), function (z) {
return z && downLast(z);
});
};
var toZipper = exports.toZipper = function toZipper(focus) {
return { left: [], focus: focus, right: [], up: function up() {
return undefined;
} };
return { left: empty, right: empty, focus: focus };
};

@@ -160,2 +162,34 @@

};
//# sourceMappingURL=data:application/json;base64,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QUFBQSxNQUFFLElBQUYsU0FBRSxJQUFGO0FBQUEsTUFBUSxLQUFSLFNBQVEsS0FBUjtBQUFBLE1BQWUsTUFBZixTQUFlLEtBQWY7QUFBQSxNQUFzQixFQUF0QixTQUFzQixFQUF0QjtBQUFBLFNBQ25CLE9BQU0sTUFBTixLQUFpQixDQUFqQixHQUFxQixTQUFyQixHQUFpQztBQUMvQixVQUFNLEVBQUUsTUFBRixDQUFTLEtBQVQsRUFBZ0IsSUFBaEIsQ0FEeUI7QUFFL0IsV0FBTyxFQUFFLElBQUYsQ0FBTyxNQUFQLENBRndCO0FBRy9CLFdBQU8sRUFBRSxJQUFGLENBQU8sQ0FBUCxFQUFVLE1BQVYsQ0FId0I7QUFJL0IsVUFKK0IsRUFEZDtBQUFBLENBQWQ7O0FBT0EsSUFBTSw4QkFBVyxTQUFYLFFBQVc7QUFBQSxTQUNyQixFQUFDLE1BQU0sRUFBUCxFQUFXLFlBQVgsRUFBa0IsT0FBTyxFQUF6QixFQUE2QixJQUFJO0FBQUEsYUFBTSxTQUFOO0FBQUEsS0FBakMsRUFEcUI7QUFBQSxDQUFqQjs7QUFHQSxJQUFNLGtDQUFhLFNBQWIsVUFBYTtBQUFBLFNBQ3hCLEtBQUssR0FBRyxDQUFILENBQUwsRUFBWTtBQUFBLFdBQU0sS0FBSyxXQUFXLEVBQVgsQ0FBTCxHQUFzQixJQUFJLENBQUosQ0FBNUI7QUFBQSxHQUFaLENBRHdCO0FBQUEsQ0FBbkIiLCJmaWxlIjoiZmFzdGVuZXIuanMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBSIGZyb20gXCJyYW1kYVwiXG5cbmNvbnN0IHBhc3MgPSAoeCwgZikgPT4gZih4KVxuXG5jb25zdCBpc09iamVjdCA9IHggPT4geCAmJiB4LmNvbnN0cnVjdG9yID09PSBPYmplY3RcbmNvbnN0IGlzQXJyYXkgPSB4ID0+IHggJiYgeC5jb25zdHJ1Y3RvciA9PT0gQXJyYXlcblxuZXhwb3J0IGNvbnN0IGdldCA9IHogPT4gei5mb2N1c1xuZXhwb3J0IGNvbnN0IHNldCA9IFIuY3VycnkoKGZvY3VzLCB6KSA9PiAoey4uLnosIGZvY3VzfSkpXG5leHBvcnQgY29uc3QgbW9kaWZ5ID0gUi5jdXJyeSgoZiwgeikgPT4gc2V0KGYoZ2V0KHopKSwgeikpXG5cbmV4cG9ydCBjb25zdCB1cCA9IHogPT4gei51cCh6KVxuXG5leHBvcnQgY29uc3QgZG93blRvID0gUi5jdXJyeSgoaywge2xlZnQ6IHVwTGVmdCwgZm9jdXMsIHJpZ2h0OiB1cFJpZ2h0LCB1cH0pID0+IHtcbiAgaWYgKGlzT2JqZWN0KGZvY3VzKSkge1xuICAgIGNvbnN0IGtleXMgPSBSLmtleXMoZm9jdXMpXG4gICAgY29uc3QgdmFsdWVzID0gUi52YWx1ZXMoZm9jdXMpXG4gICAgY29uc3QgaSA9IGtleXMuZmluZEluZGV4KFIuZXF1YWxzKGspKVxuICAgIHJldHVybiB7XG4gICAgICBsZWZ0OiB2YWx1ZXMuc2xpY2UoMCwgaSksXG4gICAgICBmb2N1czogdmFsdWVzW2ldLFxuICAgICAgcmlnaHQ6IHZhbHVlcy5zbGljZShpKzEpLFxuICAgICAgdXA6ICh7bGVmdCwgZm9jdXMsIHJpZ2h0fSkgPT4gKHtcbiAgICAgICAgbGVmdDogdXBMZWZ0LFxuICAgICAgICBmb2N1czogUi56aXBPYmooa2V5cywgWy4uLmxlZnQsIGZvY3VzLCAuLi5yaWdodF0pLFxuICAgICAgICByaWdodDogdXBSaWdodCxcbiAgICAgICAgdXBcbiAgICAgIH0pXG4gICAgfVxuICB9IGVsc2UgaWYgKGlzQXJyYXkoZm9jdXMpKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGxlZnQ6IGZvY3VzLnNsaWNlKDAsIGspLFxuICAgICAgZm9jdXM6IGZvY3VzW2tdLFxuICAgICAgcmlnaHQ6IGZvY3VzLnNsaWNlKGsrMSksXG4gICAgICB1cDogKHtsZWZ0LCBmb2N1cywgcmlnaHR9KSA9PiAoe1xuICAgICAgICBsZWZ0OiB1cExlZnQsXG4gICAgICAgIGZvY3VzOiBbLi4ubGVmdCwgZm9jdXMsIC4uLnJpZ2h0XSxcbiAgICAgICAgcmlnaHQ6IHVwUmlnaHQsXG4gICAgICAgIHVwXG4gICAgICB9KVxuICAgIH1cbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkXG4gIH1cbn0pXG5cbmNvbnN0IGRvd25Nb3N0ID0gaGVhZCA9PiB6ID0+IHtcbiAgY29uc3Qge2ZvY3VzfSA9IHpcbiAgaWYgKGlzQXJyYXkoZm9jdXMpKSB7XG4gICAgcmV0dXJuIGZvY3VzLmxlbmd0aCA/IGRvd25UbyhoZWFkID8gMCA6IGZvY3VzLmxlbmd0aC0xLCB6KSA6IHVuZGVmaW5lZFxuICB9IGVsc2UgaWYgKGlzT2JqZWN0KGZvY3VzKSkge1xuICAgIGNvbnN0IGtleXMgPSBSLmtleXMoZm9jdXMpXG4gICAgcmV0dXJuIGtleXMubGVuZ3RoID8gZG93blRvKHJpZ2h0ID8ga2V5c1swXSA6IFIubGFzdChrZXlzKSwgeikgOiB1bmRlZmluZWRcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkXG4gIH1cbn1cblxuZXhwb3J0IGNvbnN0IGRvd25IZWFkID0gZG93bk1vc3QodHJ1ZSlcbmV4cG9ydCBjb25zdCBkb3duTGFzdCA9IGRvd25Nb3N0KGZhbHNlKVxuXG4vLyBGWUk6IFRoZSBsZWZ0IGFuZCByaWdodCBvcHMgYXJlIG5vdCBhY2NpZGVudGFsbHkgTyhuKS4gIEknbSBqdXN0IGxhenkuIDopXG5leHBvcnQgY29uc3QgbGVmdCA9ICh7bGVmdCwgZm9jdXMsIHJpZ2h0LCB1cH0pID0+XG4gIGxlZnQubGVuZ3RoID09PSAwID8gdW5kZWZpbmVkIDoge1xuICAgIGxlZnQ6IFIuZHJvcExhc3QoMSwgbGVmdCksXG4gICAgZm9jdXM6IFIubGFzdChsZWZ0KSxcbiAgICByaWdodDogUi5wcmVwZW5kKGZvY3VzLCByaWdodCksXG4gICAgdXB9XG5cbmV4cG9ydCBjb25zdCByaWdodCA9ICh7bGVmdCwgZm9jdXMsIHJpZ2h0LCB1cH0pID0+XG4gIHJpZ2h0Lmxlbmd0aCA9PT0gMCA/IHVuZGVmaW5lZCA6IHtcbiAgICBsZWZ0OiBSLmFwcGVuZChmb2N1cywgbGVmdCksXG4gICAgZm9jdXM6IFIuaGVhZChyaWdodCksXG4gICAgcmlnaHQ6IFIuZHJvcCgxLCByaWdodCksXG4gICAgdXB9XG5cbmV4cG9ydCBjb25zdCB0b1ppcHBlciA9IGZvY3VzID0+XG4gICh7bGVmdDogW10sIGZvY3VzLCByaWdodDogW10sIHVwOiAoKSA9PiB1bmRlZmluZWR9KVxuXG5leHBvcnQgY29uc3QgZnJvbVppcHBlciA9IHogPT5cbiAgcGFzcyh1cCh6KSwgenogPT4genogPyBmcm9tWmlwcGVyKHp6KSA6IGdldCh6KSlcbiJdfQ==
var queryMove = exports.queryMove = R.curry(function (move, b, f, z) {
return pass(move(z), function (z) {
return z ? f(z) : b;
});
});
var bwd = function bwd(move, z) {
switch (move) {
case left:
return right;
case right:
return left;
case up:
return downTo(keyOf(z));
default:
return up;
}
};
var transformMove = exports.transformMove = R.curry(function (move, f, z) {
return queryMove(move, z, R.pipe(f, queryMove(bwd(move, z), z, R.identity)), z);
});
var everywhereG = function everywhereG(f) {
return function (z) {
return transformMove(right, everywhereG(f), everywhere(f, z));
};
};
var everywhere = exports.everywhere = R.curry(function (f, z) {
return modify(f, transformMove(downHead, everywhereG(f), z));
});
//# sourceMappingURL=data:application/json;base64,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RHVCO0FBQUEsR0FBTDtBQUFBLENBQXBCO0FBRU8sSUFBTSxrQ0FBYSxFQUFFLEtBQUYsQ0FBUSxVQUFDLENBQUQsRUFBSSxDQUFKO0FBQUEsU0FDaEMsT0FBTyxDQUFQLEVBQVUsY0FBYyxRQUFkLEVBQXdCLFlBQVksQ0FBWixDQUF4QixFQUF3QyxDQUF4QyxDQUFWLENBRGdDO0FBQUEsQ0FBUixDQUFuQiIsImZpbGUiOiJmYXN0ZW5lci5qcyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIFIgZnJvbSBcInJhbWRhXCJcblxuY29uc3QgZW1wdHkgPSBbXVxuXG5jb25zdCBwYXNzID0gKHgsIGYpID0+IGYoeClcblxuY29uc3QgaXNPYmplY3QgPSB4ID0+IHggJiYgeC5jb25zdHJ1Y3RvciA9PT0gT2JqZWN0XG5jb25zdCBpc0FycmF5ID0geCA9PiB4ICYmIHguY29uc3RydWN0b3IgPT09IEFycmF5XG5cbmV4cG9ydCBjb25zdCBnZXQgPSB6ID0+IHouZm9jdXNcbmV4cG9ydCBjb25zdCBzZXQgPSBSLmN1cnJ5KChmb2N1cywgeikgPT4gKHsuLi56LCBmb2N1c30pKVxuZXhwb3J0IGNvbnN0IG1vZGlmeSA9IFIuY3VycnkoKGYsIHopID0+IHNldChmKGdldCh6KSksIHopKVxuXG5leHBvcnQgY29uc3QgdXAgPSAoe2xlZnQsIGZvY3VzLCByaWdodCwga2V5cywgdXB9KSA9PiB7XG4gIGlmIChrZXlzKSB7XG4gICAgcmV0dXJuIHtmb2N1czogUi56aXBPYmooa2V5cywgWy4uLmxlZnQsIGZvY3VzLCAuLi5SLnJldmVyc2UocmlnaHQpXSksIC4uLnVwfVxuICB9IGVsc2UgaWYgKHVwKSB7XG4gICAgcmV0dXJuIHtmb2N1czogWy4uLmxlZnQsIGZvY3VzLCAuLi5SLnJldmVyc2UocmlnaHQpXSwgLi4udXB9XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZFxuICB9XG59XG5cbmNvbnN0IGRvd25JbmRleCA9ICh2YWx1ZXMsIGksIHJlc3QpID0+XG4gIDAgPD0gaSAmJiBpIDwgdmFsdWVzLmxlbmd0aFxuICA/ICh7bGVmdDogdmFsdWVzLnNsaWNlKDAsIGkpLFxuICAgICAgZm9jdXM6IHZhbHVlc1tpXSxcbiAgICAgIHJpZ2h0OiB2YWx1ZXMuc2xpY2UoaSsxKS5yZXZlcnNlKCksXG4gICAgICAuLi5yZXN0fSlcbiAgOiB1bmRlZmluZWRcblxuZXhwb3J0IGNvbnN0IGRvd25UbyA9IFIuY3VycnkoKGssIHtmb2N1cywgLi4udXB9KSA9PiB7XG4gIGlmIChpc09iamVjdChmb2N1cykpIHtcbiAgICBjb25zdCBrZXlzID0gUi5rZXlzKGZvY3VzKVxuICAgIHJldHVybiBkb3duSW5kZXgoUi52YWx1ZXMoZm9jdXMpLCBrZXlzLmZpbmRJbmRleChSLmVxdWFscyhrKSksIHtrZXlzLCB1cH0pXG4gIH0gZWxzZSBpZiAoaXNBcnJheShmb2N1cykpIHtcbiAgICByZXR1cm4gZG93bkluZGV4KGZvY3VzLCBrLCB7dXB9KVxuICB9IGVsc2Uge1xuICAgIHJldHVybiB1bmRlZmluZWRcbiAgfVxufSlcblxuZXhwb3J0IGNvbnN0IGtleU9mID0gKHtsZWZ0LCBrZXlzLCB1cH0pID0+XG4gIGtleXMgPyBrZXlzW2xlZnQubGVuZ3RoXSA6XG4gIHVwICAgPyBsZWZ0Lmxlbmd0aCA6XG4gIHVuZGVmaW5lZFxuXG5jb25zdCBkb3duTW9zdCA9IGhlYWQgPT4geiA9PiB7XG4gIGNvbnN0IHtmb2N1c30gPSB6XG4gIGlmIChpc0FycmF5KGZvY3VzKSkge1xuICAgIHJldHVybiBmb2N1cy5sZW5ndGggPyBkb3duVG8oaGVhZCA/IDAgOiBmb2N1cy5sZW5ndGgtMSwgeikgOiB1bmRlZmluZWRcbiAgfSBlbHNlIGlmIChpc09iamVjdChmb2N1cykpIHtcbiAgICBjb25zdCBrZXlzID0gUi5rZXlzKGZvY3VzKVxuICAgIHJldHVybiBrZXlzLmxlbmd0aCA/IGRvd25UbyhyaWdodCA/IGtleXNbMF0gOiBSLmxhc3Qoa2V5cyksIHopIDogdW5kZWZpbmVkXG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZFxuICB9XG59XG5cbmV4cG9ydCBjb25zdCBkb3duSGVhZCA9IGRvd25Nb3N0KHRydWUpXG5leHBvcnQgY29uc3QgZG93bkxhc3QgPSBkb3duTW9zdChmYWxzZSlcblxuLy8gRllJOiBUaGUgbGVmdCBhbmQgcmlnaHQgb3BzIGFyZSBub3QgYWNjaWRlbnRhbGx5IE8obikuICBJJ20ganVzdCBsYXp5LiA6KVxuY29uc3Qgc2hpZnQgPSAoZiwgYywgdCwgaykgPT5cbiAgZi5sZW5ndGggPT09IDAgPyB1bmRlZmluZWQgOiBrKFIuZHJvcExhc3QoMSwgZiksIFIubGFzdChmKSwgUi5hcHBlbmQoYywgdCkpXG5cbmV4cG9ydCBjb25zdCBsZWZ0ID0gKHtsZWZ0LCBmb2N1cywgcmlnaHQsIC4uLnJlc3R9KSA9PlxuICBzaGlmdChsZWZ0LCBmb2N1cywgcmlnaHQsIChsLCBmLCByKSA9PiAoe2xlZnQ6IGwsIGZvY3VzOiBmLCByaWdodDogciwgLi4ucmVzdH0pKVxuXG5leHBvcnQgY29uc3QgcmlnaHQgPSAoe2xlZnQsIGZvY3VzLCByaWdodCwgLi4ucmVzdH0pID0+XG4gIHNoaWZ0KHJpZ2h0LCBmb2N1cywgbGVmdCwgKHIsIGYsIGwpID0+ICh7bGVmdDogbCwgZm9jdXM6IGYsIHJpZ2h0OiByLCAuLi5yZXN0fSkpXG5cbmV4cG9ydCBjb25zdCBoZWFkID0geiA9PiBwYXNzKHVwKHopLCB6ID0+IHogJiYgZG93bkhlYWQoeikpXG5leHBvcnQgY29uc3QgbGFzdCA9IHogPT4gcGFzcyh1cCh6KSwgeiA9PiB6ICYmIGRvd25MYXN0KHopKVxuXG5leHBvcnQgY29uc3QgdG9aaXBwZXIgPSBmb2N1cyA9PiAoe2xlZnQ6IGVtcHR5LCByaWdodDogZW1wdHksIGZvY3VzfSlcblxuZXhwb3J0IGNvbnN0IGZyb21aaXBwZXIgPSB6ID0+XG4gIHBhc3ModXAoeiksIHp6ID0+IHp6ID8gZnJvbVppcHBlcih6eikgOiBnZXQoeikpXG5cbmV4cG9ydCBjb25zdCBxdWVyeU1vdmUgPSBSLmN1cnJ5KChtb3ZlLCBiLCBmLCB6KSA9PlxuICBwYXNzKG1vdmUoeiksIHogPT4geiA/IGYoeikgOiBiKSlcblxuY29uc3QgYndkID0gKG1vdmUsIHopID0+IHtcbiAgc3dpdGNoIChtb3ZlKSB7XG4gICAgY2FzZSBsZWZ0OiByZXR1cm4gcmlnaHRcbiAgICBjYXNlIHJpZ2h0OiByZXR1cm4gbGVmdFxuICAgIGNhc2UgdXA6IHJldHVybiBkb3duVG8oa2V5T2YoeikpXG4gICAgZGVmYXVsdDogcmV0dXJuIHVwXG4gIH1cbn1cblxuZXhwb3J0IGNvbnN0IHRyYW5zZm9ybU1vdmUgPSBSLmN1cnJ5KChtb3ZlLCBmLCB6KSA9PlxuICBxdWVyeU1vdmUobW92ZSwgeiwgUi5waXBlKGYsIHF1ZXJ5TW92ZShid2QobW92ZSwgeiksIHosIFIuaWRlbnRpdHkpKSwgeikpXG5cbmNvbnN0IGV2ZXJ5d2hlcmVHID0gZiA9PiB6ID0+XG4gIHRyYW5zZm9ybU1vdmUocmlnaHQsIGV2ZXJ5d2hlcmVHKGYpLCBldmVyeXdoZXJlKGYsIHopKVxuZXhwb3J0IGNvbnN0IGV2ZXJ5d2hlcmUgPSBSLmN1cnJ5KChmLCB6KSA9PlxuICBtb2RpZnkoZiwgdHJhbnNmb3JtTW92ZShkb3duSGVhZCwgZXZlcnl3aGVyZUcoZiksIHopKSlcbiJdfQ==
{
"name": "fastener",
"version": "0.1.0",
"version": "0.2.0",
"description": "Zipper for manipulating JSON",

@@ -5,0 +5,0 @@ "main": "lib/fastener.js",

@@ -0,3 +1,229 @@

[ [Tutorial](#tutorial) | [Reference](#reference) | [Related Work](#related-work) ]
[Zippers](https://www.st.cs.uni-saarland.de/edu/seminare/2005/advanced-fp/docs/huet-zipper.pdf)
are a powerful abstraction for *implementing* arbitrary queries and transforms
on immutable data structures and for step-by-step navigation and modification of
data structures. This library implements a simple zipper designed for
manipulating JSON data.
[![npm version](https://badge.fury.io/js/fastener.svg)](http://badge.fury.io/js/fastener) [![Build Status](https://travis-ci.org/polytypic/fastener.svg?branch=master)](https://travis-ci.org/polytypic/fastener) [![](https://david-dm.org/polytypic/fastener.svg)](https://david-dm.org/polytypic/fastener) [![](https://david-dm.org/polytypic/fastener/dev-status.svg)](https://david-dm.org/polytypic/fastener#info=devDependencies)
This is the very beginnings of a Zipper library for manipulating JSON.
## Tutorial
## Reference
The zipper combinators are available as named imports. Typically one just
imports the the library as:
```js
import * as F from "fastener"
```
In the following examples we will make use of the function
```js
const seq = (x, ...fs) => R.reduce((x, f) => f(x), x, fs)
```
written using [reduce](http://ramdajs.com/0.21.0/docs/#reduce) that allows one
to express a sequence of operations to perform starting from a given value.
### Introduction and Elimination
#### <a name="toZipper"></a>[`F.toZipper(json)`](#toZipper "toZipper :: JSON -> Zipper")
`F.toZipper(json)` creates a new zipper that is focused on the root of the given
JSON object.
For example:
```js
seq(F.toZipper([1,2,3]),
F.downHead,
F.modify(x => x + 1),
F.fromZipper)
// [ 2, 2, 3 ]
```
#### <a name="fromZipper"></a>[`F.fromZipper(zipper)`](#fromZipper "fromZipper :: Zipper -> JSON")
`F.fromZipper(zipper)` extracts the modified JSON object from the given zipper.
For example:
```js
seq(F.toZipper([1,2,3]),
F.downHead,
F.modify(x => x + 1),
F.fromZipper)
// [ 2, 2, 3 ]
```
### Focus
Focus combinators allow one to inspect and modify the element that a zipper is
focused on.
#### <a name="get"></a>[`F.get(zipper)`](#get "get :: Zipper -> JSON")
`F.get(zipper)` returns the element that the zipper is focused on.
For example:
```js
seq(F.toZipper(1), F.get)
// 1
seq(F.toZipper(["a","b","c"]),
F.downTo(2),
F.get)
// 'c'
```
#### <a name="modify"></a>[`F.modify(fn, zipper)`](#modify "modify :: (JSON -> JSON) -> Zipper -> Zipper")
`F.modify(fn, zipper)` is equivalent to `F.set(fn(F.get(zipper)), zipper)` and
replaces the element that the zipper is focused on with the value returned by
the given function for the element.
For example:
```js
seq(F.toZipper(["a","b","c"]),
F.downTo(2),
F.modify(x => x + x),
F.fromZipper)
// [ 'a', 'b', 'cc' ]
```
#### <a name="set"></a>[`F.set(json, zipper)`](#set "set :: JSON -> Zipper -> Zipper")
`F.set(json, zipper)` replaces the element that the zipper is focused on with
the given value.
For example:
```js
seq(F.toZipper(["a","b","c"]),
F.downTo(1),
F.set('lol'),
F.fromZipper)
// [ 'a', 'lol', 'c' ]
```
### Movement
Movement combinators can be applied to any zipper, but they return `undefined`
in case of illegal moves.
#### Parent-Child movement
Parent-Child movement is moving the focus between that parent object or array
and a child element of said parent.
##### <a name="downHead"></a>[`F.downHead(zipper)`](#downHead "downHead :: Zipper -> Maybe Zipper")
`F.downHead(zipper)` moves the focus to the leftmost element of the object or
array that the zipper is focused on.
##### <a name="downLast"></a>[`F.downLast(zipper)`](#downLast "downLast :: Zipper -> Maybe Zipper")
`F.downLast(zipper)` moves the focus to the rightmost element of the object or
array that the zipper is focused on.
##### <a name="downTo"></a>[`F.downTo(key, zipper)`](#downTo "downTo :: (String|Number) -> Zipper -> Maybe Zipper")
`F.downTo(key, zipper)` moves the focus to the specified object property or
array index of the object or array that the zipper is focused on.
##### <a name="keyOf"></a>[`F.keyOf(zipper)`](#keyOf "keyOf :: Zipper -> Maybe (String|Number)")
`F.keyOf(zipper)` returns the object property name or the array index that the
zipper is currently focused on.
##### <a name="up"></a>[`F.up(zipper)`](#up "up :: Zipper -> Maybe Zipper")
`F.up(zipper)` moves the focus from an array element or object property to the
containing array or object.
#### Sibling movement
Sibling movement is moving the focus between the elements of an array or an object.
##### <a name="head"></a>[`F.head(zipper)`](#head "head :: Zipper -> Maybe Zipper")
`F.head(zipper)` moves the focus to the leftmost sibling of the current focus.
##### <a name="last"></a>[`F.last(zipper)`](#last "last :: Zipper -> Maybe Zipper")
`F.last(zipper)` moves the focus to the rightmost sibling of the current focus.
##### <a name="left"></a>[`F.left(zipper)`](#left "left :: Zipper -> Maybe Zipper")
`F.left(zipper)` moves the focus to the element on the left of the current focus.
##### <a name="right"></a>[`F.right(zipper)`](#right "right :: Zipper -> Maybe Zipper")
`F.right(zipper)` moves the focus to the element on the right of the current focus.
### Queries
#### <a name="queryMove"></a>[`F.queryMove(move, default, fn, zipper)`](#queryMove "F.queryMove :: (Zipper -> Maybe Zipper) -> a -> (Zipper -> a) -> Zipper -> a")
`F.queryMove(move, default, fn, zipper)` applies the given function `fn` to the
zipper focused on after the given movement and returns the result unless the
move was illegal in which case the given default value is returned instead.
For example:
```js
seq(F.toZipper({x: 1}),
F.queryMove(F.downTo('y'), false, () => true))
// false
seq(F.toZipper({y: 1}),
F.queryMove(F.downTo('y'), false, () => true))
// true
```
### Transforms
#### <a name="transformMove"></a>[`F.transformMove(move, fn, zipper)`](#transformMove "F.transformMove :: (downHead|downLast|downTo(key)|left|right|up) -> (Zipper -> Zipper) -> Zipper -> Zipper")
`F.transformMove(move, fn, zipper)` applies the given function to the zipper
focused on after the given movement. The function must the return a zipper
focused on the same element that it was given. Then the focus is moved back to
the element that the zipper was originall focused on. Nothing is done in case
of an illegal move.
For example:
```js
seq(F.toZipper({y: 1}),
F.transformMove(F.downTo('y'), F.modify(x => x + 1)),
F.fromZipper)
// { y: 2 }
seq(F.toZipper({x: 1}),
F.transformMove(F.downTo('y'), F.modify(x => x + 1)),
F.fromZipper)
// { x: 1 }
```
#### <a name="everywhere"></a>[`F.everywhere(fn, zipper)`](#everywhere "F.everywhere :: (JSON -> JSON) -> Zipper -> Zipper")
`F.everywhere(fn, zipper)` performs a transform of the focused element by
modifying each possible focus of the element with a bottom-up traversal.
For example:
```js
seq(F.toZipper({foo: 1,
bar: [{lol: "bal", example: 2}]}),
F.everywhere(x => typeof x === "number" ? x + 1 : x),
F.fromZipper)
// { foo: 2, bar: [ { lol: 'bal', example: 3 } ] }
```
## Related Work
While the implementation is very different, the choice of combinators is based
on Michael D. Adams' paper
[Scrap Your Zippers](http://michaeldadams.org/papers/scrap_your_zippers/).
import * as R from "ramda"
const empty = []
const pass = (x, f) => f(x)

@@ -12,32 +14,26 @@

export const up = z => z.up(z)
export const up = ({left, focus, right, keys, up}) => {
if (keys) {
return {focus: R.zipObj(keys, [...left, focus, ...R.reverse(right)]), ...up}
} else if (up) {
return {focus: [...left, focus, ...R.reverse(right)], ...up}
} else {
return undefined
}
}
export const downTo = R.curry((k, {left: upLeft, focus, right: upRight, up}) => {
const downIndex = (values, i, rest) =>
0 <= i && i < values.length
? ({left: values.slice(0, i),
focus: values[i],
right: values.slice(i+1).reverse(),
...rest})
: undefined
export const downTo = R.curry((k, {focus, ...up}) => {
if (isObject(focus)) {
const keys = R.keys(focus)
const values = R.values(focus)
const i = keys.findIndex(R.equals(k))
return {
left: values.slice(0, i),
focus: values[i],
right: values.slice(i+1),
up: ({left, focus, right}) => ({
left: upLeft,
focus: R.zipObj(keys, [...left, focus, ...right]),
right: upRight,
up
})
}
return downIndex(R.values(focus), keys.findIndex(R.equals(k)), {keys, up})
} else if (isArray(focus)) {
return {
left: focus.slice(0, k),
focus: focus[k],
right: focus.slice(k+1),
up: ({left, focus, right}) => ({
left: upLeft,
focus: [...left, focus, ...right],
right: upRight,
up
})
}
return downIndex(focus, k, {up})
} else {

@@ -48,2 +44,7 @@ return undefined

export const keyOf = ({left, keys, up}) =>
keys ? keys[left.length] :
up ? left.length :
undefined
const downMost = head => z => {

@@ -65,20 +66,37 @@ const {focus} = z

// FYI: The left and right ops are not accidentally O(n). I'm just lazy. :)
export const left = ({left, focus, right, up}) =>
left.length === 0 ? undefined : {
left: R.dropLast(1, left),
focus: R.last(left),
right: R.prepend(focus, right),
up}
const shift = (f, c, t, k) =>
f.length === 0 ? undefined : k(R.dropLast(1, f), R.last(f), R.append(c, t))
export const right = ({left, focus, right, up}) =>
right.length === 0 ? undefined : {
left: R.append(focus, left),
focus: R.head(right),
right: R.drop(1, right),
up}
export const left = ({left, focus, right, ...rest}) =>
shift(left, focus, right, (l, f, r) => ({left: l, focus: f, right: r, ...rest}))
export const toZipper = focus =>
({left: [], focus, right: [], up: () => undefined})
export const right = ({left, focus, right, ...rest}) =>
shift(right, focus, left, (r, f, l) => ({left: l, focus: f, right: r, ...rest}))
export const head = z => pass(up(z), z => z && downHead(z))
export const last = z => pass(up(z), z => z && downLast(z))
export const toZipper = focus => ({left: empty, right: empty, focus})
export const fromZipper = z =>
pass(up(z), zz => zz ? fromZipper(zz) : get(z))
export const queryMove = R.curry((move, b, f, z) =>
pass(move(z), z => z ? f(z) : b))
const bwd = (move, z) => {
switch (move) {
case left: return right
case right: return left
case up: return downTo(keyOf(z))
default: return up
}
}
export const transformMove = R.curry((move, f, z) =>
queryMove(move, z, R.pipe(f, queryMove(bwd(move, z), z, R.identity)), z))
const everywhereG = f => z =>
transformMove(right, everywhereG(f), everywhere(f, z))
export const everywhere = R.curry((f, z) =>
modify(f, transformMove(downHead, everywhereG(f), z)))

@@ -33,3 +33,4 @@ import * as R from "ramda"

" F.downHead," +
" F.downHead," +
" F.downLast," +
" F.head," +
" F.right," +

@@ -45,4 +46,36 @@ " F.right," +

describe("illegal moves", () => {
["downHead", "downLast", "downTo(0)", "left", "right", "up"]
["downHead", "downLast", "downTo(0)", "left", "right", "up", "keyOf", "head", "last"]
.forEach(op => testEq(`seq(F.toZipper(1), F.${op})`, undefined))
testEq("seq(F.toZipper({x: 1}), F.downTo(0))", undefined)
testEq("seq(F.toZipper({x: 1}), F.downTo('y'))", undefined)
testEq("seq(F.toZipper([1,2,3]), F.downTo(5))", undefined)
})
describe("keyOf", () => {
testEq("seq(F.toZipper({x: 1, y: 2})," +
" F.downTo('x')," +
" F.keyOf)",
'x')
testEq("seq(F.toZipper({x: 1, y: 2})," +
" F.downTo('y')," +
" F.keyOf)",
'y')
testEq("seq(F.toZipper(['a','b','c','d'])," +
" F.downHead," +
" F.last," +
" F.left," +
" F.left," +
" F.right," +
" F.keyOf)",
2)
})
describe("everywhere", () => {
testEq("seq(F.toZipper({foo: [1, {y: 2}, 3], bar: 0})," +
" F.everywhere(x => typeof x == 'number' ? x+1 : x)," +
" F.fromZipper)",
{foo: [2, {y: 3}, 4], bar: 1})
})
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc