@poe-platform/safe-bash 0.1.65 → 0.1.67
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/safe-bash/browser.js +143 -43
- package/dist/safe-bash/browser.js.map +2 -2
- package/dist/safe-bash/commands/text-programs/awk-runtime.d.ts +1 -0
- package/dist/safe-bash/commands/text-programs/awk-runtime.d.ts.map +1 -1
- package/dist/safe-bash/commands/text-programs/awk-runtime.js +99 -33
- package/dist/safe-bash/commands/text-programs/awk-runtime.js.map +1 -1
- package/dist/safe-bash/commands/text-programs/sed.d.ts.map +1 -1
- package/dist/safe-bash/commands/text-programs/sed.js +11 -2
- package/dist/safe-bash/commands/text-programs/sed.js.map +1 -1
- package/dist/safe-bash/commands/text.d.ts.map +1 -1
- package/dist/safe-bash/commands/text.js +148 -43
- package/dist/safe-bash/commands/text.js.map +1 -1
- package/package.json +2 -2
|
@@ -4586,6 +4586,68 @@ function streamCommands() {
|
|
|
4586
4586
|
|
|
4587
4587
|
// packages/safe-bash/src/commands/text.ts
|
|
4588
4588
|
init_platform();
|
|
4589
|
+
var SortWork = class {
|
|
4590
|
+
constructor(signal) {
|
|
4591
|
+
this.signal = signal;
|
|
4592
|
+
}
|
|
4593
|
+
signal;
|
|
4594
|
+
#pending = 0;
|
|
4595
|
+
charge(units = 1) {
|
|
4596
|
+
this.signal.throwIfAborted();
|
|
4597
|
+
this.#pending += units;
|
|
4598
|
+
if (this.#pending >= 4096) return this.#checkpoint();
|
|
4599
|
+
}
|
|
4600
|
+
async #checkpoint() {
|
|
4601
|
+
while (this.#pending >= 4096) {
|
|
4602
|
+
this.#pending -= 4096;
|
|
4603
|
+
await yieldTurn(this.signal);
|
|
4604
|
+
this.signal.throwIfAborted();
|
|
4605
|
+
}
|
|
4606
|
+
}
|
|
4607
|
+
};
|
|
4608
|
+
async function sortRecords(records, compare, work) {
|
|
4609
|
+
if (records.length < 2) return records;
|
|
4610
|
+
let source = records;
|
|
4611
|
+
let target = new Array(records.length);
|
|
4612
|
+
for (let width = 1; width < records.length; width *= 2) {
|
|
4613
|
+
for (let begin = 0; begin < records.length; begin += width * 2) {
|
|
4614
|
+
const middle = Math.min(begin + width, records.length);
|
|
4615
|
+
const end = Math.min(begin + width * 2, records.length);
|
|
4616
|
+
let left = begin;
|
|
4617
|
+
let right = middle;
|
|
4618
|
+
for (let index = begin; index < end; index++) {
|
|
4619
|
+
const checkpoint = work.charge();
|
|
4620
|
+
if (checkpoint) await checkpoint;
|
|
4621
|
+
if (left < middle && (right === end || await compare(source[left], source[right]) <= 0)) target[index] = source[left++];
|
|
4622
|
+
else target[index] = source[right++];
|
|
4623
|
+
}
|
|
4624
|
+
}
|
|
4625
|
+
[source, target] = [target, source];
|
|
4626
|
+
}
|
|
4627
|
+
return source;
|
|
4628
|
+
}
|
|
4629
|
+
async function compareSortBytes(left, right, work) {
|
|
4630
|
+
const length = Math.min(left.length, right.length);
|
|
4631
|
+
for (let offset = 0; offset < length; offset += 1024) {
|
|
4632
|
+
const end = Math.min(offset + 1024, length);
|
|
4633
|
+
await work.charge(2 * (end - offset));
|
|
4634
|
+
const compared = import_buffer.Buffer.compare(left.subarray(offset, end), right.subarray(offset, end));
|
|
4635
|
+
if (compared) return compared;
|
|
4636
|
+
}
|
|
4637
|
+
return left.length - right.length;
|
|
4638
|
+
}
|
|
4639
|
+
async function foldSortBytes(bytes2, work) {
|
|
4640
|
+
const folded = new Uint8Array(bytes2.length);
|
|
4641
|
+
for (let offset = 0; offset < bytes2.length; offset += 1024) {
|
|
4642
|
+
const end = Math.min(offset + 1024, bytes2.length);
|
|
4643
|
+
await work.charge(end - offset);
|
|
4644
|
+
for (let index = offset; index < end; index++) {
|
|
4645
|
+
const byte = bytes2[index];
|
|
4646
|
+
folded[index] = byte >= 97 && byte <= 122 ? byte - 32 : byte;
|
|
4647
|
+
}
|
|
4648
|
+
}
|
|
4649
|
+
return folded;
|
|
4650
|
+
}
|
|
4589
4651
|
async function admitTextOutput(context, destination) {
|
|
4590
4652
|
if (destination === void 0) return;
|
|
4591
4653
|
assertCommandRequirements(context, textOutputRequirements, ["output"]);
|
|
@@ -4602,27 +4664,37 @@ function compareBytes(left, right) {
|
|
|
4602
4664
|
function fold(bytes2) {
|
|
4603
4665
|
return bytes2.map((byte) => byte >= 97 && byte <= 122 ? byte - 32 : byte);
|
|
4604
4666
|
}
|
|
4605
|
-
function parseNumeric(bytes2) {
|
|
4667
|
+
async function parseNumeric(bytes2, work) {
|
|
4668
|
+
await work.charge(bytes2.length);
|
|
4606
4669
|
const match = /^[ \t]*(-?)([0-9]*)(?:\.([0-9]*))?/u.exec(import_buffer.Buffer.from(bytes2).toString("latin1"));
|
|
4607
4670
|
const whole = (match[2] ?? "").replace(/^0+/u, "") || "0";
|
|
4608
4671
|
const fraction = (match[3] ?? "").replace(/0+$/u, "");
|
|
4609
4672
|
return { whole, fraction, negative: match[1] === "-" && (whole !== "0" || fraction !== "") };
|
|
4610
4673
|
}
|
|
4611
|
-
function compareNumericValues(first, second) {
|
|
4674
|
+
async function compareNumericValues(first, second, work) {
|
|
4612
4675
|
if (first.negative !== second.negative) return first.negative ? -1 : 1;
|
|
4613
4676
|
let compared = first.whole.length - second.whole.length;
|
|
4614
|
-
if (!compared)
|
|
4677
|
+
if (!compared) {
|
|
4678
|
+
for (let offset = 0; offset < first.whole.length && !compared; offset += 1024) {
|
|
4679
|
+
const end = Math.min(offset + 1024, first.whole.length);
|
|
4680
|
+
await work.charge(2 * (end - offset));
|
|
4681
|
+
const firstWhole = first.whole.slice(offset, end);
|
|
4682
|
+
const secondWhole = second.whole.slice(offset, end);
|
|
4683
|
+
compared = firstWhole < secondWhole ? -1 : firstWhole > secondWhole ? 1 : 0;
|
|
4684
|
+
}
|
|
4685
|
+
}
|
|
4615
4686
|
if (!compared) {
|
|
4616
4687
|
const width = Math.max(first.fraction.length, second.fraction.length);
|
|
4617
|
-
|
|
4618
|
-
|
|
4619
|
-
|
|
4688
|
+
for (let offset = 0; offset < width && !compared; offset += 1024) {
|
|
4689
|
+
const end = Math.min(offset + 1024, width);
|
|
4690
|
+
await work.charge(2 * (end - offset));
|
|
4691
|
+
const firstFraction = first.fraction.slice(offset, end).padEnd(end - offset, "0");
|
|
4692
|
+
const secondFraction = second.fraction.slice(offset, end).padEnd(end - offset, "0");
|
|
4693
|
+
compared = firstFraction < secondFraction ? -1 : firstFraction > secondFraction ? 1 : 0;
|
|
4694
|
+
}
|
|
4620
4695
|
}
|
|
4621
4696
|
return first.negative ? -compared : compared;
|
|
4622
4697
|
}
|
|
4623
|
-
function numericCompare(left, right) {
|
|
4624
|
-
return compareNumericValues(parseNumeric(left), parseNumeric(right));
|
|
4625
|
-
}
|
|
4626
4698
|
function sortKey(specification) {
|
|
4627
4699
|
const match = /^([0-9]+)(?:\.([0-9]+))?([bfnr]*)(?:,([0-9]+)(?:\.([0-9]+))?([bfnr]*))?$/u.exec(specification);
|
|
4628
4700
|
if (!match) throw new UsageError(`invalid key '${specification}'`);
|
|
@@ -4634,25 +4706,33 @@ function sortKey(specification) {
|
|
|
4634
4706
|
flags: new Set((match[3] ?? "") + (match[6] ?? ""))
|
|
4635
4707
|
};
|
|
4636
4708
|
}
|
|
4637
|
-
function keyBytes(line, key, separator, blanks) {
|
|
4709
|
+
async function keyBytes(line, key, separator, blanks, work) {
|
|
4638
4710
|
const fields = [];
|
|
4639
4711
|
if (separator !== void 0) {
|
|
4640
4712
|
let start2 = 0;
|
|
4641
|
-
for (let offset = 0; offset <= line.length; offset++)
|
|
4642
|
-
|
|
4643
|
-
|
|
4713
|
+
for (let offset = 0; offset <= line.length; offset++) {
|
|
4714
|
+
if (offset > 0 && offset % 1024 === 0) await work.charge(1024);
|
|
4715
|
+
if (offset === line.length || line[offset] === separator) {
|
|
4716
|
+
fields.push({ start: start2, end: offset });
|
|
4717
|
+
start2 = offset + 1;
|
|
4718
|
+
}
|
|
4644
4719
|
}
|
|
4645
4720
|
} else {
|
|
4646
4721
|
let offset = 0;
|
|
4647
4722
|
while (offset < line.length) {
|
|
4648
4723
|
const leading = offset;
|
|
4649
|
-
while (offset < line.length && (line[offset] === 32 || line[offset] === 9))
|
|
4724
|
+
while (offset < line.length && (line[offset] === 32 || line[offset] === 9)) {
|
|
4725
|
+
if (++offset % 1024 === 0) await work.charge(1024);
|
|
4726
|
+
}
|
|
4650
4727
|
const start2 = blanks ? offset : leading;
|
|
4651
4728
|
if (offset === line.length) break;
|
|
4652
|
-
while (offset < line.length && line[offset] !== 32 && line[offset] !== 9)
|
|
4729
|
+
while (offset < line.length && line[offset] !== 32 && line[offset] !== 9) {
|
|
4730
|
+
if (++offset % 1024 === 0) await work.charge(1024);
|
|
4731
|
+
}
|
|
4653
4732
|
fields.push({ start: start2, end: offset });
|
|
4654
4733
|
}
|
|
4655
4734
|
}
|
|
4735
|
+
await work.charge(line.length % 1024);
|
|
4656
4736
|
const start = (fields[key.start - 1]?.start ?? line.length) + key.startCharacter - 1;
|
|
4657
4737
|
const last = key.end === void 0 ? void 0 : fields[key.end - 1];
|
|
4658
4738
|
const end = key.end === void 0 ? line.length : last === void 0 ? line.length : key.endCharacter === void 0 ? last.end : Math.min(last.end, last.start + key.endCharacter);
|
|
@@ -4715,42 +4795,50 @@ function textCommands() {
|
|
|
4715
4795
|
const keys = (parsed.values.get("k") ?? []).map(sortKey);
|
|
4716
4796
|
const simple = !keys.length && !["b", "f", "n"].some((flag) => parsed.flags.has(flag));
|
|
4717
4797
|
const direction = parsed.flags.has("r") ? -1 : 1;
|
|
4718
|
-
|
|
4798
|
+
const work = new SortWork(context.signal);
|
|
4799
|
+
let compareNumeric = async (left, right) => compareNumericValues(await parseNumeric(left, work), await parseNumeric(right, work), work);
|
|
4719
4800
|
if (!keys.length && parsed.flags.has("n") && !["b", "f", "c"].some((flag) => parsed.flags.has(flag))) {
|
|
4720
4801
|
const numericValues = /* @__PURE__ */ new Map();
|
|
4721
4802
|
let retainedBytes = 0;
|
|
4722
|
-
const numericValue = (bytes2) => {
|
|
4803
|
+
const numericValue = async (bytes2) => {
|
|
4723
4804
|
const cached = numericValues.get(bytes2);
|
|
4724
4805
|
if (cached !== void 0) return cached;
|
|
4725
4806
|
context.signal.throwIfAborted();
|
|
4726
4807
|
const charge2 = 6 * bytes2.length + 2;
|
|
4727
|
-
if (numericValues.size >= 16384 || charge2 > 1048576 - retainedBytes) return parseNumeric(bytes2);
|
|
4728
|
-
const parsedValue = parseNumeric(bytes2);
|
|
4808
|
+
if (numericValues.size >= 16384 || charge2 > 1048576 - retainedBytes) return parseNumeric(bytes2, work);
|
|
4809
|
+
const parsedValue = await parseNumeric(bytes2, work);
|
|
4729
4810
|
numericValues.set(bytes2, parsedValue);
|
|
4730
4811
|
retainedBytes += charge2;
|
|
4731
4812
|
return parsedValue;
|
|
4732
4813
|
};
|
|
4733
|
-
compareNumeric = (left, right) => compareNumericValues(numericValue(left), numericValue(right));
|
|
4814
|
+
compareNumeric = async (left, right) => compareNumericValues(await numericValue(left), await numericValue(right), work);
|
|
4734
4815
|
}
|
|
4735
|
-
let keyCompare =
|
|
4816
|
+
let keyCompare = async (left, right) => {
|
|
4817
|
+
const checkpoint = work.charge();
|
|
4818
|
+
if (checkpoint) await checkpoint;
|
|
4819
|
+
if (simple) return await compareSortBytes(left, right, work) * direction;
|
|
4736
4820
|
for (const key of keys.length ? keys : [void 0]) {
|
|
4821
|
+
await work.charge();
|
|
4737
4822
|
const flags = key?.flags.size ? key.flags : parsed.flags;
|
|
4738
|
-
let first = key ? keyBytes(left, key, separator, flags.has("b")) : left;
|
|
4739
|
-
let second = key ? keyBytes(right, key, separator, flags.has("b")) : right;
|
|
4823
|
+
let first = key ? await keyBytes(left, key, separator, flags.has("b"), work) : left;
|
|
4824
|
+
let second = key ? await keyBytes(right, key, separator, flags.has("b"), work) : right;
|
|
4740
4825
|
if (!key && flags.has("b")) {
|
|
4741
|
-
const trim = (bytes2) => {
|
|
4826
|
+
const trim = async (bytes2) => {
|
|
4742
4827
|
let offset = 0;
|
|
4743
|
-
while (bytes2[offset] === 9 || bytes2[offset] === 32)
|
|
4828
|
+
while (bytes2[offset] === 9 || bytes2[offset] === 32) {
|
|
4829
|
+
if (++offset % 1024 === 0) await work.charge(1024);
|
|
4830
|
+
}
|
|
4831
|
+
await work.charge(offset % 1024);
|
|
4744
4832
|
return bytes2.subarray(offset);
|
|
4745
4833
|
};
|
|
4746
|
-
first = trim(first);
|
|
4747
|
-
second = trim(second);
|
|
4834
|
+
first = await trim(first);
|
|
4835
|
+
second = await trim(second);
|
|
4748
4836
|
}
|
|
4749
4837
|
if (flags.has("f")) {
|
|
4750
|
-
first =
|
|
4751
|
-
second =
|
|
4838
|
+
first = await foldSortBytes(first, work);
|
|
4839
|
+
second = await foldSortBytes(second, work);
|
|
4752
4840
|
}
|
|
4753
|
-
let result = flags.has("n") ? compareNumeric(first, second) :
|
|
4841
|
+
let result = flags.has("n") ? await compareNumeric(first, second) : await compareSortBytes(first, second, work);
|
|
4754
4842
|
if (flags.has("r")) result = -result;
|
|
4755
4843
|
if (result) return result;
|
|
4756
4844
|
}
|
|
@@ -4761,24 +4849,29 @@ function textCommands() {
|
|
|
4761
4849
|
if (numericKey && numericKeyFlags.has("n") && !["b", "f"].some((flag) => numericKeyFlags.has(flag)) && !parsed.flags.has("c")) {
|
|
4762
4850
|
const keyedNumericValues = /* @__PURE__ */ new Map();
|
|
4763
4851
|
let retainedKeyBytes = 0;
|
|
4764
|
-
const keyedNumericValue = (record4) => {
|
|
4852
|
+
const keyedNumericValue = async (record4) => {
|
|
4765
4853
|
const cached = keyedNumericValues.get(record4);
|
|
4766
4854
|
if (cached !== void 0) return cached;
|
|
4767
4855
|
context.signal.throwIfAborted();
|
|
4768
|
-
const bytes2 = keyBytes(record4, numericKey, separator, false);
|
|
4856
|
+
const bytes2 = await keyBytes(record4, numericKey, separator, false, work);
|
|
4769
4857
|
const charge2 = 6 * bytes2.length + 2;
|
|
4770
|
-
if (keyedNumericValues.size >= 16384 || charge2 > 1048576 - retainedKeyBytes) return parseNumeric(bytes2);
|
|
4771
|
-
const parsedValue = parseNumeric(bytes2);
|
|
4858
|
+
if (keyedNumericValues.size >= 16384 || charge2 > 1048576 - retainedKeyBytes) return parseNumeric(bytes2, work);
|
|
4859
|
+
const parsedValue = await parseNumeric(bytes2, work);
|
|
4772
4860
|
keyedNumericValues.set(record4, parsedValue);
|
|
4773
4861
|
retainedKeyBytes += charge2;
|
|
4774
4862
|
return parsedValue;
|
|
4775
4863
|
};
|
|
4776
|
-
keyCompare = (left, right) => {
|
|
4777
|
-
const
|
|
4864
|
+
keyCompare = async (left, right) => {
|
|
4865
|
+
const checkpoint = work.charge();
|
|
4866
|
+
if (checkpoint) await checkpoint;
|
|
4867
|
+
const result = await compareNumericValues(await keyedNumericValue(left), await keyedNumericValue(right), work);
|
|
4778
4868
|
return numericKeyFlags.has("r") ? -result : result;
|
|
4779
4869
|
};
|
|
4780
4870
|
}
|
|
4781
|
-
const compare =
|
|
4871
|
+
const compare = async (left, right) => {
|
|
4872
|
+
const result = await keyCompare(left, right);
|
|
4873
|
+
return result || (simple || parsed.flags.has("s") || parsed.flags.has("u") ? 0 : await compareSortBytes(left, right, work) * direction);
|
|
4874
|
+
};
|
|
4782
4875
|
const records = [];
|
|
4783
4876
|
let size = 0;
|
|
4784
4877
|
const exitCode = 0;
|
|
@@ -4798,7 +4891,7 @@ function textCommands() {
|
|
|
4798
4891
|
context.signal.throwIfAborted();
|
|
4799
4892
|
size += line.bytes.length + 1;
|
|
4800
4893
|
if (size > bufferLimit) throw new FsError("EFBIG", { message: "sort buffer limit exceeded" });
|
|
4801
|
-
if (parsed.flags.has("c") && records.length && (compare(records.at(-1), line.bytes) > 0 || parsed.flags.has("u") && keyCompare(records.at(-1), line.bytes) === 0)) {
|
|
4894
|
+
if (parsed.flags.has("c") && records.length && (await compare(records.at(-1), line.bytes) > 0 || parsed.flags.has("u") && await keyCompare(records.at(-1), line.bytes) === 0)) {
|
|
4802
4895
|
await diagnostic(context, new Error(`disorder at record ${records.length + 1}`));
|
|
4803
4896
|
return { exitCode: 1 };
|
|
4804
4897
|
}
|
|
@@ -4810,14 +4903,14 @@ function textCommands() {
|
|
|
4810
4903
|
}
|
|
4811
4904
|
}
|
|
4812
4905
|
if (parsed.flags.has("c")) return { exitCode };
|
|
4813
|
-
records
|
|
4906
|
+
const ordered = await sortRecords(records, compare, work);
|
|
4814
4907
|
const sorted = (async function* () {
|
|
4815
4908
|
let previous;
|
|
4816
4909
|
let buffer = new Uint8Array(64 * 1024);
|
|
4817
4910
|
let used = 0;
|
|
4818
|
-
for (const record4 of
|
|
4911
|
+
for (const record4 of ordered) {
|
|
4819
4912
|
context.signal.throwIfAborted();
|
|
4820
|
-
if (parsed.flags.has("u") && previous !== void 0 && keyCompare(previous, record4) === 0) continue;
|
|
4913
|
+
if (parsed.flags.has("u") && previous !== void 0 && await keyCompare(previous, record4) === 0) continue;
|
|
4821
4914
|
let offset = 0;
|
|
4822
4915
|
while (offset < record4.length) {
|
|
4823
4916
|
const length = Math.min(record4.length - offset, buffer.length - used);
|
|
@@ -17249,9 +17342,16 @@ async function execute(program, context, files, quiet, budget) {
|
|
|
17249
17342
|
}
|
|
17250
17343
|
break;
|
|
17251
17344
|
}
|
|
17252
|
-
case "y":
|
|
17253
|
-
|
|
17345
|
+
case "y": {
|
|
17346
|
+
budget.step(pattern.length);
|
|
17347
|
+
const translated = import_buffer.Buffer.allocUnsafe(pattern.length);
|
|
17348
|
+
for (let index = 0; index < pattern.length; index++) {
|
|
17349
|
+
if (index % 256 === 0) await budget.checkpoint();
|
|
17350
|
+
translated[index] = (instruction.translation.get(pattern[index]) ?? pattern[index]).charCodeAt(0);
|
|
17351
|
+
}
|
|
17352
|
+
pattern = translated.toString("latin1");
|
|
17254
17353
|
break;
|
|
17354
|
+
}
|
|
17255
17355
|
case "b":
|
|
17256
17356
|
pc = instruction.jump;
|
|
17257
17357
|
continue;
|