summaryrefslogtreecommitdiff
path: root/src/sjs.js
diff options
context:
space:
mode:
Diffstat (limited to 'src/sjs.js')
-rw-r--r--src/sjs.js304
1 files changed, 0 insertions, 304 deletions
diff --git a/src/sjs.js b/src/sjs.js
deleted file mode 100644
index 799f964..0000000
--- a/src/sjs.js
+++ /dev/null
@@ -1,304 +0,0 @@
-export const getIn = (obj, path) =>
- path.length === 0
- ? obj
- : getIn(obj?.[path[0]], path.slice(1));
-
-export const merge = (lhs, rhs) => {
- if (lhs === undefined) {
- return rhs;
- }
-
- if (rhs === undefined) {
- return lfs;
- }
-
- if (typeof lhs !== "object") {
- return rhs;
- }
-
- const lkeys = Object.keys(lhs);
- const rkeys = Object.keys(rhs);
- const allKeys = lkeys.concat(rkeys);
- return [...new Set(allKeys)].reduce(
- (o, key) => ({ ...o, [key]: merge(lhs[key], rhs[key]) }),
- {},
- );
-};
-
-export const compareObject = (lhs, rhs) => {
- const lstr = Object.entries(lhs).toSorted();
- const rstr = Object.entries(rhs).toSorted();
-
- if (lstr < rstr) {
- return -1;
- }
-
- if (lstr > rstr) {
- return 1;
- }
-
- throw new Error("unreachable");
-};
-
-const FROM = /[&<>'"]/g;
-
-const ESCAPES = {
- '&': '&amp;',
- '<': '&lt;',
- '>': '&gt;',
- "'": '&#39;',
- '"': '&quot;'
-};
-
-const mappingFn = c => ESCAPES[c];
-
-export const escape = s =>
- String.prototype.replace.call(s, FROM, mappingFn);
-
-export const eq = (a, b) => {
- if (a === b) {
- return true;
- }
-
- if (a === null || b === null) {
- return false;
- }
-
- if (typeof a != "object" || typeof b != "object") {
- return false;
- }
-
- if (Array.isArray(a) !== Array.isArray(b)) {
- return false;
- }
-
- if (Object.keys(a).length !== Object.keys(b).length) {
- return false;
- }
-
- for (const k in a) {
- if (!b.hasOwnProperty(k)) {
- return false;
- }
- if (!eq(a[k], b[k])) {
- return false;
- }
- }
- return true;
-};
-
-export const keys = (ks, obj) =>
- ks.reduce(
- (ret, k) =>
- obj.hasOwnProperty(k) ? {...ret, [k]: obj[k]} : ret,
- {},
- );
-
-export const difference = (a, b) => {
- const diff = new Set(a);
- for (const el of b) {
- diff.delete(el);
- }
- return diff;
-};
-
-export const assocIn = (obj, path, value) =>
- path.length === 0 ? obj :
- path.length === 1 ? { ...obj, [path[0]]: value } :
- {
- ...obj,
- [path[0]]: assocIn(
- (obj[path[0]] || {}),
- path.slice(1),
- value
- )
- };
-
-export const dissoc = (obj, key) => {
- const ret = { ...obj };
- delete ret[key]
- return ret;
-};
-
-export const findFirst = (arr, fn) => {
- for (const x of arr) {
- const ret = fn(x);
- if (ret) {
- return ret;
- }
- }
-
- return null;
-};
-
-export const partial = (fn, ...startArgs) =>
- (...endArgs) =>
- fn(...startArgs, ...endArgs);
-
-export const strSortFn = (a, b) => a.localeCompare(b, "POSIX");
-
-export const undefinedAsNull = x => x === undefined ? null : x;
-
-export const first = a => a[0];
-export const rest = a => a.slice(1);
-export const butlast = a => a.slice(a, a.length - 1);
-export const last = a => a[a.length - 1];
-
-export const take = function*(n, gen) {
- let i = 0n;
- for (const x of gen) {
- if (i >= n) {
- break;
- }
- i++;
- yield x;
- }
-};
-
-export const range = function*(x, y, step = 1n) {
- if (x === undefined) {
- let i = 0n;
- while (true) {
- yield i++;
- }
- }
- const [from, to] = y === undefined ?
- [0n, x] :
- [x, y];
- const fromn = BigInt(from);
- const ton = BigInt(to);
- const stepn = BigInt(step);
- if (stepn === 0n) {
- while (true) {
- yield fromn;
- }
- }
- if (step < 0n) {
- for (let i = fromn; i > ton; i+= stepn) {
- yield i;
- }
- } else {
- for (let i = fromn; i < ton; i += stepn) {
- yield i;
- }
- }
-};
-
-const t = ({ colors, err, assertEq }) => ({
- assertEq,
- tap: x => {
- err(`tap: ${x}\n`);
- return x;
- },
- start: msg => {
- err(`${msg}:\n`);
- },
- testing: async (msg, fn) => {
- err(`${colors.yellow("testing")}: ${msg}... `);
- try {
- await fn();
- } catch (e) {
- err(`${colors.red("ERR")}.\n`);
- throw e;
- }
- err(`${colors.green("OK")}.\n`);
- },
-});
-
-class UnimplementedError extends Error {}
-
-export const getJSImpl = () => {
- if (typeof scriptArgs !== "undefined") {
- return "qjs";
- }
- if (typeof Deno !== "undefined") {
- return "deno";
- }
- if (typeof process !== "undefined") {
- return "node";
- }
- // FIXME: add browser and bun
- return "unknown";
-};
-
-export const JSImpl = getJSImpl();
-
-const mappings = {
- ARGV: {
- qjs: () => scriptArgs,
- node: () => process.argv.slice(1),
- deno: () => Deno.mainModule.substring("file://".length),
- unknown: () => {
- throw new UnimplementedError(`ARGV["${JSImpl}"]`);
- },
- },
- exit: {
- qjs: async () => {
- const { exit } = await import("std");
- return exit;
- },
- node: async () => process.exit,
- deno: async () => Deno.exit,
- unknown: () => {
- throw new UnimplementedError(`exit["${JSImpl}"]`);
- },
- },
- tconf: {
- qjs: async () => await mappings.testConf.unknown(),
- deno: async () => await mappings.testConf.node(),
- browser: async () => {
- class DOMAssertionError extends Error {}
-
- const w = s => document.querySelector("#test-report").innerHTML += s;
-
- const red = s => `<span style="color: red; ">${s}</span>`;
- const green = s => `<span style="color: green; ">${s}</span>`;
- const yellow = s => `<span style="color: darkgoldenrod;">${s}</span>`;
- return {
- testStart: msg => w(`${msg}:\n`),
- testing: msg => w(`${yellow("testing")}: ${msg}...`),
- testOK: () => w(` ${green("OK")}.\n`),
- assert: (x, msg = "") => {
- if (!x) {
- w(` ${red("ERROR")}.\n`);
- w("\nSee console for details.\n");
- w("If possible, do report them.");
- throw new DOMAssertionError(msg);
- }
- },
- };
- },
-
- node: async () => {
- const assert = await import("node:assert/strict");
- const process = await import("node:process");
-
- const err = x => process.stderr.write(x);
- const red = s => `\x1b[31m${s}\x1b[0m`;
- const green = s => `\x1b[32m${s}\x1b[0m`;
- const yellow = s => `\x1b[33m${s}\x1b[0m`;
-
- return {
- err,
- assertEq: assert.deepEqual,
- colors: {
- red,
- green,
- yellow,
- },
- };
- },
- unknown: () => { throw new UnimplementedError(`exit["${JSImpl}"]`); },
- },
-};
-
-export const exit = await mappings.exit[ JSImpl]();
-export const ARGV = await mappings.ARGV[ JSImpl]();
-export const tconf = await mappings.tconf[JSImpl]();
-
-export const runTests = async tests => {
- const tFinal = t(tconf);
- for (const testFn of tests) {
- await testFn(tFinal);
- }
-};