-
Notifications
You must be signed in to change notification settings - Fork 2
Description
Summary
dart_node_core is a bootstrap shim, not a core library. It wraps roughly 5-10% of the Node.js APIs a real application needs. You cannot read files, access environment variables, exit gracefully, or make HTTP requests with typed Dart code.
What exists today
requireModule()— loads any Node module (returns untypedJSObject)consoleLog()/consoleError()— console outputgetGlobal()— read any global (untyped)child_process.spawn()— with stdin/stdout/stderr streaming and exit codeswithRetry()— exponential backoff with Result types- FP utilities:
match(),let()
What's missing — grouped by priority
P0: Cannot build any real Node.js app without these
Filesystem (fs)
None of these exist:
readFile()/writeFile()/readFileSync()/writeFileSync()stat()/lstat()/exists()readdir()/mkdir()/rmdir()/rm()rename()/copyFile()/unlink()watch()/watchFile()createReadStream()/createWriteStream()
Impact: You literally cannot read or write files from typed Dart code. Must drop to raw requireModule('fs') and use untyped JS interop.
Process (process)
None of these exist:
process.env— no typed access to environment variablesprocess.argv— no typed command-line argsprocess.cwd()— no current working directoryprocess.exit()— no way to exit gracefullyprocess.on('SIGTERM')/process.on('SIGINT')— no signal handling for graceful shutdownprocess.pid/process.ppid/process.platform/process.archprocess.stdin/process.stdout/process.stderr(typed)
Impact: A production server cannot read config from env vars, handle shutdown signals, or exit cleanly.
Path (path)
None of these exist:
path.join()/path.resolve()/path.dirname()/path.basename()path.extname()/path.parse()/path.format()path.isAbsolute()/path.relative()/path.normalize()path.sep/path.delimiter
Impact: Must use raw JS interop for every file path operation.
P1: Needed for real-world servers and tools
HTTP client
No way to make outbound HTTP requests from Dart:
http.request()/http.get()https.request()/https.get()- Or wrap
fetch()(available in Node 18+)
Impact: A server that calls external APIs (auth services, payment providers, microservices) cannot do so from typed Dart code.
Streams and Buffer
Stream/Readable/Writable/Transform/Duplex— no typed streamingBuffer— no binary data handlingpipeline()— no stream composition
Impact: Cannot handle large data, file uploads, or streaming responses.
Timers (typed wrappers)
setTimeout()/clearTimeout()setInterval()/clearInterval()setImmediate()/process.nextTick()
Dart timers work but don't integrate with Node.js's event loop semantics.
P2: Important for specific use cases
crypto— hashing, HMAC, random bytes, encryptionos— hostname, platform, memory, cpus, tmpdir, homedirurl— URL parsing (Node'sURLclass)querystring— query string parsingdns— DNS resolutionnet— TCP socketstls— TLS/SSL socketsevents— typed EventEmitterutil— promisify, inspect, types
Bug: Busy-wait retry blocks the event loop
File: packages/dart_node_core/lib/src/retry.dart
The withRetry() function uses a busy-wait loop for delays:
while (DateTime.now().millisecondsSinceEpoch < end) {
// Spins in a tight loop, blocking the entire Node.js event loop
}Impact: In a multi-request server, if ANY request triggers a retry, ALL concurrent requests freeze until the retry delay completes. This is fundamentally incompatible with Node.js's single-threaded async model.
Fix: Replace with await Future.delayed(Duration(...)) or use Node's setTimeout via JS interop.
Test gaps
File: packages/dart_node_core/test/dart_node_core_test.dart
child_process.spawn()— ZERO tests despite being the most complex code in the packagerequireModule— only checks it returns aJSObject, not that the module is usablewithRetry— properly tested (5 tests, solid)- Extensions (
match,let) — tested but trivial
Suggested implementation order
process.env+process.exit()+process.cwd()— smallest surface, biggest impactpathmodule — small API, used everywherefs— async versions first (readFile,writeFile,readdir,stat,mkdir,rm)- Fix busy-wait retry — one-line fix, removes a production crash risk
child_processtests — already implemented, just untested- HTTP client — wrap
fetch()since it's built into Node 18+ - Streams/Buffer — foundational for fs streams and HTTP
Files to modify
packages/dart_node_core/lib/src/— add new files:fs.dart,process.dart,path.dart,fetch.dart,buffer.dartpackages/dart_node_core/lib/dart_node_core.dart— export new modulespackages/dart_node_core/lib/src/retry.dart— fix busy-wait looppackages/dart_node_core/test/— add tests for each new module + child_process tests