@inditextech/weave-store-azure-web-pubsub 2.1.0 → 2.2.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/dist/client.d.ts CHANGED
@@ -185,6 +185,10 @@ declare enum MessageDataType {
185
185
  Awareness = "awareness",
186
186
  }
187
187
  interface MessageData {
188
+ payloadId?: string;
189
+ index?: number;
190
+ type?: "chunk" | "end";
191
+ totalChunks?: number;
188
192
  group: string;
189
193
  t: string;
190
194
  f: string;
@@ -223,6 +227,7 @@ declare class WeaveStoreAzureWebPubSubSyncClient extends Emittery {
223
227
  private _awareness;
224
228
  private _options;
225
229
  private _initialized;
230
+ private _chunkedMessages;
226
231
  private _updateHandler;
227
232
  private _awarenessUpdateHandler;
228
233
  /**
package/dist/client.js CHANGED
@@ -3722,6 +3722,29 @@ const WEAVE_STORE_HORIZONTAL_SYNC_HANDLER_CLIENT_TYPE = {
3722
3722
  };
3723
3723
  const WEAVE_STORE_AZURE_WEB_PUBSUB_DEFAULT_CONFIG = { resyncIntervalMs: 15e3 };
3724
3724
 
3725
+ //#endregion
3726
+ //#region src/utils.ts
3727
+ function handleChunkedMessage(chunkedMessagesMap, messageData) {
3728
+ if (messageData.payloadId && messageData.index !== void 0 && messageData.totalChunks && messageData.type === "chunk") {
3729
+ if (!chunkedMessagesMap.has(messageData.payloadId)) chunkedMessagesMap.set(messageData.payloadId, new Array(messageData.totalChunks));
3730
+ if (messageData.c) chunkedMessagesMap.get(messageData.payloadId)[messageData.index] = messageData.c;
3731
+ }
3732
+ let joined = void 0;
3733
+ if (messageData.payloadId && messageData.type === "end") {
3734
+ if (chunkedMessagesMap.has(messageData.payloadId)) {
3735
+ joined = chunkedMessagesMap.get(messageData.payloadId).join("");
3736
+ chunkedMessagesMap.delete(messageData.payloadId);
3737
+ }
3738
+ }
3739
+ return joined;
3740
+ }
3741
+ function handleMessageBufferData(normalMessagePayload, joinedMessagePayload) {
3742
+ let buf = void 0;
3743
+ if (normalMessagePayload) buf = Buffer.from(normalMessagePayload, "base64");
3744
+ if (joinedMessagePayload) buf = Buffer.from(joinedMessagePayload, "base64");
3745
+ return buf;
3746
+ }
3747
+
3725
3748
  //#endregion
3726
3749
  //#region src/client.ts
3727
3750
  const messageSyncStep1 = 0;
@@ -3774,6 +3797,7 @@ var WeaveStoreAzureWebPubSubSyncClient = class extends Emittery {
3774
3797
  this._status = WEAVE_STORE_AZURE_WEB_PUBSUB_CONNECTION_STATUS.DISCONNECTED;
3775
3798
  this._wsConnected = false;
3776
3799
  this._initialized = false;
3800
+ this._chunkedMessages = new Map();
3777
3801
  this._connectionRetries = 0;
3778
3802
  this._synced = false;
3779
3803
  this._ws = null;
@@ -3836,10 +3860,10 @@ var WeaveStoreAzureWebPubSubSyncClient = class extends Emittery {
3836
3860
  this._resyncCheckInterval = setInterval(() => {
3837
3861
  if (!this._lastReceivedSyncResponse) return;
3838
3862
  const resyncInSeconds = this._options.resyncInterval / 1e3;
3839
- const resyncLimitInSeconds = resyncInSeconds + 5;
3863
+ const resyncWindowLimitInSeconds = resyncInSeconds + 10;
3840
3864
  const now = new Date();
3841
3865
  const diffInSeconds = (now.getTime() - this._lastReceivedSyncResponse) / 1e3;
3842
- if (diffInSeconds > resyncLimitInSeconds && this._ws?.readyState === WebSocket.OPEN) {
3866
+ if (diffInSeconds > resyncWindowLimitInSeconds && this._ws?.readyState === WebSocket.OPEN) {
3843
3867
  this._ws.dispatchEvent(new CustomEvent("error", {
3844
3868
  cancelable: false,
3845
3869
  bubbles: false,
@@ -3940,8 +3964,11 @@ var WeaveStoreAzureWebPubSubSyncClient = class extends Emittery {
3940
3964
  if (message.type === MessageType.System) return;
3941
3965
  const messageData = message.data;
3942
3966
  if (messageData.t !== void 0 && messageData.t !== this._uuid) return;
3943
- const buf = Buffer$1.from(messageData.c, "base64");
3944
- const encoder = readMessage(this, buf, true, messageData.f);
3967
+ const joinedMessagePayload = handleChunkedMessage(this._chunkedMessages, messageData);
3968
+ if (messageData.type === "chunk") return;
3969
+ const buffer = handleMessageBufferData(messageData.c, joinedMessagePayload);
3970
+ if (!buffer) return;
3971
+ const encoder = readMessage(this, buffer, true, messageData.f);
3945
3972
  if (length$1(encoder) > 1) sendToControlGroup(this, this.topic, MessageDataType.Sync, toUint8Array(encoder));
3946
3973
  };
3947
3974
  websocket.onclose = () => {
@@ -3996,10 +4023,7 @@ var WeaveStoreAzureWebPubSubSyncClient = class extends Emittery {
3996
4023
  function safeSend(data) {
3997
4024
  const MAX_BYTES = 64 * 1024;
3998
4025
  const bytes = new TextEncoder().encode(data);
3999
- if (bytes.byteLength > MAX_BYTES) {
4000
- console.warn(`Message too large: ${bytes.byteLength} bytes (limit ${MAX_BYTES}). Skipping send.`);
4001
- return false;
4002
- }
4026
+ if (bytes.byteLength > MAX_BYTES) return false;
4003
4027
  return true;
4004
4028
  }
4005
4029
  function joinGroup(client, group) {
@@ -4014,13 +4038,57 @@ function sendToControlGroup(client, group, type, u8) {
4014
4038
  const payload = JSON.stringify({
4015
4039
  type: MessageType.SendToGroup,
4016
4040
  group: `${group}.host`,
4041
+ noEcho: true,
4017
4042
  data: {
4018
4043
  t: type,
4019
4044
  f: client.id,
4020
4045
  c: Buffer$1.from(u8).toString("base64")
4021
4046
  }
4022
4047
  });
4023
- if (!safeSend(payload)) return;
4048
+ if (!safeSend(payload)) {
4049
+ sendToControlGroupChunked(client, group, type, u8);
4050
+ return;
4051
+ }
4052
+ client.ws?.send(payload);
4053
+ }
4054
+ function chunkString(str, size) {
4055
+ const chunks = [];
4056
+ for (let i = 0; i < str.length; i += size) chunks.push(str.slice(i, i + size));
4057
+ return chunks;
4058
+ }
4059
+ function sendToControlGroupChunked(client, group, type, u8) {
4060
+ const base64Data = Buffer$1.from(u8).toString("base64");
4061
+ const CHUNK_SIZE = 60 * 1024;
4062
+ const chunks = chunkString(base64Data, CHUNK_SIZE);
4063
+ const payloadId = v4();
4064
+ for (let i = 0; i < chunks.length; i++) {
4065
+ const payload$1 = JSON.stringify({
4066
+ type: MessageType.SendToGroup,
4067
+ group: `${group}.host`,
4068
+ noEcho: true,
4069
+ data: {
4070
+ payloadId,
4071
+ type: "chunk",
4072
+ totalChunks: chunks.length,
4073
+ index: i,
4074
+ t: type,
4075
+ f: client.id,
4076
+ c: chunks[i]
4077
+ }
4078
+ });
4079
+ client.ws?.send(payload$1);
4080
+ }
4081
+ const payload = JSON.stringify({
4082
+ type: MessageType.SendToGroup,
4083
+ group: `${group}.host`,
4084
+ noEcho: true,
4085
+ data: {
4086
+ payloadId,
4087
+ type: "end",
4088
+ f: client.id,
4089
+ t: type
4090
+ }
4091
+ });
4024
4092
  client.ws?.send(payload);
4025
4093
  }
4026
4094
  function isRelativeUrl(url) {
package/dist/server.d.ts CHANGED
@@ -76,6 +76,7 @@ declare class WeaveStoreAzureWebPubSubSyncClient extends Emittery {
76
76
  private _awareness;
77
77
  private _options;
78
78
  private _initialized;
79
+ private _chunkedMessages;
79
80
  private _updateHandler;
80
81
  private _awarenessUpdateHandler;
81
82
  /**
@@ -193,6 +194,10 @@ declare enum MessageDataType {
193
194
  Awareness = "awareness",
194
195
  }
195
196
  interface MessageData {
197
+ payloadId?: string;
198
+ index?: number;
199
+ type?: "chunk" | "end";
200
+ totalChunks?: number;
196
201
  group: string;
197
202
  t: string;
198
203
  f: string;
@@ -1009,6 +1014,7 @@ declare class WeaveStoreAzureWebPubSubSyncHost {
1009
1014
  private _reconnectAttempts;
1010
1015
  private _forceClose;
1011
1016
  private _awareness;
1017
+ private _chunkedMessages;
1012
1018
  private _updateHandler;
1013
1019
  private _awarenessUpdateHandler;
1014
1020
  constructor(server: WeaveAzureWebPubsubServer, syncHandler: WeaveAzureWebPubsubSyncHandler, client: WebPubSubServiceClient, topic: string, doc: Y.Doc);
@@ -1019,7 +1025,10 @@ declare class WeaveStoreAzureWebPubSubSyncHost {
1019
1025
  stop(): Promise<void>;
1020
1026
  simulateWebsocketError(): void;
1021
1027
  private safeSend;
1028
+ private chunkString;
1029
+ private chunkedBroadcast;
1022
1030
  private broadcast;
1031
+ private chunkedSend;
1023
1032
  private send;
1024
1033
  private onClientInit;
1025
1034
  private onClientSync;
package/dist/server.js CHANGED
@@ -7,8 +7,8 @@ import * as Y from "yjs";
7
7
  import { URL as URL$1 } from "node:url";
8
8
  import { EOL } from "node:os";
9
9
  import process$1 from "node:process";
10
- import { WebSocket } from "ws";
11
10
  import crypto from "node:crypto";
11
+ import { WebSocket } from "ws";
12
12
  import { defaultInitialState } from "@inditextech/weave-sdk/server";
13
13
 
14
14
  //#region rolldown:runtime
@@ -20789,17 +20789,17 @@ Object.defineProperty(Emittery, "listenerRemoved", {
20789
20789
 
20790
20790
  //#endregion
20791
20791
  //#region src/types.ts
20792
- let MessageType = /* @__PURE__ */ function(MessageType$2) {
20793
- MessageType$2["System"] = "system";
20794
- MessageType$2["JoinGroup"] = "joinGroup";
20795
- MessageType$2["SendToGroup"] = "sendToGroup";
20796
- return MessageType$2;
20792
+ let MessageType = /* @__PURE__ */ function(MessageType$1) {
20793
+ MessageType$1["System"] = "system";
20794
+ MessageType$1["JoinGroup"] = "joinGroup";
20795
+ MessageType$1["SendToGroup"] = "sendToGroup";
20796
+ return MessageType$1;
20797
20797
  }({});
20798
- let MessageDataType = /* @__PURE__ */ function(MessageDataType$2) {
20799
- MessageDataType$2["Init"] = "init";
20800
- MessageDataType$2["Sync"] = "sync";
20801
- MessageDataType$2["Awareness"] = "awareness";
20802
- return MessageDataType$2;
20798
+ let MessageDataType = /* @__PURE__ */ function(MessageDataType$1) {
20799
+ MessageDataType$1["Init"] = "init";
20800
+ MessageDataType$1["Sync"] = "sync";
20801
+ MessageDataType$1["Awareness"] = "awareness";
20802
+ return MessageDataType$1;
20803
20803
  }({});
20804
20804
 
20805
20805
  //#endregion
@@ -22836,24 +22836,29 @@ const applyAwarenessUpdate = (awareness, update, origin) => {
22836
22836
  }, origin]);
22837
22837
  };
22838
22838
 
22839
+ //#endregion
22840
+ //#region src/utils.ts
22841
+ function handleChunkedMessage(chunkedMessagesMap, messageData) {
22842
+ if (messageData.payloadId && messageData.index !== void 0 && messageData.totalChunks && messageData.type === "chunk") {
22843
+ if (!chunkedMessagesMap.has(messageData.payloadId)) chunkedMessagesMap.set(messageData.payloadId, new Array(messageData.totalChunks));
22844
+ if (messageData.c) chunkedMessagesMap.get(messageData.payloadId)[messageData.index] = messageData.c;
22845
+ }
22846
+ let joined = void 0;
22847
+ if (messageData.payloadId && messageData.type === "end") {
22848
+ if (chunkedMessagesMap.has(messageData.payloadId)) {
22849
+ joined = chunkedMessagesMap.get(messageData.payloadId).join("");
22850
+ chunkedMessagesMap.delete(messageData.payloadId);
22851
+ }
22852
+ }
22853
+ return joined;
22854
+ }
22855
+
22839
22856
  //#endregion
22840
22857
  //#region src/server/azure-web-pubsub-host.ts
22841
22858
  const expirationTimeInMinutes = 60;
22842
22859
  const messageSync = 0;
22843
22860
  const messageAwareness = 1;
22844
22861
  const AzureWebPubSubJsonProtocol = "json.webpubsub.azure.v1";
22845
- let MessageType$1 = /* @__PURE__ */ function(MessageType$2) {
22846
- MessageType$2["System"] = "system";
22847
- MessageType$2["JoinGroup"] = "joinGroup";
22848
- MessageType$2["SendToGroup"] = "sendToGroup";
22849
- return MessageType$2;
22850
- }({});
22851
- let MessageDataType$1 = /* @__PURE__ */ function(MessageDataType$2) {
22852
- MessageDataType$2["Init"] = "init";
22853
- MessageDataType$2["Sync"] = "sync";
22854
- MessageDataType$2["Awareness"] = "awareness";
22855
- return MessageDataType$2;
22856
- }({});
22857
22862
  const HostUserId = "host";
22858
22863
  var WeaveStoreAzureWebPubSubSyncHost = class {
22859
22864
  _reconnectAttempts = 0;
@@ -22865,6 +22870,7 @@ var WeaveStoreAzureWebPubSubSyncHost = class {
22865
22870
  this.topic = topic;
22866
22871
  this.topicAwarenessChannel = `${topic}-awareness`;
22867
22872
  this._client = client;
22873
+ this._chunkedMessages = new Map();
22868
22874
  this._conn = null;
22869
22875
  this._awareness = new Awareness(this.doc);
22870
22876
  this._awarenessUpdateHandler = ({ added, updated, removed }, origin) => {
@@ -22918,7 +22924,7 @@ var WeaveStoreAzureWebPubSubSyncHost = class {
22918
22924
  event
22919
22925
  });
22920
22926
  ws.send(JSON.stringify({
22921
- type: MessageType$1.JoinGroup,
22927
+ type: MessageType.JoinGroup,
22922
22928
  group: `${group}.host`
22923
22929
  }));
22924
22930
  this.server.emitEvent("onWsJoinGroup", { group: `${group}.host` });
@@ -22931,18 +22937,21 @@ var WeaveStoreAzureWebPubSubSyncHost = class {
22931
22937
  event: e
22932
22938
  });
22933
22939
  const event = JSON.parse(e.data.toString());
22934
- if (event.type === "message" && event.from === "group") switch (event.data.t) {
22935
- case MessageDataType$1.Init:
22936
- this.onClientInit(group, event.data);
22937
- this.onClientSync(group, event.data);
22938
- this.sendInitAwarenessInfo(event.data.f);
22939
- return;
22940
- case MessageDataType$1.Sync:
22941
- this.onClientSync(group, event.data);
22942
- return;
22943
- case MessageDataType$1.Awareness:
22944
- this.onAwareness(group, event.data);
22945
- return;
22940
+ if (event.type === "message" && event.from === "group") {
22941
+ const joinedMessagePayload = handleChunkedMessage(this._chunkedMessages, event.data);
22942
+ switch (event.data.t) {
22943
+ case MessageDataType.Init:
22944
+ this.onClientInit(group, event.data);
22945
+ this.onClientSync(group, event.data.f, joinedMessagePayload ?? event.data.c);
22946
+ this.sendInitAwarenessInfo(event.data.f);
22947
+ return;
22948
+ case MessageDataType.Sync:
22949
+ this.onClientSync(group, event.data.f, joinedMessagePayload ?? event.data.c);
22950
+ return;
22951
+ case MessageDataType.Awareness:
22952
+ this.onAwareness(group, event.data.c);
22953
+ return;
22954
+ }
22946
22955
  }
22947
22956
  });
22948
22957
  ws.addEventListener("close", (e) => {
@@ -22990,16 +22999,51 @@ var WeaveStoreAzureWebPubSubSyncHost = class {
22990
22999
  safeSend(data) {
22991
23000
  const MAX_BYTES = 64 * 1024;
22992
23001
  const bytes = new TextEncoder().encode(data);
22993
- if (bytes.byteLength > MAX_BYTES) {
22994
- console.warn(`Message too large: ${bytes.byteLength} bytes (limit ${MAX_BYTES}). Skipping send.`);
22995
- return false;
22996
- }
23002
+ if (bytes.byteLength > MAX_BYTES) return false;
22997
23003
  return true;
22998
23004
  }
23005
+ chunkString(str, size) {
23006
+ const chunks = [];
23007
+ for (let i = 0; i < str.length; i += size) chunks.push(str.slice(i, i + size));
23008
+ return chunks;
23009
+ }
23010
+ chunkedBroadcast(group, from$1, u8) {
23011
+ const base64Data = Buffer.from(u8).toString("base64");
23012
+ const CHUNK_SIZE = 60 * 1024;
23013
+ const chunks = this.chunkString(base64Data, CHUNK_SIZE);
23014
+ const payloadId = crypto.randomUUID();
23015
+ for (let i = 0; i < chunks.length; i++) {
23016
+ const payload$1 = JSON.stringify({
23017
+ type: MessageType.SendToGroup,
23018
+ group,
23019
+ noEcho: true,
23020
+ data: {
23021
+ payloadId,
23022
+ type: "chunk",
23023
+ index: i,
23024
+ totalChunks: chunks.length,
23025
+ f: from$1,
23026
+ c: chunks[i]
23027
+ }
23028
+ });
23029
+ this._conn?.send?.(payload$1);
23030
+ }
23031
+ const payload = JSON.stringify({
23032
+ type: MessageType.SendToGroup,
23033
+ group,
23034
+ noEcho: true,
23035
+ data: {
23036
+ payloadId,
23037
+ type: "end",
23038
+ f: from$1
23039
+ }
23040
+ });
23041
+ this._conn?.send?.(payload);
23042
+ }
22999
23043
  broadcast(group, from$1, u8) {
23000
23044
  try {
23001
23045
  const payload = JSON.stringify({
23002
- type: MessageType$1.SendToGroup,
23046
+ type: MessageType.SendToGroup,
23003
23047
  group,
23004
23048
  noEcho: true,
23005
23049
  data: {
@@ -23007,16 +23051,52 @@ var WeaveStoreAzureWebPubSubSyncHost = class {
23007
23051
  c: Buffer.from(u8).toString("base64")
23008
23052
  }
23009
23053
  });
23010
- if (!this.safeSend(payload)) return;
23054
+ if (!this.safeSend(payload)) {
23055
+ this.chunkedBroadcast(group, from$1, u8);
23056
+ return;
23057
+ }
23011
23058
  this._conn?.send?.(payload);
23012
23059
  } catch (ex) {
23013
23060
  console.error("Error broadcasting message:", ex);
23014
23061
  }
23015
23062
  }
23063
+ chunkedSend(group, to, u8) {
23064
+ const base64Data = Buffer.from(u8).toString("base64");
23065
+ const CHUNK_SIZE = 60 * 1024;
23066
+ const chunks = this.chunkString(base64Data, CHUNK_SIZE);
23067
+ const payloadId = crypto.randomUUID();
23068
+ for (let i = 0; i < chunks.length; i++) {
23069
+ const payload$1 = JSON.stringify({
23070
+ type: MessageType.SendToGroup,
23071
+ group,
23072
+ noEcho: true,
23073
+ data: {
23074
+ payloadId,
23075
+ type: "chunk",
23076
+ index: i,
23077
+ totalChunks: chunks.length,
23078
+ t: to,
23079
+ c: chunks[i]
23080
+ }
23081
+ });
23082
+ this._conn?.send?.(payload$1);
23083
+ }
23084
+ const payload = JSON.stringify({
23085
+ type: MessageType.SendToGroup,
23086
+ group,
23087
+ noEcho: true,
23088
+ data: {
23089
+ payloadId,
23090
+ type: "end",
23091
+ t: to
23092
+ }
23093
+ });
23094
+ this._conn?.send?.(payload);
23095
+ }
23016
23096
  send(group, to, u8) {
23017
23097
  try {
23018
23098
  const payload = JSON.stringify({
23019
- type: MessageType$1.SendToGroup,
23099
+ type: MessageType.SendToGroup,
23020
23100
  group,
23021
23101
  noEcho: true,
23022
23102
  data: {
@@ -23024,7 +23104,10 @@ var WeaveStoreAzureWebPubSubSyncHost = class {
23024
23104
  c: Buffer.from(u8).toString("base64")
23025
23105
  }
23026
23106
  });
23027
- if (!this.safeSend(payload)) return;
23107
+ if (!this.safeSend(payload)) {
23108
+ this.chunkedSend(group, to, u8);
23109
+ return;
23110
+ }
23028
23111
  this._conn?.send?.(payload);
23029
23112
  } catch (ex) {
23030
23113
  console.error("Error sending message:", ex);
@@ -23037,17 +23120,17 @@ var WeaveStoreAzureWebPubSubSyncHost = class {
23037
23120
  const u8 = toUint8Array(encoder);
23038
23121
  this.send(group, data.f, u8);
23039
23122
  }
23040
- onClientSync(group, data) {
23123
+ onClientSync(group, from$1, data) {
23041
23124
  try {
23042
- const buf = Buffer.from(data.c, "base64");
23125
+ const buf = Buffer.from(data, "base64");
23043
23126
  const encoder = createEncoder();
23044
23127
  const decoder = createDecoder(buf);
23045
23128
  const messageType = readVarUint(decoder);
23046
23129
  switch (messageType) {
23047
23130
  case messageYjsSyncStep1:
23048
23131
  writeVarUint(encoder, messageYjsSyncStep1);
23049
- readSyncMessage(decoder, encoder, this.doc, data.f);
23050
- if (length$1(encoder) > 1) this.send(group, data.f, toUint8Array(encoder));
23132
+ readSyncMessage(decoder, encoder, this.doc, from$1);
23133
+ if (length$1(encoder) > 1) this.send(group, from$1, toUint8Array(encoder));
23051
23134
  break;
23052
23135
  }
23053
23136
  } catch (err) {
@@ -23056,7 +23139,7 @@ var WeaveStoreAzureWebPubSubSyncHost = class {
23056
23139
  }
23057
23140
  onAwareness(_, data) {
23058
23141
  try {
23059
- const buf = Buffer.from(data.c, "base64");
23142
+ const buf = Buffer.from(data, "base64");
23060
23143
  const decoder = createDecoder(buf);
23061
23144
  readVarUint(decoder);
23062
23145
  const update = readVarUint8Array(decoder);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inditextech/weave-store-azure-web-pubsub",
3
- "version": "2.1.0",
3
+ "version": "2.2.0",
4
4
  "type": "module",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Jesus Manuel Piñeiro Cid <jesusmpc@inditex.com>",
@@ -57,8 +57,8 @@
57
57
  "dependencies": {
58
58
  "@azure/identity": "4.10.2",
59
59
  "@azure/web-pubsub": "1.2.0",
60
- "@inditextech/weave-types": "2.1.0",
61
- "@inditextech/weave-sdk": "2.1.0",
60
+ "@inditextech/weave-types": "2.2.0",
61
+ "@inditextech/weave-sdk": "2.2.0",
62
62
  "@syncedstore/core": "0.6.0",
63
63
  "buffer": "6.0.3",
64
64
  "reconnecting-websocket": "4.4.0",