@meshagent/meshagent 0.3.1 → 0.4.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.
Files changed (84) hide show
  1. package/CHANGELOG.md +3 -0
  2. package/dist/browser/entrypoint.js +7956 -5611
  3. package/dist/browser/helpers.d.ts +10 -4
  4. package/dist/browser/helpers.js +14 -39
  5. package/dist/browser/index.d.ts +1 -0
  6. package/dist/browser/index.js +1 -0
  7. package/dist/browser/participant-token.d.ts +4 -4
  8. package/dist/browser/participant-token.js +4 -9
  9. package/dist/browser/protocol.d.ts +5 -1
  10. package/dist/browser/protocol.js +7 -2
  11. package/dist/browser/room-client.d.ts +4 -1
  12. package/dist/browser/room-client.js +2 -2
  13. package/dist/browser/sync-client.d.ts +5 -1
  14. package/dist/browser/sync-client.js +13 -2
  15. package/dist/esm/agent-client.d.ts +88 -0
  16. package/dist/esm/agent-client.js +166 -0
  17. package/dist/esm/agent.d.ts +103 -0
  18. package/dist/esm/agent.js +218 -0
  19. package/dist/esm/client.d.ts +90 -0
  20. package/dist/esm/client.js +443 -0
  21. package/dist/esm/completer.d.ts +9 -0
  22. package/dist/esm/completer.js +21 -0
  23. package/dist/esm/data-types.d.ts +44 -0
  24. package/dist/esm/data-types.js +110 -0
  25. package/dist/esm/database-client.d.ts +77 -0
  26. package/dist/esm/database-client.js +109 -0
  27. package/dist/esm/developer-client.d.ts +13 -0
  28. package/dist/esm/developer-client.js +31 -0
  29. package/dist/esm/document.d.ts +84 -0
  30. package/dist/esm/document.js +522 -0
  31. package/dist/esm/entrypoint.d.ts +49722 -0
  32. package/dist/esm/entrypoint.js +6313 -0
  33. package/dist/esm/event-emitter.d.ts +13 -0
  34. package/dist/esm/event-emitter.js +34 -0
  35. package/dist/esm/helpers.d.ts +32 -0
  36. package/dist/esm/helpers.js +46 -0
  37. package/dist/esm/index.d.ts +25 -0
  38. package/dist/esm/index.js +25 -0
  39. package/dist/esm/messaging-client.d.ts +76 -0
  40. package/dist/esm/messaging-client.js +241 -0
  41. package/dist/esm/participant-token.d.ts +36 -0
  42. package/dist/esm/participant-token.js +91 -0
  43. package/dist/esm/participant.d.ts +18 -0
  44. package/dist/esm/participant.js +36 -0
  45. package/dist/esm/protocol.d.ts +91 -0
  46. package/dist/esm/protocol.js +287 -0
  47. package/dist/esm/queues-client.d.ts +26 -0
  48. package/dist/esm/queues-client.js +42 -0
  49. package/dist/esm/requirement.d.ts +25 -0
  50. package/dist/esm/requirement.js +42 -0
  51. package/dist/esm/response.d.ts +60 -0
  52. package/dist/esm/response.js +128 -0
  53. package/dist/esm/room-client.d.ts +46 -0
  54. package/dist/esm/room-client.js +106 -0
  55. package/dist/esm/room-event.d.ts +60 -0
  56. package/dist/esm/room-event.js +72 -0
  57. package/dist/esm/room-server-client.d.ts +19 -0
  58. package/dist/esm/room-server-client.js +45 -0
  59. package/dist/esm/runtime.d.ts +6 -0
  60. package/dist/esm/runtime.js +1 -0
  61. package/dist/esm/schema.d.ts +83 -0
  62. package/dist/esm/schema.js +312 -0
  63. package/dist/esm/storage-client.d.ts +38 -0
  64. package/dist/esm/storage-client.js +79 -0
  65. package/dist/esm/stream-controller.d.ts +8 -0
  66. package/dist/esm/stream-controller.js +51 -0
  67. package/dist/esm/sync-client.d.ts +37 -0
  68. package/dist/esm/sync-client.js +125 -0
  69. package/dist/esm/utils.d.ts +14 -0
  70. package/dist/esm/utils.js +44 -0
  71. package/dist/node/entrypoint.js +9 -4
  72. package/dist/node/helpers.d.ts +10 -4
  73. package/dist/node/helpers.js +14 -39
  74. package/dist/node/index.d.ts +1 -0
  75. package/dist/node/index.js +1 -0
  76. package/dist/node/participant-token.d.ts +4 -4
  77. package/dist/node/participant-token.js +4 -9
  78. package/dist/node/protocol.d.ts +5 -1
  79. package/dist/node/protocol.js +7 -2
  80. package/dist/node/room-client.d.ts +4 -1
  81. package/dist/node/room-client.js +2 -2
  82. package/dist/node/sync-client.d.ts +5 -1
  83. package/dist/node/sync-client.js +13 -2
  84. package/package.json +4 -3
@@ -0,0 +1,44 @@
1
+ import { TextDecoder, TextEncoder } from "@kayahr/text-encoding";
2
+ const encoder = new TextEncoder();
3
+ const decoder = new TextDecoder();
4
+ export { encoder, decoder };
5
+ export function splitMessagePayload(packet) {
6
+ const dataView = new DataView(packet.buffer, packet.byteOffset, packet.byteLength);
7
+ const headerSize = dataView.getUint32(4, false) + dataView.getUint32(0, false) * Math.pow(2, 32);
8
+ return packet.subarray(8 + headerSize, packet.length);
9
+ }
10
+ export function splitMessageHeader(packet) {
11
+ const dataView = new DataView(packet.buffer, packet.byteOffset, packet.byteLength);
12
+ const headerSize = dataView.getUint32(4, false) + dataView.getUint32(0, false) * Math.pow(2, 32);
13
+ const payload = packet.subarray(8, 8 + headerSize);
14
+ return decoder.decode(payload);
15
+ }
16
+ export function unpackMessage(packet) {
17
+ return [JSON.parse(splitMessageHeader(packet)), splitMessagePayload(packet)];
18
+ }
19
+ export function packMessage(request, data) {
20
+ const jsonMessage = encoder.encode(JSON.stringify(request));
21
+ const size = jsonMessage.length;
22
+ const header = new Uint8Array(4 * 2);
23
+ const dataView = new DataView(header.buffer);
24
+ dataView.setUint32(0, (size & 0x000fffff00000000) / Math.pow(2, 32), false);
25
+ dataView.setUint32(4, size & 0xffffffff, false);
26
+ return mergeUint8Arrays(header, jsonMessage, data ?? new Uint8Array(0));
27
+ }
28
+ export function mergeUint8Arrays(...arrays) {
29
+ const totalSize = arrays.reduce((acc, e) => acc + e.length, 0);
30
+ const merged = new Uint8Array(totalSize);
31
+ arrays.forEach((array, i, arrays) => {
32
+ const offset = arrays
33
+ .slice(0, i)
34
+ .reduce((acc, e) => acc + e.length, 0);
35
+ merged.set(array, offset);
36
+ });
37
+ return merged;
38
+ }
39
+ export class RefCount {
40
+ constructor(ref) {
41
+ this.ref = ref;
42
+ this.count = 1;
43
+ }
44
+ }
@@ -26,7 +26,7 @@ var __copyProps = (to, from2, except, desc) => {
26
26
  };
27
27
  var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod));
28
28
  var require_base64 = __commonJS({
29
- "node_modules/base-64/base64.js"(exports, module) {
29
+ "../node_modules/base-64/base64.js"(exports, module) {
30
30
  (function (root) {
31
31
  var freeExports = typeof exports == "object" && exports;
32
32
  var freeModule = typeof module == "object" && module && module.exports == freeExports && module;
@@ -1065,9 +1065,12 @@ var DeleteSet = class {
1065
1065
  };
1066
1066
  var iterateDeletedStructs = (transaction, ds, f) => ds.clients.forEach((deletes, clientid) => {
1067
1067
  const structs = (transaction.doc.store.clients.get(clientid));
1068
- for (let i = 0; i < deletes.length; i++) {
1069
- const del = deletes[i];
1070
- iterateStructs(transaction, structs, del.clock, del.len, f);
1068
+ if (structs != null) {
1069
+ const lastStruct = structs[structs.length - 1];
1070
+ const clockState = lastStruct.id.clock + lastStruct.length;
1071
+ for (let i = 0, del = deletes[i]; i < deletes.length && del.clock < clockState; del = deletes[++i]) {
1072
+ iterateStructs(transaction, structs, del.clock, del.len, f);
1073
+ }
1071
1074
  }
1072
1075
  });
1073
1076
  var findIndexDS = (dis, clock) => {
@@ -3392,6 +3395,8 @@ var typeMapSet = (transaction, parent, key, value) => {
3392
3395
  case Boolean:
3393
3396
  case Array:
3394
3397
  case String:
3398
+ case Date:
3399
+ case BigInt:
3395
3400
  content = new ContentAny([value]);
3396
3401
  break;
3397
3402
  case Uint8Array:
@@ -10,17 +10,23 @@ export declare function deploySchema({ room, schema, name, overwrite }: {
10
10
  overwrite?: boolean;
11
11
  }): Promise<void>;
12
12
  export declare function meshagentBaseUrl(baseUrl?: string): string;
13
- export declare function websocketRoomUrl({ roomName, baseUrl }: {
13
+ export declare function websocketRoomUrl({ roomName, apiUrl }: {
14
14
  roomName: string;
15
- baseUrl?: string;
15
+ apiUrl?: string;
16
16
  }): string;
17
- export declare function participantToken({ participantName, roomName, role }: {
17
+ export declare function participantToken({ participantName, roomName, role, projectId, apiKeyId, }: {
18
18
  participantName: string;
19
19
  roomName: string;
20
20
  role?: string;
21
+ projectId: string;
22
+ apiKeyId: string;
21
23
  }): ParticipantToken;
22
- export declare function websocketProtocol({ participantName, roomName, role }: {
24
+ export declare function websocketProtocol({ participantName, roomName, role, projectId, apiKeyId, secret, apiUrl }: {
23
25
  participantName: string;
24
26
  roomName: string;
25
27
  role?: string;
28
+ projectId: string;
29
+ apiKeyId: string;
30
+ secret: string;
31
+ apiUrl?: string;
26
32
  }): Promise<WebSocketClientProtocol>;
@@ -25,41 +25,20 @@ function meshagentBaseUrl(baseUrl) {
25
25
  if (baseUrl) {
26
26
  return baseUrl;
27
27
  }
28
- return process.env.MESHAGENT_API_URL || 'https://api.meshagent.com';
28
+ return 'https://api.meshagent.com';
29
29
  }
30
- function websocketRoomUrl({ roomName, baseUrl }) {
31
- if (!baseUrl) {
32
- const envApiUrl = process.env.MESHAGENT_API_URL;
33
- if (!envApiUrl) {
34
- baseUrl = 'wss://api.meshagent.com';
35
- }
36
- else {
37
- if (envApiUrl.startsWith('https:')) {
38
- baseUrl = 'wss:' + envApiUrl.substring('https:'.length);
39
- }
40
- else if (envApiUrl.startsWith('http:')) {
41
- baseUrl = 'ws:' + envApiUrl.substring('http:'.length);
42
- }
43
- else {
44
- baseUrl = envApiUrl;
45
- }
46
- }
30
+ function websocketRoomUrl({ roomName, apiUrl }) {
31
+ const baseUrl = apiUrl || 'wss://api.meshagent.com';
32
+ let url = baseUrl;
33
+ if (baseUrl.startsWith('https:')) {
34
+ url = 'wss:' + baseUrl.substring('https:'.length);
47
35
  }
48
- return `${baseUrl}/rooms/${roomName}`;
49
- }
50
- function participantToken({ participantName, roomName, role }) {
51
- const projectId = process.env.MESHAGENT_PROJECT_ID;
52
- const apiKeyId = process.env.MESHAGENT_KEY_ID;
53
- const secret = process.env.MESHAGENT_SECRET;
54
- if (!projectId) {
55
- throw new Error('MESHAGENT_PROJECT_ID must be set. You can find this in the Meshagent Studio under API keys.');
56
- }
57
- if (!apiKeyId) {
58
- throw new Error('MESHAGENT_KEY_ID must be set. You can find this in the Meshagent Studio under API keys.');
59
- }
60
- if (!secret) {
61
- throw new Error('MESHAGENT_SECRET must be set. You can find this in the Meshagent Studio under API keys.');
36
+ else if (baseUrl.startsWith('http:')) {
37
+ url = 'ws:' + baseUrl.substring('http:'.length);
62
38
  }
39
+ return `${url}/rooms/${roomName}`;
40
+ }
41
+ function participantToken({ participantName, roomName, role, projectId, apiKeyId, }) {
63
42
  const token = new participant_token_1.ParticipantToken({ name: participantName, projectId, apiKeyId });
64
43
  token.addRoomGrant(roomName);
65
44
  if (role) {
@@ -67,13 +46,9 @@ function participantToken({ participantName, roomName, role }) {
67
46
  }
68
47
  return token;
69
48
  }
70
- async function websocketProtocol({ participantName, roomName, role }) {
71
- const url = websocketRoomUrl({ roomName });
72
- const token = participantToken({ participantName, roomName, role });
73
- const secret = process.env.MESHAGENT_SECRET;
74
- if (!secret) {
75
- throw new Error('MESHAGENT_SECRET must be set in the environment.');
76
- }
49
+ async function websocketProtocol({ participantName, roomName, role, projectId, apiKeyId, secret, apiUrl }) {
50
+ const url = websocketRoomUrl({ roomName, apiUrl });
51
+ const token = participantToken({ participantName, roomName, role, projectId, apiKeyId });
77
52
  const jwt = await token.toJwt({ token: secret });
78
53
  return new protocol_1.WebSocketClientProtocol({ url, token: jwt });
79
54
  }
@@ -22,3 +22,4 @@ export * from './storage-client';
22
22
  export * from './stream-controller';
23
23
  export * from './sync-client';
24
24
  export * from './helpers';
25
+ export * from './utils';
@@ -38,3 +38,4 @@ __exportStar(require("./storage-client"), exports);
38
38
  __exportStar(require("./stream-controller"), exports);
39
39
  __exportStar(require("./sync-client"), exports);
40
40
  __exportStar(require("./helpers"), exports);
41
+ __exportStar(require("./utils"), exports);
@@ -25,12 +25,12 @@ export declare class ParticipantToken {
25
25
  addRoleGrant(role: string): void;
26
26
  addRoomGrant(roomName: string): void;
27
27
  toJson(): Record<string, any>;
28
- toJwt({ token }?: {
29
- token?: string;
28
+ toJwt({ token }: {
29
+ token: string;
30
30
  }): Promise<string>;
31
31
  static fromJson(json: Record<string, any>): ParticipantToken;
32
- static fromJwt(jwtStr: string, options?: {
33
- token?: string;
32
+ static fromJwt(jwtStr: string, options: {
33
+ token: string;
34
34
  verify?: boolean;
35
35
  }): Promise<ParticipantToken>;
36
36
  }
@@ -51,9 +51,8 @@ class ParticipantToken {
51
51
  grants: this.grants.map((g) => g.toJson()),
52
52
  };
53
53
  }
54
- async toJwt({ token } = {}) {
55
- const secret = token || process.env.MESHAGENT_SECRET;
56
- const secretKey = new TextEncoder().encode(secret);
54
+ async toJwt({ token }) {
55
+ const secretKey = new TextEncoder().encode(token);
57
56
  const payload = {
58
57
  ...this.toJson(),
59
58
  ...this.extra,
@@ -75,13 +74,9 @@ class ParticipantToken {
75
74
  });
76
75
  }
77
76
  static async fromJwt(jwtStr, options) {
78
- const { token, verify = true } = options || {};
77
+ const { token, verify = true } = options;
79
78
  if (verify) {
80
- const secret = token || process.env.MESHAGENT_SECRET;
81
- if (!secret) {
82
- throw new Error("No secret provided to verify JWT. Provide `token` or set MESHAGENT_SECRET");
83
- }
84
- const secretKey = new TextEncoder().encode(secret);
79
+ const secretKey = new TextEncoder().encode(token);
85
80
  const { payload } = await (0, jose_1.jwtVerify)(jwtStr, secretKey, {
86
81
  algorithms: ["HS256"],
87
82
  });
@@ -75,7 +75,11 @@ export declare class Protocol {
75
75
  getNextMessageId(): number;
76
76
  send(type: string, data: Uint8Array, id?: number): Promise<void>;
77
77
  sendJson(object: any): Promise<void>;
78
- start(onMessage?: null): void;
78
+ start({ onMessage, onDone, onError }?: {
79
+ onMessage?: MessageHandler;
80
+ onDone?: () => void;
81
+ onError?: (error: any) => void;
82
+ }): void;
79
83
  dispose(): void;
80
84
  onDataReceived(dataPacket: Uint8Array): void;
81
85
  }
@@ -168,6 +168,11 @@ class Protocol {
168
168
  }
169
169
  async handleMessage(messageId, type, data) {
170
170
  const handler = this.handlers[type] ?? this.handlers["*"];
171
+ if (!handler) {
172
+ const d = data ? (0, utils_1.unpackMessage)(data) : null;
173
+ console.warn(`No handler for message type ${type}; data: ${d}`);
174
+ return;
175
+ }
171
176
  await handler(this, messageId, type, data);
172
177
  }
173
178
  getNextMessageId() {
@@ -181,11 +186,11 @@ class Protocol {
181
186
  async sendJson(object) {
182
187
  return await this.send("application/json", utils_1.encoder.encode(JSON.stringify(object)));
183
188
  }
184
- start(onMessage = null) {
189
+ start({ onMessage, onDone, onError } = {}) {
185
190
  if (onMessage != null) {
186
191
  this.addHandler("*", onMessage);
187
192
  }
188
- this.channel.start(this.onDataReceived.bind(this), {});
193
+ this.channel.start(this.onDataReceived.bind(this), { onDone, onError });
189
194
  this._iterator?.return(null);
190
195
  (async () => {
191
196
  this._iterator = this._send.stream();
@@ -30,7 +30,10 @@ export declare class RoomClient {
30
30
  });
31
31
  get localParticipant(): LocalParticipant | null;
32
32
  get ready(): Promise<boolean>;
33
- start(): Promise<void>;
33
+ start({ onDone, onError }?: {
34
+ onDone?: () => void;
35
+ onError?: (error: Error) => void;
36
+ }): Promise<void>;
34
37
  dispose(): void;
35
38
  sendRequest(type: string, request: RequestHeader, data?: Uint8Array): Promise<Response>;
36
39
  private _handleResponse;
@@ -37,8 +37,8 @@ class RoomClient {
37
37
  get ready() {
38
38
  return this._ready.fut;
39
39
  }
40
- async start() {
41
- this.sync.start();
40
+ async start({ onDone, onError } = {}) {
41
+ this.sync.start({ onDone, onError });
42
42
  await this.ready;
43
43
  }
44
44
  dispose() {
@@ -21,9 +21,13 @@ export declare class SyncClient extends EventEmitter<SyncClientEvent> {
21
21
  constructor({ room }: {
22
22
  room: RoomClient;
23
23
  });
24
- start(): void;
24
+ start({ onDone, onError }?: {
25
+ onDone?: () => void;
26
+ onError?: (error: Error) => void;
27
+ }): void;
25
28
  dispose(): void;
26
29
  private _handleSync;
30
+ private _handleStatus;
27
31
  create(path: string, json?: Record<string, any>): Promise<void>;
28
32
  open(path: string, { create }?: {
29
33
  create?: boolean;
@@ -24,9 +24,10 @@ class SyncClient extends event_emitter_1.EventEmitter {
24
24
  this._connectedDocuments = {};
25
25
  this.client = room;
26
26
  this.client.protocol.addHandler("room.sync", this._handleSync.bind(this));
27
+ this.client.protocol.addHandler("room.status", this._handleStatus.bind(this));
27
28
  }
28
- start() {
29
- this.client.protocol.start();
29
+ start({ onDone, onError } = {}) {
30
+ this.client.protocol.start({ onDone, onError });
30
31
  (async () => {
31
32
  for await (const message of this._changesToSync.stream) {
32
33
  await this.client.sendRequest("room.sync", { path: message.path }, utils_1.encoder.encode(message.base64));
@@ -60,6 +61,11 @@ class SyncClient extends event_emitter_1.EventEmitter {
60
61
  throw new room_server_client_1.RoomServerException(`received change for a document that is not connected: ${path}`);
61
62
  }
62
63
  }
64
+ async _handleStatus(protocol, messageId, data, bytes) {
65
+ const headerStr = (0, utils_1.splitMessageHeader)(bytes || new Uint8Array());
66
+ const header = JSON.parse(headerStr);
67
+ this.emit("status", header.status);
68
+ }
63
69
  async create(path, json) {
64
70
  await this.client.sendRequest("room.create", { path, json });
65
71
  }
@@ -99,6 +105,11 @@ class SyncClient extends event_emitter_1.EventEmitter {
99
105
  }
100
106
  }
101
107
  async close(path) {
108
+ const pending = this._connectingDocuments[path];
109
+ if (pending) {
110
+ await pending;
111
+ await new Promise(resolve => setTimeout(resolve, 50));
112
+ }
102
113
  const rc = this._connectedDocuments[path];
103
114
  if (!rc) {
104
115
  throw new room_server_client_1.RoomServerException(`Not connected to ${path}`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@meshagent/meshagent",
3
- "version": "0.3.1",
3
+ "version": "0.4.0",
4
4
  "description": "Meshagent Client",
5
5
  "homepage": "https://www.meshagent.com",
6
6
  "scripts": {
@@ -8,11 +8,12 @@
8
8
  "build": "mkdir -p dist && ./scripts/build.sh",
9
9
  "build-browser-test": "node ./build-browser-test.js"
10
10
  },
11
- "author": "Powerboards",
11
+ "author": "Meshagent Software",
12
12
  "license": "Apache-2.0",
13
13
  "main": "./dist/node/index.js",
14
14
  "exports": {
15
15
  ".": {
16
+ "module": "./dist/esm/index.js",
16
17
  "browser": "./dist/browser/index.js",
17
18
  "default": "./dist/node/index.js"
18
19
  },
@@ -46,4 +47,4 @@
46
47
  "uuid": "^11.0.5",
47
48
  "ws": "^8.18.0"
48
49
  }
49
- }
50
+ }