(getData, setData)
| 120 | } |
| 121 | |
| 122 | const makeRouteWithContents = (getData, setData) => ({ |
| 123 | // getData: (req: Request U Vars) -> Promise<contentsOfFile: String|Uint8Array> |
| 124 | // setData [optional]: (req: Request U Vars, newContentsOfFile: String) -> Promise<> |
| 125 | |
| 126 | // You can override file operations (like `truncate` or `getattr`) |
| 127 | // in the returned set if you want different behavior from what's |
| 128 | // defined here. |
| 129 | |
| 130 | async getattr(req) { |
| 131 | const data = await getData(req); |
| 132 | if (typeof data === 'undefined') { throw new UnixError(unix.ENOENT); } |
| 133 | return { |
| 134 | st_mode: unix.S_IFREG | 0444 | (setData ? 0222 : 0), |
| 135 | st_nlink: 1, |
| 136 | // you'll want to override this if getData() is slow, because |
| 137 | // getattr() gets called a lot more cavalierly than open(). |
| 138 | st_size: toUtf8Array(data).length |
| 139 | }; |
| 140 | }, |
| 141 | |
| 142 | // We call getData() once when the file is opened, then cache that |
| 143 | // data for all subsequent reads from that application. |
| 144 | async open(req) { |
| 145 | const data = await getData(req); |
| 146 | if (typeof data === 'undefined') { throw new UnixError(unix.ENOENT); } |
| 147 | return { fh: Cache.storeObject(req.path, toUtf8Array(data)) }; |
| 148 | }, |
| 149 | async read({fh, size, offset}) { |
| 150 | return { buf: Cache.getObjectForHandle(fh).slice(offset, offset + size) }; |
| 151 | }, |
| 152 | async write(req) { |
| 153 | const {fh, offset, buf} = req; |
| 154 | let arr = Cache.getObjectForHandle(fh); |
| 155 | const bufarr = stringToUtf8Array(buf); |
| 156 | if (offset + bufarr.length > arr.length) { |
| 157 | const newArr = new Uint8Array(offset + bufarr.length); |
| 158 | newArr.set(arr.slice(0, Math.min(offset, arr.length))); |
| 159 | arr = newArr; |
| 160 | Cache.setObjectForHandle(fh, arr); |
| 161 | } |
| 162 | arr.set(bufarr, offset); |
| 163 | // I guess caller should override write() if they want to actually |
| 164 | // patch and not just re-set the whole string (for example, |
| 165 | // if they want to hot-reload just one function the user modified) |
| 166 | await setData(req, utf8ArrayToString(arr)); return { size: bufarr.length }; |
| 167 | }, |
| 168 | async release({fh}) { Cache.removeObjectForHandle(fh); return {}; }, |
| 169 | |
| 170 | async truncate(req) { |
| 171 | let arr = toUtf8Array(await getData(req)); |
| 172 | if (req.size !== arr.length) { |
| 173 | const newArr = new Uint8Array(req.size); |
| 174 | newArr.set(arr.slice(0, Math.min(req.size, arr.length))); |
| 175 | arr = newArr; |
| 176 | } |
| 177 | Cache.setObjectForPath(req.path, arr); |
| 178 | await setData(req, utf8ArrayToString(arr)); return {}; |
| 179 | } |
no outgoing calls
no test coverage detected