MIRROR: javascript for ๐Ÿœ's, a tiny runtime with big ambitions
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

add fs module

+618 -24
+9 -15
examples/server/server.js
··· 1 - import { html } from './html'; 2 1 import meow from './meow.txt'; 2 + 3 + import { html } from './html'; 4 + import { readFile } from 'ant:fs'; 3 5 import { Radix3 } from './radix3'; 4 6 5 7 const router = new Radix3(); 6 8 7 - router.insert('/', c => { 8 - return c.res.body(`Welcome to Ant HTTP Server with Radix3 Router! 9 - 10 - Available routes: 11 - GET / 12 - GET /meow 13 - GET /hello 14 - GET /status 15 - GET /users/:id 16 - GET /users/:id/posts 17 - GET /files/*path 18 - GET /api/v1/users 19 - GET /api/v2/demo`); 20 - }); 9 + router.insert('/', c => c.res.body(`Welcome to Ant ${Ant.version}!`)); 21 10 22 11 router.insert('/meow', async c => { 23 12 return c.res.body(meow); 13 + }); 14 + 15 + router.insert('/fs/meow', async c => { 16 + const file = await readFile('./meow.txt'); 17 + return c.res.body(file); 24 18 }); 25 19 26 20 router.insert('/hello', async c => {
+10
include/modules/fs.h
··· 1 + #ifndef ANT_FS_MODULE_H 2 + #define ANT_FS_MODULE_H 3 + 4 + #include "ant.h" 5 + 6 + jsval_t fs_library(struct js *js); 7 + void fs_poll_events(void); 8 + int has_pending_fs_ops(void); 9 + 10 + #endif
+1 -1
meson.build
··· 67 67 build_date = run_command('date', '+%Y-%m-%d', check: true).stdout().strip() 68 68 69 69 version_conf = configuration_data() 70 - version_conf.set('ANT_VERSION', '0.0.6.29') 70 + version_conf.set('ANT_VERSION', '0.0.6.30') 71 71 version_conf.set('ANT_GIT_HASH', git_hash) 72 72 version_conf.set('ANT_BUILD_DATE', build_date) 73 73
+6 -3
src/ant.c
··· 17 17 18 18 #include "ant.h" 19 19 #include "config.h" 20 + 21 + #include "modules/fs.h" 20 22 #include "modules/timer.h" 21 23 #include "modules/fetch.h" 22 24 ··· 429 431 430 432 void js_poll_events(struct js *js) { 431 433 fetch_poll_events(); 434 + fs_poll_events(); 435 + 432 436 int has_timers = has_pending_timers(); 433 - 434 437 if (has_timers) { 435 438 int64_t next_timeout_ms = get_next_timer_timeout(); 436 439 if (next_timeout_ms <= 0) process_timers(js); ··· 481 484 } 482 485 483 486 void js_run_event_loop(struct js *js) { 484 - while (has_pending_microtasks() || has_pending_timers() || has_pending_coroutines() || has_pending_fetches()) { 487 + while (has_pending_microtasks() || has_pending_timers() || has_pending_coroutines() || has_pending_fetches() || has_pending_fs_ops()) { 485 488 js_poll_events(js); 486 489 487 490 if (!has_pending_microtasks() && has_pending_timers() && !has_ready_coroutines()) { ··· 489 492 if (next_timeout_ms > 0) usleep(next_timeout_ms > 1000000 ? 1000000 : next_timeout_ms * 1000); 490 493 } 491 494 492 - if (!has_pending_microtasks() && !has_pending_timers() && !has_pending_coroutines() && !has_pending_fetches()) break; 495 + if (!has_pending_microtasks() && !has_pending_timers() && !has_pending_coroutines() && !has_pending_fetches() && !has_pending_fs_ops()) break; 493 496 } 494 497 495 498 js_poll_events(js);
+4 -3
src/main.c
··· 2 2 #include <stdlib.h> 3 3 #include <string.h> 4 4 #include <libgen.h> 5 - #include <limits.h> 6 5 #include <unistd.h> 7 6 #include <argtable3.h> 8 7 ··· 13 12 14 13 #include "modules/builtin.h" 15 14 #include "modules/io.h" 15 + #include "modules/fs.h" 16 16 #include "modules/crypto.h" 17 17 #include "modules/server.h" 18 18 #include "modules/timer.h" ··· 134 134 init_timer_module(); 135 135 init_process_module(); 136 136 137 - ant_register_library("ant/shell", shell_library); 138 - 137 + ant_register_library("ant:fs", fs_library); 138 + ant_register_library("ant:shell", shell_library); 139 + 139 140 if (repl_mode) ant_repl_run(); else { 140 141 js_result = execute_module(js, module_file); 141 142 js_run_event_loop(js);
+529
src/modules/fs.c
··· 1 + #include <uv.h> 2 + #include <stdio.h> 3 + #include <stdlib.h> 4 + #include <string.h> 5 + #include <sys/stat.h> 6 + #include <fcntl.h> 7 + #include <uthash.h> 8 + #include <utarray.h> 9 + #include <unistd.h> 10 + #include "modules/fs.h" 11 + #include "runtime.h" 12 + 13 + typedef enum { 14 + FS_OP_READ, 15 + FS_OP_WRITE, 16 + FS_OP_UNLINK, 17 + FS_OP_MKDIR, 18 + FS_OP_RMDIR, 19 + FS_OP_STAT 20 + } fs_op_type_t; 21 + 22 + typedef struct fs_request_s { 23 + struct js *js; 24 + jsval_t promise; 25 + uv_fs_t uv_req; 26 + fs_op_type_t op_type; 27 + char *path; 28 + char *data; 29 + size_t data_len; 30 + uv_file fd; 31 + int completed; 32 + int failed; 33 + char *error_msg; 34 + } fs_request_t; 35 + 36 + static uv_loop_t *fs_loop = NULL; 37 + static UT_array *pending_requests = NULL; 38 + 39 + static void free_fs_request(fs_request_t *req) { 40 + if (!req) return; 41 + 42 + if (req->path) free(req->path); 43 + if (req->data) free(req->data); 44 + if (req->error_msg) free(req->error_msg); 45 + 46 + uv_fs_req_cleanup(&req->uv_req); 47 + free(req); 48 + } 49 + 50 + static void remove_pending_request(fs_request_t *req) { 51 + if (!req || !pending_requests) return; 52 + 53 + fs_request_t **p = NULL; 54 + unsigned int i = 0; 55 + 56 + while ((p = (fs_request_t**)utarray_next(pending_requests, p))) { 57 + if (*p == req) { 58 + utarray_erase(pending_requests, i, 1); 59 + break; 60 + } 61 + i++; 62 + } 63 + } 64 + 65 + static void complete_request(fs_request_t *req) { 66 + if (req->failed) { 67 + const char *err_msg = req->error_msg ? req->error_msg : "Unknown error"; 68 + jsval_t err = js_mkstr(req->js, err_msg, strlen(err_msg)); 69 + js_reject_promise(req->js, req->promise, err); 70 + } else { 71 + jsval_t result; 72 + if (req->op_type == FS_OP_READ && req->data) { 73 + result = js_mkstr(req->js, req->data, req->data_len); 74 + } else if (req->op_type == FS_OP_STAT) { 75 + result = js_mkundef(); 76 + } else { 77 + result = js_mkundef(); 78 + } 79 + js_resolve_promise(req->js, req->promise, result); 80 + } 81 + 82 + remove_pending_request(req); 83 + free_fs_request(req); 84 + } 85 + 86 + static void on_read_complete(uv_fs_t *uv_req) { 87 + fs_request_t *req = (fs_request_t *)uv_req->data; 88 + 89 + if (uv_req->result < 0) { 90 + req->failed = 1; 91 + req->error_msg = strdup(uv_strerror(uv_req->result)); 92 + req->completed = 1; 93 + complete_request(req); 94 + return; 95 + } 96 + 97 + req->data_len = uv_req->result; 98 + 99 + uv_fs_t close_req; 100 + uv_fs_close(fs_loop, &close_req, req->fd, NULL); 101 + uv_fs_req_cleanup(&close_req); 102 + 103 + req->completed = 1; 104 + complete_request(req); 105 + } 106 + 107 + static void on_open_for_read(uv_fs_t *uv_req) { 108 + fs_request_t *req = (fs_request_t *)uv_req->data; 109 + 110 + if (uv_req->result < 0) { 111 + req->failed = 1; 112 + req->error_msg = strdup(uv_strerror(uv_req->result)); 113 + req->completed = 1; 114 + complete_request(req); 115 + return; 116 + } 117 + 118 + req->fd = uv_req->result; 119 + uv_fs_req_cleanup(uv_req); 120 + 121 + uv_fs_t stat_req; 122 + int stat_result = uv_fs_fstat(fs_loop, &stat_req, req->fd, NULL); 123 + 124 + if (stat_result < 0) { 125 + req->failed = 1; 126 + req->error_msg = strdup(uv_strerror(stat_result)); 127 + req->completed = 1; 128 + uv_fs_t close_req; 129 + uv_fs_close(fs_loop, &close_req, req->fd, NULL); 130 + uv_fs_req_cleanup(&close_req); 131 + complete_request(req); 132 + return; 133 + } 134 + 135 + size_t file_size = stat_req.statbuf.st_size; 136 + uv_fs_req_cleanup(&stat_req); 137 + 138 + req->data = malloc(file_size + 1); 139 + if (!req->data) { 140 + req->failed = 1; 141 + req->error_msg = strdup("Out of memory"); 142 + req->completed = 1; 143 + uv_fs_t close_req; 144 + uv_fs_close(fs_loop, &close_req, req->fd, NULL); 145 + uv_fs_req_cleanup(&close_req); 146 + complete_request(req); 147 + return; 148 + } 149 + 150 + uv_buf_t buf = uv_buf_init(req->data, file_size); 151 + int read_result = uv_fs_read(fs_loop, uv_req, req->fd, &buf, 1, 0, on_read_complete); 152 + 153 + if (read_result < 0) { 154 + req->failed = 1; 155 + req->error_msg = strdup(uv_strerror(read_result)); 156 + req->completed = 1; 157 + uv_fs_t close_req; 158 + uv_fs_close(fs_loop, &close_req, req->fd, NULL); 159 + uv_fs_req_cleanup(&close_req); 160 + complete_request(req); 161 + return; 162 + } 163 + } 164 + 165 + static void on_write_complete(uv_fs_t *uv_req) { 166 + fs_request_t *req = (fs_request_t *)uv_req->data; 167 + 168 + if (uv_req->result < 0) { 169 + req->failed = 1; 170 + req->error_msg = strdup(uv_strerror(uv_req->result)); 171 + } 172 + 173 + uv_fs_t close_req; 174 + uv_fs_close(fs_loop, &close_req, req->fd, NULL); 175 + uv_fs_req_cleanup(&close_req); 176 + 177 + req->completed = 1; 178 + complete_request(req); 179 + } 180 + 181 + static void on_open_for_write(uv_fs_t *uv_req) { 182 + fs_request_t *req = (fs_request_t *)uv_req->data; 183 + 184 + if (uv_req->result < 0) { 185 + req->failed = 1; 186 + req->error_msg = strdup(uv_strerror(uv_req->result)); 187 + req->completed = 1; 188 + complete_request(req); 189 + return; 190 + } 191 + 192 + req->fd = uv_req->result; 193 + uv_fs_req_cleanup(uv_req); 194 + 195 + uv_buf_t buf = uv_buf_init(req->data, req->data_len); 196 + int write_result = uv_fs_write(fs_loop, uv_req, req->fd, &buf, 1, 0, on_write_complete); 197 + 198 + if (write_result < 0) { 199 + req->failed = 1; 200 + req->error_msg = strdup(uv_strerror(write_result)); 201 + req->completed = 1; 202 + uv_fs_t close_req; 203 + uv_fs_close(fs_loop, &close_req, req->fd, NULL); 204 + uv_fs_req_cleanup(&close_req); 205 + complete_request(req); 206 + return; 207 + } 208 + } 209 + 210 + static void on_unlink_complete(uv_fs_t *uv_req) { 211 + fs_request_t *req = (fs_request_t *)uv_req->data; 212 + 213 + if (uv_req->result < 0) { 214 + req->failed = 1; 215 + req->error_msg = strdup(uv_strerror(uv_req->result)); 216 + } 217 + 218 + req->completed = 1; 219 + complete_request(req); 220 + } 221 + 222 + static void on_mkdir_complete(uv_fs_t *uv_req) { 223 + fs_request_t *req = (fs_request_t *)uv_req->data; 224 + 225 + if (uv_req->result < 0) { 226 + req->failed = 1; 227 + req->error_msg = strdup(uv_strerror(uv_req->result)); 228 + } 229 + 230 + req->completed = 1; 231 + complete_request(req); 232 + } 233 + 234 + static void on_rmdir_complete(uv_fs_t *uv_req) { 235 + fs_request_t *req = (fs_request_t *)uv_req->data; 236 + 237 + if (uv_req->result < 0) { 238 + req->failed = 1; 239 + req->error_msg = strdup(uv_strerror(uv_req->result)); 240 + } 241 + 242 + req->completed = 1; 243 + complete_request(req); 244 + } 245 + 246 + static void on_stat_complete(uv_fs_t *uv_req) { 247 + fs_request_t *req = (fs_request_t *)uv_req->data; 248 + 249 + if (uv_req->result < 0) { 250 + req->failed = 1; 251 + req->error_msg = strdup(uv_strerror(uv_req->result)); 252 + req->completed = 1; 253 + complete_request(req); 254 + return; 255 + } 256 + 257 + jsval_t stat_obj = js_mkobj(req->js); 258 + js_set(req->js, stat_obj, "size", js_mknum((double)uv_req->statbuf.st_size)); 259 + js_set(req->js, stat_obj, "mode", js_mknum((double)uv_req->statbuf.st_mode)); 260 + js_set(req->js, stat_obj, "isFile", S_ISREG(uv_req->statbuf.st_mode) ? js_mktrue() : js_mkfalse()); 261 + js_set(req->js, stat_obj, "isDirectory", S_ISDIR(uv_req->statbuf.st_mode) ? js_mktrue() : js_mkfalse()); 262 + 263 + req->completed = 1; 264 + js_resolve_promise(req->js, req->promise, stat_obj); 265 + remove_pending_request(req); 266 + free_fs_request(req); 267 + } 268 + 269 + static void ensure_fs_loop(void) { 270 + if (!fs_loop) { 271 + if (rt->external_event_loop_active) { 272 + fs_loop = uv_default_loop(); 273 + } else { 274 + fs_loop = malloc(sizeof(uv_loop_t)); 275 + uv_loop_init(fs_loop); 276 + } 277 + } 278 + 279 + if (!pending_requests) { 280 + utarray_new(pending_requests, &ut_ptr_icd); 281 + } 282 + } 283 + 284 + static jsval_t builtin_fs_readFile(struct js *js, jsval_t *args, int nargs) { 285 + if (nargs < 1) return js_mkerr(js, "readFile() requires a path argument"); 286 + 287 + if (js_type(args[0]) != JS_STR) return js_mkerr(js, "readFile() path must be a string"); 288 + 289 + size_t path_len; 290 + char *path = js_getstr(js, args[0], &path_len); 291 + if (!path) return js_mkerr(js, "Failed to get path string"); 292 + 293 + ensure_fs_loop(); 294 + 295 + fs_request_t *req = calloc(1, sizeof(fs_request_t)); 296 + if (!req) return js_mkerr(js, "Out of memory"); 297 + 298 + req->js = js; 299 + req->op_type = FS_OP_READ; 300 + req->promise = js_mkpromise(js); 301 + req->path = strndup(path, path_len); 302 + req->uv_req.data = req; 303 + 304 + utarray_push_back(pending_requests, &req); 305 + 306 + int result = uv_fs_open(fs_loop, &req->uv_req, req->path, O_RDONLY, 0, on_open_for_read); 307 + 308 + if (result < 0) { 309 + req->failed = 1; 310 + req->error_msg = strdup(uv_strerror(result)); 311 + req->completed = 1; 312 + complete_request(req); 313 + } 314 + 315 + return req->promise; 316 + } 317 + 318 + static jsval_t builtin_fs_writeFile(struct js *js, jsval_t *args, int nargs) { 319 + if (nargs < 2) return js_mkerr(js, "writeFile() requires path and data arguments"); 320 + 321 + if (js_type(args[0]) != JS_STR) return js_mkerr(js, "writeFile() path must be a string"); 322 + if (js_type(args[1]) != JS_STR) return js_mkerr(js, "writeFile() data must be a string"); 323 + 324 + size_t path_len, data_len; 325 + char *path = js_getstr(js, args[0], &path_len); 326 + char *data = js_getstr(js, args[1], &data_len); 327 + 328 + if (!path || !data) return js_mkerr(js, "Failed to get arguments"); 329 + 330 + ensure_fs_loop(); 331 + 332 + fs_request_t *req = calloc(1, sizeof(fs_request_t)); 333 + if (!req) return js_mkerr(js, "Out of memory"); 334 + 335 + req->js = js; 336 + req->op_type = FS_OP_WRITE; 337 + req->promise = js_mkpromise(js); 338 + req->path = strndup(path, path_len); 339 + req->data = malloc(data_len); 340 + if (!req->data) { 341 + free(req->path); 342 + free(req); 343 + return js_mkerr(js, "Out of memory"); 344 + } 345 + 346 + memcpy(req->data, data, data_len); 347 + req->data_len = data_len; 348 + req->uv_req.data = req; 349 + 350 + utarray_push_back(pending_requests, &req); 351 + 352 + int result = uv_fs_open(fs_loop, &req->uv_req, req->path, 353 + O_WRONLY | O_CREAT | O_TRUNC, 0644, on_open_for_write); 354 + 355 + if (result < 0) { 356 + req->failed = 1; 357 + req->error_msg = strdup(uv_strerror(result)); 358 + req->completed = 1; 359 + complete_request(req); 360 + } 361 + 362 + return req->promise; 363 + } 364 + 365 + static jsval_t builtin_fs_unlink(struct js *js, jsval_t *args, int nargs) { 366 + if (nargs < 1) return js_mkerr(js, "unlink() requires a path argument"); 367 + 368 + if (js_type(args[0]) != JS_STR) return js_mkerr(js, "unlink() path must be a string"); 369 + 370 + size_t path_len; 371 + char *path = js_getstr(js, args[0], &path_len); 372 + if (!path) return js_mkerr(js, "Failed to get path string"); 373 + 374 + ensure_fs_loop(); 375 + 376 + fs_request_t *req = calloc(1, sizeof(fs_request_t)); 377 + if (!req) return js_mkerr(js, "Out of memory"); 378 + 379 + req->js = js; 380 + req->op_type = FS_OP_UNLINK; 381 + req->promise = js_mkpromise(js); 382 + req->path = strndup(path, path_len); 383 + req->uv_req.data = req; 384 + 385 + utarray_push_back(pending_requests, &req); 386 + 387 + int result = uv_fs_unlink(fs_loop, &req->uv_req, req->path, on_unlink_complete); 388 + 389 + if (result < 0) { 390 + req->failed = 1; 391 + req->error_msg = strdup(uv_strerror(result)); 392 + req->completed = 1; 393 + complete_request(req); 394 + } 395 + 396 + return req->promise; 397 + } 398 + 399 + static jsval_t builtin_fs_mkdir(struct js *js, jsval_t *args, int nargs) { 400 + if (nargs < 1) return js_mkerr(js, "mkdir() requires a path argument"); 401 + 402 + if (js_type(args[0]) != JS_STR) return js_mkerr(js, "mkdir() path must be a string"); 403 + 404 + size_t path_len; 405 + char *path = js_getstr(js, args[0], &path_len); 406 + if (!path) return js_mkerr(js, "Failed to get path string"); 407 + 408 + int mode = 0755; 409 + if (nargs >= 2 && js_type(args[1]) == JS_NUM) { 410 + mode = (int)js_getnum(args[1]); 411 + } 412 + 413 + ensure_fs_loop(); 414 + 415 + fs_request_t *req = calloc(1, sizeof(fs_request_t)); 416 + if (!req) return js_mkerr(js, "Out of memory"); 417 + 418 + req->js = js; 419 + req->op_type = FS_OP_MKDIR; 420 + req->promise = js_mkpromise(js); 421 + req->path = strndup(path, path_len); 422 + req->uv_req.data = req; 423 + 424 + utarray_push_back(pending_requests, &req); 425 + 426 + int result = uv_fs_mkdir(fs_loop, &req->uv_req, req->path, mode, on_mkdir_complete); 427 + 428 + if (result < 0) { 429 + req->failed = 1; 430 + req->error_msg = strdup(uv_strerror(result)); 431 + req->completed = 1; 432 + complete_request(req); 433 + } 434 + 435 + return req->promise; 436 + } 437 + 438 + static jsval_t builtin_fs_rmdir(struct js *js, jsval_t *args, int nargs) { 439 + if (nargs < 1) return js_mkerr(js, "rmdir() requires a path argument"); 440 + 441 + if (js_type(args[0]) != JS_STR) return js_mkerr(js, "rmdir() path must be a string"); 442 + 443 + size_t path_len; 444 + char *path = js_getstr(js, args[0], &path_len); 445 + if (!path) return js_mkerr(js, "Failed to get path string"); 446 + 447 + ensure_fs_loop(); 448 + 449 + fs_request_t *req = calloc(1, sizeof(fs_request_t)); 450 + if (!req) return js_mkerr(js, "Out of memory"); 451 + 452 + req->js = js; 453 + req->op_type = FS_OP_RMDIR; 454 + req->promise = js_mkpromise(js); 455 + req->path = strndup(path, path_len); 456 + req->uv_req.data = req; 457 + 458 + utarray_push_back(pending_requests, &req); 459 + 460 + int result = uv_fs_rmdir(fs_loop, &req->uv_req, req->path, on_rmdir_complete); 461 + 462 + if (result < 0) { 463 + req->failed = 1; 464 + req->error_msg = strdup(uv_strerror(result)); 465 + req->completed = 1; 466 + complete_request(req); 467 + } 468 + 469 + return req->promise; 470 + } 471 + 472 + static jsval_t builtin_fs_stat(struct js *js, jsval_t *args, int nargs) { 473 + if (nargs < 1) return js_mkerr(js, "stat() requires a path argument"); 474 + 475 + if (js_type(args[0]) != JS_STR) return js_mkerr(js, "stat() path must be a string"); 476 + 477 + size_t path_len; 478 + char *path = js_getstr(js, args[0], &path_len); 479 + if (!path) return js_mkerr(js, "Failed to get path string"); 480 + 481 + ensure_fs_loop(); 482 + 483 + fs_request_t *req = calloc(1, sizeof(fs_request_t)); 484 + if (!req) return js_mkerr(js, "Out of memory"); 485 + 486 + req->js = js; 487 + req->op_type = FS_OP_STAT; 488 + req->promise = js_mkpromise(js); 489 + req->path = strndup(path, path_len); 490 + req->uv_req.data = req; 491 + 492 + utarray_push_back(pending_requests, &req); 493 + 494 + int result = uv_fs_stat(fs_loop, &req->uv_req, req->path, on_stat_complete); 495 + 496 + if (result < 0) { 497 + req->failed = 1; 498 + req->error_msg = strdup(uv_strerror(result)); 499 + req->completed = 1; 500 + complete_request(req); 501 + } 502 + 503 + return req->promise; 504 + } 505 + 506 + jsval_t fs_library(struct js *js) { 507 + jsval_t lib = js_mkobj(js); 508 + 509 + js_set(js, lib, "readFile", js_mkfun(builtin_fs_readFile)); 510 + js_set(js, lib, "writeFile", js_mkfun(builtin_fs_writeFile)); 511 + js_set(js, lib, "unlink", js_mkfun(builtin_fs_unlink)); 512 + js_set(js, lib, "mkdir", js_mkfun(builtin_fs_mkdir)); 513 + js_set(js, lib, "rmdir", js_mkfun(builtin_fs_rmdir)); 514 + js_set(js, lib, "stat", js_mkfun(builtin_fs_stat)); 515 + 516 + return lib; 517 + } 518 + 519 + int has_pending_fs_ops(void) { 520 + return (pending_requests && utarray_len(pending_requests) > 0) || (fs_loop && uv_loop_alive(fs_loop)); 521 + } 522 + 523 + void fs_poll_events(void) { 524 + if (fs_loop && fs_loop == uv_default_loop() && rt->external_event_loop_active) return; 525 + if (fs_loop && uv_loop_alive(fs_loop)) { 526 + uv_run(fs_loop, UV_RUN_ONCE); 527 + if (pending_requests && utarray_len(pending_requests) > 0) usleep(1000); 528 + } 529 + }
-1
src/modules/io.c
··· 3 3 #include <string.h> 4 4 #include <stdbool.h> 5 5 #include <libgen.h> 6 - #include <limits.h> 7 6 8 7 #include "runtime.h" 9 8 #include "modules/io.h"
+58
tests/test_fs_async.js
··· 1 + import { readFile, writeFile, unlink, mkdir, rmdir, stat } from 'ant:fs'; 2 + 3 + console.log('Testing ant:fs with async/await...\n'); 4 + 5 + async function testFs() { 6 + const testDir = 'tests/.fs_test_tmp'; 7 + const testFile = testDir + '/async_test.txt'; 8 + const testData = 'Hello from async ant:fs!'; 9 + 10 + try { 11 + // Test mkdir 12 + console.log('=== Test: mkdir ==='); 13 + try { 14 + await mkdir(testDir); 15 + console.log('โœ“ Directory created'); 16 + } catch (e) { 17 + console.log('Directory might exist, continuing...'); 18 + } 19 + 20 + // Test writeFile 21 + console.log('\n=== Test: writeFile ==='); 22 + await writeFile(testFile, testData); 23 + console.log('โœ“ File written'); 24 + 25 + // Test readFile 26 + console.log('\n=== Test: readFile ==='); 27 + const content = await readFile(testFile); 28 + console.log('โœ“ File read, length:', content.length); 29 + if (content === testData) { 30 + console.log('โœ“ Content matches!'); 31 + } else { 32 + console.log('โœ— Content mismatch!'); 33 + } 34 + 35 + // Test stat 36 + console.log('\n=== Test: stat ==='); 37 + const stats = await stat(testFile); 38 + console.log('โœ“ File stats:'); 39 + console.log(' Size:', stats.size); 40 + console.log(' Is file:', stats.isFile); 41 + console.log(' Is directory:', stats.isDirectory); 42 + 43 + // Cleanup 44 + console.log('\n=== Cleanup ==='); 45 + await unlink(testFile); 46 + console.log('โœ“ File deleted'); 47 + 48 + await rmdir(testDir); 49 + console.log('โœ“ Directory deleted'); 50 + 51 + console.log('\nโœ“โœ“โœ“ All tests passed! โœ“โœ“โœ“'); 52 + } catch (error) { 53 + console.error('\nโœ— Test failed:', error); 54 + } 55 + } 56 + 57 + // Run the async function 58 + testFs();
+1 -1
tests/test_shell.js
··· 1 - import { $ } from 'ant/shell'; 1 + import { $ } from 'ant:shell'; 2 2 3 3 console.log('Testing $ shell command execution...'); 4 4