Files
antrean-anjungan/examples/nuxt3-websocket-client/node_modules/@parcel/watcher-wasm/index.mjs
2025-09-18 19:01:22 +07:00

331 lines
8.7 KiB
JavaScript

import { Environment, napi } from 'napi-wasm';
import fs from 'fs';
import Path from 'path';
import { createWrapper } from './wrapper.js';
let env;
let encoder = new TextEncoder;
let constants = {
O_ACCMODE: 0o00000003,
O_RDONLY: 0,
O_WRONLY: 0o00000001,
O_RDWR: 0o00000002,
O_CREAT: 0o00000100,
O_EXCL: 0o00000200,
O_NOCTTY: 0o00000400,
O_TRUNC: 0o00001000,
O_APPEND: 0o00002000,
O_NONBLOCK: 0o00004000,
O_SYNC: 0o00010000,
FASYNC: 0o00020000,
O_DIRECT: 0o00040000,
O_LARGEFILE: 0o00100000,
O_DIRECTORY: 0o00200000,
O_NOFOLLOW: 0o00400000,
O_NOATIME: 0o01000000,
O_CLOEXEC: 0o02000000
};
napi.napi_get_last_error_info = () => {};
const fds = new Map();
const dirs = new Map();
const regexCache = new Map();
const watches = [null];
const wasm_env = {
__syscall_newfstatat(dirfd, path, buf, flags) {
let dir = dirfd === -100 ? process.cwd() : fds.get(dirfd).path;
let p = Path.resolve(dir, env.getString(path));
let nofollow = flags & 256;
try {
let stat = nofollow ? fs.lstatSync(p, {bigint: true}) : fs.statSync(p, {bigint: true});
return writeStat(stat, buf);
} catch (err) {
env.i32[env.instance.exports.__errno_location >> 2] = err.errno;
return -1;
}
},
__syscall_lstat64(path, buf) {
let p = env.getString(path);
try {
let stat = fs.lstatSync(p, {bigint: true});
return writeStat(stat, buf);
} catch (err) {
env.i32[env.instance.exports.__errno_location >> 2] = err.errno;
return -1;
}
},
__syscall_fstat64(fd, buf) {
try {
let stat = fs.fstatSync(fd, {bigint: true});
return writeStat(stat, buf);
} catch (err) {
env.i32[env.instance.exports.__errno_location >> 2] = err.errno;
return -1;
}
},
__syscall_stat64(path, buf) {
let p = env.getString(path);
try {
let stat = fs.statSync(p, {bigint: true});
return writeStat(stat, buf);
} catch (err) {
env.i32[env.instance.exports.__errno_location >> 2] = err.errno;
return -1;
}
},
__syscall_getdents64(fd, dirp, count) {
let p = fds.get(fd).path;
let dir = dirs.get(fd);
let entries = dir?.entries;
if (!entries) {
try {
entries = fs.readdirSync(p, {withFileTypes: true});
} catch (err) {
env.i32[env.instance.exports.__errno_location >> 2] = err.errno;
return -1;
}
}
let start = dirp;
let i = dir?.index || 0;
for (; i < entries.length; i++) {
let entry = entries[i];
let type = entry.isFIFO() ? 1
: entry.isCharacterDevice() ? 2
: entry.isDirectory() ? 4
: entry.isBlockDevice() ? 6
: entry.isFile() ? 8
: entry.isSymbolicLink() ? 10
: entry.isSocket() ? 12
: 0;
let len = align(utf8Length(entry.name) + 20, 8);
if ((dirp - start + len) > count) {
break;
}
// Write a linux_dirent64 struct into wasm memory.
env.u64[dirp >> 3] = 1n; // ino
env.u64[(dirp + 8) >> 3] = BigInt((dirp - start) + len); // offset
env.u16[(dirp + 16) >> 1] = len;
env.memory[dirp + 18] = type;
let {written} = encoder.encodeInto(entry.name, env.memory.subarray(dirp + 19));
env.memory[dirp + 19 + written] = 0; // null terminate
dirp += len;
}
dirs.set(fd, {index: i, entries});
return dirp - start;
},
__syscall_openat(dirfd, path, flags, mode) {
// Convert flags to Node values.
let f = 0;
for (let c in constants) {
if (flags & constants[c]) {
f |= fs.constants[c] || 0;
}
}
let dir = dirfd === -100 ? process.cwd() : fds.get(dirfd)?.path;
if (!dir) {
env.i32[env.instance.exports.__errno_location >> 2] = 9970; // ENOTDIR
return -1;
}
let p = Path.resolve(dir, env.getString(path));
try {
let fd = fs.openSync(p, f);
fds.set(fd, {path: p, flags});
return fd;
} catch (err) {
env.i32[env.instance.exports.__errno_location >> 2] = err.errno;
return -1;
}
},
__syscall_fcntl64(fd, cmd) {
switch (cmd) {
case 3:
return fds.get(fd).flags;
case 2:
return 0;
default:
throw new Error('Unknown fcntl64 call: ' + cmd);
}
},
__syscall_ioctl() {},
emscripten_resize_heap() {
return 0;
},
_abort_js() {},
wasm_backend_add_watch(filename, backend) {
let path = env.getString(filename);
let watch = fs.watch(path, {encoding: 'buffer'}, (eventType, filename) => {
if (filename) {
let type = eventType === 'change' ? 1 : 2;
let fptr = env.instance.exports.malloc(filename.byteLength + 1);
env.memory.set(filename, fptr);
env.memory[fptr + filename.byteLength] = 0;
env.instance.exports.wasm_backend_event_handler(backend, wd, type, fptr);
env.instance.exports.free(fptr);
}
});
let wd = watches.length;
watches.push(watch);
return wd;
},
wasm_backend_remove_watch(wd) {
watches[wd].close();
watches[wd] = undefined;
},
set_timeout(ms, ctx) {
return setTimeout(() => {
env.instance.exports.on_timeout(ctx);
}, ms);
},
clear_timeout(t) {
clearTimeout(t);
},
_setitimer_js() {},
emscripten_date_now() {
return Date.now();
},
_emscripten_get_now_is_monotonic() {
return true;
},
_emscripten_runtime_keepalive_clear() {},
emscripten_get_now() {
return performance.now();
},
wasm_regex_match(string, regex) {
let re = regexCache.get(regex);
if (!re) {
re = new RegExp(env.getString(regex));
regexCache.set(regex, re);
}
return re.test(env.getString(string)) ? 1 : 0;
}
};
const wasi = {
fd_close(fd) {
fs.closeSync(fd);
fds.delete(fd);
dirs.delete(fd);
return 0;
},
fd_seek(fd, offset_low, offset_high, whence, newOffset) {
return 0;
},
fd_write(fd, iov, iovcnt, pnum) {
let buffers = [];
for (let i = 0; i < iovcnt; i++) {
let ptr = env.u32[iov >> 2];
let len = env.u32[(iov + 4) >> 2];
iov += 8;
if (len > 0) {
buffers.push(env.memory.subarray(ptr, ptr + len));
}
}
let wrote = fs.writevSync(fd, buffers);
env.u32[pnum >> 2] = wrote;
return 0;
},
fd_read(fd, iov, iovcnt, pnum) {
let buffers = [];
for (let i = 0; i < iovcnt; i++) {
let ptr = env.u32[iov >> 2];
let len = env.u32[(iov + 4) >> 2];
iov += 8;
if (len > 0) {
buffers.push(env.memory.subarray(ptr, ptr + len));
}
}
let read = fs.readvSync(fd, buffers);
env.u32[pnum >> 2] = read;
return 0;
},
proc_exit() {},
clock_time_get() {}
};
function writeStat(stat, buf) {
env.i32[buf >> 2] = Number(stat.dev);
env.i32[(buf + 4) >> 2] = Number(stat.mode);
env.u32[(buf + 8) >> 2] = Number(stat.nlink);
env.i32[(buf + 12) >> 2] = Number(stat.uid);
env.i32[(buf + 16) >> 2] = Number(stat.gid);
env.i32[(buf + 20) >> 2] = Number(stat.rdev);
env.u64[(buf + 24) >> 3] = stat.size;
env.i32[(buf + 32) >> 2] = Number(stat.blksize);
env.i32[(buf + 36) >> 2] = Number(stat.blocks);
env.u64[(buf + 40) >> 3] = stat.atimeMs;
env.u32[(buf + 48) >> 2] = Number(stat.atimeNs);
env.u64[(buf + 56) >> 3] = stat.mtimeMs;
env.u32[(buf + 64) >> 2] = Number(stat.mtimeNs);
env.u64[(buf + 72) >> 3] = stat.ctimeMs;
env.u32[(buf + 80) >> 2] = Number(stat.ctimeNs);
env.u64[(buf + 88) >> 3] = stat.ino;
return 0;
}
function utf8Length(string) {
let len = 0;
for (let i = 0; i < string.length; i++) {
let c = string.charCodeAt(i);
if (c >= 0xd800 && c <= 0xdbff && i < string.length - 1) {
let c2 = string.charCodeAt(++i);
if ((c2 & 0xfc00) === 0xdc00) {
c = ((c & 0x3ff) << 10) + (c2 & 0x3ff) + 0x10000;
} else {
// unmatched surrogate.
i--;
}
}
if ((c & 0xffffff80) === 0) {
len++;
} else if ((c & 0xfffff800) === 0) {
len += 2;
} else if ((c & 0xffff0000) === 0) {
len += 3;
} else if ((c & 0xffe00000) === 0) {
len += 4;
}
}
return len;
}
function align(len, p) {
return Math.ceil(len / p) * p;
}
let wasmBytes = fs.readFileSync(new URL('watcher.wasm', import.meta.url));
let wasmModule = new WebAssembly.Module(wasmBytes);
let instance = new WebAssembly.Instance(wasmModule, {
napi,
env: wasm_env,
wasi_snapshot_preview1: wasi
});
env = new Environment(instance);
let wrapper = createWrapper(env.exports);
export function writeSnapshot(dir, snapshot, opts) {
return wrapper.writeSnapshot(dir, snapshot, opts);
}
export function getEventsSince(dir, snapshot, opts) {
return wrapper.getEventsSince(dir, snapshot, opts);
}
export function subscribe(dir, fn, opts) {
return wrapper.subscribe(dir, fn, opts);
}
export function unsubscribe(dir, fn, opts) {
return wrapper.unsubscribe(dir, fn, opts);
}