diff --git a/packages/cosmic-swingset/bin/ag-solo-xs.js b/packages/cosmic-swingset/bin/ag-solo-xs.js index b6f1060142d..82009d054e6 100644 --- a/packages/cosmic-swingset/bin/ag-solo-xs.js +++ b/packages/cosmic-swingset/bin/ag-solo-xs.js @@ -34,7 +34,7 @@ export default async function main() { for (const [internal, external] of Object.entries(native)) { cmap[internal] = Compartment.map[external]; } - const endowments = { console, require, setImmediate, setInterval, URL }; + const endowments = { console, require, setImmediate, setInterval, setTimeout, URL }; try { // console.log('making compartment...'); diff --git a/packages/cosmic-swingset/lib/xs-node-api/fs.js b/packages/cosmic-swingset/lib/xs-node-api/fs.js index 1b66c732225..2e015f81974 100644 --- a/packages/cosmic-swingset/lib/xs-node-api/fs.js +++ b/packages/cosmic-swingset/lib/xs-node-api/fs.js @@ -9,19 +9,18 @@ export function makePathAccess(path) { return makePath(path, { File, Iterator }); } +const mkp = makePathAccess; + function readFileSync(path) { - const p = makePath(path, { File, Iterator }); - return p.readFileSync(); + return mkp(path).readFileSync(); } -function readdirSync(path) { - const p = makePath(path, { File, Iterator }); - return p.readdirSync(); +function readdirSync(path, options) { + return mkp(path).readdirSync(options); } function statSync(path) { - const p = makePath(path, { File, Iterator }); - return p.statSync(); + return mkp(path).statSync(); } export function realpathSync(path) { @@ -59,26 +58,36 @@ const openFiles = (() => { })(); function later(thunk) { - Promise.resolve(null).then(thunk); + return new Promise((resolve, reject) => { + try { + resolve(thunk()); + } catch (err) { + reject(err); + } + }); } const promises = harden({ + readFile(path) { + return mkp(path).readFile(); + }, + writeFile(file, data) { + return mkp(file).writeFile(data); + }, write(fd, text) { - later(() => { - openFiles.lookup(fd).write(text); - }); + return later(() => openFiles.lookup(fd).write(text)); }, close(fd) { - later(() => openFiles.close(fd)); + return later(() => openFiles.close(fd)); }, readdir(path) { - return makePath(path, { File, Iterator }).readdir(); + return mkp(path).readdir(); }, rename(from, to) { - later(() => File.rename(from, to)); + return later(() => File.rename(from, to)); }, unlink(path) { - later(() => File.delete(path)); + return later(() => File.delete(path)); }, }); @@ -97,6 +106,7 @@ export function openSync(path, mode = 'r') { throw new Error('already exists'); } catch (_doesNotExist) { // ok + // ISSUE: need to distinguish doesNotExist from no permission etc.? } return openFiles.add(path, true); } diff --git a/packages/cosmic-swingset/lib/xs-node-api/pathlib.js b/packages/cosmic-swingset/lib/xs-node-api/pathlib.js index 3b6de2e9f86..69e45a83bf8 100644 --- a/packages/cosmic-swingset/lib/xs-node-api/pathlib.js +++ b/packages/cosmic-swingset/lib/xs-node-api/pathlib.js @@ -33,6 +33,16 @@ export function join(...paths) { return normalize(paths.join('/')); } +function later(thunk) { + return new Promise((resolve, reject) => { + try { + resolve(thunk()); + } catch (err) { + reject(err); + } + }); +} + export function makePath(filename, { File, Iterator }) { const mk = there => makePath(there, { File, Iterator }); @@ -74,46 +84,37 @@ export function makePath(filename, { File, Iterator }) { } function atomicReplace(contents) { - return new Promise((resolve, reject) => { - try { - const tmp = mk(`${filename}.tmp`); - const tmpF = new File(tmp, true); - tmpF.write(contents); - tmpF.close(); - File.rename(tmp, filename); - } catch (oops) { - reject(oops); - return; - } - resolve(); + return later(() => { + const tmp = mk(`${filename}.tmp`); + const tmpF = new File(tmp, true); + tmpF.write(contents); + tmpF.close(); + File.rename(tmp, filename); }); } - function readdirSync(options) { + function readdirSync(options = {}) { const dirIter = new Iterator(filename); let item; const items = []; while ((item = dirIter.next())) { - const f = typeof item.length === 'number'; - items.push( - harden({ - name: item.name, - isFile: () => f, - }), - ); + if (options.withFileTypes) { + const f = typeof item.length === 'number'; + items.push( + harden({ + name: item.name, + isFile: () => f, + }), + ); + } else { + items.push(item.name); + } } return items; } - function readdir() { - return new Promise((resolve, reject) => { - try { - const names = readdirSync({}).map(item => item.name); - resolve(names); - } catch (oops) { - reject(oops); - } - }); + function readdir(options) { + return later(() => readdirSync(options)); } function butLast(p) { @@ -166,6 +167,9 @@ export function makePath(filename, { File, Iterator }) { exists, statSync, readFileSync, + readFile() { + return later(() => readFileSync()); + }, readlinesSync() { const text = readFileSync(); if (text === '') { @@ -177,6 +181,12 @@ export function makePath(filename, { File, Iterator }) { readdir, bundleSource, atomicReplace, + writeFile(data, options) { + return later(() => { + const f = new File(filename, true); + f.write(data); + }); + }, withWriting, }); } diff --git a/packages/cosmic-swingset/lib/xs-npm/deterministic-json.js b/packages/cosmic-swingset/lib/xs-npm/deterministic-json.js index 8b49f2a41b7..1159b061277 100644 --- a/packages/cosmic-swingset/lib/xs-npm/deterministic-json.js +++ b/packages/cosmic-swingset/lib/xs-npm/deterministic-json.js @@ -1,3 +1,4 @@ -export default function () { - throw 'TODO!'; -} +// ISSUE: why are we using deterministic-json? Are we using the buffer stuff? +import stringify from '@agoric/swingset-vat/src/kernel/json-stable-stringify'; + +export default { stringify };