@plugjs/plug
Version:
PlugJS Build System ===================
283 lines (281 loc) • 8.81 kB
JavaScript
;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// utils/diff.ts
var diff_exports = {};
__export(diff_exports, {
diff: () => diff,
textDiff: () => textDiff
});
module.exports = __toCommonJS(diff_exports);
var import_node_assert = require("node:assert");
var import_node_util = require("node:util");
var import_asserts = require("../asserts.cjs");
var import_logging = require("../logging.cjs");
function compareLongestCommonSubsequence(lhsCtx, rhsCtx) {
let lhsStart = 0;
let rhsStart = 0;
let lhsItem = 0;
let rhsItem = 0;
const changes = [];
while (lhsItem < lhsCtx.length || rhsItem < rhsCtx.length) {
if (lhsItem < lhsCtx.length && !lhsCtx.modified[lhsItem] && rhsItem < rhsCtx.length && !rhsCtx.modified[rhsItem]) {
lhsItem++;
rhsItem++;
continue;
}
lhsStart = lhsItem;
rhsStart = rhsItem;
while (lhsItem < lhsCtx.length && (rhsItem >= rhsCtx.length || lhsCtx.modified[lhsItem])) {
lhsItem++;
}
while (rhsItem < rhsCtx.length && (lhsItem >= lhsCtx.length || rhsCtx.modified[rhsItem])) {
rhsItem++;
}
if (lhsStart < lhsItem || rhsStart < rhsItem) {
const lat = Math.min(lhsStart, lhsCtx.length ? lhsCtx.length - 1 : 0);
const rat = Math.min(rhsStart, rhsCtx.length ? rhsCtx.length - 1 : 0);
changes.push({
lhsPos: lat,
lhsDel: lhsItem - lhsStart,
rhsPos: rat,
rhsAdd: rhsItem - rhsStart
});
}
}
return changes;
}
function getShortestMiddleSnake(lhsCtx, lhsLower, lhsUpper, rhsCtx, rhsLower, rhsUpper, vectorU, vectorD) {
const max = lhsCtx.length + rhsCtx.length + 1;
const kdown = lhsLower - rhsLower;
const kup = lhsUpper - rhsUpper;
const delta = lhsUpper - lhsLower - (rhsUpper - rhsLower);
const odd = (delta & 1) != 0;
const offsetDown = max - kdown;
const offsetUp = max - kup;
const maxd = (lhsUpper - lhsLower + rhsUpper - rhsLower) / 2 + 1;
const ret = { x: 0, y: 0 };
let d;
let k;
let x;
let y;
vectorD[offsetDown + kdown + 1] = lhsLower;
vectorU[offsetUp + kup - 1] = lhsUpper;
for (d = 0; d <= maxd; ++d) {
for (k = kdown - d; k <= kdown + d; k += 2) {
if (k === kdown - d) {
x = vectorD[offsetDown + k + 1];
} else {
x = vectorD[offsetDown + k - 1] + 1;
if (k < kdown + d && vectorD[offsetDown + k + 1] >= x) {
x = vectorD[offsetDown + k + 1];
}
}
y = x - k;
while (x < lhsUpper && y < rhsUpper && lhsCtx.codes[x] === rhsCtx.codes[y]) {
x++;
y++;
}
vectorD[offsetDown + k] = x;
if (odd && kup - d < k && k < kup + d) {
if (vectorU[offsetUp + k] <= vectorD[offsetDown + k]) {
ret.x = vectorD[offsetDown + k];
ret.y = vectorD[offsetDown + k] - k;
return ret;
}
}
}
for (k = kup - d; k <= kup + d; k += 2) {
if (k === kup + d) {
x = vectorU[offsetUp + k - 1];
} else {
x = vectorU[offsetUp + k + 1] - 1;
if (k > kup - d && vectorU[offsetUp + k - 1] < x) {
x = vectorU[offsetUp + k - 1];
}
}
y = x - k;
while (x > lhsLower && y > rhsLower && lhsCtx.codes[x - 1] === rhsCtx.codes[y - 1]) {
x--;
y--;
}
vectorU[offsetUp + k] = x;
if (!odd && kdown - d <= k && k <= kdown + d) {
if (vectorU[offsetUp + k] <= vectorD[offsetDown + k]) {
ret.x = vectorD[offsetDown + k];
ret.y = vectorD[offsetDown + k] - k;
return ret;
}
}
}
}
(0, import_node_assert.fail)("Unexpected state computing diff");
}
function getLongestCommonSubsequence(lhsCtx, lhsLower, lhsUpper, rhsCtx, rhsLower, rhsUpper, vectorU = [], vectorD = []) {
while (lhsLower < lhsUpper && rhsLower < rhsUpper && lhsCtx.codes[lhsLower] === rhsCtx.codes[rhsLower]) {
++lhsLower;
++rhsLower;
}
while (lhsLower < lhsUpper && rhsLower < rhsUpper && lhsCtx.codes[lhsUpper - 1] === rhsCtx.codes[rhsUpper - 1]) {
--lhsUpper;
--rhsUpper;
}
if (lhsLower === lhsUpper) {
while (rhsLower < rhsUpper) {
rhsCtx.modified[rhsLower++] = true;
}
} else if (rhsLower === rhsUpper) {
while (lhsLower < lhsUpper) {
lhsCtx.modified[lhsLower++] = true;
}
} else {
const { x, y } = getShortestMiddleSnake(
lhsCtx,
lhsLower,
lhsUpper,
rhsCtx,
rhsLower,
rhsUpper,
vectorU,
vectorD
);
getLongestCommonSubsequence(
lhsCtx,
lhsLower,
x,
rhsCtx,
rhsLower,
y,
vectorU,
vectorD
);
getLongestCommonSubsequence(
lhsCtx,
x,
lhsUpper,
rhsCtx,
y,
rhsUpper,
vectorU,
vectorD
);
}
}
var Context = class {
/** Keep a tab on modified items */
modified;
/** A _code table_ for all the items in this context */
codes;
/** The number of item held by this context */
length;
/** Construct with a _code table_ */
constructor(codes) {
const length = this.length = codes.length;
this.modified = new Array(length);
this.codes = codes;
}
};
var Coder = class {
_primitives = /* @__PURE__ */ new Map();
_objects = [];
_index = 1;
_getObjectCode(item) {
for (const [object, code2] of this._objects) {
if ((0, import_node_util.isDeepStrictEqual)(item, object)) return code2;
}
const code = ++this._index;
this._objects.push([item, code]);
return code;
}
_getPrimitiveCode(item) {
let code = this._primitives.get(item);
if (code) return code;
code = ++this._index;
this._primitives.set(item, code);
return code;
}
/** Get the code table for an {@link Iterable} */
getCodes(iterable) {
const codes = [];
for (const item of iterable) {
const type = item === null ? "null" : typeof item;
const code = type === "object" ? this._getObjectCode(item) : this._getPrimitiveCode(item);
codes.push(code);
}
return codes;
}
};
var inspectOptions = {
showHidden: false,
depth: 10,
colors: false,
maxArrayLength: 100,
maxStringLength: 250,
breakLength: Infinity,
compact: false,
sorted: true,
getters: true
};
function diff(lhs, rhs) {
(0, import_asserts.assert)(lhs !== void 0, "Left-Hand side undefined");
(0, import_asserts.assert)(rhs !== void 0, "Right-Hand side undefined");
const codec = new Coder();
const lhsCtx = new Context(codec.getCodes(lhs));
const rhsCtx = new Context(codec.getCodes(rhs));
getLongestCommonSubsequence(
lhsCtx,
0,
lhsCtx.length,
rhsCtx,
0,
rhsCtx.length
);
return compareLongestCommonSubsequence(lhsCtx, rhsCtx);
}
function textDiff(lhs, rhs, add, del, not) {
const _add = add || (import_logging.logOptions.colors ? import_logging.$grn : (s) => `+ ${s}`);
const _del = del || (import_logging.logOptions.colors ? import_logging.$red : (s) => `- ${s}`);
const _not = not || (import_logging.logOptions.colors ? (s) => s : (s) => ` ${s}`);
let lhsLines;
let rhsLines;
if (typeof lhs === "string" && typeof rhs === "string") {
lhsLines = lhs.split("\n");
rhsLines = rhs.split("\n");
} else {
lhsLines = (0, import_node_util.inspect)(lhs, inspectOptions).split("\n");
rhsLines = (0, import_node_util.inspect)(rhs, inspectOptions).split("\n");
}
const changes = diff(lhsLines, rhsLines);
if (changes.length === 0) return "";
let offset = 0;
const result = [];
changes.forEach(({ lhsPos, lhsDel, rhsPos, rhsAdd }) => {
if (offset != lhsPos) result.push(...lhsLines.slice(offset, lhsPos).map(_not));
if (lhsDel) result.push(...lhsLines.slice(lhsPos, lhsPos + lhsDel).map(_del));
if (rhsAdd) result.push(...rhsLines.slice(rhsPos, rhsPos + rhsAdd).map(_add));
offset = lhsPos + lhsDel;
});
if (offset < lhsLines.length) result.push(...lhsLines.slice(offset).map(_not));
return result.join("\n");
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
diff,
textDiff
});
//# sourceMappingURL=diff.cjs.map