@tsukilabs/nil-ffi 0.7.5 → 0.7.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +18 -12
- package/dist/index.js +40 -31
- package/package.json +7 -4
package/dist/index.d.ts
CHANGED
|
@@ -6,21 +6,20 @@ import * as ffi from "node:ffi";
|
|
|
6
6
|
export * from './def';
|
|
7
7
|
export * from './error';
|
|
8
8
|
export type Handle = ffi.DynamicLibraryResult<typeof definitions>;
|
|
9
|
-
export type { ErrorHandler } from './queue';
|
|
9
|
+
export type { ErrorHandler, QueueOptions } from './queue';
|
|
10
10
|
export declare const VERSION: string;
|
|
11
11
|
export declare const USER_AGENT: string;
|
|
12
|
-
export declare class Nil implements
|
|
12
|
+
export declare class Nil implements AsyncDisposable {
|
|
13
|
+
#private;
|
|
13
14
|
readonly path: string;
|
|
14
15
|
private readonly handle;
|
|
15
|
-
readonly functions
|
|
16
|
+
private readonly functions;
|
|
16
17
|
private readonly queue;
|
|
17
|
-
private
|
|
18
|
+
private closed;
|
|
19
|
+
private closePromise;
|
|
18
20
|
private constructor();
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
static downloadLatest(outDir?: Option<string>): Promise<string>;
|
|
22
|
-
[Symbol.dispose](): void;
|
|
23
|
-
close(): void;
|
|
21
|
+
[Symbol.asyncDispose](): Promise<void>;
|
|
22
|
+
close(): Promise<void>;
|
|
24
23
|
isClosed(): boolean;
|
|
25
24
|
authorize(req: AuthorizeRequest): Promise<string>;
|
|
26
25
|
getClientVersion(): Promise<string>;
|
|
@@ -46,12 +45,19 @@ export declare class Nil implements Disposable {
|
|
|
46
45
|
setUserAgent(userAgent: string): Promise<import('@tb-dev/utils').nil>;
|
|
47
46
|
spawnPlayer(req: SpawnPlayerRequest): Promise<import('@tb-dev/utils').nil>;
|
|
48
47
|
startServer(options: WorldOptions): Promise<LocalServer>;
|
|
49
|
-
startServerWithSavedata(
|
|
48
|
+
startServerWithSavedata(savedataPath: string): Promise<LocalServer>;
|
|
50
49
|
stopClient(): Promise<import('@tb-dev/utils').nil>;
|
|
51
50
|
stopServer(): Promise<import('@tb-dev/utils').nil>;
|
|
52
51
|
updateClient(options: ClientOptions): Promise<import('@tb-dev/utils').nil>;
|
|
53
52
|
validateToken(req: ValidateTokenRequest): Promise<ValidateTokenResponse>;
|
|
53
|
+
static init(dll: string, options?: NilOptions): Promise<Nil>;
|
|
54
|
+
static initLatest(options?: InitLatestOptions): Promise<Nil>;
|
|
55
|
+
static downloadLatest(options?: DownloadLatestOptions): Promise<string>;
|
|
56
|
+
}
|
|
57
|
+
export interface NilOptions extends QueueOptions {
|
|
54
58
|
}
|
|
55
|
-
export interface
|
|
56
|
-
|
|
59
|
+
export interface DownloadLatestOptions {
|
|
60
|
+
outDir?: Option<string>;
|
|
61
|
+
overwrite?: boolean;
|
|
57
62
|
}
|
|
63
|
+
export type InitLatestOptions = DownloadLatestOptions & NilOptions;
|
package/dist/index.js
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import * as ffi from "node:ffi";
|
|
2
|
+
import * as path from "node:path";
|
|
2
3
|
import * as process from "node:process";
|
|
3
4
|
import { cwd } from "node:process";
|
|
5
|
+
import { existsSync } from "node:fs";
|
|
6
|
+
import * as fs from "node:fs/promises";
|
|
4
7
|
import { ffi_Status } from "@tsukilabs/nil-bindings";
|
|
5
|
-
import {
|
|
8
|
+
import { attemptAsync } from "es-toolkit/util";
|
|
6
9
|
import { EventEmitter } from "node:events";
|
|
7
10
|
import { isNil } from "es-toolkit/predicate";
|
|
8
|
-
import { join, resolve } from "node:path";
|
|
9
11
|
//#region src/def.ts
|
|
10
12
|
//! Copyright (C) Call of Nil contributors
|
|
11
13
|
//! SPDX-License-Identifier: AGPL-3.0-only
|
|
@@ -752,7 +754,7 @@ var Queue = class Queue {
|
|
|
752
754
|
};
|
|
753
755
|
//#endregion
|
|
754
756
|
//#region package.json
|
|
755
|
-
var version = "0.7.
|
|
757
|
+
var version = "0.7.7";
|
|
756
758
|
//#endregion
|
|
757
759
|
//#region \0@oxc-project+runtime@0.139.0/helpers/esm/decorate.js
|
|
758
760
|
function __decorate(decorators, target, key, desc) {
|
|
@@ -769,43 +771,31 @@ var VERSION = version;
|
|
|
769
771
|
var USER_AGENT = `nil-ffi-node/${VERSION}`;
|
|
770
772
|
var Nil = class Nil {
|
|
771
773
|
constructor(dll, options) {
|
|
772
|
-
this.
|
|
774
|
+
this.closed = false;
|
|
773
775
|
if (!dll.endsWith(ffi.suffix)) dll = `${dll}.${ffi.suffix}`;
|
|
774
|
-
this.path = resolve(dll);
|
|
776
|
+
this.path = path.resolve(dll);
|
|
775
777
|
this.handle = ffi.dlopen(dll, definitions);
|
|
776
778
|
this.functions = this.handle.functions;
|
|
777
779
|
this.queue = new Queue(this.handle, options);
|
|
778
780
|
}
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
await nil.setUserAgent(USER_AGENT);
|
|
782
|
-
return nil;
|
|
783
|
-
}
|
|
784
|
-
static async initLatest(outDir, options) {
|
|
785
|
-
const dll = await this.downloadLatest(outDir);
|
|
786
|
-
return this.init(dll, options);
|
|
787
|
-
}
|
|
788
|
-
static async downloadLatest(outDir) {
|
|
789
|
-
const file = `libnil.${ffi.suffix}`;
|
|
790
|
-
const response = await fetch(`https://tsukilabs.dev.br/${file}`);
|
|
791
|
-
if (!response.ok) throw new Error(`failed to download ${file}: ${response.status} ${response.statusText}`);
|
|
792
|
-
const bytes = await response.bytes();
|
|
793
|
-
const path = join(outDir ?? cwd(), file);
|
|
794
|
-
await writeFile(path, bytes);
|
|
795
|
-
return resolve(path);
|
|
781
|
+
async [Symbol.asyncDispose]() {
|
|
782
|
+
await this.close();
|
|
796
783
|
}
|
|
797
|
-
|
|
798
|
-
this.
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
this.disposed = true;
|
|
784
|
+
async #close() {
|
|
785
|
+
if (this.closed) return;
|
|
786
|
+
this.closed = true;
|
|
787
|
+
await attemptAsync(this.stopClient.bind(this));
|
|
788
|
+
await attemptAsync(this.stopServer.bind(this));
|
|
803
789
|
this.queue[Symbol.dispose]();
|
|
804
790
|
this.functions.nil_ffi_shutdown();
|
|
805
791
|
this.handle[Symbol.dispose]();
|
|
806
792
|
}
|
|
793
|
+
async close() {
|
|
794
|
+
this.closePromise ??= this.#close();
|
|
795
|
+
return this.closePromise;
|
|
796
|
+
}
|
|
807
797
|
isClosed() {
|
|
808
|
-
return this.
|
|
798
|
+
return this.closed;
|
|
809
799
|
}
|
|
810
800
|
async authorize(req) {
|
|
811
801
|
return this.queue.request((requestId) => {
|
|
@@ -927,9 +917,9 @@ var Nil = class Nil {
|
|
|
927
917
|
this.functions.nil_start_server(requestId, JSON.stringify(options));
|
|
928
918
|
});
|
|
929
919
|
}
|
|
930
|
-
async startServerWithSavedata(
|
|
920
|
+
async startServerWithSavedata(savedataPath) {
|
|
931
921
|
return this.queue.request((requestId) => {
|
|
932
|
-
this.functions.nil_start_server_with_savedata(requestId, JSON.stringify(
|
|
922
|
+
this.functions.nil_start_server_with_savedata(requestId, JSON.stringify(savedataPath));
|
|
933
923
|
});
|
|
934
924
|
}
|
|
935
925
|
async stopClient() {
|
|
@@ -952,6 +942,25 @@ var Nil = class Nil {
|
|
|
952
942
|
this.functions.nil_validate_token(requestId, JSON.stringify(req));
|
|
953
943
|
});
|
|
954
944
|
}
|
|
945
|
+
static async init(dll, options) {
|
|
946
|
+
const nil = new Nil(dll, options);
|
|
947
|
+
await nil.setUserAgent(USER_AGENT);
|
|
948
|
+
return nil;
|
|
949
|
+
}
|
|
950
|
+
static async initLatest(options) {
|
|
951
|
+
const dll = await this.downloadLatest(options);
|
|
952
|
+
return this.init(dll, options);
|
|
953
|
+
}
|
|
954
|
+
static async downloadLatest(options) {
|
|
955
|
+
const file = `libnil.${ffi.suffix}`;
|
|
956
|
+
const filePath = path.resolve(options?.outDir ?? cwd(), file);
|
|
957
|
+
if (!(options?.overwrite ?? true) && existsSync(filePath)) return filePath;
|
|
958
|
+
const response = await fetch(`https://tsukilabs.dev.br/download/nil/${file}`, { headers: { "User-Agent": USER_AGENT } });
|
|
959
|
+
if (!response.ok) throw new Error(`failed to download ${file}: ${response.status} ${response.statusText}`);
|
|
960
|
+
const bytes = await response.bytes();
|
|
961
|
+
await fs.writeFile(filePath, bytes);
|
|
962
|
+
return filePath;
|
|
963
|
+
}
|
|
955
964
|
};
|
|
956
965
|
__decorate([ThrowIfClosed], Nil.prototype, "authorize", null);
|
|
957
966
|
__decorate([ThrowIfClosed], Nil.prototype, "getClientVersion", null);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tsukilabs/nil-ffi",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.7",
|
|
4
4
|
"description": "FFI bindings for Call of Nil",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"packageManager": "pnpm@11.18.0",
|
|
@@ -30,11 +30,14 @@
|
|
|
30
30
|
"typedoc": "typedoc --plugin typedoc-plugin-mdn-links"
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@tb-dev/utils": "^8.1.
|
|
34
|
-
"@tsukilabs/nil-bindings": "^0.7.
|
|
33
|
+
"@tb-dev/utils": "^8.1.2",
|
|
34
|
+
"@tsukilabs/nil-bindings": "^0.7.6",
|
|
35
35
|
"es-toolkit": "^1.50.0"
|
|
36
36
|
},
|
|
37
37
|
"files": ["dist"],
|
|
38
38
|
"main": "./dist/index.js",
|
|
39
|
-
"types": "./dist/index.d.ts"
|
|
39
|
+
"types": "./dist/index.d.ts",
|
|
40
|
+
"engines": {
|
|
41
|
+
"node": ">=26.5.1"
|
|
42
|
+
}
|
|
40
43
|
}
|