@@ -466,6 +466,45 @@ namespace hdiffpatchNode
466466 return Napi::String::New (env, outNewPath);
467467 }
468468
469+ // ============ 异步 Window Diff Worker ============
470+ class DiffWindowAsyncWorker : public Napi ::AsyncWorker {
471+ public:
472+ DiffWindowAsyncWorker (Napi::Function& callback,
473+ std::string oldPath,
474+ std::string newPath,
475+ std::string outDiffPath)
476+ : Napi::AsyncWorker(callback),
477+ oldPath_ (std::move(oldPath)),
478+ newPath_(std::move(newPath)),
479+ outDiffPath_(std::move(outDiffPath)) {
480+ }
481+
482+ void Execute () override {
483+ try {
484+ hdiff_window (oldPath_.c_str (), newPath_.c_str (), outDiffPath_.c_str ());
485+ } catch (const std::exception& e) {
486+ SetError (e.what ());
487+ }
488+ }
489+
490+ void OnOK () override {
491+ Napi::Env env = Env ();
492+ Napi::HandleScope scope (env);
493+ Callback ().Call ({env.Null (), Napi::String::New (env, outDiffPath_)});
494+ }
495+
496+ void OnError (const Napi::Error& e) override {
497+ Napi::Env env = Env ();
498+ Napi::HandleScope scope (env);
499+ Callback ().Call ({e.Value ()});
500+ }
501+
502+ private:
503+ std::string oldPath_;
504+ std::string newPath_;
505+ std::string outDiffPath_;
506+ };
507+
469508 // ============ 同步/异步 diffSingleStream ============
470509 // single 格式(HDIFFSF20)的流式生成:低内存(块匹配),产物与 diff()
471510 // 同格式,所有既有 single 应用端(含历史客户端)可直接应用。
@@ -503,6 +542,44 @@ namespace hdiffpatchNode
503542 return Napi::String::New (env, outDiffPath);
504543 }
505544
545+ // ============ 同步/异步 diffWindow ============
546+ // single 格式(HDIFFSF20)的 window 模式生成:大块流式匹配 + 窗口内
547+ // 后缀串精修,匹配质量接近内存版 diff() 而内存占用保持流式档。
548+ // 产物与 diff()/diffSingleStream() 同格式,既有应用端可直接应用。
549+ Napi::Value diffWindow (const Napi::CallbackInfo& info) {
550+ Napi::Env env = info.Env ();
551+
552+ std::string oldPath;
553+ std::string newPath;
554+ std::string outDiffPath;
555+ if (info.Length () < 3 ||
556+ !getStringUtf8 (info[0 ], oldPath) ||
557+ !getStringUtf8 (info[1 ], newPath) ||
558+ !getStringUtf8 (info[2 ], outDiffPath)) {
559+ Napi::TypeError::New (env, " Invalid arguments: expected (oldPath, newPath, outDiffPath)." )
560+ .ThrowAsJavaScriptException ();
561+ return env.Undefined ();
562+ }
563+
564+ if (info.Length () > 3 && info[3 ].IsFunction ()) {
565+ Napi::Function callback = info[3 ].As <Napi::Function>();
566+ DiffWindowAsyncWorker* worker = new DiffWindowAsyncWorker (
567+ callback, oldPath, newPath, outDiffPath
568+ );
569+ worker->Queue ();
570+ return env.Undefined ();
571+ }
572+
573+ try {
574+ hdiff_window (oldPath.c_str (), newPath.c_str (), outDiffPath.c_str ());
575+ } catch (const std::exception& e) {
576+ Napi::Error::New (env, e.what ()).ThrowAsJavaScriptException ();
577+ return env.Undefined ();
578+ }
579+
580+ return Napi::String::New (env, outDiffPath);
581+ }
582+
506583 // ============ 同步/异步 patchSingleStream ============
507584 Napi::Value patchSingleStream (const Napi::CallbackInfo& info) {
508585 Napi::Env env = info.Env ();
@@ -544,6 +621,7 @@ namespace hdiffpatchNode
544621 exports.Set (Napi::String::New (env, " diffStream" ), Napi::Function::New (env, diffStream));
545622 exports.Set (Napi::String::New (env, " patchStream" ), Napi::Function::New (env, patchStream));
546623 exports.Set (Napi::String::New (env, " diffSingleStream" ), Napi::Function::New (env, diffSingleStream));
624+ exports.Set (Napi::String::New (env, " diffWindow" ), Napi::Function::New (env, diffWindow));
547625 exports.Set (Napi::String::New (env, " patchSingleStream" ), Napi::Function::New (env, patchSingleStream));
548626 return exports;
549627 }
0 commit comments