@hashgrid/sdk 0.2.8 → 0.3.1

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/README.md CHANGED
@@ -50,9 +50,6 @@ The SDK provides the following resources:
50
50
  - **`User`** - User data model
51
51
  - **`Quota`** - Quota data model
52
52
  - **`Message`** - Message for recv/send operations
53
- - Constructor: `new Message(peer_id, round, message = "", score = null)`
54
- - **`Status`** - Status response from send operations
55
- - Properties: `peer_id`, `round`, `success`
56
53
 
57
54
  ## Examples
58
55
 
package/dist/client.d.ts CHANGED
@@ -1,12 +1,13 @@
1
1
  /** Main Hashgrid client class. */
2
2
  import { Grid } from "./resources";
3
3
  export declare class Hashgrid {
4
- private api_key?;
5
- private base_url;
4
+ private apiKey?;
5
+ private baseUrl;
6
6
  private timeout;
7
- constructor(api_key?: string, base_url?: string, timeout?: number);
7
+ constructor(apiKey?: string, baseUrl?: string, timeout?: number);
8
8
  private _getHeaders;
9
- _request(method: string, endpoint: string, params?: Record<string, any>, json_data?: any): Promise<any>;
9
+ request(method: string, endpoint: string, params?: Record<string, any>, jsonData?: any): Promise<any>;
10
10
  _handleResponse(response: Response): Promise<any>;
11
- static connect(api_key?: string, base_url?: string, timeout?: number): Promise<Grid>;
11
+ stream(method: string, endpoint: string, params?: Record<string, any>, jsonData?: any): AsyncGenerator<string>;
12
+ static connect(apiKey?: string, baseUrl?: string, timeout?: number): Promise<Grid>;
12
13
  }
package/dist/client.js CHANGED
@@ -5,9 +5,9 @@ exports.Hashgrid = void 0;
5
5
  const exceptions_1 = require("./exceptions");
6
6
  const resources_1 = require("./resources");
7
7
  class Hashgrid {
8
- constructor(api_key, base_url = "https://dna.hashgrid.ai", timeout = 30000) {
9
- this.api_key = api_key;
10
- this.base_url = base_url.replace(/\/$/, "");
8
+ constructor(apiKey, baseUrl = "https://dna.hashgrid.ai", timeout = 30000) {
9
+ this.apiKey = apiKey;
10
+ this.baseUrl = baseUrl.replace(/\/$/, "");
11
11
  this.timeout = timeout;
12
12
  }
13
13
  _getHeaders() {
@@ -15,18 +15,18 @@ class Hashgrid {
15
15
  "Content-Type": "application/json",
16
16
  Accept: "application/json",
17
17
  };
18
- if (this.api_key) {
19
- headers["Authorization"] = `Bearer ${this.api_key}`;
18
+ if (this.apiKey) {
19
+ headers["Authorization"] = `Bearer ${this.apiKey}`;
20
20
  }
21
21
  return headers;
22
22
  }
23
- async _request(method, endpoint, params, json_data) {
23
+ async request(method, endpoint, params, jsonData) {
24
24
  let url;
25
25
  if (endpoint.startsWith("http://") || endpoint.startsWith("https://")) {
26
26
  url = endpoint;
27
27
  }
28
28
  else {
29
- const base = this.base_url.endsWith("/") ? this.base_url.slice(0, -1) : this.base_url;
29
+ const base = this.baseUrl.endsWith("/") ? this.baseUrl.slice(0, -1) : this.baseUrl;
30
30
  const path = endpoint.startsWith("/") ? endpoint : `/${endpoint}`;
31
31
  url = `${base}${path}`;
32
32
  }
@@ -45,8 +45,8 @@ class Hashgrid {
45
45
  headers,
46
46
  signal: controller.signal,
47
47
  };
48
- if (json_data !== undefined) {
49
- options.body = JSON.stringify(json_data);
48
+ if (jsonData !== undefined) {
49
+ options.body = JSON.stringify(jsonData);
50
50
  }
51
51
  try {
52
52
  const response = await fetch(url, options);
@@ -104,9 +104,58 @@ class Hashgrid {
104
104
  throw new exceptions_1.HashgridAPIError(`Response handling failed: ${error}`);
105
105
  }
106
106
  }
107
- static async connect(api_key, base_url = "https://dna.hashgrid.ai", timeout = 30000) {
108
- const client = new Hashgrid(api_key, base_url, timeout);
109
- const data = await client._request("GET", "/api/v1");
107
+ async *stream(method, endpoint, params, jsonData) {
108
+ const base = this.baseUrl.endsWith("/") ? this.baseUrl.slice(0, -1) : this.baseUrl;
109
+ const path = endpoint.startsWith("/") ? endpoint : `/${endpoint}`;
110
+ let url = `${base}${path}`;
111
+ if (params) {
112
+ const searchParams = new URLSearchParams();
113
+ Object.entries(params).forEach(([key, value]) => {
114
+ searchParams.append(key, String(value));
115
+ });
116
+ url += `?${searchParams.toString()}`;
117
+ }
118
+ const headers = this._getHeaders();
119
+ headers["Accept"] = "text/event-stream";
120
+ const options = {
121
+ method,
122
+ headers,
123
+ };
124
+ if (jsonData !== undefined) {
125
+ options.body = JSON.stringify(jsonData);
126
+ }
127
+ const response = await fetch(url, options);
128
+ if (!response.ok) {
129
+ throw new exceptions_1.HashgridAPIError(`SSE connection failed: ${response.status}`);
130
+ }
131
+ const reader = response.body?.getReader();
132
+ const decoder = new TextDecoder();
133
+ let buffer = "";
134
+ if (!reader) {
135
+ throw new exceptions_1.HashgridAPIError("Response body is not readable");
136
+ }
137
+ try {
138
+ while (true) {
139
+ const { done, value } = await reader.read();
140
+ if (done)
141
+ break;
142
+ buffer += decoder.decode(value, { stream: true });
143
+ const lines = buffer.split("\n\n");
144
+ buffer = lines.pop() || "";
145
+ for (const line of lines) {
146
+ if (line.startsWith("data: ")) {
147
+ yield line.slice(6).trim();
148
+ }
149
+ }
150
+ }
151
+ }
152
+ finally {
153
+ reader.releaseLock();
154
+ }
155
+ }
156
+ static async connect(apiKey, baseUrl = "https://dna.hashgrid.ai", timeout = 30000) {
157
+ const client = new Hashgrid(apiKey, baseUrl, timeout);
158
+ const data = await client.request("GET", "/api/v1");
110
159
  const grid = new resources_1.Grid(data.name, data.tick, client);
111
160
  return grid;
112
161
  }
@@ -3,16 +3,16 @@ export declare class HashgridError extends Error {
3
3
  constructor(message: string);
4
4
  }
5
5
  export declare class HashgridAPIError extends HashgridError {
6
- status_code?: number;
6
+ statusCode?: number;
7
7
  response?: Response;
8
- constructor(message: string, status_code?: number, response?: Response);
8
+ constructor(message: string, statusCode?: number, response?: Response);
9
9
  }
10
10
  export declare class HashgridAuthenticationError extends HashgridAPIError {
11
- constructor(message: string, status_code?: number, response?: Response);
11
+ constructor(message: string, statusCode?: number, response?: Response);
12
12
  }
13
13
  export declare class HashgridNotFoundError extends HashgridAPIError {
14
- constructor(message: string, status_code?: number, response?: Response);
14
+ constructor(message: string, statusCode?: number, response?: Response);
15
15
  }
16
16
  export declare class HashgridValidationError extends HashgridAPIError {
17
- constructor(message: string, status_code?: number, response?: Response);
17
+ constructor(message: string, statusCode?: number, response?: Response);
18
18
  }
@@ -11,34 +11,34 @@ class HashgridError extends Error {
11
11
  }
12
12
  exports.HashgridError = HashgridError;
13
13
  class HashgridAPIError extends HashgridError {
14
- constructor(message, status_code, response) {
14
+ constructor(message, statusCode, response) {
15
15
  super(message);
16
16
  this.name = "HashgridAPIError";
17
- this.status_code = status_code;
17
+ this.statusCode = statusCode;
18
18
  this.response = response;
19
19
  Object.setPrototypeOf(this, HashgridAPIError.prototype);
20
20
  }
21
21
  }
22
22
  exports.HashgridAPIError = HashgridAPIError;
23
23
  class HashgridAuthenticationError extends HashgridAPIError {
24
- constructor(message, status_code, response) {
25
- super(message, status_code, response);
24
+ constructor(message, statusCode, response) {
25
+ super(message, statusCode, response);
26
26
  this.name = "HashgridAuthenticationError";
27
27
  Object.setPrototypeOf(this, HashgridAuthenticationError.prototype);
28
28
  }
29
29
  }
30
30
  exports.HashgridAuthenticationError = HashgridAuthenticationError;
31
31
  class HashgridNotFoundError extends HashgridAPIError {
32
- constructor(message, status_code, response) {
33
- super(message, status_code, response);
32
+ constructor(message, statusCode, response) {
33
+ super(message, statusCode, response);
34
34
  this.name = "HashgridNotFoundError";
35
35
  Object.setPrototypeOf(this, HashgridNotFoundError.prototype);
36
36
  }
37
37
  }
38
38
  exports.HashgridNotFoundError = HashgridNotFoundError;
39
39
  class HashgridValidationError extends HashgridAPIError {
40
- constructor(message, status_code, response) {
41
- super(message, status_code, response);
40
+ constructor(message, statusCode, response) {
41
+ super(message, statusCode, response);
42
42
  this.name = "HashgridValidationError";
43
43
  Object.setPrototypeOf(this, HashgridValidationError.prototype);
44
44
  }
@@ -1,59 +1,59 @@
1
1
  /** Hashgrid API resources. */
2
2
  import { Hashgrid } from "./client";
3
3
  export declare class User {
4
- user_id: string;
4
+ userId: string;
5
5
  name: string;
6
- is_superuser: boolean;
7
- quota_id: string;
8
- constructor(user_id: string, name: string, is_superuser: boolean, quota_id: string);
6
+ isSuperuser: boolean;
7
+ quotaId: string;
8
+ constructor(userId: string, name: string, isSuperuser: boolean, quotaId: string);
9
9
  }
10
10
  export declare class Quota {
11
- quota_id: string;
11
+ quotaId: string;
12
12
  name: string;
13
13
  capacity: number;
14
- constructor(quota_id: string, name: string, capacity: number);
14
+ constructor(quotaId: string, name: string, capacity: number);
15
15
  }
16
16
  export declare class Edge {
17
- node_id: string;
18
- peer_id: string;
19
- recv_message: string;
20
- send_message: string | null;
17
+ nodeId: string;
18
+ peerId: string;
19
+ recvMessage: string;
20
+ sendMessage: string | null;
21
21
  score: number | null;
22
22
  round: number;
23
- constructor(node_id: string, peer_id: string, recv_message: string, send_message: string | null, score: number | null, round: number);
23
+ constructor(nodeId: string, peerId: string, recvMessage: string, sendMessage: string | null, score: number | null, round: number);
24
24
  }
25
25
  export declare class Message {
26
- peer_id: string;
26
+ peerId: string;
27
27
  round: number;
28
28
  message: string;
29
29
  score: number | null;
30
- constructor(peer_id: string, round: number, message?: string, score?: number | null);
30
+ constructor(peerId: string, round: number, message?: string, score?: number | null);
31
31
  }
32
32
  export declare class Status {
33
- peer_id: string;
33
+ peerId: string;
34
34
  round: number;
35
35
  success: boolean;
36
- constructor(peer_id: string, round: number, success: boolean);
36
+ constructor(peerId: string, round: number, success: boolean);
37
37
  }
38
38
  export declare class Grid {
39
39
  name: string;
40
40
  tick: number;
41
41
  private _client;
42
42
  constructor(name: string, tick: number, client: Hashgrid);
43
- listen(poll_interval?: number): AsyncGenerator<number>;
43
+ listen(): AsyncGenerator<number>;
44
44
  nodes(): AsyncGenerator<Node>;
45
- create_node(name: string, message?: string, capacity?: number): Promise<Node>;
45
+ createNode(name: string, message?: string, capacity?: number): Promise<Node>;
46
46
  }
47
47
  export declare class Node {
48
- node_id: string;
49
- owner_id: string;
48
+ nodeId: string;
49
+ ownerId: string;
50
50
  name: string;
51
51
  message: string;
52
52
  capacity: number;
53
53
  private _client;
54
- constructor(node_id: string, owner_id: string, name: string, message: string, capacity: number, client: Hashgrid);
54
+ constructor(nodeId: string, ownerId: string, name: string, message: string, capacity: number, client: Hashgrid);
55
55
  recv(): Promise<Message[]>;
56
- send(replies: Message[]): Promise<Status[]>;
56
+ send(replies: Message[]): Promise<Message[]>;
57
57
  update(name?: string, message?: string, capacity?: number): Promise<Node>;
58
58
  delete(): Promise<void>;
59
59
  }
package/dist/resources.js CHANGED
@@ -3,36 +3,36 @@
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
4
  exports.Node = exports.Grid = exports.Status = exports.Message = exports.Edge = exports.Quota = exports.User = void 0;
5
5
  class User {
6
- constructor(user_id, name, is_superuser, quota_id) {
7
- this.user_id = user_id;
6
+ constructor(userId, name, isSuperuser, quotaId) {
7
+ this.userId = userId;
8
8
  this.name = name;
9
- this.is_superuser = is_superuser;
10
- this.quota_id = quota_id;
9
+ this.isSuperuser = isSuperuser;
10
+ this.quotaId = quotaId;
11
11
  }
12
12
  }
13
13
  exports.User = User;
14
14
  class Quota {
15
- constructor(quota_id, name, capacity) {
16
- this.quota_id = quota_id;
15
+ constructor(quotaId, name, capacity) {
16
+ this.quotaId = quotaId;
17
17
  this.name = name;
18
18
  this.capacity = capacity;
19
19
  }
20
20
  }
21
21
  exports.Quota = Quota;
22
22
  class Edge {
23
- constructor(node_id, peer_id, recv_message, send_message, score, round) {
24
- this.node_id = node_id;
25
- this.peer_id = peer_id;
26
- this.recv_message = recv_message;
27
- this.send_message = send_message;
23
+ constructor(nodeId, peerId, recvMessage, sendMessage, score, round) {
24
+ this.nodeId = nodeId;
25
+ this.peerId = peerId;
26
+ this.recvMessage = recvMessage;
27
+ this.sendMessage = sendMessage;
28
28
  this.score = score;
29
29
  this.round = round;
30
30
  }
31
31
  }
32
32
  exports.Edge = Edge;
33
33
  class Message {
34
- constructor(peer_id, round, message = "", score = null) {
35
- this.peer_id = peer_id;
34
+ constructor(peerId, round, message = "", score = null) {
35
+ this.peerId = peerId;
36
36
  this.round = round;
37
37
  this.message = message;
38
38
  this.score = score;
@@ -40,8 +40,8 @@ class Message {
40
40
  }
41
41
  exports.Message = Message;
42
42
  class Status {
43
- constructor(peer_id, round, success) {
44
- this.peer_id = peer_id;
43
+ constructor(peerId, round, success) {
44
+ this.peerId = peerId;
45
45
  this.round = round;
46
46
  this.success = success;
47
47
  }
@@ -53,56 +53,45 @@ class Grid {
53
53
  this.tick = tick;
54
54
  this._client = client;
55
55
  }
56
- async *listen(poll_interval = 30000) {
57
- let last_tick = -1;
58
- while (true) {
59
- try {
60
- const data = await this._client._request("GET", "/api/v1");
61
- this.name = data.name;
62
- this.tick = data.tick;
63
- const current_tick = this.tick;
64
- if (current_tick !== last_tick) {
65
- yield current_tick;
66
- last_tick = current_tick;
67
- }
68
- await new Promise((resolve) => setTimeout(resolve, poll_interval));
69
- }
70
- catch (error) {
71
- console.warn(`Error while listening for ticks: ${error}`);
72
- await new Promise((resolve) => setTimeout(resolve, poll_interval * 2));
56
+ async *listen() {
57
+ for await (const data of this._client.stream("GET", "/api/v1/listen")) {
58
+ const tick = parseInt(data, 10);
59
+ if (!isNaN(tick) && tick !== this.tick) {
60
+ this.tick = tick;
61
+ yield tick;
73
62
  }
74
63
  }
75
64
  }
76
65
  async *nodes() {
77
- const data = await this._client._request("GET", "/api/v1/node");
66
+ const data = await this._client.request("GET", "/api/v1/node");
78
67
  for (const item of data) {
79
- yield new Node(item.node_id, item.owner_id, item.name, item.message, item.capacity, this._client);
68
+ yield new Node(item.node_id || item.nodeId, item.owner_id || item.ownerId, item.name, item.message, item.capacity, this._client);
80
69
  }
81
70
  }
82
- async create_node(name, message = "", capacity = 100) {
83
- const json_data = { name, message, capacity };
84
- const data = await this._client._request("POST", "/api/v1/node", undefined, json_data);
85
- return new Node(data.node_id, data.owner_id, data.name, data.message, data.capacity, this._client);
71
+ async createNode(name, message = "", capacity = 100) {
72
+ const jsonData = { name, message, capacity };
73
+ const data = await this._client.request("POST", "/api/v1/node", undefined, jsonData);
74
+ return new Node(data.node_id || data.nodeId, data.owner_id || data.ownerId, data.name, data.message, data.capacity, this._client);
86
75
  }
87
76
  }
88
77
  exports.Grid = Grid;
89
78
  class Node {
90
- constructor(node_id, owner_id, name, message, capacity, client) {
91
- this.node_id = node_id;
92
- this.owner_id = owner_id;
79
+ constructor(nodeId, ownerId, name, message, capacity, client) {
80
+ this.nodeId = nodeId;
81
+ this.ownerId = ownerId;
93
82
  this.name = name;
94
83
  this.message = message;
95
84
  this.capacity = capacity;
96
85
  this._client = client;
97
86
  }
98
87
  async recv() {
99
- const data = await this._client._request("GET", `/api/v1/node/${this.node_id}/recv`);
100
- return data.map((item) => new Message(item.peer_id, item.round, item.message, item.score ?? null));
88
+ const data = await this._client.request("GET", `/api/v1/node/${this.nodeId}/recv`);
89
+ return data.map((item) => new Message(item.peer_id || item.peerId, item.round, item.message, item.score ?? null));
101
90
  }
102
91
  async send(replies) {
103
- const json_data = replies.map((msg) => {
92
+ const jsonData = replies.map((msg) => {
104
93
  const obj = {
105
- peer_id: msg.peer_id,
94
+ peer_id: msg.peerId,
106
95
  message: msg.message,
107
96
  round: msg.round,
108
97
  };
@@ -111,21 +100,21 @@ class Node {
111
100
  }
112
101
  return obj;
113
102
  });
114
- const data = await this._client._request("POST", `/api/v1/node/${this.node_id}/send`, undefined, json_data);
115
- return data.map((item) => new Status(item.peer_id, item.round, item.success));
103
+ const data = await this._client.request("POST", `/api/v1/node/${this.nodeId}/send`, undefined, jsonData);
104
+ return data.map((item) => new Message(item.peer_id || item.peerId, item.round, item.message, item.score ?? null));
116
105
  }
117
106
  async update(name, message, capacity) {
118
- const json_data = {};
107
+ const jsonData = {};
119
108
  if (name !== undefined)
120
- json_data.name = name;
109
+ jsonData.name = name;
121
110
  if (message !== undefined)
122
- json_data.message = message;
111
+ jsonData.message = message;
123
112
  if (capacity !== undefined)
124
- json_data.capacity = capacity;
125
- if (Object.keys(json_data).length === 0) {
113
+ jsonData.capacity = capacity;
114
+ if (Object.keys(jsonData).length === 0) {
126
115
  return this;
127
116
  }
128
- const data = await this._client._request("PUT", `/api/v1/node/${this.node_id}`, undefined, json_data);
117
+ const data = await this._client.request("PUT", `/api/v1/node/${this.nodeId}`, undefined, jsonData);
129
118
  // Update local attributes
130
119
  if (data.name !== undefined)
131
120
  this.name = data.name;
@@ -136,7 +125,7 @@ class Node {
136
125
  return this;
137
126
  }
138
127
  async delete() {
139
- await this._client._request("DELETE", `/api/v1/node/${this.node_id}`);
128
+ await this._client.request("DELETE", `/api/v1/node/${this.nodeId}`);
140
129
  }
141
130
  }
142
131
  exports.Node = Node;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hashgrid/sdk",
3
- "version": "0.2.8",
3
+ "version": "0.3.1",
4
4
  "description": "Hashgrid TypeScript/JavaScript SDK",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
package/src/client.ts CHANGED
@@ -9,17 +9,17 @@ import {
9
9
  import { Grid } from "./resources";
10
10
 
11
11
  export class Hashgrid {
12
- private api_key?: string;
13
- private base_url: string;
12
+ private apiKey?: string;
13
+ private baseUrl: string;
14
14
  private timeout: number;
15
15
 
16
16
  constructor(
17
- api_key?: string,
18
- base_url: string = "https://dna.hashgrid.ai",
17
+ apiKey?: string,
18
+ baseUrl: string = "https://dna.hashgrid.ai",
19
19
  timeout: number = 30000
20
20
  ) {
21
- this.api_key = api_key;
22
- this.base_url = base_url.replace(/\/$/, "");
21
+ this.apiKey = apiKey;
22
+ this.baseUrl = baseUrl.replace(/\/$/, "");
23
23
  this.timeout = timeout;
24
24
  }
25
25
 
@@ -28,23 +28,23 @@ export class Hashgrid {
28
28
  "Content-Type": "application/json",
29
29
  Accept: "application/json",
30
30
  };
31
- if (this.api_key) {
32
- headers["Authorization"] = `Bearer ${this.api_key}`;
31
+ if (this.apiKey) {
32
+ headers["Authorization"] = `Bearer ${this.apiKey}`;
33
33
  }
34
34
  return headers;
35
35
  }
36
36
 
37
- async _request(
37
+ async request(
38
38
  method: string,
39
39
  endpoint: string,
40
40
  params?: Record<string, any>,
41
- json_data?: any
41
+ jsonData?: any
42
42
  ): Promise<any> {
43
43
  let url: string;
44
44
  if (endpoint.startsWith("http://") || endpoint.startsWith("https://")) {
45
45
  url = endpoint;
46
46
  } else {
47
- const base = this.base_url.endsWith("/") ? this.base_url.slice(0, -1) : this.base_url;
47
+ const base = this.baseUrl.endsWith("/") ? this.baseUrl.slice(0, -1) : this.baseUrl;
48
48
  const path = endpoint.startsWith("/") ? endpoint : `/${endpoint}`;
49
49
  url = `${base}${path}`;
50
50
  }
@@ -72,8 +72,8 @@ export class Hashgrid {
72
72
  signal: controller.signal,
73
73
  };
74
74
 
75
- if (json_data !== undefined) {
76
- options.body = JSON.stringify(json_data);
75
+ if (jsonData !== undefined) {
76
+ options.body = JSON.stringify(jsonData);
77
77
  }
78
78
 
79
79
  try {
@@ -148,15 +148,82 @@ export class Hashgrid {
148
148
  }
149
149
  }
150
150
 
151
+ async *stream(
152
+ method: string,
153
+ endpoint: string,
154
+ params?: Record<string, any>,
155
+ jsonData?: any
156
+ ): AsyncGenerator<string> {
157
+ const base = this.baseUrl.endsWith("/") ? this.baseUrl.slice(0, -1) : this.baseUrl;
158
+ const path = endpoint.startsWith("/") ? endpoint : `/${endpoint}`;
159
+ let url = `${base}${path}`;
160
+
161
+ if (params) {
162
+ const searchParams = new URLSearchParams();
163
+ Object.entries(params).forEach(([key, value]) => {
164
+ searchParams.append(key, String(value));
165
+ });
166
+ url += `?${searchParams.toString()}`;
167
+ }
168
+
169
+ const headers = this._getHeaders();
170
+ headers["Accept"] = "text/event-stream";
171
+
172
+ const options: {
173
+ method: string;
174
+ headers: Record<string, string>;
175
+ body?: string;
176
+ } = {
177
+ method,
178
+ headers,
179
+ };
180
+
181
+ if (jsonData !== undefined) {
182
+ options.body = JSON.stringify(jsonData);
183
+ }
184
+
185
+ const response = await fetch(url, options);
186
+
187
+ if (!response.ok) {
188
+ throw new HashgridAPIError(`SSE connection failed: ${response.status}`);
189
+ }
190
+
191
+ const reader = response.body?.getReader();
192
+ const decoder = new TextDecoder();
193
+ let buffer = "";
194
+
195
+ if (!reader) {
196
+ throw new HashgridAPIError("Response body is not readable");
197
+ }
198
+
199
+ try {
200
+ while (true) {
201
+ const { done, value } = await reader.read();
202
+ if (done) break;
203
+
204
+ buffer += decoder.decode(value, { stream: true });
205
+ const lines = buffer.split("\n\n");
206
+ buffer = lines.pop() || "";
207
+
208
+ for (const line of lines) {
209
+ if (line.startsWith("data: ")) {
210
+ yield line.slice(6).trim();
211
+ }
212
+ }
213
+ }
214
+ } finally {
215
+ reader.releaseLock();
216
+ }
217
+ }
218
+
151
219
  static async connect(
152
- api_key?: string,
153
- base_url: string = "https://dna.hashgrid.ai",
220
+ apiKey?: string,
221
+ baseUrl: string = "https://dna.hashgrid.ai",
154
222
  timeout: number = 30000
155
223
  ): Promise<Grid> {
156
- const client = new Hashgrid(api_key, base_url, timeout);
157
- const data = await client._request("GET", "/api/v1");
224
+ const client = new Hashgrid(apiKey, baseUrl, timeout);
225
+ const data = await client.request("GET", "/api/v1");
158
226
  const grid = new Grid(data.name, data.tick, client);
159
227
  return grid;
160
228
  }
161
229
  }
162
-
package/src/exceptions.ts CHANGED
@@ -9,39 +9,38 @@ export class HashgridError extends Error {
9
9
  }
10
10
 
11
11
  export class HashgridAPIError extends HashgridError {
12
- status_code?: number;
12
+ statusCode?: number;
13
13
  response?: Response;
14
14
 
15
- constructor(message: string, status_code?: number, response?: Response) {
15
+ constructor(message: string, statusCode?: number, response?: Response) {
16
16
  super(message);
17
17
  this.name = "HashgridAPIError";
18
- this.status_code = status_code;
18
+ this.statusCode = statusCode;
19
19
  this.response = response;
20
20
  Object.setPrototypeOf(this, HashgridAPIError.prototype);
21
21
  }
22
22
  }
23
23
 
24
24
  export class HashgridAuthenticationError extends HashgridAPIError {
25
- constructor(message: string, status_code?: number, response?: Response) {
26
- super(message, status_code, response);
25
+ constructor(message: string, statusCode?: number, response?: Response) {
26
+ super(message, statusCode, response);
27
27
  this.name = "HashgridAuthenticationError";
28
28
  Object.setPrototypeOf(this, HashgridAuthenticationError.prototype);
29
29
  }
30
30
  }
31
31
 
32
32
  export class HashgridNotFoundError extends HashgridAPIError {
33
- constructor(message: string, status_code?: number, response?: Response) {
34
- super(message, status_code, response);
33
+ constructor(message: string, statusCode?: number, response?: Response) {
34
+ super(message, statusCode, response);
35
35
  this.name = "HashgridNotFoundError";
36
36
  Object.setPrototypeOf(this, HashgridNotFoundError.prototype);
37
37
  }
38
38
  }
39
39
 
40
40
  export class HashgridValidationError extends HashgridAPIError {
41
- constructor(message: string, status_code?: number, response?: Response) {
42
- super(message, status_code, response);
41
+ constructor(message: string, statusCode?: number, response?: Response) {
42
+ super(message, statusCode, response);
43
43
  this.name = "HashgridValidationError";
44
44
  Object.setPrototypeOf(this, HashgridValidationError.prototype);
45
45
  }
46
46
  }
47
-
package/src/resources.ts CHANGED
@@ -3,74 +3,74 @@
3
3
  import { Hashgrid } from "./client";
4
4
 
5
5
  export class User {
6
- user_id: string;
6
+ userId: string;
7
7
  name: string;
8
- is_superuser: boolean;
9
- quota_id: string;
8
+ isSuperuser: boolean;
9
+ quotaId: string;
10
10
 
11
11
  constructor(
12
- user_id: string,
12
+ userId: string,
13
13
  name: string,
14
- is_superuser: boolean,
15
- quota_id: string
14
+ isSuperuser: boolean,
15
+ quotaId: string
16
16
  ) {
17
- this.user_id = user_id;
17
+ this.userId = userId;
18
18
  this.name = name;
19
- this.is_superuser = is_superuser;
20
- this.quota_id = quota_id;
19
+ this.isSuperuser = isSuperuser;
20
+ this.quotaId = quotaId;
21
21
  }
22
22
  }
23
23
 
24
24
  export class Quota {
25
- quota_id: string;
25
+ quotaId: string;
26
26
  name: string;
27
27
  capacity: number;
28
28
 
29
- constructor(quota_id: string, name: string, capacity: number) {
30
- this.quota_id = quota_id;
29
+ constructor(quotaId: string, name: string, capacity: number) {
30
+ this.quotaId = quotaId;
31
31
  this.name = name;
32
32
  this.capacity = capacity;
33
33
  }
34
34
  }
35
35
 
36
36
  export class Edge {
37
- node_id: string;
38
- peer_id: string;
39
- recv_message: string;
40
- send_message: string | null;
37
+ nodeId: string;
38
+ peerId: string;
39
+ recvMessage: string;
40
+ sendMessage: string | null;
41
41
  score: number | null;
42
42
  round: number;
43
43
 
44
44
  constructor(
45
- node_id: string,
46
- peer_id: string,
47
- recv_message: string,
48
- send_message: string | null,
45
+ nodeId: string,
46
+ peerId: string,
47
+ recvMessage: string,
48
+ sendMessage: string | null,
49
49
  score: number | null,
50
50
  round: number
51
51
  ) {
52
- this.node_id = node_id;
53
- this.peer_id = peer_id;
54
- this.recv_message = recv_message;
55
- this.send_message = send_message;
52
+ this.nodeId = nodeId;
53
+ this.peerId = peerId;
54
+ this.recvMessage = recvMessage;
55
+ this.sendMessage = sendMessage;
56
56
  this.score = score;
57
57
  this.round = round;
58
58
  }
59
59
  }
60
60
 
61
61
  export class Message {
62
- peer_id: string;
62
+ peerId: string;
63
63
  round: number;
64
64
  message: string;
65
65
  score: number | null;
66
66
 
67
67
  constructor(
68
- peer_id: string,
68
+ peerId: string,
69
69
  round: number,
70
70
  message: string = "",
71
71
  score: number | null = null
72
72
  ) {
73
- this.peer_id = peer_id;
73
+ this.peerId = peerId;
74
74
  this.round = round;
75
75
  this.message = message;
76
76
  this.score = score;
@@ -78,12 +78,12 @@ export class Message {
78
78
  }
79
79
 
80
80
  export class Status {
81
- peer_id: string;
81
+ peerId: string;
82
82
  round: number;
83
83
  success: boolean;
84
84
 
85
- constructor(peer_id: string, round: number, success: boolean) {
86
- this.peer_id = peer_id;
85
+ constructor(peerId: string, round: number, success: boolean) {
86
+ this.peerId = peerId;
87
87
  this.round = round;
88
88
  this.success = success;
89
89
  }
@@ -100,34 +100,22 @@ export class Grid {
100
100
  this._client = client;
101
101
  }
102
102
 
103
- async *listen(poll_interval: number = 30000): AsyncGenerator<number> {
104
- let last_tick = -1;
105
- while (true) {
106
- try {
107
- const data = await this._client._request("GET", "/api/v1");
108
- this.name = data.name;
109
- this.tick = data.tick;
110
- const current_tick = this.tick;
111
-
112
- if (current_tick !== last_tick) {
113
- yield current_tick;
114
- last_tick = current_tick;
115
- }
116
-
117
- await new Promise((resolve) => setTimeout(resolve, poll_interval));
118
- } catch (error) {
119
- console.warn(`Error while listening for ticks: ${error}`);
120
- await new Promise((resolve) => setTimeout(resolve, poll_interval * 2));
103
+ async *listen(): AsyncGenerator<number> {
104
+ for await (const data of this._client.stream("GET", "/api/v1/listen")) {
105
+ const tick = parseInt(data, 10);
106
+ if (!isNaN(tick) && tick !== this.tick) {
107
+ this.tick = tick;
108
+ yield tick;
121
109
  }
122
110
  }
123
111
  }
124
112
 
125
113
  async *nodes(): AsyncGenerator<Node> {
126
- const data = await this._client._request("GET", "/api/v1/node");
114
+ const data = await this._client.request("GET", "/api/v1/node");
127
115
  for (const item of data) {
128
116
  yield new Node(
129
- item.node_id,
130
- item.owner_id,
117
+ item.node_id || item.nodeId,
118
+ item.owner_id || item.ownerId,
131
119
  item.name,
132
120
  item.message,
133
121
  item.capacity,
@@ -136,16 +124,16 @@ export class Grid {
136
124
  }
137
125
  }
138
126
 
139
- async create_node(
127
+ async createNode(
140
128
  name: string,
141
129
  message: string = "",
142
130
  capacity: number = 100
143
131
  ): Promise<Node> {
144
- const json_data = { name, message, capacity };
145
- const data = await this._client._request("POST", "/api/v1/node", undefined, json_data);
132
+ const jsonData = { name, message, capacity };
133
+ const data = await this._client.request("POST", "/api/v1/node", undefined, jsonData);
146
134
  return new Node(
147
- data.node_id,
148
- data.owner_id,
135
+ data.node_id || data.nodeId,
136
+ data.owner_id || data.ownerId,
149
137
  data.name,
150
138
  data.message,
151
139
  data.capacity,
@@ -155,23 +143,23 @@ export class Grid {
155
143
  }
156
144
 
157
145
  export class Node {
158
- node_id: string;
159
- owner_id: string;
146
+ nodeId: string;
147
+ ownerId: string;
160
148
  name: string;
161
149
  message: string;
162
150
  capacity: number;
163
151
  private _client: Hashgrid;
164
152
 
165
153
  constructor(
166
- node_id: string,
167
- owner_id: string,
154
+ nodeId: string,
155
+ ownerId: string,
168
156
  name: string,
169
157
  message: string,
170
158
  capacity: number,
171
159
  client: Hashgrid
172
160
  ) {
173
- this.node_id = node_id;
174
- this.owner_id = owner_id;
161
+ this.nodeId = nodeId;
162
+ this.ownerId = ownerId;
175
163
  this.name = name;
176
164
  this.message = message;
177
165
  this.capacity = capacity;
@@ -179,20 +167,20 @@ export class Node {
179
167
  }
180
168
 
181
169
  async recv(): Promise<Message[]> {
182
- const data = await this._client._request(
170
+ const data = await this._client.request(
183
171
  "GET",
184
- `/api/v1/node/${this.node_id}/recv`
172
+ `/api/v1/node/${this.nodeId}/recv`
185
173
  );
186
174
  return data.map(
187
175
  (item: any) =>
188
- new Message(item.peer_id, item.round, item.message, item.score ?? null)
176
+ new Message(item.peer_id || item.peerId, item.round, item.message, item.score ?? null)
189
177
  );
190
178
  }
191
179
 
192
- async send(replies: Message[]): Promise<Status[]> {
193
- const json_data = replies.map((msg) => {
180
+ async send(replies: Message[]): Promise<Message[]> {
181
+ const jsonData = replies.map((msg) => {
194
182
  const obj: any = {
195
- peer_id: msg.peer_id,
183
+ peer_id: msg.peerId,
196
184
  message: msg.message,
197
185
  round: msg.round,
198
186
  };
@@ -201,13 +189,16 @@ export class Node {
201
189
  }
202
190
  return obj;
203
191
  });
204
- const data = await this._client._request(
192
+ const data = await this._client.request(
205
193
  "POST",
206
- `/api/v1/node/${this.node_id}/send`,
194
+ `/api/v1/node/${this.nodeId}/send`,
207
195
  undefined,
208
- json_data
196
+ jsonData
197
+ );
198
+ return data.map(
199
+ (item: any) =>
200
+ new Message(item.peer_id || item.peerId, item.round, item.message, item.score ?? null)
209
201
  );
210
- return data.map((item: any) => new Status(item.peer_id, item.round, item.success));
211
202
  }
212
203
 
213
204
  async update(
@@ -215,20 +206,20 @@ export class Node {
215
206
  message?: string,
216
207
  capacity?: number
217
208
  ): Promise<Node> {
218
- const json_data: any = {};
219
- if (name !== undefined) json_data.name = name;
220
- if (message !== undefined) json_data.message = message;
221
- if (capacity !== undefined) json_data.capacity = capacity;
209
+ const jsonData: any = {};
210
+ if (name !== undefined) jsonData.name = name;
211
+ if (message !== undefined) jsonData.message = message;
212
+ if (capacity !== undefined) jsonData.capacity = capacity;
222
213
 
223
- if (Object.keys(json_data).length === 0) {
214
+ if (Object.keys(jsonData).length === 0) {
224
215
  return this;
225
216
  }
226
217
 
227
- const data = await this._client._request(
218
+ const data = await this._client.request(
228
219
  "PUT",
229
- `/api/v1/node/${this.node_id}`,
220
+ `/api/v1/node/${this.nodeId}`,
230
221
  undefined,
231
- json_data
222
+ jsonData
232
223
  );
233
224
 
234
225
  // Update local attributes
@@ -240,7 +231,6 @@ export class Node {
240
231
  }
241
232
 
242
233
  async delete(): Promise<void> {
243
- await this._client._request("DELETE", `/api/v1/node/${this.node_id}`);
234
+ await this._client.request("DELETE", `/api/v1/node/${this.nodeId}`);
244
235
  }
245
236
  }
246
-