@peerbit/server 1.1.2 → 2.0.0

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/src/client.ts CHANGED
@@ -1,19 +1,28 @@
1
- import { StartByBase64, StartByVariant, StartProgram } from "./types.js";
1
+ import { InstallDependency, StartProgram } from "./types.js";
2
2
  import {
3
3
  ADDRESS_PATH,
4
4
  BOOTSTRAP_PATH,
5
+ TERMINATE_PATH,
5
6
  INSTALL_PATH,
6
7
  LOCAL_PORT,
7
8
  PEER_ID_PATH,
8
9
  PROGRAMS_PATH,
9
10
  PROGRAM_PATH,
11
+ RESTART_PATH,
10
12
  } from "./routes.js";
11
13
  import { Address } from "@peerbit/program";
12
14
  import { multiaddr } from "@multiformats/multiaddr";
13
15
 
14
16
  export const client = async (
17
+ password: string,
15
18
  endpoint: string = "http://localhost:" + LOCAL_PORT
16
19
  ) => {
20
+ const isLocalHost = endpoint.startsWith("http://localhost");
21
+
22
+ if (!isLocalHost && password == null) {
23
+ throw new Error("Expecting password when starting the client");
24
+ }
25
+
17
26
  const { default: axios } = await import("axios");
18
27
 
19
28
  const validateStatus = (status: number) => {
@@ -43,16 +52,20 @@ export const client = async (
43
52
  );
44
53
  };
45
54
  const getId = async () =>
46
- throwIfNot200(await axios.get(endpoint + PEER_ID_PATH, { validateStatus }))
47
- .data;
55
+ throwIfNot200(
56
+ await axios.get(endpoint + PEER_ID_PATH, {
57
+ validateStatus,
58
+ timeout: 5000,
59
+ })
60
+ ).data;
48
61
 
49
62
  const getHeaders = async () => {
50
- const config = await import("./config.js");
51
63
  const headers = {
52
- authorization: "Basic admin:" + (await config.loadPassword()),
64
+ authorization: "Basic admin:" + password,
53
65
  };
54
66
  return headers;
55
67
  };
68
+
56
69
  return {
57
70
  peer: {
58
71
  id: {
@@ -137,11 +150,15 @@ export const client = async (
137
150
  },
138
151
  },
139
152
  dependency: {
140
- install: async (name: string): Promise<string[]> => {
141
- const resp = await axios.put(endpoint + INSTALL_PATH, name, {
142
- validateStatus,
143
- headers: await getHeaders(),
144
- });
153
+ install: async (instruction: InstallDependency): Promise<string[]> => {
154
+ const resp = await axios.put(
155
+ endpoint + INSTALL_PATH,
156
+ JSON.stringify(instruction),
157
+ {
158
+ validateStatus,
159
+ headers: await getHeaders(),
160
+ }
161
+ );
145
162
  if (resp.status !== 200) {
146
163
  throw new Error(
147
164
  typeof resp.data === "string" ? resp.data : resp.data.toString()
@@ -160,5 +177,21 @@ export const client = async (
160
177
  );
161
178
  },
162
179
  },
180
+ restart: async (): Promise<void> => {
181
+ throwIfNot200(
182
+ await axios.post(endpoint + RESTART_PATH, undefined, {
183
+ validateStatus,
184
+ headers: await getHeaders(),
185
+ })
186
+ );
187
+ },
188
+ terminate: async (): Promise<void> => {
189
+ throwIfNot200(
190
+ await axios.post(endpoint + TERMINATE_PATH, undefined, {
191
+ validateStatus,
192
+ headers: await getHeaders(),
193
+ })
194
+ );
195
+ },
163
196
  };
164
197
  };
package/src/config.ts CHANGED
@@ -2,15 +2,34 @@ import path from "path";
2
2
  import os from "os";
3
3
  import fs from "fs";
4
4
 
5
- export const getHomeConfigDir = async (): Promise<string> => {
5
+ import { Duplex } from "stream"; // Native Node Module
6
+
7
+ const bufferToStream = (myBuffer) => {
8
+ const tmp = new Duplex();
9
+ tmp.push(myBuffer);
10
+ tmp.push(null);
11
+ return tmp;
12
+ };
13
+
14
+ export const getHomeConfigDir = (): string => {
6
15
  const configDir = path.join(os.homedir(), ".peerbit");
7
16
  return configDir;
8
17
  };
9
18
 
10
- export const getCredentialsPath = async (
11
- configDir: string
12
- ): Promise<string> => {
13
- return path.join(configDir, "credentials");
19
+ export const getCredentialsPath = (configDir: string): string => {
20
+ return path.join(configDir, "credentials.json");
21
+ };
22
+
23
+ export const getServerConfigPath = (configDir: string): string => {
24
+ return path.join(configDir, "server");
25
+ };
26
+
27
+ export const getRemotesPath = (configDir: string): string => {
28
+ return path.join(configDir, "remotes.json");
29
+ };
30
+
31
+ export const getNodePath = (directory: string): string => {
32
+ return path.join(directory, "node");
14
33
  };
15
34
 
16
35
  export const getKeysPath = async (configDir: string): Promise<string> => {
@@ -32,8 +51,10 @@ export const checkExistPath = async (path: string) => {
32
51
  }
33
52
  };
34
53
 
35
- export const loadPassword = async (): Promise<string> => {
36
- const configDir = await getHomeConfigDir();
54
+ export const loadPassword = async (
55
+ configDirectory: string
56
+ ): Promise<string> => {
57
+ const configDir = configDirectory || (await getHomeConfigDir());
37
58
  const credentialsPath = await getCredentialsPath(configDir);
38
59
  if (!(await checkExistPath(credentialsPath))) {
39
60
  throw new NotFoundError("Credentials file does not exist");
@@ -47,12 +68,16 @@ export const loadPassword = async (): Promise<string> => {
47
68
  return password;
48
69
  };
49
70
 
50
- export const getPackageName = async (path: string): Promise<string> => {
71
+ export const getPackageName = async (
72
+ path: string | Uint8Array
73
+ ): Promise<string> => {
51
74
  const tar = await import("tar-stream");
52
75
  const zlib = await import("zlib");
53
76
 
54
- if (!fs.existsSync(path)) {
55
- throw new Error("File does not exist");
77
+ if (typeof path === "string") {
78
+ if (!fs.existsSync(path)) {
79
+ throw new Error("File does not exist");
80
+ }
56
81
  }
57
82
  return new Promise((resolve, reject) => {
58
83
  try {
@@ -84,7 +109,11 @@ export const getPackageName = async (path: string): Promise<string> => {
84
109
  reject(e);
85
110
  });
86
111
 
87
- fs.createReadStream(path).pipe(zlib.createGunzip()).pipe(extract);
112
+ if (typeof path === "string") {
113
+ fs.createReadStream(path).pipe(zlib.createGunzip()).pipe(extract);
114
+ } else {
115
+ bufferToStream(path).pipe(zlib.createGunzip()).pipe(extract);
116
+ }
88
117
  } catch (error) {
89
118
  reject(error);
90
119
  }
package/src/peerbit.ts CHANGED
@@ -1,8 +1,20 @@
1
1
  import { DirectBlock } from "@peerbit/blocks";
2
2
  import { DirectSub } from "@peerbit/pubsub";
3
3
  import { Peerbit } from "peerbit";
4
+ import path from "path";
5
+
6
+ export const LIBP2P_LISTEN_PORT = 8001;
7
+ export const create = (properties: {
8
+ directory?: string;
9
+ domain?: string;
10
+ listenPort?: number;
11
+ }) => {
12
+ const listenPort = properties.listenPort ?? LIBP2P_LISTEN_PORT;
13
+ const blocksDirectory =
14
+ properties.directory != null
15
+ ? path.join(properties.directory, "/blocks").toString()
16
+ : undefined;
4
17
 
5
- export const create = (properties: { directory?: string; domain?: string }) => {
6
18
  return Peerbit.create({
7
19
  libp2p: {
8
20
  addresses: {
@@ -12,14 +24,23 @@ export const create = (properties: { directory?: string; domain?: string }) => {
12
24
  `/dns4/${properties.domain}/tcp/4003/wss`,
13
25
  ]
14
26
  : undefined,
15
- listen: ["/ip4/127.0.0.1/tcp/8001", "/ip4/127.0.0.1/tcp/8002/ws"],
27
+ listen: [
28
+ `/ip4/127.0.0.1/tcp/${listenPort}`,
29
+ `/ip4/127.0.0.1/tcp/${
30
+ listenPort !== 0 ? listenPort + 1 : listenPort
31
+ }/ws`,
32
+ ],
16
33
  },
17
34
  connectionManager: {
18
35
  maxConnections: Infinity,
19
36
  minConnections: 0,
20
37
  },
21
38
  services: {
22
- blocks: (c) => new DirectBlock(c, { canRelayMessage: true }),
39
+ blocks: (c) =>
40
+ new DirectBlock(c, {
41
+ directory: blocksDirectory,
42
+ canRelayMessage: true,
43
+ }),
23
44
  pubsub: (c) => new DirectSub(c, { canRelayMessage: true }),
24
45
  },
25
46
  },
@@ -0,0 +1 @@
1
+ // Not supported
package/src/remotes.ts ADDED
@@ -0,0 +1,65 @@
1
+ import fs from "fs";
2
+
3
+ interface RemoteObject {
4
+ address: string;
5
+ name: string;
6
+ password: string;
7
+ }
8
+
9
+ interface RemotesObject {
10
+ remotes: RemoteObject[];
11
+ }
12
+
13
+ export class Remotes {
14
+ private data: RemotesObject;
15
+
16
+ constructor(readonly path: string) {
17
+ if (fs.existsSync(path)) {
18
+ this.data = JSON.parse(
19
+ fs.readFileSync(path).toString("utf-8")
20
+ ) as RemotesObject;
21
+ } else {
22
+ this.data = {
23
+ remotes: [],
24
+ };
25
+ }
26
+ }
27
+
28
+ save() {
29
+ fs.writeFileSync(this.path, JSON.stringify(this.data));
30
+ }
31
+
32
+ getByName(name: string) {
33
+ return this.data.remotes.find((x) => x.name === name);
34
+ }
35
+ getByAddress(address: string) {
36
+ return this.data.remotes.find((x) => x.address === address);
37
+ }
38
+ add(name: string, address: string, password: string) {
39
+ const obj: RemoteObject = {
40
+ address,
41
+ name,
42
+ password,
43
+ };
44
+ const existing = this.data.remotes.findIndex((x) => x.name === name);
45
+ if (existing >= 0) {
46
+ this.data.remotes[existing] = obj;
47
+ } else {
48
+ this.data.remotes.push(obj);
49
+ }
50
+ this.save();
51
+ }
52
+
53
+ remove(name: string) {
54
+ const existing = this.data.remotes.findIndex((x) => x.name === name);
55
+ if (existing >= 0) {
56
+ this.data.remotes.splice(existing, 1);
57
+ return true;
58
+ }
59
+ return false;
60
+ }
61
+
62
+ async all(): Promise<RemoteObject[]> {
63
+ return this.data.remotes;
64
+ }
65
+ }
package/src/routes.ts CHANGED
@@ -18,3 +18,5 @@ export const PROGRAM_PATH = "/program";
18
18
  export const PROGRAMS_PATH = "/programs";
19
19
  export const INSTALL_PATH = "/install";
20
20
  export const BOOTSTRAP_PATH = "/network/bootstrap";
21
+ export const RESTART_PATH = "/restart";
22
+ export const TERMINATE_PATH = "/terminate";