@dcl/sdk 7.3.31 → 7.3.32-7170667436.commit-11a2181

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 (46) hide show
  1. package/internal/transports/logger.js +7 -4
  2. package/internal/transports/rendererTransport.js +3 -2
  3. package/message-bus.js +8 -6
  4. package/network/binary-message-bus.d.ts +18 -0
  5. package/network/binary-message-bus.js +68 -0
  6. package/network/entities.d.ts +11 -0
  7. package/network/entities.js +77 -0
  8. package/network/filter.d.ts +2 -0
  9. package/network/filter.js +37 -0
  10. package/network/index.d.ts +2 -0
  11. package/network/index.js +7 -0
  12. package/network/message-bus-sync.d.ts +17 -0
  13. package/network/message-bus-sync.js +52 -0
  14. package/network/state.js +39 -0
  15. package/network/utils.d.ts +18 -0
  16. package/network/utils.js +69 -0
  17. package/package.json +6 -6
  18. package/src/internal/transports/logger.ts +9 -4
  19. package/src/internal/transports/rendererTransport.ts +2 -1
  20. package/src/message-bus.ts +7 -9
  21. package/src/network/README.md +122 -0
  22. package/src/network/binary-message-bus.ts +72 -0
  23. package/src/network/entities.ts +132 -0
  24. package/src/network/filter.ts +64 -0
  25. package/src/network/index.ts +13 -0
  26. package/src/network/message-bus-sync.ts +97 -0
  27. package/src/network/state.ts +65 -0
  28. package/src/network/utils.ts +145 -0
  29. package/network-transport/client.d.ts +0 -5
  30. package/network-transport/client.js +0 -68
  31. package/network-transport/index.d.ts +0 -10
  32. package/network-transport/index.js +0 -29
  33. package/network-transport/server.d.ts +0 -2
  34. package/network-transport/server.js +0 -62
  35. package/network-transport/state.js +0 -11
  36. package/network-transport/types.d.ts +0 -36
  37. package/network-transport/types.js +0 -7
  38. package/network-transport/utils.d.ts +0 -8
  39. package/network-transport/utils.js +0 -46
  40. package/src/network-transport/client.ts +0 -77
  41. package/src/network-transport/index.ts +0 -45
  42. package/src/network-transport/server.ts +0 -66
  43. package/src/network-transport/state.ts +0 -13
  44. package/src/network-transport/types.ts +0 -41
  45. package/src/network-transport/utils.ts +0 -67
  46. /package/{network-transport → network}/state.d.ts +0 -0
@@ -1,77 +0,0 @@
1
- import { craftMessage, createNetworkManager, encodeString, syncFilter } from './utils'
2
- import { Transport, engine } from '@dcl/ecs'
3
- import { getHeaders } from '~system/SignedFetch'
4
-
5
- import { MessageType, NetworkManager, Socket } from './types'
6
-
7
- export type ClientTransportConfig = {
8
- serverUrl: string
9
- }
10
-
11
- export async function createClientTransport({ serverUrl }: ClientTransportConfig): Promise<NetworkManager> {
12
- const messagesToProcess: Uint8Array[] = []
13
-
14
- return new Promise<NetworkManager>((resolve, reject) => {
15
- try {
16
- const ws = new WebSocket(serverUrl) as Socket
17
- ws.binaryType = 'arraybuffer'
18
-
19
- ws.onopen = async () => {
20
- console.log('WS Server Sync connected')
21
- const { headers } = await getHeaders({ url: serverUrl, init: { headers: {} } })
22
- ws.send(craftMessage(MessageType.Auth, encodeString(JSON.stringify(headers))))
23
-
24
- const transport: Transport = {
25
- filter: syncFilter,
26
- send: async (message: Uint8Array) => {
27
- if (ws.readyState === WebSocket.OPEN) {
28
- ws.send(craftMessage(MessageType.Crdt, message))
29
- }
30
- if (messagesToProcess && messagesToProcess.length) {
31
- if (transport.onmessage) {
32
- for (const byteArray of messagesToProcess) {
33
- transport.onmessage(byteArray)
34
- }
35
- }
36
- }
37
- messagesToProcess.length = 0
38
- }
39
- }
40
- engine.addTransport(transport)
41
- }
42
-
43
- ws.onmessage = (event) => {
44
- if (event.data.byteLength) {
45
- let offset = 0
46
- const r = new Uint8Array(event.data)
47
- const view = new DataView(r.buffer)
48
- const msgType = view.getUint8(offset)
49
- offset += 1
50
-
51
- if (msgType === MessageType.Crdt) {
52
- messagesToProcess.push(r.subarray(offset))
53
- } else if (msgType === MessageType.Init) {
54
- const start = view.getUint32(offset)
55
- offset += 4
56
- const size = view.getUint32(offset)
57
- offset += 4
58
- const localEntitiesReserved = view.getUint32(offset)
59
- offset += 4
60
- resolve(createNetworkManager(localEntitiesReserved, [start, start + size]))
61
- messagesToProcess.push(r.subarray(offset))
62
- }
63
- }
64
- }
65
-
66
- ws.onerror = (e) => {
67
- console.error(e)
68
- reject(e)
69
- }
70
- ws.onclose = () => {
71
- reject(new Error('socket closed'))
72
- }
73
- } catch (err) {
74
- reject(err)
75
- }
76
- })
77
- }
@@ -1,45 +0,0 @@
1
- import { isServer } from '~system/EngineApi'
2
-
3
- import { NetworkManager, ServerTransportConfig } from './types'
4
- import { Schemas, engine } from '@dcl/ecs'
5
- import { createServerTransport } from './server'
6
- import { ClientTransportConfig, createClientTransport } from './client'
7
-
8
- export { NetworkManager } from './types'
9
-
10
- export type NetworkTransportConfig = ClientTransportConfig & Partial<ServerTransportConfig>
11
-
12
- export let connected = false
13
-
14
- const DEFAULT_NETWORK_ENTITY_LIMIT_SERVER = 512
15
- const DEFAULT_NETWORK_ENTITY_LIMIT_CLIENT = 100
16
- const DEFAULT_RESERVED_LOCAL_ENTITIES = 2560
17
-
18
- export let reservedLocalEntities: number
19
- /**
20
- * @alpha
21
- * Connect to CRDT server
22
- */
23
- export async function createNetworkManager(config: NetworkTransportConfig): Promise<NetworkManager> {
24
- if (connected) {
25
- throw new Error('Transport is already created')
26
- }
27
-
28
- const serverConfig = {
29
- networkEntitiesLimit: config.networkEntitiesLimit ?? {
30
- serverLimit: DEFAULT_NETWORK_ENTITY_LIMIT_SERVER,
31
- clientLimit: DEFAULT_NETWORK_ENTITY_LIMIT_CLIENT
32
- },
33
- reservedLocalEntities: config.reservedLocalEntities || DEFAULT_RESERVED_LOCAL_ENTITIES
34
- }
35
- reservedLocalEntities = serverConfig.reservedLocalEntities
36
-
37
- const networkFactory =
38
- isServer && (await isServer({})).isServer ? createServerTransport(serverConfig) : createClientTransport(config)
39
- connected = true
40
- return networkFactory
41
- }
42
-
43
- export const PlayersConnected = engine.defineComponent('chore:network:players', {
44
- usersId: Schemas.Array(Schemas.String)
45
- })
@@ -1,66 +0,0 @@
1
- import { engine, SyncComponents, Transport } from '@dcl/ecs'
2
- import { engineToCrdt } from './state'
3
- import { syncFilter, createNetworkManager } from './utils'
4
- import { NetworkManager, ServerTransportConfig } from './types'
5
- import { PlayersConnected } from '.'
6
-
7
- export async function createServerTransport(config: ServerTransportConfig): Promise<NetworkManager> {
8
- const connectedClients = new Set<string>()
9
- engine.addTransport({
10
- send: async (message) => {
11
- if (message.byteLength) {
12
- globalThis.updateCRDTState(engineToCrdt(engine))
13
- }
14
- },
15
- filter: syncFilter
16
- })
17
-
18
- let time = 0
19
- function initialCrdtState(dt: number) {
20
- time += dt
21
- if (time >= 1) {
22
- globalThis.updateCRDTState(engineToCrdt(engine))
23
- engine.removeSystem(initialCrdtState)
24
- }
25
- }
26
-
27
- engine.addSystem(initialCrdtState)
28
- globalThis.registerScene(config, (event) => {
29
- const { type } = event
30
- if (type === 'open') {
31
- const { clientId, client } = event
32
- const transport: Transport = {
33
- filter: (message) => {
34
- if (!connectedClients.has(clientId)) return false
35
- return syncFilter(message)
36
- },
37
- send: async (message) => {
38
- if (message.byteLength > 0) {
39
- await client.sendCrdtMessage(message)
40
- }
41
-
42
- if (transport.onmessage) {
43
- const messages = client.getMessages()
44
- for (const byteArray of messages) {
45
- transport.onmessage(byteArray)
46
- }
47
- }
48
- }
49
- }
50
-
51
- engine.addTransport(transport)
52
- connectedClients.add(event.clientId)
53
- } else if (type === 'close') {
54
- connectedClients.delete(event.clientId)
55
- }
56
- PlayersConnected.createOrReplace(players, { usersId: [...connectedClients.values()].map(String) })
57
- })
58
-
59
- const networkEntityFactory = createNetworkManager(config.reservedLocalEntities, [
60
- config.reservedLocalEntities,
61
- config.reservedLocalEntities + config.networkEntitiesLimit.serverLimit
62
- ])
63
- const players = networkEntityFactory.addEntity()
64
- SyncComponents.create(players, { componentIds: [PlayersConnected.componentId] })
65
- return networkEntityFactory
66
- }
@@ -1,13 +0,0 @@
1
- import { ReadWriteByteBuffer } from '@dcl/ecs/dist/serialization/ByteBuffer'
2
- import { IEngine, SyncComponents } from '@dcl/ecs'
3
-
4
- export function engineToCrdt(engine: IEngine): Uint8Array {
5
- const crdtBuffer = new ReadWriteByteBuffer()
6
- const syncEntities = new Set(Array.from(engine.getEntitiesWith(SyncComponents)).map(($) => $[0]))
7
-
8
- for (const itComponentDefinition of engine.componentsIter()) {
9
- itComponentDefinition.dumpCrdtStateToBuffer(crdtBuffer, (entity) => syncEntities.has(entity))
10
- }
11
-
12
- return crdtBuffer.toBinary()
13
- }
@@ -1,41 +0,0 @@
1
- import { Entity, engine } from '@dcl/ecs'
2
-
3
- export type Socket = WebSocket & {
4
- binaryType: string
5
- send(data: string | Uint8Array): void
6
- }
7
-
8
- export type NetworkManager = {
9
- addEntity(theEngine: typeof engine): Entity
10
- }
11
-
12
- export enum MessageType {
13
- Auth = 1,
14
- Init = 2,
15
- Crdt = 3
16
- }
17
-
18
- export type ServerTransportConfig = {
19
- reservedLocalEntities: number
20
- networkEntitiesLimit: {
21
- serverLimit: number
22
- clientLimit: number
23
- }
24
- }
25
-
26
- declare global {
27
- type ClientEvent =
28
- | {
29
- type: 'open'
30
- clientId: string
31
- client: {
32
- sendCrdtMessage(message: Uint8Array): Promise<void>
33
- getMessages(): Uint8Array[]
34
- }
35
- }
36
- | { type: 'close'; clientId: string }
37
- // eslint-disable-next-line no-var
38
- var updateCRDTState: (crdt: Uint8Array) => void
39
- // eslint-disable-next-line no-var
40
- var registerScene: (serverConfig: ServerTransportConfig, fn: (event: ClientEvent) => void) => void
41
- }
@@ -1,67 +0,0 @@
1
- import { ReadWriteByteBuffer } from '@dcl/ecs/dist/serialization/ByteBuffer'
2
- import {
3
- engine,
4
- TransportMessage,
5
- PointerEventsResult,
6
- RESERVED_STATIC_ENTITIES,
7
- SyncComponents,
8
- CrdtMessageType,
9
- EntityUtils,
10
- GltfContainerLoadingState
11
- } from '@dcl/ecs'
12
- import { MessageType } from './types'
13
- import { connected, reservedLocalEntities } from '.'
14
-
15
- export function encodeString(s: string): Uint8Array {
16
- const buffer = new ReadWriteByteBuffer()
17
- buffer.writeUtf8String(s)
18
- return buffer.readBuffer()
19
- }
20
-
21
- export function craftMessage(msgType: MessageType, payload: Uint8Array): Uint8Array {
22
- const msg = new Uint8Array(payload.byteLength + 1)
23
- msg.set([msgType])
24
- msg.set(payload, 1)
25
- return msg
26
- }
27
-
28
- export function createNetworkManager(reservedLocalEntities: number, range: [number, number]) {
29
- return engine.addNetworkManager(reservedLocalEntities, range)
30
- }
31
-
32
- export function syncFilter(message: Omit<TransportMessage, 'messageBuffer'>) {
33
- if (!connected) return false
34
- const componentId = (message as any).componentId
35
- if ([PointerEventsResult.componentId, GltfContainerLoadingState.componentId].includes(componentId)) {
36
- return false
37
- }
38
-
39
- const [entityId] = EntityUtils.fromEntityId(message.entityId)
40
- // filter messages from reserved entities.
41
- if (entityId < RESERVED_STATIC_ENTITIES) {
42
- return false
43
- }
44
-
45
- if (entityId < reservedLocalEntities) {
46
- return false
47
- }
48
-
49
- // Network Entity Always
50
- if (message.type === CrdtMessageType.DELETE_ENTITY) {
51
- return true
52
- }
53
-
54
- // TBD: First component
55
- if ((message as any).timestamp <= 1) {
56
- return true
57
- }
58
-
59
- const sync = SyncComponents.getOrNull(message.entityId)
60
- if (!sync) return false
61
-
62
- if ((message as any).componentId && sync.componentIds.includes((message as any).componentId)) {
63
- return true
64
- }
65
-
66
- return false
67
- }
File without changes