@thingd/sdk 0.37.10 → 0.38.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.
@@ -5,7 +5,7 @@ type LocalSortBy = {
5
5
  field: SortField;
6
6
  direction?: SortDirection;
7
7
  };
8
- export declare function readBody(req: IncomingMessage): Promise<string>;
8
+ export declare function readBody(req: IncomingMessage, maxSize?: number): Promise<string>;
9
9
  export declare function sendJson(res: ServerResponse, status: number, data: unknown): void;
10
10
  export declare function sendData(res: ServerResponse, data: unknown): void;
11
11
  export declare function sendDataList(res: ServerResponse, data: unknown[], total?: number): void;
@@ -1 +1 @@
1
- {"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../src/rest/helpers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAEjE,KAAK,SAAS,GAAG,IAAI,GAAG,YAAY,GAAG,YAAY,GAAG,YAAY,GAAG,SAAS,CAAC;AAC/E,KAAK,aAAa,GAAG,KAAK,GAAG,MAAM,CAAC;AAEpC,KAAK,WAAW,GAAG;IACjB,KAAK,EAAE,SAAS,CAAC;IACjB,SAAS,CAAC,EAAE,aAAa,CAAC;CAC3B,CAAC;AAEF,wBAAgB,QAAQ,CAAC,GAAG,EAAE,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC,CAS9D;AAED,wBAAgB,QAAQ,CAAC,GAAG,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,IAAI,CAGjF;AAED,wBAAgB,QAAQ,CAAC,GAAG,EAAE,cAAc,EAAE,IAAI,EAAE,OAAO,GAAG,IAAI,CAEjE;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,cAAc,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAEvF;AAED,wBAAgB,SAAS,CACvB,GAAG,EAAE,cAAc,EACnB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,GACd,IAAI,CAEN;AAED,wBAAgB,WAAW,CAAC,MAAM,EAAE,eAAe,GAAG,WAAW,GAAG,SAAS,CAY5E;AAED,wBAAgB,WAAW,CAAC,MAAM,EAAE,eAAe,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAWxF;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,GAAG,SAAS,CAMtE"}
1
+ {"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../src/rest/helpers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAEjE,KAAK,SAAS,GAAG,IAAI,GAAG,YAAY,GAAG,YAAY,GAAG,YAAY,GAAG,SAAS,CAAC;AAC/E,KAAK,aAAa,GAAG,KAAK,GAAG,MAAM,CAAC;AAEpC,KAAK,WAAW,GAAG;IACjB,KAAK,EAAE,SAAS,CAAC;IACjB,SAAS,CAAC,EAAE,aAAa,CAAC;CAC3B,CAAC;AAIF,wBAAgB,QAAQ,CAAC,GAAG,EAAE,eAAe,EAAE,OAAO,SAAgB,GAAG,OAAO,CAAC,MAAM,CAAC,CAavF;AAED,wBAAgB,QAAQ,CAAC,GAAG,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,IAAI,CAGjF;AAED,wBAAgB,QAAQ,CAAC,GAAG,EAAE,cAAc,EAAE,IAAI,EAAE,OAAO,GAAG,IAAI,CAEjE;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,cAAc,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAEvF;AAED,wBAAgB,SAAS,CACvB,GAAG,EAAE,cAAc,EACnB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,GACd,IAAI,CAEN;AAED,wBAAgB,WAAW,CAAC,MAAM,EAAE,eAAe,GAAG,WAAW,GAAG,SAAS,CAY5E;AAED,wBAAgB,WAAW,CAAC,MAAM,EAAE,eAAe,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAWxF;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,GAAG,SAAS,CAMtE"}
@@ -1,8 +1,13 @@
1
- export function readBody(req) {
1
+ const MAX_BODY_SIZE = 524_288; // 512KB
2
+ export function readBody(req, maxSize = MAX_BODY_SIZE) {
2
3
  return new Promise((resolve, reject) => {
3
4
  let body = "";
4
5
  req.on("data", (chunk) => {
5
6
  body += chunk.toString();
7
+ if (body.length > maxSize) {
8
+ req.destroy(new Error(`Request body exceeds ${maxSize} bytes`));
9
+ reject(new Error(`Request body exceeds ${maxSize} bytes`));
10
+ }
6
11
  });
7
12
  req.on("end", () => resolve(body));
8
13
  req.on("error", reject);
@@ -49,6 +49,7 @@ export declare class CloudThingStore implements ThingStore {
49
49
  };
50
50
  private callTool;
51
51
  private restBaseUrl;
52
+ private authHeaders;
52
53
  private restGet;
53
54
  private restPost;
54
55
  private restDelete;
@@ -1 +1 @@
1
- {"version":3,"file":"cloud-thing-store.d.ts","sourceRoot":"","sources":["../../src/stores/cloud-thing-store.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cloud-thing-store.d.ts","sourceRoot":"","sources":["../../src/stores/cloud-thing-store.ts"],"names":[],"mappings":"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"}
@@ -163,31 +163,15 @@ export class CloudThingStore {
163
163
  return this.callTool("thing_count_dead_jobs", {});
164
164
  }
165
165
  async countLinks() {
166
- try {
167
- const res = (await this.restGet("/v1/counts/links"));
168
- return res.data?.count ?? 0;
169
- }
170
- catch {
171
- return 0;
172
- }
166
+ const res = (await this.restGet("/v1/counts/links"));
167
+ return res.data?.count ?? 0;
173
168
  }
174
169
  async putBatch(collection, objects) {
175
- const results = [];
176
- for (const obj of objects) {
177
- const result = await this.put(collection, obj);
178
- results.push(result);
179
- }
180
- return results;
170
+ return Promise.all(objects.map((obj) => this.put(collection, obj)));
181
171
  }
182
172
  async deleteBatch(collection, ids) {
183
- let count = 0;
184
- for (const id of ids) {
185
- const deleted = await this.delete(collection, id);
186
- if (deleted) {
187
- count++;
188
- }
189
- }
190
- return count;
173
+ const results = await Promise.all(ids.map((id) => this.delete(collection, id)));
174
+ return results.filter(Boolean).length;
191
175
  }
192
176
  async createLink(fromRef, linkType, toRef, weight, metadataJson) {
193
177
  const body = { fromRef, linkType, toRef };
@@ -205,8 +189,11 @@ export class CloudThingStore {
205
189
  await this.restDelete(`/v1/links/${encodeURIComponent(id)}`);
206
190
  return true;
207
191
  }
208
- catch {
209
- return false;
192
+ catch (err) {
193
+ if (err instanceof Error && err.message.includes("404")) {
194
+ return false;
195
+ }
196
+ throw err;
210
197
  }
211
198
  }
212
199
  async getLink(id) {
@@ -214,8 +201,11 @@ export class CloudThingStore {
214
201
  const res = (await this.restGet(`/v1/links/${encodeURIComponent(id)}`));
215
202
  return res.data ?? null;
216
203
  }
217
- catch {
218
- return null;
204
+ catch (err) {
205
+ if (err instanceof Error && err.message.includes("404")) {
206
+ return null;
207
+ }
208
+ throw err;
219
209
  }
220
210
  }
221
211
  async getNeighbors(reference, direction, options) {
@@ -226,13 +216,8 @@ export class CloudThingStore {
226
216
  if (options.limit !== undefined) {
227
217
  params.set("limit", String(options.limit));
228
218
  }
229
- try {
230
- const res = (await this.restGet(`/v1/links?${params.toString()}`));
231
- return res.data ?? [];
232
- }
233
- catch {
234
- return [];
235
- }
219
+ const res = (await this.restGet(`/v1/links?${params.toString()}`));
220
+ return res.data ?? [];
236
221
  }
237
222
  async listCollections() {
238
223
  return this.callTool("thing_list_collections", {});
@@ -256,48 +241,69 @@ export class CloudThingStore {
256
241
  const url = resolveMcpUrl(this.connectOptions.url);
257
242
  return url.replace(/\/mcp$/, "");
258
243
  }
244
+ authHeaders() {
245
+ if (this.connectOptions.authToken) {
246
+ return { Authorization: `Bearer ${this.connectOptions.authToken}` };
247
+ }
248
+ return {};
249
+ }
259
250
  async restGet(path) {
260
251
  const base = this.restBaseUrl();
261
- const headers = { "Content-Type": "application/json" };
262
- if (this.connectOptions.authToken) {
263
- headers.Authorization = `Bearer ${this.connectOptions.authToken}`;
252
+ const controller = new AbortController();
253
+ const timeout = setTimeout(() => controller.abort(), 30_000);
254
+ try {
255
+ const res = await fetch(`${base}${path}`, {
256
+ headers: this.authHeaders(),
257
+ signal: controller.signal,
258
+ });
259
+ if (!res.ok) {
260
+ throw new Error(`REST request failed: ${res.status} ${res.statusText}`);
261
+ }
262
+ return res.json();
264
263
  }
265
- const res = await fetch(`${base}${path}`, { headers });
266
- if (!res.ok) {
267
- throw new Error(`REST request failed: ${res.status} ${res.statusText}`);
264
+ finally {
265
+ clearTimeout(timeout);
268
266
  }
269
- return res.json();
270
267
  }
271
268
  async restPost(path, body) {
272
269
  const base = this.restBaseUrl();
273
- const headers = { "Content-Type": "application/json" };
274
- if (this.connectOptions.authToken) {
275
- headers.Authorization = `Bearer ${this.connectOptions.authToken}`;
270
+ const controller = new AbortController();
271
+ const timeout = setTimeout(() => controller.abort(), 30_000);
272
+ try {
273
+ const res = await fetch(`${base}${path}`, {
274
+ method: "POST",
275
+ headers: { ...this.authHeaders(), "Content-Type": "application/json" },
276
+ body: JSON.stringify(body),
277
+ signal: controller.signal,
278
+ });
279
+ if (!res.ok) {
280
+ throw new Error(`REST request failed: ${res.status} ${res.statusText}`);
281
+ }
282
+ return res.json();
276
283
  }
277
- const res = await fetch(`${base}${path}`, {
278
- method: "POST",
279
- headers,
280
- body: JSON.stringify(body),
281
- });
282
- if (!res.ok) {
283
- throw new Error(`REST request failed: ${res.status} ${res.statusText}`);
284
+ finally {
285
+ clearTimeout(timeout);
284
286
  }
285
- return res.json();
286
287
  }
287
288
  async restDelete(path) {
288
289
  const base = this.restBaseUrl();
289
- const headers = { "Content-Type": "application/json" };
290
- if (this.connectOptions.authToken) {
291
- headers.Authorization = `Bearer ${this.connectOptions.authToken}`;
290
+ const controller = new AbortController();
291
+ const timeout = setTimeout(() => controller.abort(), 30_000);
292
+ try {
293
+ const res = await fetch(`${base}${path}`, {
294
+ method: "DELETE",
295
+ headers: this.authHeaders(),
296
+ signal: controller.signal,
297
+ });
298
+ if (!res.ok) {
299
+ throw new Error(`REST request failed: ${res.status} ${res.statusText}`);
300
+ }
301
+ const text = await res.text();
302
+ return text ? JSON.parse(text) : null;
292
303
  }
293
- const res = await fetch(`${base}${path}`, {
294
- method: "DELETE",
295
- headers,
296
- });
297
- if (!res.ok) {
298
- throw new Error(`REST request failed: ${res.status} ${res.statusText}`);
304
+ finally {
305
+ clearTimeout(timeout);
299
306
  }
300
- return res.json();
301
307
  }
302
308
  async callToolOnce(name, args, retryOnTransportError) {
303
309
  let result;
@@ -306,8 +312,8 @@ export class CloudThingStore {
306
312
  }
307
313
  catch (error) {
308
314
  // Transport-level error (connection dropped, ECONNRESET, etc.).
309
- // Attempt one reconnect and retry before propagating.
310
- if (retryOnTransportError) {
315
+ // Only reconnect+retry for network errors, not API errors.
316
+ if (retryOnTransportError && isTransportError(error)) {
311
317
  try {
312
318
  await this.reconnect();
313
319
  }
@@ -342,3 +348,19 @@ function parseJsonToolResult(result) {
342
348
  }
343
349
  return JSON.parse(text);
344
350
  }
351
+ function isTransportError(error) {
352
+ if (error instanceof TypeError) {
353
+ return true;
354
+ }
355
+ if (error instanceof Error) {
356
+ const msg = error.message.toLowerCase();
357
+ return (msg.includes("econnreset") ||
358
+ msg.includes("econnrefused") ||
359
+ msg.includes("eof") ||
360
+ msg.includes("fetch failed") ||
361
+ msg.includes("network") ||
362
+ msg.includes("timed out") ||
363
+ msg.includes("abort"));
364
+ }
365
+ return false;
366
+ }
package/dist/version.d.ts CHANGED
@@ -2,5 +2,5 @@
2
2
  * The published version of the thingd SDK.
3
3
  * Updated automatically by semantic-release during the publish process.
4
4
  */
5
- export declare const SDK_VERSION = "0.37.9";
5
+ export declare const SDK_VERSION = "0.37.11";
6
6
  //# sourceMappingURL=version.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,eAAO,MAAM,WAAW,WAAW,CAAC"}
1
+ {"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,eAAO,MAAM,WAAW,YAAY,CAAC"}
package/dist/version.js CHANGED
@@ -2,4 +2,4 @@
2
2
  * The published version of the thingd SDK.
3
3
  * Updated automatically by semantic-release during the publish process.
4
4
  */
5
- export const SDK_VERSION = "0.37.9";
5
+ export const SDK_VERSION = "0.37.11";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thingd/sdk",
3
- "version": "0.37.10",
3
+ "version": "0.38.0",
4
4
  "description": "A fast object-first data engine for applications and AI agents.",
5
5
  "type": "module",
6
6
  "author": "Sayan Mohsin",
@@ -63,7 +63,7 @@
63
63
  "zod": "^4.4.3"
64
64
  },
65
65
  "optionalDependencies": {
66
- "@thingd/native": "0.37.10"
66
+ "@thingd/native": "0.38.0"
67
67
  },
68
68
  "engines": {
69
69
  "node": ">=24.0.0"