@meshagent/meshagent 0.35.5 → 0.35.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.
Files changed (47) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/browser/containers-client.d.ts +79 -2
  3. package/dist/browser/containers-client.js +341 -19
  4. package/dist/browser/database-client.d.ts +95 -24
  5. package/dist/browser/database-client.js +150 -49
  6. package/dist/browser/messaging-client.d.ts +33 -52
  7. package/dist/browser/messaging-client.js +180 -184
  8. package/dist/browser/participant.d.ts +5 -3
  9. package/dist/browser/participant.js +9 -1
  10. package/dist/browser/room-client.js +2 -0
  11. package/dist/browser/room-event.d.ts +6 -2
  12. package/dist/browser/room-event.js +4 -2
  13. package/dist/browser/secrets-client.d.ts +86 -16
  14. package/dist/browser/secrets-client.js +243 -44
  15. package/dist/browser/storage-client.d.ts +17 -4
  16. package/dist/browser/storage-client.js +141 -30
  17. package/dist/esm/containers-client.d.ts +79 -2
  18. package/dist/esm/containers-client.js +341 -19
  19. package/dist/esm/database-client.d.ts +95 -24
  20. package/dist/esm/database-client.js +150 -49
  21. package/dist/esm/messaging-client.d.ts +33 -52
  22. package/dist/esm/messaging-client.js +179 -180
  23. package/dist/esm/participant.d.ts +5 -3
  24. package/dist/esm/participant.js +9 -1
  25. package/dist/esm/room-client.js +2 -0
  26. package/dist/esm/room-event.d.ts +6 -2
  27. package/dist/esm/room-event.js +4 -2
  28. package/dist/esm/secrets-client.d.ts +86 -16
  29. package/dist/esm/secrets-client.js +243 -44
  30. package/dist/esm/storage-client.d.ts +17 -4
  31. package/dist/esm/storage-client.js +140 -30
  32. package/dist/node/containers-client.d.ts +79 -2
  33. package/dist/node/containers-client.js +341 -19
  34. package/dist/node/database-client.d.ts +95 -24
  35. package/dist/node/database-client.js +150 -49
  36. package/dist/node/messaging-client.d.ts +33 -52
  37. package/dist/node/messaging-client.js +180 -184
  38. package/dist/node/participant.d.ts +5 -3
  39. package/dist/node/participant.js +9 -1
  40. package/dist/node/room-client.js +2 -0
  41. package/dist/node/room-event.d.ts +6 -2
  42. package/dist/node/room-event.js +4 -2
  43. package/dist/node/secrets-client.d.ts +86 -16
  44. package/dist/node/secrets-client.js +243 -44
  45. package/dist/node/storage-client.d.ts +17 -4
  46. package/dist/node/storage-client.js +141 -30
  47. package/package.json +1 -1
@@ -1,11 +1,61 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.StorageClient = exports.FileHandle = void 0;
3
+ exports.StorageClient = exports.StorageEntry = exports.FileHandle = void 0;
4
4
  const room_event_1 = require("./room-event");
5
5
  const response_1 = require("./response");
6
6
  const utils_1 = require("./utils");
7
7
  const event_emitter_1 = require("./event-emitter");
8
8
  const room_server_client_1 = require("./room-server-client");
9
+ const _DEFAULT_UPLOAD_MIME_TYPE = "application/octet-stream";
10
+ const _UPLOAD_MIME_TYPES_BY_SUFFIX = new Map([
11
+ [".tar.gz", "application/x-tar"],
12
+ [".tgz", "application/x-tar"],
13
+ ]);
14
+ const _UPLOAD_MIME_TYPES_BY_EXTENSION = new Map([
15
+ [".bin", "application/octet-stream"],
16
+ [".css", "text/css"],
17
+ [".csv", "text/csv"],
18
+ [".gif", "image/gif"],
19
+ [".gz", "application/gzip"],
20
+ [".htm", "text/html"],
21
+ [".html", "text/html"],
22
+ [".jpeg", "image/jpeg"],
23
+ [".jpg", "image/jpeg"],
24
+ [".js", "text/javascript"],
25
+ [".json", "application/json"],
26
+ [".md", "text/markdown"],
27
+ [".mp3", "audio/mpeg"],
28
+ [".mp4", "video/mp4"],
29
+ [".pdf", "application/pdf"],
30
+ [".png", "image/png"],
31
+ [".svg", "image/svg+xml"],
32
+ [".tar", "application/x-tar"],
33
+ [".txt", "text/plain"],
34
+ [".ts", "text/typescript"],
35
+ [".tsx", "text/tsx"],
36
+ [".wasm", "application/wasm"],
37
+ [".webp", "image/webp"],
38
+ [".xml", "application/xml"],
39
+ [".yaml", "application/yaml"],
40
+ [".yml", "application/yaml"],
41
+ [".zip", "application/zip"],
42
+ ]);
43
+ function _unexpectedStorageResponseError(operation) {
44
+ return new room_server_client_1.RoomServerException(`unexpected return type from storage.${operation}`);
45
+ }
46
+ function _parseStorageTimestamp(value, operation) {
47
+ if (value == null) {
48
+ return null;
49
+ }
50
+ if (typeof value !== "string") {
51
+ throw _unexpectedStorageResponseError(operation);
52
+ }
53
+ const timestamp = new Date(value);
54
+ if (Number.isNaN(timestamp.getTime())) {
55
+ throw _unexpectedStorageResponseError(operation);
56
+ }
57
+ return timestamp;
58
+ }
9
59
  class FileHandle {
10
60
  constructor({ id }) {
11
61
  this.id = id;
@@ -13,10 +63,12 @@ class FileHandle {
13
63
  }
14
64
  exports.FileHandle = FileHandle;
15
65
  class StorageEntry {
16
- constructor({ name, isFolder, size = null }) {
66
+ constructor({ name, isFolder, size = null, createdAt = null, updatedAt = null }) {
17
67
  this.name = name;
18
68
  this.isFolder = isFolder;
19
69
  this.size = size;
70
+ this.createdAt = createdAt;
71
+ this.updatedAt = updatedAt;
20
72
  }
21
73
  nameWithoutExtension() {
22
74
  const segments = this.name
@@ -27,6 +79,7 @@ class StorageEntry {
27
79
  .replace(/\.[^/.]+$/, "");
28
80
  }
29
81
  }
82
+ exports.StorageEntry = StorageEntry;
30
83
  class StorageClient extends event_emitter_1.EventEmitter {
31
84
  constructor({ room }) {
32
85
  super();
@@ -36,18 +89,32 @@ class StorageClient extends event_emitter_1.EventEmitter {
36
89
  }
37
90
  async _handleFileUpdated(protocol, messageId, type, bytes) {
38
91
  const [data, _] = (0, utils_1.unpackMessage)(bytes || new Uint8Array());
39
- const event = new room_event_1.FileUpdatedEvent({ path: data["path"] });
92
+ const event = new room_event_1.FileUpdatedEvent({ path: data["path"], participantId: data["participant_id"] });
40
93
  this.client.emit(event);
41
94
  this.emit('file.updated', event);
42
95
  }
43
96
  async _handleFileDeleted(protocol, messageId, type, bytes) {
44
97
  const [data, _] = (0, utils_1.unpackMessage)(bytes || new Uint8Array());
45
- const event = new room_event_1.FileDeletedEvent({ path: data["path"] });
98
+ const event = new room_event_1.FileDeletedEvent({ path: data["path"], participantId: data["participant_id"] });
46
99
  this.client.emit(event);
47
100
  this.emit('file.deleted', event);
48
101
  }
49
102
  _unexpectedResponseError(operation) {
50
- return new room_server_client_1.RoomServerException(`unexpected return type from storage.${operation}`);
103
+ return _unexpectedStorageResponseError(operation);
104
+ }
105
+ _storageEntry(operation, value) {
106
+ if (typeof value["name"] !== "string" ||
107
+ typeof value["is_folder"] !== "boolean" ||
108
+ (value["size"] != null && typeof value["size"] !== "number")) {
109
+ throw this._unexpectedResponseError(operation);
110
+ }
111
+ return new StorageEntry({
112
+ name: value["name"],
113
+ isFolder: value["is_folder"],
114
+ size: typeof value["size"] === "number" ? value["size"] : null,
115
+ createdAt: _parseStorageTimestamp(value["created_at"], operation),
116
+ updatedAt: _parseStorageTimestamp(value["updated_at"], operation),
117
+ });
51
118
  }
52
119
  async _invoke(operation, input, callerContext) {
53
120
  return await this.client.invoke({
@@ -59,22 +126,26 @@ class StorageClient extends event_emitter_1.EventEmitter {
59
126
  }
60
127
  async list(path) {
61
128
  const response = await this._invoke("list", { path });
62
- if (!(response instanceof response_1.JsonContent)) {
129
+ if (!(response instanceof response_1.JsonContent) || !Array.isArray(response.json["files"])) {
63
130
  throw this._unexpectedResponseError("list");
64
131
  }
65
132
  const files = response.json["files"];
66
- const entries = files.map((f) => {
67
- return new StorageEntry({
68
- name: f["name"],
69
- isFolder: f["is_folder"],
70
- size: typeof f["size"] === "number" ? f["size"] : null,
71
- });
72
- });
133
+ const entries = files.map((f) => this._storageEntry("list", f));
73
134
  entries.sort((a, b) => a.name.localeCompare(b.name));
74
135
  return entries;
75
136
  }
76
- async delete(path) {
77
- await this._invoke("delete", { path, recursive: null });
137
+ async stat(path) {
138
+ const response = await this._invoke("stat", { path });
139
+ if (!(response instanceof response_1.JsonContent) || typeof response.json["exists"] !== "boolean") {
140
+ throw this._unexpectedResponseError("stat");
141
+ }
142
+ if (!response.json["exists"]) {
143
+ return null;
144
+ }
145
+ return this._storageEntry("stat", response.json);
146
+ }
147
+ async delete(path, { recursive = null, } = {}) {
148
+ await this._invoke("delete", { path, recursive });
78
149
  }
79
150
  async exists(path) {
80
151
  const result = await this._invoke("exists", { path });
@@ -91,6 +162,22 @@ class StorageClient extends event_emitter_1.EventEmitter {
91
162
  const lastSegment = segments.length > 0 ? segments[segments.length - 1] : undefined;
92
163
  return lastSegment ?? path;
93
164
  }
165
+ _defaultUploadMimeType(name, mimeType) {
166
+ if (typeof mimeType === "string" && mimeType.length > 0) {
167
+ return mimeType;
168
+ }
169
+ const lowerName = name.toLowerCase();
170
+ for (const [suffix, contentType] of _UPLOAD_MIME_TYPES_BY_SUFFIX.entries()) {
171
+ if (lowerName.endsWith(suffix)) {
172
+ return contentType;
173
+ }
174
+ }
175
+ const lastDot = lowerName.lastIndexOf(".");
176
+ if (lastDot >= 0) {
177
+ return _UPLOAD_MIME_TYPES_BY_EXTENSION.get(lowerName.slice(lastDot)) ?? _DEFAULT_UPLOAD_MIME_TYPE;
178
+ }
179
+ return _DEFAULT_UPLOAD_MIME_TYPE;
180
+ }
94
181
  async upload(path, bytes, { overwrite = false, name, mimeType = null, } = {}) {
95
182
  async function* singleChunk() {
96
183
  yield bytes;
@@ -104,6 +191,7 @@ class StorageClient extends event_emitter_1.EventEmitter {
104
191
  }
105
192
  async uploadStream(path, chunks, { overwrite = false, chunkSize = 64 * 1024, size = null, name, mimeType = null, } = {}) {
106
193
  const resolvedName = this._defaultUploadName(path, name);
194
+ const resolvedMimeType = this._defaultUploadMimeType(resolvedName, mimeType);
107
195
  const input = new _StorageUploadInputStream({
108
196
  path,
109
197
  overwrite,
@@ -111,7 +199,7 @@ class StorageClient extends event_emitter_1.EventEmitter {
111
199
  chunkSize,
112
200
  size,
113
201
  name: resolvedName,
114
- mimeType,
202
+ mimeType: resolvedMimeType,
115
203
  });
116
204
  const response = await this.client.invokeStream({
117
205
  toolkit: "storage",
@@ -135,7 +223,10 @@ class StorageClient extends event_emitter_1.EventEmitter {
135
223
  if (chunk.headers["kind"] !== "pull") {
136
224
  throw this._unexpectedResponseError("upload");
137
225
  }
138
- input.requestNext();
226
+ const rawChunkSize = chunk.headers["chunk_size"];
227
+ input.requestNext(typeof rawChunkSize === "number" && rawChunkSize > 0
228
+ ? rawChunkSize
229
+ : null);
139
230
  }
140
231
  }
141
232
  finally {
@@ -326,7 +417,7 @@ class _StorageDownloadInputStream {
326
417
  class _StorageUploadInputStream {
327
418
  constructor({ path, overwrite, chunks, chunkSize, size, name, mimeType, }) {
328
419
  this.closed = false;
329
- this.pendingPulls = 0;
420
+ this.pendingPulls = [];
330
421
  this.waitingResolver = null;
331
422
  this.pendingChunk = new Uint8Array(0);
332
423
  this.pendingOffset = 0;
@@ -339,11 +430,11 @@ class _StorageUploadInputStream {
339
430
  this.name = name;
340
431
  this.mimeType = mimeType;
341
432
  }
342
- requestNext() {
433
+ requestNext(chunkSize = null) {
343
434
  if (this.closed) {
344
435
  return;
345
436
  }
346
- this.pendingPulls += 1;
437
+ this.pendingPulls.push(chunkSize);
347
438
  if (this.waitingResolver) {
348
439
  const resolver = this.waitingResolver;
349
440
  this.waitingResolver = null;
@@ -361,21 +452,26 @@ class _StorageUploadInputStream {
361
452
  resolver();
362
453
  }
363
454
  }
364
- async nextChunk() {
365
- while (true) {
455
+ async nextChunk(requestedChunkSize) {
456
+ const parts = [];
457
+ let totalLength = 0;
458
+ while (totalLength < requestedChunkSize) {
366
459
  if (this.pendingOffset < this.pendingChunk.length) {
367
460
  const start = this.pendingOffset;
368
- const end = Math.min(start + this.chunkSize, this.pendingChunk.length);
461
+ const end = Math.min(start + (requestedChunkSize - totalLength), this.pendingChunk.length);
462
+ const part = this.pendingChunk.slice(start, end);
369
463
  this.pendingOffset = end;
370
- return this.pendingChunk.slice(start, end);
464
+ parts.push(part);
465
+ totalLength += part.length;
466
+ continue;
371
467
  }
372
468
  if (this.sourceExhausted) {
373
- return null;
469
+ break;
374
470
  }
375
471
  const next = await this.source.next();
376
472
  if (next.done) {
377
473
  this.sourceExhausted = true;
378
- return null;
474
+ break;
379
475
  }
380
476
  if (next.value.length === 0) {
381
477
  continue;
@@ -383,6 +479,19 @@ class _StorageUploadInputStream {
383
479
  this.pendingChunk = next.value;
384
480
  this.pendingOffset = 0;
385
481
  }
482
+ if (totalLength === 0) {
483
+ return null;
484
+ }
485
+ if (parts.length === 1) {
486
+ return parts[0];
487
+ }
488
+ const combined = new Uint8Array(totalLength);
489
+ let offset = 0;
490
+ for (const part of parts) {
491
+ combined.set(part, offset);
492
+ offset += part.length;
493
+ }
494
+ return combined;
386
495
  }
387
496
  async *stream() {
388
497
  yield new response_1.BinaryContent({
@@ -397,7 +506,7 @@ class _StorageUploadInputStream {
397
506
  },
398
507
  });
399
508
  while (!this.closed) {
400
- if (this.pendingPulls === 0) {
509
+ if (this.pendingPulls.length === 0) {
401
510
  await new Promise((resolve) => {
402
511
  this.waitingResolver = resolve;
403
512
  });
@@ -405,11 +514,13 @@ class _StorageUploadInputStream {
405
514
  if (this.closed) {
406
515
  return;
407
516
  }
408
- if (this.pendingPulls === 0) {
517
+ if (this.pendingPulls.length === 0) {
409
518
  continue;
410
519
  }
411
- this.pendingPulls -= 1;
412
- const chunk = await this.nextChunk();
520
+ const requestedChunkSize = this.pendingPulls.shift();
521
+ const chunk = await this.nextChunk(typeof requestedChunkSize === "number" && requestedChunkSize > 0
522
+ ? requestedChunkSize
523
+ : this.chunkSize);
413
524
  if (chunk == null) {
414
525
  return;
415
526
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@meshagent/meshagent",
3
- "version": "0.35.5",
3
+ "version": "0.35.7",
4
4
  "description": "Meshagent Client",
5
5
  "homepage": "https://github.com/meshagent/meshagent-ts",
6
6
  "scripts": {