pubo-node 1.0.158 → 1.0.160
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/lib/index.d.ts +2 -1
- package/package.json +4 -17
- package/dist/pubo-node.js +0 -1
- package/es/child-process/index.d.ts +0 -12
- package/es/child-process/index.js +0 -157
- package/es/file-system/index.d.ts +0 -22
- package/es/file-system/index.js +0 -28
- package/es/ftp-client/index.d.ts +0 -64
- package/es/ftp-client/index.js +0 -135
- package/es/grpc/index.d.ts +0 -27
- package/es/grpc/index.js +0 -103
- package/es/index.d.ts +0 -8
- package/es/index.js +0 -8
- package/es/ros/topic.d.ts +0 -20
- package/es/ros/topic.js +0 -80
- package/es/storage/json.d.ts +0 -15
- package/es/storage/json.js +0 -181
- package/es/utils/index.d.ts +0 -1
- package/es/utils/index.js +0 -14
- package/es/utils/network.d.ts +0 -2
- package/es/utils/network.js +0 -35
package/es/ftp-client/index.d.ts
DELETED
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
import type { Stream } from 'stream';
|
|
2
|
-
export interface FtpFile {
|
|
3
|
-
name: string;
|
|
4
|
-
owner: string;
|
|
5
|
-
group: string;
|
|
6
|
-
size: number;
|
|
7
|
-
date: Date;
|
|
8
|
-
type: string;
|
|
9
|
-
}
|
|
10
|
-
export interface FtpConnectOptions {
|
|
11
|
-
user: string;
|
|
12
|
-
host: string;
|
|
13
|
-
password: string;
|
|
14
|
-
driver: any;
|
|
15
|
-
}
|
|
16
|
-
type GetFile = (path: string) => Promise<Buffer>;
|
|
17
|
-
type PutFile = (input: string | Buffer | Stream, path: string) => Promise<string>;
|
|
18
|
-
type DeleteFile = (path: string) => Promise<string>;
|
|
19
|
-
type ListFiles = (path: string) => Promise<FtpFile[]>;
|
|
20
|
-
type RenameFile = (path: string, old: string) => Promise<string>;
|
|
21
|
-
export interface FtpClientInterface {
|
|
22
|
-
get: GetFile;
|
|
23
|
-
put: PutFile;
|
|
24
|
-
delete: DeleteFile;
|
|
25
|
-
list: ListFiles;
|
|
26
|
-
rename: RenameFile;
|
|
27
|
-
}
|
|
28
|
-
export declare class FtpClient implements FtpClientInterface {
|
|
29
|
-
private readonly driver;
|
|
30
|
-
private readonly options;
|
|
31
|
-
private readonly state;
|
|
32
|
-
private client;
|
|
33
|
-
private _len;
|
|
34
|
-
id: string;
|
|
35
|
-
constructor({ driver, ...options }: FtpConnectOptions);
|
|
36
|
-
get len(): number;
|
|
37
|
-
set len(n: number);
|
|
38
|
-
put: (...args: any[]) => Promise<any>;
|
|
39
|
-
delete: (...args: any[]) => Promise<any>;
|
|
40
|
-
list: (...args: any[]) => Promise<any>;
|
|
41
|
-
rename: (...args: any[]) => Promise<any>;
|
|
42
|
-
private connect;
|
|
43
|
-
private close;
|
|
44
|
-
private run;
|
|
45
|
-
private bind;
|
|
46
|
-
get(...args: any[]): Promise<Buffer>;
|
|
47
|
-
}
|
|
48
|
-
export declare class FtpClientPool implements FtpClientInterface {
|
|
49
|
-
private readonly options;
|
|
50
|
-
private readonly maxConnection;
|
|
51
|
-
private readonly pool;
|
|
52
|
-
constructor({ maxConnection, ...options }: {
|
|
53
|
-
maxConnection?: number;
|
|
54
|
-
} & FtpConnectOptions);
|
|
55
|
-
get: (...args: any[]) => Promise<any>;
|
|
56
|
-
put: (...args: any[]) => Promise<any>;
|
|
57
|
-
delete: (...args: any[]) => Promise<any>;
|
|
58
|
-
list: (...args: any[]) => Promise<any>;
|
|
59
|
-
rename: (...args: any[]) => Promise<any>;
|
|
60
|
-
get len(): number;
|
|
61
|
-
private get client();
|
|
62
|
-
private bind;
|
|
63
|
-
}
|
|
64
|
-
export {};
|
package/es/ftp-client/index.js
DELETED
|
@@ -1,135 +0,0 @@
|
|
|
1
|
-
import { random, waitFor } from 'pubo-utils';
|
|
2
|
-
export class FtpClient {
|
|
3
|
-
driver;
|
|
4
|
-
options;
|
|
5
|
-
state = { running: false, connected: false, destroyed: false, connecting: false };
|
|
6
|
-
client;
|
|
7
|
-
_len = 0;
|
|
8
|
-
id = random();
|
|
9
|
-
constructor({ driver, ...options }) {
|
|
10
|
-
this.driver = driver;
|
|
11
|
-
this.options = options;
|
|
12
|
-
}
|
|
13
|
-
get len() {
|
|
14
|
-
return this._len;
|
|
15
|
-
}
|
|
16
|
-
set len(n) {
|
|
17
|
-
this._len = n;
|
|
18
|
-
if (this._len < 1) {
|
|
19
|
-
this.close();
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
put = this.bind('put');
|
|
23
|
-
delete = this.bind('delete');
|
|
24
|
-
list = this.bind('list');
|
|
25
|
-
rename = this.bind('rename');
|
|
26
|
-
async connect() {
|
|
27
|
-
if (!this.client) {
|
|
28
|
-
this.client = new this.driver();
|
|
29
|
-
}
|
|
30
|
-
this.state.destroyed = false;
|
|
31
|
-
if (this.state.connecting) {
|
|
32
|
-
await waitFor(() => this.state.connected, { checkTime: 1000, timeout: 10000 });
|
|
33
|
-
return 'connected';
|
|
34
|
-
}
|
|
35
|
-
this.state.connecting = true;
|
|
36
|
-
return new Promise((resolve, reject) => {
|
|
37
|
-
this.client.once('ready', () => {
|
|
38
|
-
this.state.connected = true;
|
|
39
|
-
resolve('connected');
|
|
40
|
-
this.state.connecting = false;
|
|
41
|
-
});
|
|
42
|
-
this.client.once('error', (err) => {
|
|
43
|
-
reject(err);
|
|
44
|
-
this.close();
|
|
45
|
-
});
|
|
46
|
-
this.client.connect({ ...this.options });
|
|
47
|
-
});
|
|
48
|
-
}
|
|
49
|
-
close() {
|
|
50
|
-
this.client.end();
|
|
51
|
-
this.state.connected = false;
|
|
52
|
-
this.state.destroyed = true;
|
|
53
|
-
this.state.connecting = false;
|
|
54
|
-
this.client = null;
|
|
55
|
-
}
|
|
56
|
-
async run({ fn, args }) {
|
|
57
|
-
this.len += 1;
|
|
58
|
-
if (!this.state.connected) {
|
|
59
|
-
await this.connect();
|
|
60
|
-
}
|
|
61
|
-
if (this.state.running) {
|
|
62
|
-
await waitFor(() => !this.state.running, { checkTime: 1000, timeout: 6000000 });
|
|
63
|
-
}
|
|
64
|
-
this.state.running = true;
|
|
65
|
-
return new Promise((resolve, reject) => {
|
|
66
|
-
this.client[fn](...args, (err, res) => {
|
|
67
|
-
if (err) {
|
|
68
|
-
reject(err);
|
|
69
|
-
}
|
|
70
|
-
else {
|
|
71
|
-
resolve(res);
|
|
72
|
-
}
|
|
73
|
-
});
|
|
74
|
-
});
|
|
75
|
-
}
|
|
76
|
-
bind(fn) {
|
|
77
|
-
return async (...args) => {
|
|
78
|
-
const res = await this.run({ fn, args });
|
|
79
|
-
this.state.running = false;
|
|
80
|
-
this.len -= 1;
|
|
81
|
-
return res;
|
|
82
|
-
};
|
|
83
|
-
}
|
|
84
|
-
async get(...args) {
|
|
85
|
-
let res = Buffer.alloc(0);
|
|
86
|
-
const stream = await this.run({ fn: 'get', args });
|
|
87
|
-
return new Promise((resolve) => {
|
|
88
|
-
stream.on('data', (chunk) => {
|
|
89
|
-
res = Buffer.concat([res, chunk], res.byteLength + chunk.byteLength);
|
|
90
|
-
});
|
|
91
|
-
stream.on('end', () => {
|
|
92
|
-
resolve(res);
|
|
93
|
-
this.state.running = false;
|
|
94
|
-
this.len -= 1;
|
|
95
|
-
});
|
|
96
|
-
});
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
export class FtpClientPool {
|
|
100
|
-
options;
|
|
101
|
-
maxConnection;
|
|
102
|
-
pool = [];
|
|
103
|
-
constructor({ maxConnection = 5, ...options }) {
|
|
104
|
-
this.options = options;
|
|
105
|
-
this.maxConnection = maxConnection;
|
|
106
|
-
}
|
|
107
|
-
get = this.bind('get');
|
|
108
|
-
put = this.bind('put');
|
|
109
|
-
delete = this.bind('delete');
|
|
110
|
-
list = this.bind('list');
|
|
111
|
-
rename = this.bind('rename');
|
|
112
|
-
get len() {
|
|
113
|
-
return this.pool.length;
|
|
114
|
-
}
|
|
115
|
-
get client() {
|
|
116
|
-
if (this.pool.length < this.maxConnection) {
|
|
117
|
-
const client = new FtpClient(this.options);
|
|
118
|
-
this.pool.push(client);
|
|
119
|
-
return client;
|
|
120
|
-
}
|
|
121
|
-
this.pool.sort((a, b) => a.len - b.len);
|
|
122
|
-
return this.pool[0];
|
|
123
|
-
}
|
|
124
|
-
bind(fn) {
|
|
125
|
-
return async (...args) => {
|
|
126
|
-
const client = this.client;
|
|
127
|
-
const res = await client[fn](...args);
|
|
128
|
-
if (client.len < 1) {
|
|
129
|
-
const index = this.pool.findIndex((item) => item.id === client.id);
|
|
130
|
-
this.pool.splice(index, 1);
|
|
131
|
-
}
|
|
132
|
-
return res;
|
|
133
|
-
};
|
|
134
|
-
}
|
|
135
|
-
}
|
package/es/grpc/index.d.ts
DELETED
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
export interface CreateClientProps {
|
|
2
|
-
url: string;
|
|
3
|
-
options?: any;
|
|
4
|
-
ServiceImp: any;
|
|
5
|
-
Grpc: any;
|
|
6
|
-
cert?: Buffer;
|
|
7
|
-
}
|
|
8
|
-
declare class GrpcClient {
|
|
9
|
-
private readonly url;
|
|
10
|
-
private readonly options;
|
|
11
|
-
private readonly Grpc;
|
|
12
|
-
private readonly credentials;
|
|
13
|
-
private client;
|
|
14
|
-
private _timeout;
|
|
15
|
-
connections: number;
|
|
16
|
-
constructor({ url, options, Grpc, cert }: any);
|
|
17
|
-
request(service: any, method: any, data: any): Promise<Buffer>;
|
|
18
|
-
_request({ service, method, data }: {
|
|
19
|
-
service: any;
|
|
20
|
-
method: any;
|
|
21
|
-
data: any;
|
|
22
|
-
}): Promise<Buffer>;
|
|
23
|
-
close(): void;
|
|
24
|
-
}
|
|
25
|
-
export declare const GrpcList: GrpcClient[];
|
|
26
|
-
export declare function createRpcClient<T>({ url, options, ServiceImp, Grpc, cert }: CreateClientProps): T;
|
|
27
|
-
export {};
|
package/es/grpc/index.js
DELETED
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
const passThrough = (argument) => argument;
|
|
2
|
-
class GrpcClient {
|
|
3
|
-
url;
|
|
4
|
-
options;
|
|
5
|
-
Grpc;
|
|
6
|
-
credentials;
|
|
7
|
-
client;
|
|
8
|
-
_timeout;
|
|
9
|
-
connections = 0;
|
|
10
|
-
constructor({ url, options = {}, Grpc, cert }) {
|
|
11
|
-
const opt = { 'grpc.max_send_message_length': -1, 'grpc.max_receive_message_length': -1, ...options };
|
|
12
|
-
const credentials = cert ? Grpc.credentials.createSsl(cert) : Grpc.credentials.createInsecure();
|
|
13
|
-
this.url = url;
|
|
14
|
-
this.Grpc = Grpc;
|
|
15
|
-
this.credentials = credentials;
|
|
16
|
-
this.options = opt;
|
|
17
|
-
this.options.timeout = this.options.timeout ?? 10000;
|
|
18
|
-
Grpc = null;
|
|
19
|
-
options = null;
|
|
20
|
-
cert = null;
|
|
21
|
-
}
|
|
22
|
-
async request(service, method, data) {
|
|
23
|
-
if (this._timeout) {
|
|
24
|
-
clearTimeout(this._timeout);
|
|
25
|
-
this._timeout = null;
|
|
26
|
-
}
|
|
27
|
-
this.connections += 1;
|
|
28
|
-
if (!this.client) {
|
|
29
|
-
this.client = new this.Grpc.Client(this.url, this.credentials, this.options);
|
|
30
|
-
}
|
|
31
|
-
let error;
|
|
32
|
-
let result = Buffer.alloc(0);
|
|
33
|
-
try {
|
|
34
|
-
result = await this._request({ service, method, data });
|
|
35
|
-
}
|
|
36
|
-
catch (err) {
|
|
37
|
-
error = err;
|
|
38
|
-
}
|
|
39
|
-
service = null;
|
|
40
|
-
method = null;
|
|
41
|
-
data = null;
|
|
42
|
-
this.connections -= 1;
|
|
43
|
-
if (this.connections < 0) {
|
|
44
|
-
this.connections = 0;
|
|
45
|
-
}
|
|
46
|
-
if (this.connections < 1) {
|
|
47
|
-
if (this._timeout) {
|
|
48
|
-
clearTimeout(this._timeout);
|
|
49
|
-
this._timeout = null;
|
|
50
|
-
}
|
|
51
|
-
this._timeout = setTimeout(() => this.close(), 60000);
|
|
52
|
-
}
|
|
53
|
-
if (error) {
|
|
54
|
-
console.log(error);
|
|
55
|
-
this.close();
|
|
56
|
-
throw new Error('grpc connection error.');
|
|
57
|
-
}
|
|
58
|
-
return result;
|
|
59
|
-
}
|
|
60
|
-
_request({ service, method, data }) {
|
|
61
|
-
return new Promise((resolve, reject) => {
|
|
62
|
-
let _ended = false;
|
|
63
|
-
const _timeout = setTimeout(() => {
|
|
64
|
-
_ended = true;
|
|
65
|
-
this.close();
|
|
66
|
-
console.log('rpc request timeout');
|
|
67
|
-
reject(new Error('timeout'));
|
|
68
|
-
}, this.options.timeout);
|
|
69
|
-
const onResponse = (err, res) => {
|
|
70
|
-
if (_ended) {
|
|
71
|
-
return;
|
|
72
|
-
}
|
|
73
|
-
else {
|
|
74
|
-
clearTimeout(_timeout);
|
|
75
|
-
}
|
|
76
|
-
if (err) {
|
|
77
|
-
reject(err);
|
|
78
|
-
}
|
|
79
|
-
else {
|
|
80
|
-
resolve(res);
|
|
81
|
-
}
|
|
82
|
-
};
|
|
83
|
-
this.client.makeUnaryRequest(`/${service}/${method}`, passThrough, passThrough, data ? Buffer.from(data) : Buffer.alloc(0), onResponse);
|
|
84
|
-
});
|
|
85
|
-
}
|
|
86
|
-
close() {
|
|
87
|
-
if (this._timeout) {
|
|
88
|
-
clearTimeout(this._timeout);
|
|
89
|
-
delete this._timeout;
|
|
90
|
-
}
|
|
91
|
-
this.client?.close();
|
|
92
|
-
this.client = null;
|
|
93
|
-
delete this.client;
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
export const GrpcList = [];
|
|
97
|
-
export function createRpcClient({ url, options = {}, ServiceImp, Grpc, cert }) {
|
|
98
|
-
const client = new GrpcClient({ url, options, Grpc, cert });
|
|
99
|
-
GrpcList.push(client);
|
|
100
|
-
Grpc = null;
|
|
101
|
-
options = null;
|
|
102
|
-
return new ServiceImp({ request: client.request.bind(client) });
|
|
103
|
-
}
|
package/es/index.d.ts
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
export { JsonStorage } from './storage/json';
|
|
2
|
-
export { FtpClient, FtpClientPool, FtpConnectOptions, FtpFile } from './ftp-client';
|
|
3
|
-
export { createRpcClient, GrpcList } from './grpc';
|
|
4
|
-
export { SIGKILL, isProcessDied, getProcessName, getProcessTree, getProcessByPpid, getProcessCpuUseByPid, getProcessCommandByPid, heartbeat, } from './child-process';
|
|
5
|
-
export { isPortAvailable } from './utils';
|
|
6
|
-
export { getWifiName, getNetworks } from './utils/network';
|
|
7
|
-
export { RosTopicManager, RosTopic } from './ros/topic';
|
|
8
|
-
export { PuboFileSystem } from './file-system';
|
package/es/index.js
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
export { JsonStorage } from './storage/json';
|
|
2
|
-
export { FtpClient, FtpClientPool } from './ftp-client';
|
|
3
|
-
export { createRpcClient, GrpcList } from './grpc';
|
|
4
|
-
export { SIGKILL, isProcessDied, getProcessName, getProcessTree, getProcessByPpid, getProcessCpuUseByPid, getProcessCommandByPid, heartbeat, } from './child-process';
|
|
5
|
-
export { isPortAvailable } from './utils';
|
|
6
|
-
export { getWifiName, getNetworks } from './utils/network';
|
|
7
|
-
export { RosTopicManager, RosTopic } from './ros/topic';
|
|
8
|
-
export { PuboFileSystem } from './file-system';
|
package/es/ros/topic.d.ts
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import { Emitter } from 'pubo-utils';
|
|
2
|
-
export declare class RosTopic {
|
|
3
|
-
topic: string;
|
|
4
|
-
messageType: string;
|
|
5
|
-
emitter: Emitter;
|
|
6
|
-
private subscribed;
|
|
7
|
-
private readonly dog;
|
|
8
|
-
private readonly strSplit;
|
|
9
|
-
private subscribeChildProcess;
|
|
10
|
-
constructor(topic: any, messageType: any);
|
|
11
|
-
private onTimeout;
|
|
12
|
-
private onData;
|
|
13
|
-
subscribe(): Promise<void>;
|
|
14
|
-
unsubscribe(): Promise<void>;
|
|
15
|
-
publish(payload: any): Promise<unknown>;
|
|
16
|
-
}
|
|
17
|
-
export declare const RosTopicManager: {
|
|
18
|
-
cache: never[];
|
|
19
|
-
getTopic: (topic: any, messageType: any) => RosTopic;
|
|
20
|
-
};
|
package/es/ros/topic.js
DELETED
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
import { exec, spawn } from 'child_process';
|
|
2
|
-
import { Emitter, WatchDog, StringSplit, sleep } from 'pubo-utils';
|
|
3
|
-
import * as YAML from 'yaml';
|
|
4
|
-
import { SIGKILL } from '../child-process';
|
|
5
|
-
export class RosTopic {
|
|
6
|
-
topic;
|
|
7
|
-
messageType;
|
|
8
|
-
emitter = new Emitter();
|
|
9
|
-
subscribed = false;
|
|
10
|
-
dog = new WatchDog({ limit: 10, onTimeout: this.onTimeout.bind(this) });
|
|
11
|
-
strSplit = new StringSplit('---');
|
|
12
|
-
subscribeChildProcess;
|
|
13
|
-
constructor(topic, messageType) {
|
|
14
|
-
this.topic = topic;
|
|
15
|
-
this.messageType = messageType;
|
|
16
|
-
this.subscribed = false;
|
|
17
|
-
this.emitter = new Emitter();
|
|
18
|
-
}
|
|
19
|
-
async onTimeout() {
|
|
20
|
-
if (!this.subscribed) {
|
|
21
|
-
return;
|
|
22
|
-
}
|
|
23
|
-
await this.unsubscribe();
|
|
24
|
-
await sleep(1000);
|
|
25
|
-
await this.subscribe();
|
|
26
|
-
}
|
|
27
|
-
onData(data) {
|
|
28
|
-
const tmp = this.strSplit.split(data.toString()).slice(-1)[0];
|
|
29
|
-
if (!tmp) {
|
|
30
|
-
return;
|
|
31
|
-
}
|
|
32
|
-
this.dog.feed();
|
|
33
|
-
const res = YAML.parse(tmp);
|
|
34
|
-
this.emitter.emit('message', res);
|
|
35
|
-
}
|
|
36
|
-
async subscribe() {
|
|
37
|
-
if (this.subscribeChildProcess) {
|
|
38
|
-
return;
|
|
39
|
-
}
|
|
40
|
-
this.subscribed = true;
|
|
41
|
-
this.dog.init();
|
|
42
|
-
this.subscribeChildProcess = spawn(`rostopic`, ['echo', this.topic]);
|
|
43
|
-
this.subscribeChildProcess.stdout.on('data', this.onData.bind(this));
|
|
44
|
-
this.subscribeChildProcess.stderr.on('data', (buf) => console.log(buf.toString()));
|
|
45
|
-
}
|
|
46
|
-
async unsubscribe() {
|
|
47
|
-
if (!this.subscribeChildProcess) {
|
|
48
|
-
return;
|
|
49
|
-
}
|
|
50
|
-
this.dog.stop();
|
|
51
|
-
this.subscribed = false;
|
|
52
|
-
await SIGKILL(this.subscribeChildProcess.pid);
|
|
53
|
-
this.subscribeChildProcess = null;
|
|
54
|
-
}
|
|
55
|
-
publish(payload) {
|
|
56
|
-
const data = YAML.stringify(payload);
|
|
57
|
-
return new Promise((resolve, reject) => {
|
|
58
|
-
exec(`rostopic pub -1 ${this.topic} ${this.messageType} "${data}"`, (err, stdout) => {
|
|
59
|
-
if (err) {
|
|
60
|
-
reject(err);
|
|
61
|
-
}
|
|
62
|
-
else {
|
|
63
|
-
resolve(stdout);
|
|
64
|
-
}
|
|
65
|
-
});
|
|
66
|
-
});
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
export const RosTopicManager = {
|
|
70
|
-
cache: [],
|
|
71
|
-
getTopic: function (topic, messageType) {
|
|
72
|
-
const tmp = this.cache.find((item) => item.topic === topic);
|
|
73
|
-
if (tmp) {
|
|
74
|
-
return tmp;
|
|
75
|
-
}
|
|
76
|
-
const instance = new RosTopic(topic, messageType);
|
|
77
|
-
this.cache.push(instance);
|
|
78
|
-
return instance;
|
|
79
|
-
},
|
|
80
|
-
};
|
package/es/storage/json.d.ts
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
export interface JsonStorageOptions {
|
|
2
|
-
initialState?: any;
|
|
3
|
-
defaultState?: any;
|
|
4
|
-
}
|
|
5
|
-
export declare class JsonStorage {
|
|
6
|
-
private readonly instance;
|
|
7
|
-
private readonly queue;
|
|
8
|
-
constructor(path: string, options?: JsonStorageOptions);
|
|
9
|
-
private getState;
|
|
10
|
-
private setState;
|
|
11
|
-
get(key?: string): Promise<any>;
|
|
12
|
-
set(key: string, values: any): Promise<void>;
|
|
13
|
-
merge(values: any): Promise<void>;
|
|
14
|
-
remove(key: string): Promise<void>;
|
|
15
|
-
}
|
package/es/storage/json.js
DELETED
|
@@ -1,181 +0,0 @@
|
|
|
1
|
-
import { readFileSync, writeFile, mkdirSync, writeFileSync } from 'fs';
|
|
2
|
-
import { SyncQueue } from 'pubo-utils';
|
|
3
|
-
import { v4 as uuid } from 'uuid';
|
|
4
|
-
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
5
|
-
const cluster = require('cluster');
|
|
6
|
-
// 主线程的实现
|
|
7
|
-
class Manager {
|
|
8
|
-
path;
|
|
9
|
-
_state = {};
|
|
10
|
-
queue = new SyncQueue();
|
|
11
|
-
key;
|
|
12
|
-
defaultState;
|
|
13
|
-
constructor(path, defaultState) {
|
|
14
|
-
this.path = path;
|
|
15
|
-
this.defaultState = defaultState;
|
|
16
|
-
this.key = encodeURIComponent(path);
|
|
17
|
-
cluster.on('online', (worker) => {
|
|
18
|
-
worker.on('message', (message) => {
|
|
19
|
-
this.onMessage(message, worker);
|
|
20
|
-
message = null;
|
|
21
|
-
});
|
|
22
|
-
});
|
|
23
|
-
cluster.on('exit', (worker) => {
|
|
24
|
-
worker.removeAllListeners('message');
|
|
25
|
-
worker = null;
|
|
26
|
-
});
|
|
27
|
-
this.restore();
|
|
28
|
-
if (global.GlobalEmitter) {
|
|
29
|
-
global.GlobalEmitter.on('SIGINT', this.kill.bind(this));
|
|
30
|
-
}
|
|
31
|
-
else {
|
|
32
|
-
process.on('SIGINT', () => {
|
|
33
|
-
this.kill().then(() => process.exit(0));
|
|
34
|
-
});
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
// 进程退出时,同步文件
|
|
38
|
-
async kill() {
|
|
39
|
-
await this.queue.push(() => this.syncFile());
|
|
40
|
-
}
|
|
41
|
-
async onMessage(message, worker) {
|
|
42
|
-
if (message.key !== this.key) {
|
|
43
|
-
return;
|
|
44
|
-
}
|
|
45
|
-
let payload;
|
|
46
|
-
if (message.type === 'get') {
|
|
47
|
-
payload = await this.getState();
|
|
48
|
-
}
|
|
49
|
-
else if (message.type === 'set') {
|
|
50
|
-
payload = await this.setState(message.payload);
|
|
51
|
-
}
|
|
52
|
-
worker.send({ uid: message.uid, key: this.key, payload });
|
|
53
|
-
message = null;
|
|
54
|
-
worker = null;
|
|
55
|
-
}
|
|
56
|
-
sync() {
|
|
57
|
-
if (this.queue.length > 0) {
|
|
58
|
-
return;
|
|
59
|
-
}
|
|
60
|
-
this.queue.push(this._syncFile.bind(this));
|
|
61
|
-
}
|
|
62
|
-
// 同步文件备份
|
|
63
|
-
syncFile() {
|
|
64
|
-
writeFileSync(this.path, JSON.stringify(this._state));
|
|
65
|
-
}
|
|
66
|
-
// 异步文件备份
|
|
67
|
-
async _syncFile() {
|
|
68
|
-
return new Promise((resolve, reject) => {
|
|
69
|
-
writeFile(this.path, JSON.stringify(this._state), (err) => {
|
|
70
|
-
if (err) {
|
|
71
|
-
reject(err);
|
|
72
|
-
}
|
|
73
|
-
else {
|
|
74
|
-
setTimeout(resolve, 100);
|
|
75
|
-
}
|
|
76
|
-
});
|
|
77
|
-
});
|
|
78
|
-
}
|
|
79
|
-
restore() {
|
|
80
|
-
try {
|
|
81
|
-
const buf = readFileSync(this.path);
|
|
82
|
-
this._state = JSON.parse(buf.toString());
|
|
83
|
-
}
|
|
84
|
-
catch (err) {
|
|
85
|
-
const str = process.platform === 'win32' ? '\\' : '/';
|
|
86
|
-
if (str) {
|
|
87
|
-
mkdirSync(this.path.split(str).slice(0, -1).join(str), { recursive: true });
|
|
88
|
-
}
|
|
89
|
-
this.setState(this.defaultState ?? {});
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
async getState() {
|
|
93
|
-
return this._state;
|
|
94
|
-
}
|
|
95
|
-
async setState(values) {
|
|
96
|
-
this._state = values;
|
|
97
|
-
this.sync();
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
// work 线程的实现
|
|
101
|
-
class Worker {
|
|
102
|
-
key;
|
|
103
|
-
callback = {};
|
|
104
|
-
constructor(path) {
|
|
105
|
-
this.key = encodeURIComponent(path);
|
|
106
|
-
process.on('message', this.onMessage.bind(this));
|
|
107
|
-
}
|
|
108
|
-
onMessage(message) {
|
|
109
|
-
if (message.key !== this.key) {
|
|
110
|
-
return;
|
|
111
|
-
}
|
|
112
|
-
if (typeof this.callback[message.uid] === 'function') {
|
|
113
|
-
this.callback[message.uid](message.payload);
|
|
114
|
-
delete this.callback[message.uid];
|
|
115
|
-
}
|
|
116
|
-
message = null;
|
|
117
|
-
}
|
|
118
|
-
async call({ type, payload }) {
|
|
119
|
-
return new Promise((resolve) => {
|
|
120
|
-
const uid = uuid();
|
|
121
|
-
this.callback[uid] = (data) => resolve(data);
|
|
122
|
-
//@ts-ignore
|
|
123
|
-
process.send({ uid, type, payload, key: this.key });
|
|
124
|
-
payload = null;
|
|
125
|
-
type = null;
|
|
126
|
-
});
|
|
127
|
-
}
|
|
128
|
-
async getState() {
|
|
129
|
-
return this.call({ type: 'get', payload: {} });
|
|
130
|
-
}
|
|
131
|
-
async setState(payload) {
|
|
132
|
-
return this.call({ type: 'set', payload });
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
export class JsonStorage {
|
|
136
|
-
instance;
|
|
137
|
-
queue = new SyncQueue();
|
|
138
|
-
constructor(path, options = {}) {
|
|
139
|
-
if (cluster.isPrimary) {
|
|
140
|
-
this.instance = new Manager(path, options.defaultState);
|
|
141
|
-
}
|
|
142
|
-
else {
|
|
143
|
-
this.instance = new Worker(path);
|
|
144
|
-
}
|
|
145
|
-
if (options?.initialState) {
|
|
146
|
-
this.merge(options.initialState);
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
async getState() {
|
|
150
|
-
return this.queue.push(this.instance.getState.bind(this.instance));
|
|
151
|
-
}
|
|
152
|
-
async setState(state) {
|
|
153
|
-
return this.queue.push(() => this.instance.setState(state));
|
|
154
|
-
}
|
|
155
|
-
async get(key) {
|
|
156
|
-
if (!key) {
|
|
157
|
-
return this.getState();
|
|
158
|
-
}
|
|
159
|
-
else {
|
|
160
|
-
const state = await this.getState();
|
|
161
|
-
return state[key];
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
async set(key, values) {
|
|
165
|
-
const state = await this.getState();
|
|
166
|
-
state[key] = values;
|
|
167
|
-
await this.setState(state);
|
|
168
|
-
}
|
|
169
|
-
async merge(values) {
|
|
170
|
-
const state = await this.getState();
|
|
171
|
-
for (const key of Object.keys(values)) {
|
|
172
|
-
state[key] = values[key];
|
|
173
|
-
}
|
|
174
|
-
await this.setState(state);
|
|
175
|
-
}
|
|
176
|
-
async remove(key) {
|
|
177
|
-
const state = await this.getState();
|
|
178
|
-
delete state[key];
|
|
179
|
-
await this.setState(state);
|
|
180
|
-
}
|
|
181
|
-
}
|
package/es/utils/index.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare const isPortAvailable: (port: any) => Promise<unknown>;
|
package/es/utils/index.js
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
export const isPortAvailable = (port) => {
|
|
2
|
-
return new Promise((resolve) => {
|
|
3
|
-
const net = require('net');
|
|
4
|
-
const server = net.createServer();
|
|
5
|
-
server.listen(port, () => {
|
|
6
|
-
resolve(true);
|
|
7
|
-
server.close();
|
|
8
|
-
});
|
|
9
|
-
server.on('error', () => {
|
|
10
|
-
resolve(false);
|
|
11
|
-
server.close();
|
|
12
|
-
});
|
|
13
|
-
});
|
|
14
|
-
};
|
package/es/utils/network.d.ts
DELETED