dumpfs-ts 0.1.0

Node.js bindings for dumpfs - A tool for dumping codebase information for LLMs
Documentation
mod bindings;

use bindings::*;
use dumpfs::Subject;
use napi::bindgen_prelude::{AsyncTask, Result, Task};
use napi::{Env, Error, Status};
use std::sync::Arc;

#[macro_use]
extern crate napi_derive;

#[napi]
pub struct DumpfsScanData {
    output: Arc<dumpfs::fs::FsScanOutput>,
}

#[napi(ts_return_type = "Promise<DumpfsScanData>")]
pub fn scan(input: String, opts: Option<ScanOpts>) -> AsyncTask<ScanTask> {
    AsyncTask::new(ScanTask {
        input,
        opts: opts.map(Into::into).unwrap_or_default(),
    })
}

#[napi]
impl DumpfsScanData {
    #[napi(ts_return_type = "Promise<string>")]
    pub fn llm_text(&self, opts: Option<LlmTextOpts>) -> AsyncTask<LlmTextTask> {
        AsyncTask::new(LlmTextTask {
            output: self.output.clone(),
            opts: opts.map(Into::into).unwrap_or_default(),
        })
    }
}

// --------------------------------------------
// Tasks
// --------------------------------------------

pub struct ScanTask {
    input: String,
    opts: dumpfs::fs::FsScannerOpts,
}

#[napi]
impl Task for ScanTask {
    type Output = Arc<dumpfs::fs::FsScanOutput>;
    type JsValue = DumpfsScanData;

    fn compute(&mut self) -> Result<Self::Output> {
        Subject::new(dumpfs::SubjectOpts {
            input: self.input.clone(),
            reporter: None,
        })
        .and_then(|v| v.scan(self.opts.clone()))
        .map(Arc::new)
        .map_err(|e| Error::new(Status::GenericFailure, e.to_string()))
    }

    fn resolve(&mut self, _env: Env, output: Self::Output) -> Result<Self::JsValue> {
        Ok(DumpfsScanData { output })
    }

    fn reject(&mut self, _env: Env, err: Error) -> Result<Self::JsValue> {
        Err(err)
    }
}

pub struct LlmTextTask {
    output: Arc<dumpfs::fs::FsScanOutput>,
    opts: dumpfs::fs::FsFmtOpts,
}

#[napi]
impl Task for LlmTextTask {
    type Output = String;
    type JsValue = napi::JsString;

    fn compute(&mut self) -> Result<Self::Output> {
        let mut buf = String::new();
        self.output
            .llmtext_to(&mut buf, self.opts.clone())
            .map_err(|err| Error::new(Status::GenericFailure, err.to_string()))?;
        Ok(buf)
    }

    fn resolve(&mut self, mut env: Env, output: Self::Output) -> Result<Self::JsValue> {
        env.adjust_external_memory(output.len() as i64)?;
        env.create_string_from_std(output)
    }

    fn reject(&mut self, _env: Env, err: Error) -> Result<Self::JsValue> {
        Err(err)
    }
}