diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..04975e2 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,11 @@ +root = true + +[*] +indent_style = space +indent_size = 2 +end_of_line = lf +charset = utf-8 +insert_final_newline = true + +[*.{rs,toml}] +indent_size = 4 diff --git a/biome.json b/biome.json new file mode 100644 index 0000000..0cc7a82 --- /dev/null +++ b/biome.json @@ -0,0 +1,36 @@ +{ + "$schema": "https://biomejs.dev/schemas/2.3.6/schema.json", + "vcs": { + "enabled": true, + "clientKind": "git", + "useIgnoreFile": true + }, + "files": { + "includes": ["**", "!!**/dist"] + }, + "formatter": { + "enabled": true, + "formatWithErrors": true, + "attributePosition": "auto", + "indentStyle": "space", + "indentWidth": 2, + "lineWidth": 110, + "lineEnding": "lf" + }, + "javascript": { + "formatter": { + "arrowParentheses": "always", + "bracketSameLine": false, + "bracketSpacing": true, + "jsxQuoteStyle": "double", + "quoteProperties": "asNeeded", + "semicolons": "always", + "trailingCommas": "all" + } + }, + "json": { + "formatter": { + "trailingCommas": "none" + } + } +} diff --git a/flake.nix b/flake.nix index dffb1d1..dd2e7c3 100644 --- a/flake.nix +++ b/flake.nix @@ -26,9 +26,9 @@ valgrind claude-code - # Node.js tooling for TypeScript build nodejs nodePackages.npm + biome ]; }; } diff --git a/nix-js/runtime-ts/src/builtins/arithmetic.ts b/nix-js/runtime-ts/src/builtins/arithmetic.ts index 43aac79..6d6f879 100644 --- a/nix-js/runtime-ts/src/builtins/arithmetic.ts +++ b/nix-js/runtime-ts/src/builtins/arithmetic.ts @@ -2,52 +2,68 @@ * Arithmetic builtin functions */ -import type { NixBool, NixInt, NixNumber, NixValue } from '../types'; -import { force_numeric, coerce_numeric, force_int } from '../type-assert'; +import type { NixBool, NixInt, NixNumber, NixValue } from "../types"; +import { force_numeric, coerce_numeric, force_int } from "../type-assert"; -export const add = (a: NixValue) => (b: NixValue): bigint | number => { - const [av, bv] = coerce_numeric(force_numeric(a), force_numeric(b)); - return (av as any) + (bv as any); -}; +export const add = + (a: NixValue) => + (b: NixValue): bigint | number => { + const [av, bv] = coerce_numeric(force_numeric(a), force_numeric(b)); + return (av as any) + (bv as any); + }; -export const sub = (a: NixValue) => (b: NixValue): bigint | number => { - const [av, bv] = coerce_numeric(force_numeric(a), force_numeric(b)); - return (av as any) - (bv as any); -}; +export const sub = + (a: NixValue) => + (b: NixValue): bigint | number => { + const [av, bv] = coerce_numeric(force_numeric(a), force_numeric(b)); + return (av as any) - (bv as any); + }; -export const mul = (a: NixValue) => (b: NixValue): bigint | number => { - const [av, bv] = coerce_numeric(force_numeric(a), force_numeric(b)); - return (av as any) * (bv as any); -}; +export const mul = + (a: NixValue) => + (b: NixValue): bigint | number => { + const [av, bv] = coerce_numeric(force_numeric(a), force_numeric(b)); + return (av as any) * (bv as any); + }; -export const div = (a: NixValue) => (b: NixValue): NixNumber => { - const [av, bv] = coerce_numeric(force_numeric(a), force_numeric(b)); +export const div = + (a: NixValue) => + (b: NixValue): NixNumber => { + const [av, bv] = coerce_numeric(force_numeric(a), force_numeric(b)); - if (bv === 0 || bv === 0n) { - throw new RangeError('Division by zero'); - } + if (bv === 0 || bv === 0n) { + throw new RangeError("Division by zero"); + } - return (av as any) / (bv as any) -}; + return (av as any) / (bv as any); + }; // Bitwise operations - only for integers -export const bitAnd = (a: NixValue) => (b: NixValue): NixInt => { - const av = force_int(a); - const bv = force_int(b); - return av & bv; -}; +export const bitAnd = + (a: NixValue) => + (b: NixValue): NixInt => { + const av = force_int(a); + const bv = force_int(b); + return av & bv; + }; -export const bitOr = (a: NixValue) => (b: NixValue): NixInt => { - const av = force_int(a); - const bv = force_int(b); - return av | bv; -}; +export const bitOr = + (a: NixValue) => + (b: NixValue): NixInt => { + const av = force_int(a); + const bv = force_int(b); + return av | bv; + }; -export const bitXor = (a: NixValue) => (b: NixValue): NixInt => { - const av = force_int(a); - const bv = force_int(b); - return av ^ bv; -}; +export const bitXor = + (a: NixValue) => + (b: NixValue): NixInt => { + const av = force_int(a); + const bv = force_int(b); + return av ^ bv; + }; -export const lessThan = (a: NixValue) => (b: NixValue): NixBool => - force_numeric(a) < force_numeric(b); +export const lessThan = + (a: NixValue) => + (b: NixValue): NixBool => + force_numeric(a) < force_numeric(b); diff --git a/nix-js/runtime-ts/src/builtins/attrs.ts b/nix-js/runtime-ts/src/builtins/attrs.ts index dcdc55c..3641890 100644 --- a/nix-js/runtime-ts/src/builtins/attrs.ts +++ b/nix-js/runtime-ts/src/builtins/attrs.ts @@ -2,28 +2,34 @@ * Attribute set operation builtin functions */ -import type { NixValue, NixAttrs, NixList } from '../types'; -import { force_attrs, force_string, force_function, force_list } from '../type-assert'; +import type { NixValue, NixAttrs, NixList } from "../types"; +import { force_attrs, force_string, force_function, force_list } from "../type-assert"; export const attrNames = (set: NixValue): string[] => Object.keys(force_attrs(set)); export const attrValues = (set: NixValue): NixValue[] => Object.values(force_attrs(set)); -export const getAttr = (s: NixValue) => (set: NixValue): NixValue => - force_attrs(set)[force_string(s)]; +export const getAttr = + (s: NixValue) => + (set: NixValue): NixValue => + force_attrs(set)[force_string(s)]; -export const hasAttr = (s: NixValue) => (set: NixValue): boolean => - Object.prototype.hasOwnProperty.call(force_attrs(set), force_string(s)); +export const hasAttr = + (s: NixValue) => + (set: NixValue): boolean => + Object.prototype.hasOwnProperty.call(force_attrs(set), force_string(s)); -export const mapAttrs = (f: NixValue) => (attrs: NixValue): NixAttrs => { - const new_attrs: NixAttrs = {}; - const forced_attrs = force_attrs(attrs); - const forced_f = force_function(f); - for (const key in forced_attrs) { - new_attrs[key] = forced_f(key)(forced_attrs[key]); - } - return new_attrs; -}; +export const mapAttrs = + (f: NixValue) => + (attrs: NixValue): NixAttrs => { + const new_attrs: NixAttrs = {}; + const forced_attrs = force_attrs(attrs); + const forced_f = force_function(f); + for (const key in forced_attrs) { + new_attrs[key] = forced_f(key)(forced_attrs[key]); + } + return new_attrs; + }; export const listToAttrs = (e: NixValue): NixAttrs => { const attrs: NixAttrs = {}; @@ -35,33 +41,39 @@ export const listToAttrs = (e: NixValue): NixAttrs => { return attrs; }; -export const intersectAttrs = (e1: NixValue) => (e2: NixValue): NixAttrs => { - const f1 = force_attrs(e1); - const f2 = force_attrs(e2); - const attrs: NixAttrs = {}; - for (const key of Object.keys(f2)) { - if (Object.prototype.hasOwnProperty.call(f1, key)) { - attrs[key] = f2[key]; +export const intersectAttrs = + (e1: NixValue) => + (e2: NixValue): NixAttrs => { + const f1 = force_attrs(e1); + const f2 = force_attrs(e2); + const attrs: NixAttrs = {}; + for (const key of Object.keys(f2)) { + if (Object.prototype.hasOwnProperty.call(f1, key)) { + attrs[key] = f2[key]; + } } - } - return attrs; -}; + return attrs; + }; -export const catAttrs = (attr: NixValue) => (list: NixValue): NixList => { - const key = force_string(attr); - return force_list(list) - .map((set) => force_attrs(set)[key]) - .filter((val) => val !== undefined); -}; +export const catAttrs = + (attr: NixValue) => + (list: NixValue): NixList => { + const key = force_string(attr); + return force_list(list) + .map((set) => force_attrs(set)[key]) + .filter((val) => val !== undefined); + }; -export const groupBy = (f: NixValue) => (list: NixValue): NixAttrs => { - const attrs: NixAttrs = {}; - const forced_f = force_function(f); - const forced_list = force_list(list); - for (const elem of forced_list) { - const key = force_string(forced_f(elem)); - if (!attrs[key]) attrs[key] = []; - (attrs[key] as NixList).push(elem); - } - return attrs; -}; +export const groupBy = + (f: NixValue) => + (list: NixValue): NixAttrs => { + const attrs: NixAttrs = {}; + const forced_f = force_function(f); + const forced_list = force_list(list); + for (const elem of forced_list) { + const key = force_string(forced_f(elem)); + if (!attrs[key]) attrs[key] = []; + (attrs[key] as NixList).push(elem); + } + return attrs; + }; diff --git a/nix-js/runtime-ts/src/builtins/conversion.ts b/nix-js/runtime-ts/src/builtins/conversion.ts index d7e8664..8a33883 100644 --- a/nix-js/runtime-ts/src/builtins/conversion.ts +++ b/nix-js/runtime-ts/src/builtins/conversion.ts @@ -2,24 +2,24 @@ * Conversion and serialization builtin functions (unimplemented) */ -import type { NixValue } from '../types'; +import type { NixValue } from "../types"; export const fromJSON = (e: NixValue): never => { - throw 'Not implemented: fromJSON'; + throw "Not implemented: fromJSON"; }; export const fromTOML = (e: NixValue): never => { - throw 'Not implemented: fromTOML'; + throw "Not implemented: fromTOML"; }; export const toJSON = (e: NixValue): never => { - throw 'Not implemented: toJSON'; + throw "Not implemented: toJSON"; }; export const toXML = (e: NixValue): never => { - throw 'Not implemented: toXML'; + throw "Not implemented: toXML"; }; export const toString = (name: NixValue, s: NixValue): never => { - throw 'Not implemented: toString'; + throw "Not implemented: toString"; }; diff --git a/nix-js/runtime-ts/src/builtins/functional.ts b/nix-js/runtime-ts/src/builtins/functional.ts index 5983938..aeadcdb 100644 --- a/nix-js/runtime-ts/src/builtins/functional.ts +++ b/nix-js/runtime-ts/src/builtins/functional.ts @@ -2,17 +2,21 @@ * Functional programming builtin functions */ -import type { NixValue } from '../types'; -import { force } from '../thunk'; +import type { NixValue } from "../types"; +import { force } from "../thunk"; -export const seq = (e1: NixValue) => (e2: NixValue): NixValue => { - force(e1); // Force evaluation of e1 - return e2; -}; +export const seq = + (e1: NixValue) => + (e2: NixValue): NixValue => { + force(e1); // Force evaluation of e1 + return e2; + }; -export const deepSeq = (e1: NixValue) => (e2: NixValue): never => { - throw 'Not implemented: deepSeq'; -}; +export const deepSeq = + (e1: NixValue) => + (e2: NixValue): never => { + throw "Not implemented: deepSeq"; + }; export const abort = (s: NixValue): never => { throw `evaluation aborted with the following error message: '${force(s)}'`; @@ -27,9 +31,11 @@ export const trace = (e1: NixValue, e2: NixValue): NixValue => { return e2; }; -export const warn = (e1: NixValue) => (e2: NixValue): NixValue => { - console.log(`evaluation warning: ${force(e1)}`); - return e2; -}; +export const warn = + (e1: NixValue) => + (e2: NixValue): NixValue => { + console.log(`evaluation warning: ${force(e1)}`); + return e2; + }; export const breakFunc = (v: NixValue): NixValue => v; diff --git a/nix-js/runtime-ts/src/builtins/index.ts b/nix-js/runtime-ts/src/builtins/index.ts index 7fcf7ae..31c233d 100644 --- a/nix-js/runtime-ts/src/builtins/index.ts +++ b/nix-js/runtime-ts/src/builtins/index.ts @@ -3,13 +3,13 @@ * Combines all builtin function categories into the global `builtins` object */ -import { create_thunk } from '../thunk'; +import { create_thunk } from "../thunk"; /** * Symbol used to mark functions as primops (primitive operations) * This is similar to IS_THUNK but for builtin functions */ -export const IS_PRIMOP = Symbol('is_primop'); +export const IS_PRIMOP = Symbol("is_primop"); /** * Metadata interface for primop functions @@ -37,7 +37,7 @@ export const markPrimop = ( func: T, name: string, arity: number, - applied: number = 0 + applied: number = 0, ): T => { // Mark this function as a primop (func as any)[IS_PRIMOP] = { @@ -52,7 +52,7 @@ export const markPrimop = ( const wrappedFunc = ((...args: any[]) => { const result = func(...args); // If result is a function, mark it as the next layer - if (typeof result === 'function') { + if (typeof result === "function") { return markPrimop(result, name, arity, applied + args.length); } return result; @@ -78,9 +78,9 @@ export const markPrimop = ( */ export const is_primop = (value: unknown): value is Function & { [IS_PRIMOP]: PrimopMetadata } => { return ( - typeof value === 'function' && + typeof value === "function" && IS_PRIMOP in value && - typeof value[IS_PRIMOP] === 'object' && + typeof value[IS_PRIMOP] === "object" && value[IS_PRIMOP] !== null ); }; @@ -98,16 +98,16 @@ export const get_primop_metadata = (func: unknown): PrimopMetadata | undefined = }; // Import all builtin categories -import * as arithmetic from './arithmetic'; -import * as math from './math'; -import * as typeCheck from './type-check'; -import * as list from './list'; -import * as attrs from './attrs'; -import * as string from './string'; -import * as functional from './functional'; -import * as io from './io'; -import * as conversion from './conversion'; -import * as misc from './misc'; +import * as arithmetic from "./arithmetic"; +import * as math from "./math"; +import * as typeCheck from "./type-check"; +import * as list from "./list"; +import * as attrs from "./attrs"; +import * as string from "./string"; +import * as functional from "./functional"; +import * as io from "./io"; +import * as conversion from "./conversion"; +import * as misc from "./misc"; /** * The global builtins object @@ -120,122 +120,126 @@ import * as misc from './misc'; * All primop functions are marked with IS_PRIMOP symbol for runtime introspection */ export const builtins: any = { - add: markPrimop(arithmetic.add, 'add', 2), - sub: markPrimop(arithmetic.sub, 'sub', 2), - mul: markPrimop(arithmetic.mul, 'mul', 2), - div: markPrimop(arithmetic.div, 'div', 2), - bitAnd: markPrimop(arithmetic.bitAnd, 'bitAnd', 2), - bitOr: markPrimop(arithmetic.bitOr, 'bitOr', 2), - bitXor: markPrimop(arithmetic.bitXor, 'bitXor', 2), - lessThan: markPrimop(arithmetic.lessThan, 'lessThan', 2), + add: markPrimop(arithmetic.add, "add", 2), + sub: markPrimop(arithmetic.sub, "sub", 2), + mul: markPrimop(arithmetic.mul, "mul", 2), + div: markPrimop(arithmetic.div, "div", 2), + bitAnd: markPrimop(arithmetic.bitAnd, "bitAnd", 2), + bitOr: markPrimop(arithmetic.bitOr, "bitOr", 2), + bitXor: markPrimop(arithmetic.bitXor, "bitXor", 2), + lessThan: markPrimop(arithmetic.lessThan, "lessThan", 2), - ceil: markPrimop(math.ceil, 'ceil', 1), - floor: markPrimop(math.floor, 'floor', 1), + ceil: markPrimop(math.ceil, "ceil", 1), + floor: markPrimop(math.floor, "floor", 1), - isAttrs: markPrimop(typeCheck.isAttrs, 'isAttrs', 1), - isBool: markPrimop(typeCheck.isBool, 'isBool', 1), - isFloat: markPrimop(typeCheck.isFloat, 'isFloat', 1), - isFunction: markPrimop(typeCheck.isFunction, 'isFunction', 1), - isInt: markPrimop(typeCheck.isInt, 'isInt', 1), - isList: markPrimop(typeCheck.isList, 'isList', 1), - isNull: markPrimop(typeCheck.isNull, 'isNull', 1), - isPath: markPrimop(typeCheck.isPath, 'isPath', 1), - isString: markPrimop(typeCheck.isString, 'isString', 1), - typeOf: markPrimop(typeCheck.typeOf, 'typeOf', 1), + isAttrs: markPrimop(typeCheck.isAttrs, "isAttrs", 1), + isBool: markPrimop(typeCheck.isBool, "isBool", 1), + isFloat: markPrimop(typeCheck.isFloat, "isFloat", 1), + isFunction: markPrimop(typeCheck.isFunction, "isFunction", 1), + isInt: markPrimop(typeCheck.isInt, "isInt", 1), + isList: markPrimop(typeCheck.isList, "isList", 1), + isNull: markPrimop(typeCheck.isNull, "isNull", 1), + isPath: markPrimop(typeCheck.isPath, "isPath", 1), + isString: markPrimop(typeCheck.isString, "isString", 1), + typeOf: markPrimop(typeCheck.typeOf, "typeOf", 1), - map: markPrimop(list.map, 'map', 2), - filter: markPrimop(list.filter, 'filter', 2), - length: markPrimop(list.length, 'length', 1), - head: markPrimop(list.head, 'head', 1), - tail: markPrimop(list.tail, 'tail', 1), - elem: markPrimop(list.elem, 'elem', 2), - elemAt: markPrimop(list.elemAt, 'elemAt', 2), - concatLists: markPrimop(list.concatLists, 'concatLists', 1), - concatMap: markPrimop(list.concatMap, 'concatMap', 2), - 'foldl\'': markPrimop(list.foldlPrime, 'foldl\'', 3), - sort: markPrimop(list.sort, 'sort', 2), - partition: markPrimop(list.partition, 'partition', 2), - genList: markPrimop(list.genList, 'genList', 2), - all: markPrimop(list.all, 'all', 2), - any: markPrimop(list.any, 'any', 2), + map: markPrimop(list.map, "map", 2), + filter: markPrimop(list.filter, "filter", 2), + length: markPrimop(list.length, "length", 1), + head: markPrimop(list.head, "head", 1), + tail: markPrimop(list.tail, "tail", 1), + elem: markPrimop(list.elem, "elem", 2), + elemAt: markPrimop(list.elemAt, "elemAt", 2), + concatLists: markPrimop(list.concatLists, "concatLists", 1), + concatMap: markPrimop(list.concatMap, "concatMap", 2), + "foldl'": markPrimop(list.foldlPrime, "foldl'", 3), + sort: markPrimop(list.sort, "sort", 2), + partition: markPrimop(list.partition, "partition", 2), + genList: markPrimop(list.genList, "genList", 2), + all: markPrimop(list.all, "all", 2), + any: markPrimop(list.any, "any", 2), - attrNames: markPrimop(attrs.attrNames, 'attrNames', 1), - attrValues: markPrimop(attrs.attrValues, 'attrValues', 1), - getAttr: markPrimop(attrs.getAttr, 'getAttr', 2), - hasAttr: markPrimop(attrs.hasAttr, 'hasAttr', 2), - mapAttrs: markPrimop(attrs.mapAttrs, 'mapAttrs', 2), - listToAttrs: markPrimop(attrs.listToAttrs, 'listToAttrs', 1), - intersectAttrs: markPrimop(attrs.intersectAttrs, 'intersectAttrs', 2), - catAttrs: markPrimop(attrs.catAttrs, 'catAttrs', 2), - groupBy: markPrimop(attrs.groupBy, 'groupBy', 2), + attrNames: markPrimop(attrs.attrNames, "attrNames", 1), + attrValues: markPrimop(attrs.attrValues, "attrValues", 1), + getAttr: markPrimop(attrs.getAttr, "getAttr", 2), + hasAttr: markPrimop(attrs.hasAttr, "hasAttr", 2), + mapAttrs: markPrimop(attrs.mapAttrs, "mapAttrs", 2), + listToAttrs: markPrimop(attrs.listToAttrs, "listToAttrs", 1), + intersectAttrs: markPrimop(attrs.intersectAttrs, "intersectAttrs", 2), + catAttrs: markPrimop(attrs.catAttrs, "catAttrs", 2), + groupBy: markPrimop(attrs.groupBy, "groupBy", 2), - stringLength: markPrimop(string.stringLength, 'stringLength', 1), - substring: markPrimop(string.substring, 'substring', 3), - concatStringsSep: markPrimop(string.concatStringsSep, 'concatStringsSep', 2), - baseNameOf: markPrimop(string.baseNameOf, 'baseNameOf', 1), + stringLength: markPrimop(string.stringLength, "stringLength", 1), + substring: markPrimop(string.substring, "substring", 3), + concatStringsSep: markPrimop(string.concatStringsSep, "concatStringsSep", 2), + baseNameOf: markPrimop(string.baseNameOf, "baseNameOf", 1), - seq: markPrimop(functional.seq, 'seq', 2), - deepSeq: markPrimop(functional.deepSeq, 'deepSeq', 2), - abort: markPrimop(functional.abort, 'abort', 1), - throw: markPrimop(functional.throwFunc, 'throw', 1), - trace: markPrimop(functional.trace, 'trace', 2), - warn: markPrimop(functional.warn, 'warn', 2), - break: markPrimop(functional.breakFunc, 'break', 1), + seq: markPrimop(functional.seq, "seq", 2), + deepSeq: markPrimop(functional.deepSeq, "deepSeq", 2), + abort: markPrimop(functional.abort, "abort", 1), + throw: markPrimop(functional.throwFunc, "throw", 1), + trace: markPrimop(functional.trace, "trace", 2), + warn: markPrimop(functional.warn, "warn", 2), + break: markPrimop(functional.breakFunc, "break", 1), - import: markPrimop(io.importFunc, 'import', 1), - scopedImport: markPrimop(io.scopedImport, 'scopedImport', 2), - fetchClosure: markPrimop(io.fetchClosure, 'fetchClosure', 1), - fetchGit: markPrimop(io.fetchGit, 'fetchGit', 1), - fetchTarball: markPrimop(io.fetchTarball, 'fetchTarball', 1), - fetchTree: markPrimop(io.fetchTree, 'fetchTree', 1), - fetchurl: markPrimop(io.fetchurl, 'fetchurl', 1), - readDir: markPrimop(io.readDir, 'readDir', 1), - readFile: markPrimop(io.readFile, 'readFile', 1), - readFileType: markPrimop(io.readFileType, 'readFileType', 1), - pathExists: markPrimop(io.pathExists, 'pathExists', 1), - path: markPrimop(io.path, 'path', 1), - toFile: markPrimop(io.toFile, 'toFile', 2), - toPath: markPrimop(io.toPath, 'toPath', 1), - filterSource: markPrimop(io.filterSource, 'filterSource', 2), - findFile: markPrimop(io.findFile, 'findFile', 2), - getEnv: markPrimop(io.getEnv, 'getEnv', 1), + import: markPrimop(io.importFunc, "import", 1), + scopedImport: markPrimop(io.scopedImport, "scopedImport", 2), + fetchClosure: markPrimop(io.fetchClosure, "fetchClosure", 1), + fetchGit: markPrimop(io.fetchGit, "fetchGit", 1), + fetchTarball: markPrimop(io.fetchTarball, "fetchTarball", 1), + fetchTree: markPrimop(io.fetchTree, "fetchTree", 1), + fetchurl: markPrimop(io.fetchurl, "fetchurl", 1), + readDir: markPrimop(io.readDir, "readDir", 1), + readFile: markPrimop(io.readFile, "readFile", 1), + readFileType: markPrimop(io.readFileType, "readFileType", 1), + pathExists: markPrimop(io.pathExists, "pathExists", 1), + path: markPrimop(io.path, "path", 1), + toFile: markPrimop(io.toFile, "toFile", 2), + toPath: markPrimop(io.toPath, "toPath", 1), + filterSource: markPrimop(io.filterSource, "filterSource", 2), + findFile: markPrimop(io.findFile, "findFile", 2), + getEnv: markPrimop(io.getEnv, "getEnv", 1), - fromJSON: markPrimop(conversion.fromJSON, 'fromJSON', 1), - fromTOML: markPrimop(conversion.fromTOML, 'fromTOML', 1), - toJSON: markPrimop(conversion.toJSON, 'toJSON', 1), - toXML: markPrimop(conversion.toXML, 'toXML', 1), - toString: markPrimop(conversion.toString, 'toString', 1), + fromJSON: markPrimop(conversion.fromJSON, "fromJSON", 1), + fromTOML: markPrimop(conversion.fromTOML, "fromTOML", 1), + toJSON: markPrimop(conversion.toJSON, "toJSON", 1), + toXML: markPrimop(conversion.toXML, "toXML", 1), + toString: markPrimop(conversion.toString, "toString", 1), - getContext: markPrimop(misc.getContext, 'getContext', 1), - hasContext: markPrimop(misc.hasContext, 'hasContext', 1), - hashFile: markPrimop(misc.hashFile, 'hashFile', 2), - hashString: markPrimop(misc.hashString, 'hashString', 2), - convertHash: markPrimop(misc.convertHash, 'convertHash', 2), - unsafeDiscardOutputDependency: markPrimop(misc.unsafeDiscardOutputDependency, 'unsafeDiscardOutputDependency', 1), - unsafeDiscardStringContext: markPrimop(misc.unsafeDiscardStringContext, 'unsafeDiscardStringContext', 1), - unsafeGetAttrPos: markPrimop(misc.unsafeGetAttrPos, 'unsafeGetAttrPos', 2), - addDrvOutputDependencies: markPrimop(misc.addDrvOutputDependencies, 'addDrvOutputDependencies', 2), - compareVersions: markPrimop(misc.compareVersions, 'compareVersions', 2), - dirOf: markPrimop(misc.dirOf, 'dirOf', 1), - flakeRefToString: markPrimop(misc.flakeRefToString, 'flakeRefToString', 1), - functionArgs: markPrimop(misc.functionArgs, 'functionArgs', 1), - genericClosure: markPrimop(misc.genericClosure, 'genericClosure', 1), - getFlake: markPrimop(misc.getFlake, 'getFlake', 1), - match: markPrimop(misc.match, 'match', 2), - outputOf: markPrimop(misc.outputOf, 'outputOf', 2), - parseDrvName: markPrimop(misc.parseDrvName, 'parseDrvName', 1), - parseFlakeName: markPrimop(misc.parseFlakeName, 'parseFlakeName', 1), - placeholder: markPrimop(misc.placeholder, 'placeholder', 1), - replaceStrings: markPrimop(misc.replaceStrings, 'replaceStrings', 3), - split: markPrimop(misc.split, 'split', 2), - splitVersion: markPrimop(misc.splitVersion, 'splitVersion', 1), - traceVerbose: markPrimop(misc.traceVerbose, 'traceVerbose', 2), - tryEval: markPrimop(misc.tryEval, 'tryEval', 1), - zipAttrsWith: markPrimop(misc.zipAttrsWith, 'zipAttrsWith', 2), + getContext: markPrimop(misc.getContext, "getContext", 1), + hasContext: markPrimop(misc.hasContext, "hasContext", 1), + hashFile: markPrimop(misc.hashFile, "hashFile", 2), + hashString: markPrimop(misc.hashString, "hashString", 2), + convertHash: markPrimop(misc.convertHash, "convertHash", 2), + unsafeDiscardOutputDependency: markPrimop( + misc.unsafeDiscardOutputDependency, + "unsafeDiscardOutputDependency", + 1, + ), + unsafeDiscardStringContext: markPrimop(misc.unsafeDiscardStringContext, "unsafeDiscardStringContext", 1), + unsafeGetAttrPos: markPrimop(misc.unsafeGetAttrPos, "unsafeGetAttrPos", 2), + addDrvOutputDependencies: markPrimop(misc.addDrvOutputDependencies, "addDrvOutputDependencies", 2), + compareVersions: markPrimop(misc.compareVersions, "compareVersions", 2), + dirOf: markPrimop(misc.dirOf, "dirOf", 1), + flakeRefToString: markPrimop(misc.flakeRefToString, "flakeRefToString", 1), + functionArgs: markPrimop(misc.functionArgs, "functionArgs", 1), + genericClosure: markPrimop(misc.genericClosure, "genericClosure", 1), + getFlake: markPrimop(misc.getFlake, "getFlake", 1), + match: markPrimop(misc.match, "match", 2), + outputOf: markPrimop(misc.outputOf, "outputOf", 2), + parseDrvName: markPrimop(misc.parseDrvName, "parseDrvName", 1), + parseFlakeName: markPrimop(misc.parseFlakeName, "parseFlakeName", 1), + placeholder: markPrimop(misc.placeholder, "placeholder", 1), + replaceStrings: markPrimop(misc.replaceStrings, "replaceStrings", 3), + split: markPrimop(misc.split, "split", 2), + splitVersion: markPrimop(misc.splitVersion, "splitVersion", 1), + traceVerbose: markPrimop(misc.traceVerbose, "traceVerbose", 2), + tryEval: markPrimop(misc.tryEval, "tryEval", 1), + zipAttrsWith: markPrimop(misc.zipAttrsWith, "zipAttrsWith", 2), builtins: create_thunk(() => builtins), currentSystem: create_thunk(() => { - throw 'Not implemented: currentSystem'; + throw "Not implemented: currentSystem"; }), currentTime: create_thunk(() => Date.now()), @@ -245,6 +249,6 @@ export const builtins: any = { langVersion: 6, nixPath: [], - nixVersion: 'NIX_JS_VERSION', - storeDir: '/nix/store', + nixVersion: "NIX_JS_VERSION", + storeDir: "/nix/store", }; diff --git a/nix-js/runtime-ts/src/builtins/io.ts b/nix-js/runtime-ts/src/builtins/io.ts index 571b2cf..c157585 100644 --- a/nix-js/runtime-ts/src/builtins/io.ts +++ b/nix-js/runtime-ts/src/builtins/io.ts @@ -3,72 +3,76 @@ * These functions require Node.js/Deno APIs not available in V8 */ -import type { NixValue } from '../types'; +import type { NixValue } from "../types"; export const importFunc = (path: NixValue): never => { - throw 'Not implemented: import'; + throw "Not implemented: import"; }; -export const scopedImport = (scope: NixValue) => (path: NixValue): never => { - throw 'Not implemented: scopedImport'; -}; +export const scopedImport = + (scope: NixValue) => + (path: NixValue): never => { + throw "Not implemented: scopedImport"; + }; export const fetchClosure = (args: NixValue): never => { - throw 'Not implemented: fetchClosure'; + throw "Not implemented: fetchClosure"; }; export const fetchGit = (args: NixValue): never => { - throw 'Not implemented: fetchGit'; + throw "Not implemented: fetchGit"; }; export const fetchTarball = (args: NixValue): never => { - throw 'Not implemented: fetchTarball'; + throw "Not implemented: fetchTarball"; }; export const fetchTree = (args: NixValue): never => { - throw 'Not implemented: fetchTree'; + throw "Not implemented: fetchTree"; }; export const fetchurl = (args: NixValue): never => { - throw 'Not implemented: fetchurl'; + throw "Not implemented: fetchurl"; }; export const readDir = (path: NixValue): never => { - throw 'Not implemented: readDir'; + throw "Not implemented: readDir"; }; export const readFile = (path: NixValue): never => { - throw 'Not implemented: readFile'; + throw "Not implemented: readFile"; }; export const readFileType = (path: NixValue): never => { - throw 'Not implemented: readFileType'; + throw "Not implemented: readFileType"; }; export const pathExists = (path: NixValue): never => { - throw 'Not implemented: pathExists'; + throw "Not implemented: pathExists"; }; export const path = (args: NixValue): never => { - throw 'Not implemented: path'; + throw "Not implemented: path"; }; export const toFile = (name: NixValue, s: NixValue): never => { - throw 'Not implemented: toFile'; + throw "Not implemented: toFile"; }; export const toPath = (name: NixValue, s: NixValue): never => { - throw 'Not implemented: toPath'; + throw "Not implemented: toPath"; }; export const filterSource = (args: NixValue): never => { - throw 'Not implemented: filterSource'; + throw "Not implemented: filterSource"; }; -export const findFile = (search: NixValue) => (lookup: NixValue): never => { - throw 'Not implemented: findFile'; -}; +export const findFile = + (search: NixValue) => + (lookup: NixValue): never => { + throw "Not implemented: findFile"; + }; export const getEnv = (s: NixValue): never => { - throw 'Not implemented: getEnv'; + throw "Not implemented: getEnv"; }; diff --git a/nix-js/runtime-ts/src/builtins/list.ts b/nix-js/runtime-ts/src/builtins/list.ts index 76f85d1..94f269a 100644 --- a/nix-js/runtime-ts/src/builtins/list.ts +++ b/nix-js/runtime-ts/src/builtins/list.ts @@ -3,19 +3,23 @@ * All functions are properly curried */ -import type { NixValue, NixList, NixAttrs } from '../types'; -import { force } from '../thunk'; -import { force_list, force_function, force_numeric, force_int } from '../type-assert'; +import type { NixValue, NixList, NixAttrs } from "../types"; +import { force } from "../thunk"; +import { force_list, force_function, force_numeric, force_int } from "../type-assert"; -export const map = (f: NixValue) => (list: NixValue): NixList => - force_list(list).map(force_function(f)); +export const map = + (f: NixValue) => + (list: NixValue): NixList => + force_list(list).map(force_function(f)); -export const filter = (f: NixValue) => (list: NixValue): NixList => - force_list(list).filter(force_function(f)); +export const filter = + (f: NixValue) => + (list: NixValue): NixList => + force_list(list).filter(force_function(f)); export const length = (e: NixValue): bigint => { const forced = force(e); - if (typeof forced === 'string') return BigInt(forced.length); + if (typeof forced === "string") return BigInt(forced.length); return BigInt(force_list(forced).length); }; @@ -23,19 +27,23 @@ export const head = (list: NixValue): NixValue => force_list(list)[0]; export const tail = (list: NixValue): NixList => force_list(list).slice(1); -export const elem = (x: NixValue) => (xs: NixValue): boolean => - force_list(xs).includes(force(x)); +export const elem = + (x: NixValue) => + (xs: NixValue): boolean => + force_list(xs).includes(force(x)); -export const elemAt = (xs: NixValue) => (n: NixValue): NixValue => { - const list = force_list(xs); - const idx = Number(force_int(n)); +export const elemAt = + (xs: NixValue) => + (n: NixValue): NixValue => { + const list = force_list(xs); + const idx = Number(force_int(n)); - if (idx < 0 || idx >= list.length) { - throw new RangeError(`Index ${idx} out of bounds for list of length ${list.length}`); - } + if (idx < 0 || idx >= list.length) { + throw new RangeError(`Index ${idx} out of bounds for list of length ${list.length}`); + } - return list[idx]; -}; + return list[idx]; + }; export const concatLists = (lists: NixValue): NixList => { return force_list(lists).reduce((acc: NixList, cur: NixValue) => { @@ -43,60 +51,75 @@ export const concatLists = (lists: NixValue): NixList => { }, []); }; -export const concatMap = (f: NixValue) => (lists: NixValue): NixList => { - const fn = force_function(f); - return force_list(lists).reduce((acc: NixList, cur: NixValue) => { - return acc.concat(force(fn(cur)) as NixList); - }, []); -}; - -export const foldlPrime = (op_fn: NixValue) => (nul: NixValue) => (list: NixValue): NixValue => { - const forced_op = force_function(op_fn); - return force_list(list).reduce((acc: NixValue, cur: NixValue) => { - return forced_op(acc)(cur); - }, nul); -}; - -export const sort = (cmp: NixValue) => (list: NixValue): NixList => { - const forced_list = [...force_list(list)]; - const forced_cmp = force_function(cmp); - return forced_list.sort((a, b) => { - if (force(forced_cmp(a)(b))) return -1; - if (force(forced_cmp(b)(a))) return 1; - return 0; - }); -}; - -export const partition = (pred: NixValue) => (list: NixValue): NixAttrs => { - const forced_list = force_list(list); - const forced_pred = force_function(pred); - const attrs: NixAttrs = { - right: [], - wrong: [], +export const concatMap = + (f: NixValue) => + (lists: NixValue): NixList => { + const fn = force_function(f); + return force_list(lists).reduce((acc: NixList, cur: NixValue) => { + return acc.concat(force(fn(cur)) as NixList); + }, []); }; - for (const elem of forced_list) { - if (force(forced_pred(elem))) { - (attrs.right as NixList).push(elem); - } else { - (attrs.wrong as NixList).push(elem); + +export const foldlPrime = + (op_fn: NixValue) => + (nul: NixValue) => + (list: NixValue): NixValue => { + const forced_op = force_function(op_fn); + return force_list(list).reduce((acc: NixValue, cur: NixValue) => { + return forced_op(acc)(cur); + }, nul); + }; + +export const sort = + (cmp: NixValue) => + (list: NixValue): NixList => { + const forced_list = [...force_list(list)]; + const forced_cmp = force_function(cmp); + return forced_list.sort((a, b) => { + if (force(forced_cmp(a)(b))) return -1; + if (force(forced_cmp(b)(a))) return 1; + return 0; + }); + }; + +export const partition = + (pred: NixValue) => + (list: NixValue): NixAttrs => { + const forced_list = force_list(list); + const forced_pred = force_function(pred); + const attrs: NixAttrs = { + right: [], + wrong: [], + }; + for (const elem of forced_list) { + if (force(forced_pred(elem))) { + (attrs.right as NixList).push(elem); + } else { + (attrs.wrong as NixList).push(elem); + } } - } - return attrs; -}; + return attrs; + }; -export const genList = (f: NixValue) => (len: NixValue): NixList => { - const func = force_function(f); - const length = force_int(len); +export const genList = + (f: NixValue) => + (len: NixValue): NixList => { + const func = force_function(f); + const length = force_int(len); - if (length < 0) { - throw new TypeError(`genList length must be non-negative integer, got ${length}`); - } + if (length < 0) { + throw new TypeError(`genList length must be non-negative integer, got ${length}`); + } - return [...Array(Number(length)).keys()].map(i => func(BigInt(i))); -}; + return [...Array(Number(length)).keys()].map((i) => func(BigInt(i))); + }; -export const all = (pred: NixValue) => (list: NixValue): boolean => - force_list(list).every(force_function(pred)); +export const all = + (pred: NixValue) => + (list: NixValue): boolean => + force_list(list).every(force_function(pred)); -export const any = (pred: NixValue) => (list: NixValue): boolean => - force_list(list).some(force_function(pred)); +export const any = + (pred: NixValue) => + (list: NixValue): boolean => + force_list(list).some(force_function(pred)); diff --git a/nix-js/runtime-ts/src/builtins/math.ts b/nix-js/runtime-ts/src/builtins/math.ts index de8e7a4..0c6e668 100644 --- a/nix-js/runtime-ts/src/builtins/math.ts +++ b/nix-js/runtime-ts/src/builtins/math.ts @@ -2,17 +2,17 @@ * Math builtin functions */ -import type { NixValue } from '../types'; -import { force_numeric } from '../type-assert'; +import type { NixValue } from "../types"; +import { force_numeric } from "../type-assert"; export const ceil = (x: NixValue): bigint => { const val = force_numeric(x); - if (typeof val === 'bigint') return val; // Already an integer - return BigInt(Math.ceil(val)); // Convert to integer + if (typeof val === "bigint") return val; // Already an integer + return BigInt(Math.ceil(val)); // Convert to integer }; export const floor = (x: NixValue): bigint => { const val = force_numeric(x); - if (typeof val === 'bigint') return val; // Already an integer - return BigInt(Math.floor(val)); // Convert to integer + if (typeof val === "bigint") return val; // Already an integer + return BigInt(Math.floor(val)); // Convert to integer }; diff --git a/nix-js/runtime-ts/src/builtins/misc.ts b/nix-js/runtime-ts/src/builtins/misc.ts index e2d857d..70bd76d 100644 --- a/nix-js/runtime-ts/src/builtins/misc.ts +++ b/nix-js/runtime-ts/src/builtins/misc.ts @@ -2,108 +2,125 @@ * Miscellaneous unimplemented builtin functions */ -import type { NixValue } from '../types'; +import type { NixValue } from "../types"; export const getContext = (s: NixValue): never => { - throw 'Not implemented: getContext'; + throw "Not implemented: getContext"; }; export const hasContext = (s: NixValue): never => { - throw 'Not implemented: hasContext'; + throw "Not implemented: hasContext"; }; -export const hashFile = (type: NixValue) => (p: NixValue): never => { - throw 'Not implemented: hashFile'; -}; +export const hashFile = + (type: NixValue) => + (p: NixValue): never => { + throw "Not implemented: hashFile"; + }; -export const hashString = (type: NixValue) => (p: NixValue): never => { - throw 'Not implemented: hashString'; -}; +export const hashString = + (type: NixValue) => + (p: NixValue): never => { + throw "Not implemented: hashString"; + }; export const convertHash = (args: NixValue): never => { - throw 'Not implemented: convertHash'; + throw "Not implemented: convertHash"; }; export const unsafeDiscardOutputDependency = (s: NixValue): never => { - throw 'Not implemented: unsafeDiscardOutputDependency'; + throw "Not implemented: unsafeDiscardOutputDependency"; }; export const unsafeDiscardStringContext = (s: NixValue): never => { - throw 'Not implemented: unsafeDiscardStringContext'; + throw "Not implemented: unsafeDiscardStringContext"; }; export const unsafeGetAttrPos = (s: NixValue): never => { - throw 'Not implemented: unsafeGetAttrPos'; + throw "Not implemented: unsafeGetAttrPos"; }; export const addDrvOutputDependencies = (s: NixValue): never => { - throw 'Not implemented: addDrvOutputDependencies'; + throw "Not implemented: addDrvOutputDependencies"; }; -export const compareVersions = (s1: NixValue) => (s2: NixValue): never => { - throw 'Not implemented: compareVersions'; -}; +export const compareVersions = + (s1: NixValue) => + (s2: NixValue): never => { + throw "Not implemented: compareVersions"; + }; export const dirOf = (s: NixValue): never => { - throw 'Not implemented: dirOf'; + throw "Not implemented: dirOf"; }; export const flakeRefToString = (attrs: NixValue): never => { - throw 'Not implemented: flakeRefToString'; + throw "Not implemented: flakeRefToString"; }; export const functionArgs = (f: NixValue): never => { - throw 'Not implemented: functionArgs'; + throw "Not implemented: functionArgs"; }; export const genericClosure = (args: NixValue): never => { - throw 'Not implemented: genericClosure'; + throw "Not implemented: genericClosure"; }; export const getFlake = (attrs: NixValue): never => { - throw 'Not implemented: getFlake'; + throw "Not implemented: getFlake"; }; -export const match = (regex: NixValue) => (str: NixValue): never => { - throw 'Not implemented: match'; -}; +export const match = + (regex: NixValue) => + (str: NixValue): never => { + throw "Not implemented: match"; + }; -export const outputOf = (drv: NixValue) => (out: NixValue): never => { - throw 'Not implemented: outputOf'; -}; +export const outputOf = + (drv: NixValue) => + (out: NixValue): never => { + throw "Not implemented: outputOf"; + }; export const parseDrvName = (s: NixValue): never => { - throw 'Not implemented: parseDrvName'; + throw "Not implemented: parseDrvName"; }; export const parseFlakeName = (s: NixValue): never => { - throw 'Not implemented: parseFlakeName'; + throw "Not implemented: parseFlakeName"; }; export const placeholder = (output: NixValue): never => { - throw 'Not implemented: placeholder'; + throw "Not implemented: placeholder"; }; -export const replaceStrings = (from: NixValue) => (to: NixValue) => (s: NixValue): never => { - throw 'Not implemented: replaceStrings'; -}; +export const replaceStrings = + (from: NixValue) => + (to: NixValue) => + (s: NixValue): never => { + throw "Not implemented: replaceStrings"; + }; export const split = (regex: NixValue, str: NixValue): never => { - throw 'Not implemented: split'; + throw "Not implemented: split"; }; export const splitVersion = (s: NixValue): never => { - throw 'Not implemented: splitVersion'; + throw "Not implemented: splitVersion"; }; export const traceVerbose = (e1: NixValue, e2: NixValue): never => { - throw 'Not implemented: traceVerbose'; + throw "Not implemented: traceVerbose"; }; -export const tryEval = (e1: NixValue) => (e2: NixValue): never => { - throw 'Not implemented: tryEval'; -}; +export const tryEval = + (e1: NixValue) => + (e2: NixValue): never => { + throw "Not implemented: tryEval"; + }; -export const zipAttrsWith = (f: NixValue) => (list: NixValue): never => { - throw 'Not implemented: zipAttrsWith'; -}; +export const zipAttrsWith = + (f: NixValue) => + (list: NixValue): never => { + throw "Not implemented: zipAttrsWith"; + }; diff --git a/nix-js/runtime-ts/src/builtins/string.ts b/nix-js/runtime-ts/src/builtins/string.ts index ac6d9a1..e223cbb 100644 --- a/nix-js/runtime-ts/src/builtins/string.ts +++ b/nix-js/runtime-ts/src/builtins/string.ts @@ -2,32 +2,37 @@ * String operation builtin functions */ -import type { NixValue } from '../types'; -import { force_string, force_list, force_int } from '../type-assert'; +import type { NixValue } from "../types"; +import { force_string, force_list, force_int } from "../type-assert"; export const stringLength = (e: NixValue): number => force_string(e).length; -export const substring = (start: NixValue) => (len: NixValue) => (s: NixValue): string => { - const str = force_string(s); - const startPos = Number(force_int(start)); - const length = Number(force_int(len)); - return str.substring(startPos, startPos + length); -}; +export const substring = + (start: NixValue) => + (len: NixValue) => + (s: NixValue): string => { + const str = force_string(s); + const startPos = Number(force_int(start)); + const length = Number(force_int(len)); + return str.substring(startPos, startPos + length); + }; -export const concatStringsSep = (sep: NixValue) => (list: NixValue): string => - force_list(list).join(force_string(sep)); +export const concatStringsSep = + (sep: NixValue) => + (list: NixValue): string => + force_list(list).join(force_string(sep)); export const baseNameOf = (x: NixValue): string => { const str = force_string(x); - if (str.length === 0) return ''; + if (str.length === 0) return ""; let last = str.length - 1; - if (str[last] === '/' && last > 0) last -= 1; + if (str[last] === "/" && last > 0) last -= 1; let pos = last; - while (pos >= 0 && str[pos] !== '/') pos -= 1; + while (pos >= 0 && str[pos] !== "/") pos -= 1; - if (pos !== 0 || (pos === 0 && str[pos] === '/')) { + if (pos !== 0 || (pos === 0 && str[pos] === "/")) { pos += 1; } diff --git a/nix-js/runtime-ts/src/builtins/type-check.ts b/nix-js/runtime-ts/src/builtins/type-check.ts index f9ff4f3..943e97c 100644 --- a/nix-js/runtime-ts/src/builtins/type-check.ts +++ b/nix-js/runtime-ts/src/builtins/type-check.ts @@ -2,26 +2,36 @@ * Type checking builtin functions */ -import type { NixAttrs, NixBool, NixFloat, NixFunction, NixInt, NixList, NixNull, NixString, NixValue } from '../types'; -import { force } from '../thunk'; +import type { + NixAttrs, + NixBool, + NixFloat, + NixFunction, + NixInt, + NixList, + NixNull, + NixString, + NixValue, +} from "../types"; +import { force } from "../thunk"; export const isAttrs = (e: NixValue): e is NixAttrs => { const val = force(e); - return typeof val === 'object' && !Array.isArray(val) && val !== null; + return typeof val === "object" && !Array.isArray(val) && val !== null; }; -export const isBool = (e: NixValue): e is NixBool => typeof force(e) === 'boolean'; +export const isBool = (e: NixValue): e is NixBool => typeof force(e) === "boolean"; export const isFloat = (e: NixValue): e is NixFloat => { const val = force(e); - return typeof val === 'number'; // Only number is float + return typeof val === "number"; // Only number is float }; -export const isFunction = (e: NixValue): e is NixFunction => typeof force(e) === 'function'; +export const isFunction = (e: NixValue): e is NixFunction => typeof force(e) === "function"; export const isInt = (e: NixValue): e is NixInt => { const val = force(e); - return typeof val === 'bigint'; // Only bigint is int + return typeof val === "bigint"; // Only bigint is int }; export const isList = (e: NixValue): e is NixList => Array.isArray(force(e)); @@ -29,22 +39,22 @@ export const isList = (e: NixValue): e is NixList => Array.isArray(force(e)); export const isNull = (e: NixValue): e is NixNull => force(e) === null; export const isPath = (e: NixValue): never => { - throw 'Not implemented: isPath'; + throw "Not implemented: isPath"; }; -export const isString = (e: NixValue): e is NixString => typeof force(e) === 'string'; +export const isString = (e: NixValue): e is NixString => typeof force(e) === "string"; export const typeOf = (e: NixValue): string => { const val = force(e); - if (typeof val === 'bigint') return 'int'; - if (typeof val === 'number') return 'float'; - if (typeof val === 'boolean') return 'bool'; - if (typeof val === 'string') return 'string'; - if (val === null) return 'null'; - if (Array.isArray(val)) return 'list'; - if (typeof val === 'function') return 'lambda'; - if (typeof val === 'object') return 'set'; + if (typeof val === "bigint") return "int"; + if (typeof val === "number") return "float"; + if (typeof val === "boolean") return "bool"; + if (typeof val === "string") return "string"; + if (val === null) return "null"; + if (Array.isArray(val)) return "list"; + if (typeof val === "function") return "lambda"; + if (typeof val === "object") return "set"; throw new TypeError(`Unknown Nix type: ${typeof val}`); }; diff --git a/nix-js/runtime-ts/src/helpers.ts b/nix-js/runtime-ts/src/helpers.ts index 959e9ac..a49dca6 100644 --- a/nix-js/runtime-ts/src/helpers.ts +++ b/nix-js/runtime-ts/src/helpers.ts @@ -3,8 +3,8 @@ * Implements attribute selection, parameter validation, and lazy sets */ -import type { NixValue, NixAttrs } from './types'; -import { force_attrs, force_string } from './type-assert'; +import type { NixValue, NixAttrs } from "./types"; +import { force_attrs, force_string } from "./type-assert"; /** * Select an attribute from an attribute set @@ -35,11 +35,7 @@ export const select = (obj: NixValue, key: NixValue): NixValue => { * @param default_val - Value to return if key not found * @returns obj[key] if exists, otherwise default_val */ -export const select_with_default = ( - obj: NixValue, - key: NixValue, - default_val: NixValue -): NixValue => { +export const select_with_default = (obj: NixValue, key: NixValue, default_val: NixValue): NixValue => { const forced_obj = force_attrs(obj); const forced_key = force_string(key); @@ -72,7 +68,7 @@ export const select_with_default = ( export const validate_params = ( arg: NixValue, required: string[] | null, - allowed: string[] | null + allowed: string[] | null, ): NixAttrs => { const forced_arg = force_attrs(arg); diff --git a/nix-js/runtime-ts/src/index.ts b/nix-js/runtime-ts/src/index.ts index 08f5eb4..5a248de 100644 --- a/nix-js/runtime-ts/src/index.ts +++ b/nix-js/runtime-ts/src/index.ts @@ -4,10 +4,10 @@ * All functionality is exported via the global `Nix` object */ -import { create_thunk, force, is_thunk, IS_THUNK } from './thunk'; -import { select, select_with_default, validate_params } from './helpers'; -import { op } from './operators'; -import { builtins, IS_PRIMOP } from './builtins'; +import { create_thunk, force, is_thunk, IS_THUNK } from "./thunk"; +import { select, select_with_default, validate_params } from "./helpers"; +import { op } from "./operators"; +import { builtins, IS_PRIMOP } from "./builtins"; export type NixRuntime = typeof Nix; @@ -31,5 +31,5 @@ export const Nix = { globalThis.Nix = Nix; declare global { - var Nix: NixRuntime + var Nix: NixRuntime; } diff --git a/nix-js/runtime-ts/src/operators.ts b/nix-js/runtime-ts/src/operators.ts index 430a0c1..e90ad5d 100644 --- a/nix-js/runtime-ts/src/operators.ts +++ b/nix-js/runtime-ts/src/operators.ts @@ -3,9 +3,9 @@ * Implements all binary and unary operators used by codegen */ -import type { NixValue, NixList, NixAttrs } from './types'; -import { force } from './thunk'; -import { force_numeric, force_list, force_attrs, coerce_numeric } from './type-assert'; +import type { NixValue, NixList, NixAttrs } from "./types"; +import { force } from "./thunk"; +import { force_numeric, force_list, force_attrs, coerce_numeric } from "./type-assert"; /** * Operator object exported as Nix.op @@ -33,10 +33,10 @@ export const op = { const [av, bv] = coerce_numeric(force_numeric(a), force_numeric(b)); if (bv === 0 || bv === 0n) { - throw new RangeError('Division by zero'); + throw new RangeError("Division by zero"); } - return (av as any) / (bv as any) + return (av as any) / (bv as any); }, // Comparison operators (JavaScript natively supports bigint/number mixed comparison) @@ -44,13 +44,13 @@ export const op = { // FIXME: Int and Float const av = force(a); const bv = force(b); - return av === bv + return av === bv; }, neq: (a: NixValue, b: NixValue): boolean => { // FIXME: Int and Float const av = force(a); const bv = force(b); - return av !== bv + return av !== bv; }, lt: (a: NixValue, b: NixValue): boolean => { // FIXME: Non-numeric diff --git a/nix-js/runtime-ts/src/thunk.ts b/nix-js/runtime-ts/src/thunk.ts index 04ecc00..7816b5c 100644 --- a/nix-js/runtime-ts/src/thunk.ts +++ b/nix-js/runtime-ts/src/thunk.ts @@ -3,13 +3,13 @@ * Implements thunks for lazy evaluation of Nix expressions */ -import type { NixValue, NixThunkInterface } from './types'; +import type { NixValue, NixThunkInterface } from "./types"; /** * Symbol used to mark objects as thunks * This is exported to Rust via Nix.IS_THUNK */ -export const IS_THUNK = Symbol('is_thunk'); +export const IS_THUNK = Symbol("is_thunk"); /** * NixThunk class - represents a lazy, unevaluated expression @@ -35,12 +35,7 @@ export class NixThunk implements NixThunkInterface { * @returns true if value is a NixThunk */ export const is_thunk = (value: unknown): value is NixThunkInterface => { - return ( - value !== null && - typeof value === 'object' && - IS_THUNK in value && - value[IS_THUNK] === true - ); + return value !== null && typeof value === "object" && IS_THUNK in value && value[IS_THUNK] === true; }; /** diff --git a/nix-js/runtime-ts/src/type-assert.ts b/nix-js/runtime-ts/src/type-assert.ts index ce251dc..c9680bb 100644 --- a/nix-js/runtime-ts/src/type-assert.ts +++ b/nix-js/runtime-ts/src/type-assert.ts @@ -3,8 +3,8 @@ * These functions force evaluation and verify the type, throwing errors on mismatch */ -import type { NixValue, NixList, NixAttrs, NixFunction, NixInt, NixFloat, NixNumber } from './types'; -import { force } from './thunk'; +import type { NixValue, NixList, NixAttrs, NixFunction, NixInt, NixFloat, NixNumber } from "./types"; +import { force } from "./thunk"; /** * Force a value and assert it's a list @@ -24,7 +24,7 @@ export const force_list = (value: NixValue): NixList => { */ export const force_function = (value: NixValue): NixFunction => { const forced = force(value); - if (typeof forced !== 'function') { + if (typeof forced !== "function") { throw new TypeError(`Expected function, got ${typeof forced}`); } return forced; @@ -36,7 +36,7 @@ export const force_function = (value: NixValue): NixFunction => { */ export const force_attrs = (value: NixValue): NixAttrs => { const forced = force(value); - if (typeof forced !== 'object' || forced === null || Array.isArray(forced)) { + if (typeof forced !== "object" || forced === null || Array.isArray(forced)) { throw new TypeError(`Expected attribute set, got ${typeof forced}`); } return forced as NixAttrs; @@ -48,7 +48,7 @@ export const force_attrs = (value: NixValue): NixAttrs => { */ export const force_string = (value: NixValue): string => { const forced = force(value); - if (typeof forced !== 'string') { + if (typeof forced !== "string") { throw new TypeError(`Expected string, got ${typeof forced}`); } return forced; @@ -60,7 +60,7 @@ export const force_string = (value: NixValue): string => { */ export const force_bool = (value: NixValue): boolean => { const forced = force(value); - if (typeof forced !== 'boolean') { + if (typeof forced !== "boolean") { throw new TypeError(`Expected boolean, got ${typeof forced}`); } return forced; @@ -72,7 +72,7 @@ export const force_bool = (value: NixValue): boolean => { */ export const force_int = (value: NixValue): NixInt => { const forced = force(value); - if (typeof forced === 'bigint') { + if (typeof forced === "bigint") { return forced; } throw new TypeError(`Expected int, got ${typeof forced}`); @@ -84,7 +84,7 @@ export const force_int = (value: NixValue): NixInt => { */ export const force_float = (value: NixValue): NixFloat => { const forced = force(value); - if (typeof forced === 'number') { + if (typeof forced === "number") { return forced; } throw new TypeError(`Expected float, got ${typeof forced}`); @@ -96,7 +96,7 @@ export const force_float = (value: NixValue): NixFloat => { */ export const force_numeric = (value: NixValue): NixNumber => { const forced = force(value); - if (typeof forced === 'bigint' || typeof forced === 'number') { + if (typeof forced === "bigint" || typeof forced === "number") { return forced; } throw new TypeError(`Expected numeric type, got ${typeof forced}`); @@ -107,19 +107,13 @@ export const force_numeric = (value: NixValue): NixNumber => { * Rule: If either is float, convert both to float; otherwise keep as bigint * @returns [a, b] tuple of coerced values */ -export const coerce_numeric = ( - a: NixNumber, - b: NixNumber -): [NixFloat, NixFloat] | [NixInt, NixInt] => { - const aIsInt = typeof a === 'bigint'; - const bIsInt = typeof b === 'bigint'; +export const coerce_numeric = (a: NixNumber, b: NixNumber): [NixFloat, NixFloat] | [NixInt, NixInt] => { + const aIsInt = typeof a === "bigint"; + const bIsInt = typeof b === "bigint"; // If either is float, convert both to float if (!aIsInt || !bIsInt) { - return [ - aIsInt ? Number(a) : a, - bIsInt ? Number(b) : b - ]; + return [aIsInt ? Number(a) : a, bIsInt ? Number(b) : b]; } // Both are integers diff --git a/nix-js/runtime-ts/src/types.ts b/nix-js/runtime-ts/src/types.ts index df56761..e4644a3 100644 --- a/nix-js/runtime-ts/src/types.ts +++ b/nix-js/runtime-ts/src/types.ts @@ -32,12 +32,7 @@ export type NixPrimitive = NixNull | NixBool | NixInt | NixFloat | NixString; * NixValue: Union type representing any possible Nix value * This is the core type used throughout the runtime */ -export type NixValue = - | NixPrimitive - | NixList - | NixAttrs - | NixFunction - | NixThunkInterface; +export type NixValue = NixPrimitive | NixList | NixAttrs | NixFunction | NixThunkInterface; // Operator function signatures export type BinaryOp = (a: T, b: U) => R;