@dcl/sdk 7.22.5-24836126953.commit-ddc8da1 → 7.22.5

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 (65) hide show
  1. package/network/binary-message-bus.d.ts +3 -6
  2. package/network/binary-message-bus.js +5 -9
  3. package/network/entities.js +11 -3
  4. package/network/index.d.ts +2 -8
  5. package/network/index.js +3 -16
  6. package/network/message-bus-sync.d.ts +1 -14
  7. package/network/message-bus-sync.js +103 -161
  8. package/network/state.js +10 -5
  9. package/package.json +6 -6
  10. package/src/network/binary-message-bus.ts +4 -9
  11. package/src/network/entities.ts +10 -2
  12. package/src/network/index.ts +3 -40
  13. package/src/network/message-bus-sync.ts +110 -174
  14. package/src/network/state.ts +10 -4
  15. package/atom.d.ts +0 -19
  16. package/atom.js +0 -83
  17. package/future.d.ts +0 -8
  18. package/future.js +0 -26
  19. package/network/chunking.d.ts +0 -5
  20. package/network/chunking.js +0 -38
  21. package/network/events/implementation.d.ts +0 -93
  22. package/network/events/implementation.js +0 -221
  23. package/network/events/index.d.ts +0 -42
  24. package/network/events/index.js +0 -43
  25. package/network/events/protocol.d.ts +0 -27
  26. package/network/events/protocol.js +0 -66
  27. package/network/events/registry.d.ts +0 -8
  28. package/network/events/registry.js +0 -3
  29. package/network/server/index.d.ts +0 -14
  30. package/network/server/index.js +0 -219
  31. package/network/server/utils.d.ts +0 -18
  32. package/network/server/utils.js +0 -135
  33. package/server/env-var.d.ts +0 -15
  34. package/server/env-var.js +0 -31
  35. package/server/index.d.ts +0 -2
  36. package/server/index.js +0 -3
  37. package/server/storage/constants.d.ts +0 -23
  38. package/server/storage/constants.js +0 -2
  39. package/server/storage/index.d.ts +0 -22
  40. package/server/storage/index.js +0 -29
  41. package/server/storage/player.d.ts +0 -43
  42. package/server/storage/player.js +0 -92
  43. package/server/storage/scene.d.ts +0 -38
  44. package/server/storage/scene.js +0 -90
  45. package/server/storage-url.d.ts +0 -10
  46. package/server/storage-url.js +0 -29
  47. package/server/utils.d.ts +0 -35
  48. package/server/utils.js +0 -56
  49. package/src/atom.ts +0 -98
  50. package/src/future.ts +0 -38
  51. package/src/network/chunking.ts +0 -45
  52. package/src/network/events/implementation.ts +0 -271
  53. package/src/network/events/index.ts +0 -48
  54. package/src/network/events/protocol.ts +0 -94
  55. package/src/network/events/registry.ts +0 -18
  56. package/src/network/server/index.ts +0 -301
  57. package/src/network/server/utils.ts +0 -189
  58. package/src/server/env-var.ts +0 -36
  59. package/src/server/index.ts +0 -2
  60. package/src/server/storage/constants.ts +0 -22
  61. package/src/server/storage/index.ts +0 -44
  62. package/src/server/storage/player.ts +0 -156
  63. package/src/server/storage/scene.ts +0 -149
  64. package/src/server/storage-url.ts +0 -34
  65. package/src/server/utils.ts +0 -73
@@ -1,53 +1,27 @@
1
- import { IEngine, Transport, RealmInfo } from '@dcl/ecs'
1
+ import { IEngine, Transport, RealmInfo, PlayerIdentityData } from '@dcl/ecs'
2
2
  import { type SendBinaryRequest, type SendBinaryResponse } from '~system/CommunicationsController'
3
3
 
4
4
  import { syncFilter } from './filter'
5
5
  import { engineToCrdt } from './state'
6
- import { BinaryMessageBus, CommsMessage } from './binary-message-bus'
6
+ import { BinaryMessageBus, CommsMessage, decodeString, encodeString } from './binary-message-bus'
7
7
  import { fetchProfile } from './utils'
8
8
  import { entityUtils } from './entities'
9
- import { createServerValidator } from './server'
10
9
  import { GetUserDataRequest, GetUserDataResponse } from '~system/UserIdentity'
11
10
  import { definePlayerHelper } from '../players'
12
11
  import { serializeCrdtMessages } from '../internal/transports/logger'
13
- import { IsServerRequest, IsServerResponse } from '~system/EngineApi'
14
- import { Atom } from '../atom'
15
- import { setGlobalRoom, Room } from './events/implementation'
16
12
 
17
13
  export type IProfile = { networkId: number; userId: string }
18
14
  // user that we asked for the inital crdt state
19
- export const AUTH_SERVER_PEER_ID = 'authoritative-server'
20
- export const DEBUG_NETWORK_MESSAGES = () => (globalThis as any).DEBUG_NETWORK_MESSAGES ?? false
21
-
22
- // Test environment detection without 'as any'
23
- const isTestEnvironment = (): boolean => {
24
- try {
25
- if (typeof globalThis === 'undefined') return false
26
- const globalWithProcess = globalThis as unknown as { process?: { env?: { NODE_ENV?: string } } }
27
- return globalWithProcess.process?.env?.NODE_ENV === 'test'
28
- } catch {
29
- return false
30
- }
31
- }
32
-
33
15
  export function addSyncTransport(
34
16
  engine: IEngine,
35
17
  sendBinary: (msg: SendBinaryRequest) => Promise<SendBinaryResponse>,
36
- getUserData: (value: GetUserDataRequest) => Promise<GetUserDataResponse>,
37
- isServerFn: (request: IsServerRequest) => Promise<IsServerResponse>,
38
- name: string
18
+ getUserData: (value: GetUserDataRequest) => Promise<GetUserDataResponse>
39
19
  ) {
20
+ const DEBUG_NETWORK_MESSAGES = () => (globalThis as any).DEBUG_NETWORK_MESSAGES ?? false
40
21
  // Profile Info
41
22
  const myProfile: IProfile = {} as IProfile
42
23
  fetchProfile(myProfile!, getUserData)
43
24
 
44
- const isServerAtom = Atom<boolean>()
45
- const isRoomReadyAtom = Atom<boolean>(false)
46
-
47
- void isServerFn({}).then(($: IsServerResponse) => {
48
- return isServerAtom.swap(!!$.isServer)
49
- })
50
-
51
25
  // Entity utils
52
26
  const entityDefinitions = entityUtils(engine, myProfile)
53
27
 
@@ -66,190 +40,108 @@ export function addSyncTransport(
66
40
  const players = definePlayerHelper(engine)
67
41
 
68
42
  let stateIsSyncronized = false
43
+ let transportInitialzed = false
69
44
 
70
- /**
71
- * We need to wait till 2 ticks that is when the engine is ready to send new messages.
72
- * The first tick is for the client engine processing the CRDT messages,
73
- * and the second one are the messages created by the main() function.
74
- * So to avoid sending those messages, that all the clients have, through the network we put this validation here.
75
- */
76
- let tick = 0
77
- const TRANSPORT_INITIALIZED_NUMBER = isTestEnvironment() ? 0 : 2
78
45
  // Add Sync Transport
79
46
  const transport: Transport = {
80
47
  filter: syncFilter(engine),
81
48
  send: async (messages) => {
82
- if (tick <= TRANSPORT_INITIALIZED_NUMBER) tick++
83
- for (const message of tick > TRANSPORT_INITIALIZED_NUMBER ? [messages].flat() : []) {
84
- if (message.byteLength) {
49
+ for (const message of [messages].flat()) {
50
+ if (message.byteLength && transportInitialzed) {
85
51
  DEBUG_NETWORK_MESSAGES() &&
86
52
  console.log(...Array.from(serializeCrdtMessages('[NetworkMessage sent]:', message, engine)))
87
-
88
- // Convert regular messages to network messages for broadcasting with chunking
89
- for (const chunk of serverValidator.convertRegularToNetworkMessage(message)) {
90
- binaryMessageBus.emit(CommsMessage.CRDT, chunk)
91
- }
53
+ binaryMessageBus.emit(CommsMessage.CRDT, message)
92
54
  }
93
55
  }
94
56
  const peerMessages = getMessagesToSend()
57
+ let totalSize = 0
58
+ for (const message of peerMessages) {
59
+ for (const data of message.data) {
60
+ totalSize += data.byteLength
61
+ }
62
+ }
63
+ if (totalSize) {
64
+ DEBUG_NETWORK_MESSAGES() && console.log('Sending network messages: ', totalSize / 1024, 'KB')
65
+ }
95
66
  const response = await sendBinary({ data: [], peerData: peerMessages })
96
67
  binaryMessageBus.__processMessages(response.data)
68
+ transportInitialzed = true
97
69
  },
98
- type: name
70
+ type: 'network'
99
71
  }
100
-
101
- // Server validation setup
102
- const serverValidator = createServerValidator({
103
- engine,
104
- binaryMessageBus
105
- })
106
-
107
- // Initialize Event Bus with registered schemas
108
- const eventBus = new Room(engine, binaryMessageBus, isServerAtom, isRoomReadyAtom)
109
-
110
- // Set global eventBus instance
111
- setGlobalRoom(eventBus)
112
-
113
72
  engine.addTransport(transport)
114
73
  // End add sync transport
115
74
 
116
75
  // Receive & Process CRDT_STATE
117
- binaryMessageBus.on(CommsMessage.REQ_CRDT_STATE, async (data, sender) => {
118
- DEBUG_NETWORK_MESSAGES() && console.log('[REQ_CRDT_STATE]', sender, Date.now())
119
- const chunks = engineToCrdt(engine)
120
- if (chunks.length === 0) {
121
- DEBUG_NETWORK_MESSAGES() && console.log('[Emiting empty state:]', sender, Date.now())
122
- binaryMessageBus.emit(CommsMessage.RES_CRDT_STATE, new Uint8Array(), [sender])
123
- } else {
124
- for (const chunk of chunks) {
125
- DEBUG_NETWORK_MESSAGES() && console.log('[Emiting:]', sender, Date.now())
126
- binaryMessageBus.emit(CommsMessage.RES_CRDT_STATE, chunk, [sender])
127
- }
128
- }
129
- })
130
- binaryMessageBus.on(CommsMessage.RES_CRDT_STATE, async (data, sender) => {
131
- requestingState = false
132
- elapsedTimeSinceRequest = 0
133
- if (isServerAtom.getOrNull() || sender !== AUTH_SERVER_PEER_ID) return
76
+ binaryMessageBus.on(CommsMessage.RES_CRDT_STATE, (value) => {
77
+ const { sender, data } = decodeCRDTState(value)
78
+ if (sender !== myProfile.userId) return
134
79
  DEBUG_NETWORK_MESSAGES() && console.log('[Processing CRDT State]', data.byteLength / 1024, 'KB')
135
- if (data.byteLength > 0) {
136
- transport.onmessage!(serverValidator.processClientMessages(data, sender))
137
- }
80
+ transport.onmessage!(data)
138
81
  stateIsSyncronized = true
82
+ })
83
+
84
+ // Answer to REQ_CRDT_STATE
85
+ binaryMessageBus.on(CommsMessage.REQ_CRDT_STATE, async (_, userId) => {
86
+ DEBUG_NETWORK_MESSAGES() && console.log(`Sending CRDT State to: ${userId}`)
139
87
 
140
- // IMPORTANT: Only mark room as ready AFTER state is synchronized
141
- // This ensures comms is truly connected and working
142
- const realmInfo = RealmInfo.getOrNull(engine.RootEntity)
143
- if (realmInfo) {
144
- DEBUG_NETWORK_MESSAGES() && console.log('[isRoomReady] Marking room as ready after state sync')
145
- isRoomReadyAtom.swap(true)
88
+ for (const chunk of engineToCrdt(engine)) {
89
+ binaryMessageBus.emit(CommsMessage.RES_CRDT_STATE, encodeCRDTState(userId, chunk), [userId])
146
90
  }
147
91
  })
148
92
 
149
- // received message from the network
150
- binaryMessageBus.on(CommsMessage.CRDT, (value, sender) => {
151
- const isServer = isServerAtom.getOrNull()
93
+ // Process CRDT messages here
94
+ binaryMessageBus.on(CommsMessage.CRDT, (value) => {
152
95
  DEBUG_NETWORK_MESSAGES() &&
153
- console.log(
154
- transport.type,
155
- ...Array.from(serializeCrdtMessages('[NetworkMessage received]:', value, engine)),
156
- isServer
157
- )
158
- if (isServer) {
159
- transport.onmessage!(serverValidator.processServerMessages(value, sender))
160
- } else if (sender === AUTH_SERVER_PEER_ID) {
161
- // Process network messages from server and convert to regular messages
162
- transport.onmessage!(serverValidator.processClientMessages(value, sender))
163
- }
96
+ console.log(Array.from(serializeCrdtMessages('[NetworkMessage received]:', value, engine)))
97
+ transport.onmessage!(value)
164
98
  })
165
99
 
166
- // received authoritative message from server - force apply to fix invalid local state
167
- binaryMessageBus.on(CommsMessage.CRDT_AUTHORITATIVE, (value, sender) => {
168
- // Only accept authoritative messages from authoritative server
169
- if (sender !== AUTH_SERVER_PEER_ID) return
100
+ async function requestState(retryCount: number = 1) {
101
+ let players = Array.from(engine.getEntitiesWith(PlayerIdentityData))
102
+ DEBUG_NETWORK_MESSAGES() && console.log(`Requesting state. Players connected: ${players.length - 1}`)
103
+
104
+ if (!RealmInfo.getOrNull(engine.RootEntity)?.isConnectedSceneRoom) {
105
+ DEBUG_NETWORK_MESSAGES() && console.log(`Aborting Requesting state?. Disconnected`)
106
+ return
107
+ }
170
108
 
171
- // DEBUG_NETWORK_MESSAGES() &&
172
- console.log('[AUTHORITATIVE] Received authoritative message from server:', value.byteLength, 'bytes')
109
+ binaryMessageBus.emit(CommsMessage.REQ_CRDT_STATE, new Uint8Array())
173
110
 
174
- // Process authoritative messages by forcing them through normal CRDT processing
175
- // but with a timestamp that's guaranteed to be accepted
176
- const authoritativeBuffer = serverValidator.processClientMessages(value, sender, true)
177
- if (authoritativeBuffer.byteLength > 0) {
178
- // Apply authoritative message through normal transport, but the server's messages
179
- // should be processed as authoritative with special timestamp handling
180
- transport.onmessage!(authoritativeBuffer)
111
+ // Wait ~5s for the response.
112
+ await sleep(5000)
181
113
 
182
- DEBUG_NETWORK_MESSAGES() && console.log('[AUTHORITATIVE] Applied server authoritative message to local state')
114
+ players = Array.from(engine.getEntitiesWith(PlayerIdentityData))
115
+
116
+ if (!stateIsSyncronized) {
117
+ if (players.length > 1 && retryCount <= 2) {
118
+ DEBUG_NETWORK_MESSAGES() &&
119
+ console.log(`Requesting state again ${retryCount} (no response). Players connected: ${players.length - 1}`)
120
+ void requestState(retryCount + 1)
121
+ } else {
122
+ DEBUG_NETWORK_MESSAGES() && console.log('No active players. State syncronized')
123
+ stateIsSyncronized = true
124
+ }
183
125
  }
184
- })
126
+ }
185
127
 
186
128
  players.onEnterScene((player) => {
187
129
  DEBUG_NETWORK_MESSAGES() && console.log('[onEnterScene]', player.userId)
188
- if (!isServerAtom.getOrNull() && myProfile.userId === player.userId) {
189
- requestState()
190
- }
191
130
  })
192
131
 
193
132
  // Asks for the REQ_CRDT_STATE when its connected to comms
194
133
  RealmInfo.onChange(engine.RootEntity, (value) => {
195
- const isServer = isServerAtom.getOrNull()
196
-
197
134
  if (!value?.isConnectedSceneRoom) {
198
- // Only react when actually transitioning from ready to not ready
199
- if (isRoomReadyAtom.getOrNull() === true) {
200
- DEBUG_NETWORK_MESSAGES() && console.log('Disconnected from comms')
201
- isRoomReadyAtom.swap(false)
202
- if (!isServer) {
203
- stateIsSyncronized = false
204
- }
205
- }
135
+ DEBUG_NETWORK_MESSAGES() && console.log('Disconnected from comms')
136
+ stateIsSyncronized = false
206
137
  }
207
138
 
208
139
  if (value?.isConnectedSceneRoom) {
209
- requestState()
210
-
211
- // For servers, mark as ready immediately when connected
212
- // (servers don't need to sync state from anyone)
213
- if (isServer && isRoomReadyAtom.getOrNull() === false) {
214
- DEBUG_NETWORK_MESSAGES() && console.log('[isRoomReady] Server marking room as ready')
215
- isRoomReadyAtom.swap(true)
216
- }
217
- // For clients, room will be marked ready after receiving CRDT state (above)
218
- }
219
- })
220
-
221
- let requestingState = false
222
- let elapsedTimeSinceRequest = 0
223
- const STATE_REQUEST_RETRY_INTERVAL = 2.0 // seconds
224
-
225
- /**
226
- * Why we have to request the state if we have a server that can send us the state when we joined?
227
- * The thing is that when the server detects a new JOIN_PARTICIPANT on livekit room, it sends automatically the state to that peer.
228
- * But in unity, it takes more time, so that message is not being delivered to the client.
229
- * So instead, when we are finally connected to the room, we request the state, and then the server answers with the state :)
230
- *
231
- * If no response is received within 2 seconds, the request is automatically retried.
232
- */
233
- function requestState() {
234
- if (isServerAtom.getOrNull()) return
235
- if (RealmInfo.getOrNull(engine.RootEntity)?.isConnectedSceneRoom && !requestingState) {
236
- requestingState = true
237
- elapsedTimeSinceRequest = 0
238
- DEBUG_NETWORK_MESSAGES() && console.log('Requesting state...')
239
- binaryMessageBus.emit(CommsMessage.REQ_CRDT_STATE, new Uint8Array())
140
+ DEBUG_NETWORK_MESSAGES() && console.log('Connected to comms')
240
141
  }
241
- }
242
142
 
243
- // System to retry state request if no response is received within the retry interval
244
- engine.addSystem((dt: number) => {
245
- if (requestingState && !stateIsSyncronized) {
246
- elapsedTimeSinceRequest += dt
247
- if (elapsedTimeSinceRequest >= STATE_REQUEST_RETRY_INTERVAL) {
248
- DEBUG_NETWORK_MESSAGES() && console.log('State request timed out, retrying...')
249
- elapsedTimeSinceRequest = 0
250
- requestingState = false
251
- requestState()
252
- }
143
+ if (value?.isConnectedSceneRoom && !stateIsSyncronized) {
144
+ void requestState()
253
145
  }
254
146
  })
255
147
 
@@ -261,12 +153,56 @@ export function addSyncTransport(
261
153
  return stateIsSyncronized
262
154
  }
263
155
 
156
+ function sleep(ms: number) {
157
+ return new Promise<void>((resolve) => {
158
+ let timer = 0
159
+ function sleepSystem(dt: number) {
160
+ timer += dt
161
+ if (timer * 1000 >= ms) {
162
+ engine.removeSystem(sleepSystem)
163
+ resolve()
164
+ }
165
+ }
166
+ engine.addSystem(sleepSystem)
167
+ })
168
+ }
169
+
264
170
  return {
265
171
  ...entityDefinitions,
266
172
  myProfile,
267
- isStateSyncronized,
268
- binaryMessageBus,
269
- eventBus,
270
- isRoomReadyAtom
173
+ isStateSyncronized
271
174
  }
272
175
  }
176
+
177
+ /**
178
+ * Messages Protocol Encoding
179
+ *
180
+ * CRDT: Plain Uint8Array
181
+ *
182
+ * CRDT_STATE_RES { sender: string, data: Uint8Array}
183
+ */
184
+ function decodeCRDTState(data: Uint8Array) {
185
+ let offset = 0
186
+ const r = new Uint8Array(data)
187
+ const view = new DataView(r.buffer)
188
+ const senderLength = view.getUint8(offset)
189
+ offset += 1
190
+ const sender = decodeString(data.subarray(1, senderLength + 1))
191
+ offset += senderLength
192
+ const state = r.subarray(offset)
193
+
194
+ return { sender, data: state }
195
+ }
196
+
197
+ function encodeCRDTState(address: string, data: Uint8Array) {
198
+ // address to uint8array
199
+ const addressBuffer = encodeString(address)
200
+ const addressOffset = 1
201
+ const messageLength = addressOffset + addressBuffer.byteLength + data.byteLength
202
+
203
+ const serializedMessage = new Uint8Array(messageLength)
204
+ serializedMessage.set(new Uint8Array([addressBuffer.byteLength]), 0)
205
+ serializedMessage.set(addressBuffer, 1)
206
+ serializedMessage.set(data, addressBuffer.byteLength + 1)
207
+ return serializedMessage
208
+ }
@@ -13,6 +13,8 @@ import {
13
13
  AudioEvent,
14
14
  EngineInfo,
15
15
  GltfContainerLoadingState,
16
+ PhysicsCombinedForce,
17
+ PhysicsCombinedImpulse,
16
18
  PointerEventsResult,
17
19
  RaycastResult,
18
20
  RealmInfo,
@@ -25,7 +27,7 @@ import {
25
27
  UiTransform,
26
28
  ComponentDefinition
27
29
  } from '@dcl/ecs'
28
- import { LIVEKIT_MAX_SIZE } from './server'
30
+ import { LIVEKIT_MAX_SIZE } from '@dcl/ecs/dist/systems/crdt'
29
31
 
30
32
  export const NOT_SYNC_COMPONENTS: ComponentDefinition<unknown>[] = [
31
33
  VideoEvent,
@@ -33,6 +35,8 @@ export const NOT_SYNC_COMPONENTS: ComponentDefinition<unknown>[] = [
33
35
  AudioEvent,
34
36
  EngineInfo,
35
37
  GltfContainerLoadingState,
38
+ PhysicsCombinedForce,
39
+ PhysicsCombinedImpulse,
36
40
  PointerEventsResult,
37
41
  RaycastResult,
38
42
  RealmInfo,
@@ -46,7 +50,8 @@ export const NOT_SYNC_COMPONENTS: ComponentDefinition<unknown>[] = [
46
50
 
47
51
  export const NOT_SYNC_COMPONENTS_IDS = NOT_SYNC_COMPONENTS.map(($) => $.componentId)
48
52
  export const NOT_SYNC_COMPONENTS_NAMES: string[] = [
49
- 'asset-packs::Script' // ComponentName from: https://github.com/decentraland/asset-packs/blob/main/src/enums.ts
53
+ 'asset-packs::Script', // ComponentName from: https://github.com/decentraland/asset-packs/blob/main/src/enums.ts
54
+ 'asset-packs::ActionTypes'
50
55
  ]
51
56
 
52
57
  export function shouldSyncComponent(component: ComponentDefinition<unknown>): boolean {
@@ -72,9 +77,9 @@ export function engineToCrdt(engine: IEngine): Uint8Array[] {
72
77
  if (!shouldSyncComponent(itComponentDefinition)) {
73
78
  continue
74
79
  }
75
-
76
80
  itComponentDefinition.dumpCrdtStateToBuffer(crdtBuffer, (entity) => {
77
- return NetworkEntity.has(entity)
81
+ const isNetworkEntity = NetworkEntity.has(entity)
82
+ return isNetworkEntity
78
83
  })
79
84
  }
80
85
 
@@ -96,6 +101,7 @@ export function engineToCrdt(engine: IEngine): Uint8Array[] {
96
101
  }
97
102
 
98
103
  // If the message itself is larger than the limit, we need to handle it specially
104
+ // For now, we'll skip it to prevent infinite loops
99
105
  if (messageSize / 1024 > LIVEKIT_MAX_SIZE) {
100
106
  console.error(
101
107
  `Message too large (${messageSize} bytes), skipping component ${message.componentId} for entity ${message.entityId}`
package/atom.d.ts DELETED
@@ -1,19 +0,0 @@
1
- declare class SimpleObservable<T> {
2
- private observers;
3
- private onceObservers;
4
- add(callback: (value: T) => void): (value: T) => void;
5
- addOnce(callback: (value: T) => void): void;
6
- remove(callback: (value: T) => void): void;
7
- notifyObservers(value: T): void;
8
- }
9
- declare const EMPTY: unique symbol;
10
- type EMPTY = typeof EMPTY;
11
- export type Atom<T> = {
12
- deref(): Promise<T>;
13
- getOrNull(): T | null;
14
- observable: SimpleObservable<T>;
15
- swap(value: T): T | void;
16
- pipe(fn: (value: T) => void | Promise<void>): Promise<void>;
17
- };
18
- export declare function Atom<T>(initialValue?: T | EMPTY): Atom<T>;
19
- export {};
package/atom.js DELETED
@@ -1,83 +0,0 @@
1
- import future from './future';
2
- // atom value wrapper like in clojure
3
- // Simple Observable implementation to replace Babylon.js dependency
4
- class SimpleObservable {
5
- constructor() {
6
- this.observers = [];
7
- this.onceObservers = [];
8
- }
9
- add(callback) {
10
- this.observers.push(callback);
11
- return callback;
12
- }
13
- addOnce(callback) {
14
- this.onceObservers.push(callback);
15
- }
16
- remove(callback) {
17
- const index = this.observers.indexOf(callback);
18
- if (index > -1) {
19
- this.observers.splice(index, 1);
20
- }
21
- }
22
- notifyObservers(value) {
23
- this.observers.forEach((observer) => observer(value));
24
- if (this.onceObservers.length > 0) {
25
- this.onceObservers.forEach((observer) => observer(value));
26
- this.onceObservers.length = 0;
27
- }
28
- }
29
- }
30
- const EMPTY = Symbol('empty');
31
- export function Atom(initialValue = EMPTY) {
32
- const observable = new SimpleObservable();
33
- let value = initialValue;
34
- const valueFutures = [];
35
- observable.addOnce((value) => {
36
- valueFutures.forEach(($) => $.resolve(value));
37
- valueFutures.length = 0;
38
- });
39
- return {
40
- async pipe(fn) {
41
- observable.add(async (t) => {
42
- try {
43
- await fn(t);
44
- }
45
- catch (err) {
46
- console.error(err);
47
- }
48
- });
49
- if (value !== EMPTY) {
50
- try {
51
- await fn(value);
52
- }
53
- catch (err) {
54
- console.error(err);
55
- }
56
- }
57
- },
58
- deref() {
59
- if (value === EMPTY) {
60
- const ret = future();
61
- valueFutures.push(ret);
62
- return ret;
63
- }
64
- return Promise.resolve(value);
65
- },
66
- getOrNull() {
67
- if (value === EMPTY) {
68
- return null;
69
- }
70
- return value;
71
- },
72
- observable,
73
- swap(newValue) {
74
- const oldValue = value;
75
- if (newValue !== value) {
76
- value = newValue;
77
- observable.notifyObservers(value);
78
- }
79
- return oldValue === EMPTY ? undefined : oldValue;
80
- }
81
- };
82
- }
83
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXRvbS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInNyYy9hdG9tLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sTUFBbUIsTUFBTSxVQUFVLENBQUE7QUFFMUMscUNBQXFDO0FBRXJDLG9FQUFvRTtBQUNwRSxNQUFNLGdCQUFnQjtJQUF0QjtRQUNVLGNBQVMsR0FBMkIsRUFBRSxDQUFBO1FBQ3RDLGtCQUFhLEdBQTJCLEVBQUUsQ0FBQTtJQTBCcEQsQ0FBQztJQXhCQyxHQUFHLENBQUMsUUFBNEI7UUFDOUIsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUE7UUFDN0IsT0FBTyxRQUFRLENBQUE7SUFDakIsQ0FBQztJQUVELE9BQU8sQ0FBQyxRQUE0QjtRQUNsQyxJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQTtJQUNuQyxDQUFDO0lBRUQsTUFBTSxDQUFDLFFBQTRCO1FBQ2pDLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxDQUFBO1FBQzlDLElBQUksS0FBSyxHQUFHLENBQUMsQ0FBQyxFQUFFO1lBQ2QsSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsS0FBSyxFQUFFLENBQUMsQ0FBQyxDQUFBO1NBQ2hDO0lBQ0gsQ0FBQztJQUVELGVBQWUsQ0FBQyxLQUFRO1FBQ3RCLElBQUksQ0FBQyxTQUFTLENBQUMsT0FBTyxDQUFDLENBQUMsUUFBUSxFQUFFLEVBQUUsQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQTtRQUVyRCxJQUFJLElBQUksQ0FBQyxhQUFhLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRTtZQUNqQyxJQUFJLENBQUMsYUFBYSxDQUFDLE9BQU8sQ0FBQyxDQUFDLFFBQVEsRUFBRSxFQUFFLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUE7WUFDekQsSUFBSSxDQUFDLGFBQWEsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFBO1NBQzlCO0lBQ0gsQ0FBQztDQUNGO0FBRUQsTUFBTSxLQUFLLEdBQUcsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFBO0FBVzdCLE1BQU0sVUFBVSxJQUFJLENBQUksZUFBMEIsS0FBSztJQUNyRCxNQUFNLFVBQVUsR0FBRyxJQUFJLGdCQUFnQixFQUFLLENBQUE7SUFDNUMsSUFBSSxLQUFLLEdBQWMsWUFBWSxDQUFBO0lBQ25DLE1BQU0sWUFBWSxHQUFpQixFQUFFLENBQUE7SUFFckMsVUFBVSxDQUFDLE9BQU8sQ0FBQyxDQUFDLEtBQUssRUFBRSxFQUFFO1FBQzNCLFlBQVksQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQTtRQUM3QyxZQUFZLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQTtJQUN6QixDQUFDLENBQUMsQ0FBQTtJQUVGLE9BQU87UUFDTCxLQUFLLENBQUMsSUFBSSxDQUFDLEVBQUU7WUFDWCxVQUFVLENBQUMsR0FBRyxDQUFDLEtBQUssRUFBRSxDQUFDLEVBQUUsRUFBRTtnQkFDekIsSUFBSTtvQkFDRixNQUFNLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQTtpQkFDWjtnQkFBQyxPQUFPLEdBQUcsRUFBRTtvQkFDWixPQUFPLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFBO2lCQUNuQjtZQUNILENBQUMsQ0FBQyxDQUFBO1lBQ0YsSUFBSSxLQUFLLEtBQUssS0FBSyxFQUFFO2dCQUNuQixJQUFJO29CQUNGLE1BQU0sRUFBRSxDQUFDLEtBQUssQ0FBQyxDQUFBO2lCQUNoQjtnQkFBQyxPQUFPLEdBQUcsRUFBRTtvQkFDWixPQUFPLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFBO2lCQUNuQjthQUNGO1FBQ0gsQ0FBQztRQUNELEtBQUs7WUFDSCxJQUFJLEtBQUssS0FBSyxLQUFLLEVBQUU7Z0JBQ25CLE1BQU0sR0FBRyxHQUFHLE1BQU0sRUFBSyxDQUFBO2dCQUN2QixZQUFZLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFBO2dCQUN0QixPQUFPLEdBQUcsQ0FBQTthQUNYO1lBQ0QsT0FBTyxPQUFPLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFBO1FBQy9CLENBQUM7UUFDRCxTQUFTO1lBQ1AsSUFBSSxLQUFLLEtBQUssS0FBSyxFQUFFO2dCQUNuQixPQUFPLElBQUksQ0FBQTthQUNaO1lBQ0QsT0FBTyxLQUFLLENBQUE7UUFDZCxDQUFDO1FBQ0QsVUFBVTtRQUNWLElBQUksQ0FBQyxRQUFRO1lBQ1gsTUFBTSxRQUFRLEdBQUcsS0FBSyxDQUFBO1lBQ3RCLElBQUksUUFBUSxLQUFLLEtBQUssRUFBRTtnQkFDdEIsS0FBSyxHQUFHLFFBQVEsQ0FBQTtnQkFDaEIsVUFBVSxDQUFDLGVBQWUsQ0FBQyxLQUFLLENBQUMsQ0FBQTthQUNsQztZQUNELE9BQU8sUUFBUSxLQUFLLEtBQUssQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUE7UUFDbEQsQ0FBQztLQUNGLENBQUE7QUFDSCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IGZ1dHVyZSwgeyBJRnV0dXJlIH0gZnJvbSAnLi9mdXR1cmUnXG5cbi8vIGF0b20gdmFsdWUgd3JhcHBlciBsaWtlIGluIGNsb2p1cmVcblxuLy8gU2ltcGxlIE9ic2VydmFibGUgaW1wbGVtZW50YXRpb24gdG8gcmVwbGFjZSBCYWJ5bG9uLmpzIGRlcGVuZGVuY3lcbmNsYXNzIFNpbXBsZU9ic2VydmFibGU8VD4ge1xuICBwcml2YXRlIG9ic2VydmVyczogKCh2YWx1ZTogVCkgPT4gdm9pZClbXSA9IFtdXG4gIHByaXZhdGUgb25jZU9ic2VydmVyczogKCh2YWx1ZTogVCkgPT4gdm9pZClbXSA9IFtdXG5cbiAgYWRkKGNhbGxiYWNrOiAodmFsdWU6IFQpID0+IHZvaWQpOiAodmFsdWU6IFQpID0+IHZvaWQge1xuICAgIHRoaXMub2JzZXJ2ZXJzLnB1c2goY2FsbGJhY2spXG4gICAgcmV0dXJuIGNhbGxiYWNrXG4gIH1cblxuICBhZGRPbmNlKGNhbGxiYWNrOiAodmFsdWU6IFQpID0+IHZvaWQpOiB2b2lkIHtcbiAgICB0aGlzLm9uY2VPYnNlcnZlcnMucHVzaChjYWxsYmFjaylcbiAgfVxuXG4gIHJlbW92ZShjYWxsYmFjazogKHZhbHVlOiBUKSA9PiB2b2lkKTogdm9pZCB7XG4gICAgY29uc3QgaW5kZXggPSB0aGlzLm9ic2VydmVycy5pbmRleE9mKGNhbGxiYWNrKVxuICAgIGlmIChpbmRleCA+IC0xKSB7XG4gICAgICB0aGlzLm9ic2VydmVycy5zcGxpY2UoaW5kZXgsIDEpXG4gICAgfVxuICB9XG5cbiAgbm90aWZ5T2JzZXJ2ZXJzKHZhbHVlOiBUKTogdm9pZCB7XG4gICAgdGhpcy5vYnNlcnZlcnMuZm9yRWFjaCgob2JzZXJ2ZXIpID0+IG9ic2VydmVyKHZhbHVlKSlcblxuICAgIGlmICh0aGlzLm9uY2VPYnNlcnZlcnMubGVuZ3RoID4gMCkge1xuICAgICAgdGhpcy5vbmNlT2JzZXJ2ZXJzLmZvckVhY2goKG9ic2VydmVyKSA9PiBvYnNlcnZlcih2YWx1ZSkpXG4gICAgICB0aGlzLm9uY2VPYnNlcnZlcnMubGVuZ3RoID0gMFxuICAgIH1cbiAgfVxufVxuXG5jb25zdCBFTVBUWSA9IFN5bWJvbCgnZW1wdHknKVxudHlwZSBFTVBUWSA9IHR5cGVvZiBFTVBUWVxuXG5leHBvcnQgdHlwZSBBdG9tPFQ+ID0ge1xuICBkZXJlZigpOiBQcm9taXNlPFQ+XG4gIGdldE9yTnVsbCgpOiBUIHwgbnVsbFxuICBvYnNlcnZhYmxlOiBTaW1wbGVPYnNlcnZhYmxlPFQ+XG4gIHN3YXAodmFsdWU6IFQpOiBUIHwgdm9pZFxuICBwaXBlKGZuOiAodmFsdWU6IFQpID0+IHZvaWQgfCBQcm9taXNlPHZvaWQ+KTogUHJvbWlzZTx2b2lkPlxufVxuXG5leHBvcnQgZnVuY3Rpb24gQXRvbTxUPihpbml0aWFsVmFsdWU6IFQgfCBFTVBUWSA9IEVNUFRZKTogQXRvbTxUPiB7XG4gIGNvbnN0IG9ic2VydmFibGUgPSBuZXcgU2ltcGxlT2JzZXJ2YWJsZTxUPigpXG4gIGxldCB2YWx1ZTogVCB8IEVNUFRZID0gaW5pdGlhbFZhbHVlXG4gIGNvbnN0IHZhbHVlRnV0dXJlczogSUZ1dHVyZTxUPltdID0gW11cblxuICBvYnNlcnZhYmxlLmFkZE9uY2UoKHZhbHVlKSA9PiB7XG4gICAgdmFsdWVGdXR1cmVzLmZvckVhY2goKCQpID0+ICQucmVzb2x2ZSh2YWx1ZSkpXG4gICAgdmFsdWVGdXR1cmVzLmxlbmd0aCA9IDBcbiAgfSlcblxuICByZXR1cm4ge1xuICAgIGFzeW5jIHBpcGUoZm4pIHtcbiAgICAgIG9ic2VydmFibGUuYWRkKGFzeW5jICh0KSA9PiB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgYXdhaXQgZm4odClcbiAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgY29uc29sZS5lcnJvcihlcnIpXG4gICAgICAgIH1cbiAgICAgIH0pXG4gICAgICBpZiAodmFsdWUgIT09IEVNUFRZKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgYXdhaXQgZm4odmFsdWUpXG4gICAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyKVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfSxcbiAgICBkZXJlZigpIHtcbiAgICAgIGlmICh2YWx1ZSA9PT0gRU1QVFkpIHtcbiAgICAgICAgY29uc3QgcmV0ID0gZnV0dXJlPFQ+KClcbiAgICAgICAgdmFsdWVGdXR1cmVzLnB1c2gocmV0KVxuICAgICAgICByZXR1cm4gcmV0XG4gICAgICB9XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHZhbHVlKVxuICAgIH0sXG4gICAgZ2V0T3JOdWxsKCkge1xuICAgICAgaWYgKHZhbHVlID09PSBFTVBUWSkge1xuICAgICAgICByZXR1cm4gbnVsbFxuICAgICAgfVxuICAgICAgcmV0dXJuIHZhbHVlXG4gICAgfSxcbiAgICBvYnNlcnZhYmxlLFxuICAgIHN3YXAobmV3VmFsdWUpIHtcbiAgICAgIGNvbnN0IG9sZFZhbHVlID0gdmFsdWVcbiAgICAgIGlmIChuZXdWYWx1ZSAhPT0gdmFsdWUpIHtcbiAgICAgICAgdmFsdWUgPSBuZXdWYWx1ZVxuICAgICAgICBvYnNlcnZhYmxlLm5vdGlmeU9ic2VydmVycyh2YWx1ZSlcbiAgICAgIH1cbiAgICAgIHJldHVybiBvbGRWYWx1ZSA9PT0gRU1QVFkgPyB1bmRlZmluZWQgOiBvbGRWYWx1ZVxuICAgIH1cbiAgfVxufVxuIl19
package/future.d.ts DELETED
@@ -1,8 +0,0 @@
1
- export type IFuture<T> = Promise<T> & {
2
- resolve: (x: T) => void;
3
- reject: (x: Error) => void;
4
- finally: (fn: () => void) => void;
5
- isPending: boolean;
6
- };
7
- export declare function future<T = any>(): IFuture<T>;
8
- export default future;
package/future.js DELETED
@@ -1,26 +0,0 @@
1
- export function future() {
2
- let resolver;
3
- let rejecter;
4
- const promise = new Promise((ok, err) => {
5
- resolver = (x) => {
6
- ok(x);
7
- promise.isPending = false;
8
- };
9
- rejecter = (x) => {
10
- err(x);
11
- promise.isPending = false;
12
- };
13
- }).catch((e) => Promise.reject(e));
14
- promise.resolve = resolver;
15
- promise.reject = rejecter;
16
- if (!('finally' in promise)) {
17
- promise.finally = (fn) => {
18
- promise.then(fn);
19
- promise.catch(fn);
20
- };
21
- }
22
- promise.isPending = true;
23
- return promise;
24
- }
25
- export default future;
26
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZnV0dXJlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsic3JjL2Z1dHVyZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFPQSxNQUFNLFVBQVUsTUFBTTtJQUNwQixJQUFJLFFBQXdCLENBQUE7SUFDNUIsSUFBSSxRQUE0QixDQUFBO0lBRWhDLE1BQU0sT0FBTyxHQUFRLElBQUksT0FBTyxDQUFDLENBQUMsRUFBRSxFQUFFLEdBQUcsRUFBRSxFQUFFO1FBQzNDLFFBQVEsR0FBRyxDQUFDLENBQUksRUFBRSxFQUFFO1lBQ2xCLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQTtZQUNMLE9BQU8sQ0FBQyxTQUFTLEdBQUcsS0FBSyxDQUFBO1FBQzNCLENBQUMsQ0FBQTtRQUNELFFBQVEsR0FBRyxDQUFDLENBQVEsRUFBRSxFQUFFO1lBQ3RCLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQTtZQUNOLE9BQU8sQ0FBQyxTQUFTLEdBQUcsS0FBSyxDQUFBO1FBQzNCLENBQUMsQ0FBQTtJQUNILENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFBO0lBRWxDLE9BQU8sQ0FBQyxPQUFPLEdBQUcsUUFBUyxDQUFBO0lBQzNCLE9BQU8sQ0FBQyxNQUFNLEdBQUcsUUFBUyxDQUFBO0lBRTFCLElBQUksQ0FBQyxDQUFDLFNBQVMsSUFBSSxPQUFPLENBQUMsRUFBRTtRQUMzQixPQUFPLENBQUMsT0FBTyxHQUFHLENBQUMsRUFBTyxFQUFFLEVBQUU7WUFDNUIsT0FBTyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQTtZQUNoQixPQUFPLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxDQUFBO1FBQ25CLENBQUMsQ0FBQTtLQUNGO0lBRUQsT0FBTyxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUE7SUFFeEIsT0FBTyxPQUFxQixDQUFBO0FBQzlCLENBQUM7QUFFRCxlQUFlLE1BQU0sQ0FBQSIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCB0eXBlIElGdXR1cmU8VD4gPSBQcm9taXNlPFQ+ICYge1xuICByZXNvbHZlOiAoeDogVCkgPT4gdm9pZFxuICByZWplY3Q6ICh4OiBFcnJvcikgPT4gdm9pZFxuICBmaW5hbGx5OiAoZm46ICgpID0+IHZvaWQpID0+IHZvaWRcbiAgaXNQZW5kaW5nOiBib29sZWFuXG59XG5cbmV4cG9ydCBmdW5jdGlvbiBmdXR1cmU8VCA9IGFueT4oKTogSUZ1dHVyZTxUPiB7XG4gIGxldCByZXNvbHZlcjogKHg6IFQpID0+IHZvaWRcbiAgbGV0IHJlamVjdGVyOiAoeDogRXJyb3IpID0+IHZvaWRcblxuICBjb25zdCBwcm9taXNlOiBhbnkgPSBuZXcgUHJvbWlzZSgob2ssIGVycikgPT4ge1xuICAgIHJlc29sdmVyID0gKHg6IFQpID0+IHtcbiAgICAgIG9rKHgpXG4gICAgICBwcm9taXNlLmlzUGVuZGluZyA9IGZhbHNlXG4gICAgfVxuICAgIHJlamVjdGVyID0gKHg6IEVycm9yKSA9PiB7XG4gICAgICBlcnIoeClcbiAgICAgIHByb21pc2UuaXNQZW5kaW5nID0gZmFsc2VcbiAgICB9XG4gIH0pLmNhdGNoKChlKSA9PiBQcm9taXNlLnJlamVjdChlKSlcblxuICBwcm9taXNlLnJlc29sdmUgPSByZXNvbHZlciFcbiAgcHJvbWlzZS5yZWplY3QgPSByZWplY3RlciFcblxuICBpZiAoISgnZmluYWxseScgaW4gcHJvbWlzZSkpIHtcbiAgICBwcm9taXNlLmZpbmFsbHkgPSAoZm46IGFueSkgPT4ge1xuICAgICAgcHJvbWlzZS50aGVuKGZuKVxuICAgICAgcHJvbWlzZS5jYXRjaChmbilcbiAgICB9XG4gIH1cblxuICBwcm9taXNlLmlzUGVuZGluZyA9IHRydWVcblxuICByZXR1cm4gcHJvbWlzZSBhcyBJRnV0dXJlPFQ+XG59XG5cbmV4cG9ydCBkZWZhdWx0IGZ1dHVyZVxuIl19
@@ -1,5 +0,0 @@
1
- /**
2
- * Chunks CRDT messages from a Uint8Array buffer, respecting message boundaries
3
- * Uses the comprehensive readMessages function that handles all message types
4
- */
5
- export declare function chunkCrdtMessages(data: Uint8Array, maxSizeKB?: number): Uint8Array[];
@@ -1,38 +0,0 @@
1
- import { ReadWriteByteBuffer } from '@dcl/ecs/dist/serialization/ByteBuffer';
2
- import { readMessages } from './server/utils';
3
- /**
4
- * Chunks CRDT messages from a Uint8Array buffer, respecting message boundaries
5
- * Uses the comprehensive readMessages function that handles all message types
6
- */
7
- export function chunkCrdtMessages(data, maxSizeKB = 12) {
8
- if (data.length === 0) {
9
- return [];
10
- }
11
- const networkBuffer = new ReadWriteByteBuffer();
12
- const chunks = [];
13
- for (const message of readMessages(data)) {
14
- // Check if adding this message would exceed the size limit
15
- const currentBufferSize = networkBuffer.toBinary().byteLength;
16
- const messageSize = message.messageBuffer.byteLength;
17
- if ((currentBufferSize + messageSize) / 1024 > maxSizeKB) {
18
- // If the current buffer has content, save it as a chunk
19
- if (currentBufferSize > 0) {
20
- chunks.push(networkBuffer.toCopiedBinary());
21
- networkBuffer.resetBuffer();
22
- }
23
- // If the message itself is larger than the limit, skip it
24
- if (messageSize / 1024 > maxSizeKB) {
25
- console.error(`Message too large (${messageSize} bytes), skipping CRDT message`);
26
- continue;
27
- }
28
- }
29
- // Add message to current buffer
30
- networkBuffer.writeBuffer(message.messageBuffer, false);
31
- }
32
- // Add any remaining data as the final chunk
33
- if (networkBuffer.currentWriteOffset() > 0) {
34
- chunks.push(networkBuffer.toBinary());
35
- }
36
- return chunks;
37
- }
38
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2h1bmtpbmcuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvbmV0d29yay9jaHVua2luZy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSx3Q0FBd0MsQ0FBQTtBQUM1RSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sZ0JBQWdCLENBQUE7QUFFN0M7OztHQUdHO0FBQ0gsTUFBTSxVQUFVLGlCQUFpQixDQUFDLElBQWdCLEVBQUUsWUFBb0IsRUFBRTtJQUN4RSxJQUFJLElBQUksQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFO1FBQ3JCLE9BQU8sRUFBRSxDQUFBO0tBQ1Y7SUFFRCxNQUFNLGFBQWEsR0FBRyxJQUFJLG1CQUFtQixFQUFFLENBQUE7SUFDL0MsTUFBTSxNQUFNLEdBQWlCLEVBQUUsQ0FBQTtJQUUvQixLQUFLLE1BQU0sT0FBTyxJQUFJLFlBQVksQ0FBQyxJQUFJLENBQUMsRUFBRTtRQUN4QywyREFBMkQ7UUFDM0QsTUFBTSxpQkFBaUIsR0FBRyxhQUFhLENBQUMsUUFBUSxFQUFFLENBQUMsVUFBVSxDQUFBO1FBQzdELE1BQU0sV0FBVyxHQUFHLE9BQU8sQ0FBQyxhQUFhLENBQUMsVUFBVSxDQUFBO1FBRXBELElBQUksQ0FBQyxpQkFBaUIsR0FBRyxXQUFXLENBQUMsR0FBRyxJQUFJLEdBQUcsU0FBUyxFQUFFO1lBQ3hELHdEQUF3RDtZQUN4RCxJQUFJLGlCQUFpQixHQUFHLENBQUMsRUFBRTtnQkFDekIsTUFBTSxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsY0FBYyxFQUFFLENBQUMsQ0FBQTtnQkFDM0MsYUFBYSxDQUFDLFdBQVcsRUFBRSxDQUFBO2FBQzVCO1lBRUQsMERBQTBEO1lBQzFELElBQUksV0FBVyxHQUFHLElBQUksR0FBRyxTQUFTLEVBQUU7Z0JBQ2xDLE9BQU8sQ0FBQyxLQUFLLENBQUMsc0JBQXNCLFdBQVcsZ0NBQWdDLENBQUMsQ0FBQTtnQkFDaEYsU0FBUTthQUNUO1NBQ0Y7UUFFRCxnQ0FBZ0M7UUFDaEMsYUFBYSxDQUFDLFdBQVcsQ0FBQyxPQUFPLENBQUMsYUFBYSxFQUFFLEtBQUssQ0FBQyxDQUFBO0tBQ3hEO0lBRUQsNENBQTRDO0lBQzVDLElBQUksYUFBYSxDQUFDLGtCQUFrQixFQUFFLEdBQUcsQ0FBQyxFQUFFO1FBQzFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUE7S0FDdEM7SUFFRCxPQUFPLE1BQU0sQ0FBQTtBQUNmLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBSZWFkV3JpdGVCeXRlQnVmZmVyIH0gZnJvbSAnQGRjbC9lY3MvZGlzdC9zZXJpYWxpemF0aW9uL0J5dGVCdWZmZXInXG5pbXBvcnQgeyByZWFkTWVzc2FnZXMgfSBmcm9tICcuL3NlcnZlci91dGlscydcblxuLyoqXG4gKiBDaHVua3MgQ1JEVCBtZXNzYWdlcyBmcm9tIGEgVWludDhBcnJheSBidWZmZXIsIHJlc3BlY3RpbmcgbWVzc2FnZSBib3VuZGFyaWVzXG4gKiBVc2VzIHRoZSBjb21wcmVoZW5zaXZlIHJlYWRNZXNzYWdlcyBmdW5jdGlvbiB0aGF0IGhhbmRsZXMgYWxsIG1lc3NhZ2UgdHlwZXNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNodW5rQ3JkdE1lc3NhZ2VzKGRhdGE6IFVpbnQ4QXJyYXksIG1heFNpemVLQjogbnVtYmVyID0gMTIpOiBVaW50OEFycmF5W10ge1xuICBpZiAoZGF0YS5sZW5ndGggPT09IDApIHtcbiAgICByZXR1cm4gW11cbiAgfVxuXG4gIGNvbnN0IG5ldHdvcmtCdWZmZXIgPSBuZXcgUmVhZFdyaXRlQnl0ZUJ1ZmZlcigpXG4gIGNvbnN0IGNodW5rczogVWludDhBcnJheVtdID0gW11cblxuICBmb3IgKGNvbnN0IG1lc3NhZ2Ugb2YgcmVhZE1lc3NhZ2VzKGRhdGEpKSB7XG4gICAgLy8gQ2hlY2sgaWYgYWRkaW5nIHRoaXMgbWVzc2FnZSB3b3VsZCBleGNlZWQgdGhlIHNpemUgbGltaXRcbiAgICBjb25zdCBjdXJyZW50QnVmZmVyU2l6ZSA9IG5ldHdvcmtCdWZmZXIudG9CaW5hcnkoKS5ieXRlTGVuZ3RoXG4gICAgY29uc3QgbWVzc2FnZVNpemUgPSBtZXNzYWdlLm1lc3NhZ2VCdWZmZXIuYnl0ZUxlbmd0aFxuXG4gICAgaWYgKChjdXJyZW50QnVmZmVyU2l6ZSArIG1lc3NhZ2VTaXplKSAvIDEwMjQgPiBtYXhTaXplS0IpIHtcbiAgICAgIC8vIElmIHRoZSBjdXJyZW50IGJ1ZmZlciBoYXMgY29udGVudCwgc2F2ZSBpdCBhcyBhIGNodW5rXG4gICAgICBpZiAoY3VycmVudEJ1ZmZlclNpemUgPiAwKSB7XG4gICAgICAgIGNodW5rcy5wdXNoKG5ldHdvcmtCdWZmZXIudG9Db3BpZWRCaW5hcnkoKSlcbiAgICAgICAgbmV0d29ya0J1ZmZlci5yZXNldEJ1ZmZlcigpXG4gICAgICB9XG5cbiAgICAgIC8vIElmIHRoZSBtZXNzYWdlIGl0c2VsZiBpcyBsYXJnZXIgdGhhbiB0aGUgbGltaXQsIHNraXAgaXRcbiAgICAgIGlmIChtZXNzYWdlU2l6ZSAvIDEwMjQgPiBtYXhTaXplS0IpIHtcbiAgICAgICAgY29uc29sZS5lcnJvcihgTWVzc2FnZSB0b28gbGFyZ2UgKCR7bWVzc2FnZVNpemV9IGJ5dGVzKSwgc2tpcHBpbmcgQ1JEVCBtZXNzYWdlYClcbiAgICAgICAgY29udGludWVcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBBZGQgbWVzc2FnZSB0byBjdXJyZW50IGJ1ZmZlclxuICAgIG5ldHdvcmtCdWZmZXIud3JpdGVCdWZmZXIobWVzc2FnZS5tZXNzYWdlQnVmZmVyLCBmYWxzZSlcbiAgfVxuXG4gIC8vIEFkZCBhbnkgcmVtYWluaW5nIGRhdGEgYXMgdGhlIGZpbmFsIGNodW5rXG4gIGlmIChuZXR3b3JrQnVmZmVyLmN1cnJlbnRXcml0ZU9mZnNldCgpID4gMCkge1xuICAgIGNodW5rcy5wdXNoKG5ldHdvcmtCdWZmZXIudG9CaW5hcnkoKSlcbiAgfVxuXG4gIHJldHVybiBjaHVua3Ncbn1cbiJdfQ==