@symbo.ls/sdk 3.1.1 → 3.2.3
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/README.md +174 -13
- package/dist/cjs/config/environment.js +32 -42
- package/dist/cjs/index.js +31 -24
- package/dist/cjs/services/AIService.js +3 -3
- package/dist/cjs/services/AuthService.js +44 -3
- package/dist/cjs/services/BasedService.js +530 -24
- package/dist/cjs/services/CollabService.js +420 -0
- package/dist/cjs/services/CoreService.js +2295 -0
- package/dist/cjs/services/SocketService.js +207 -59
- package/dist/cjs/services/SymstoryService.js +135 -49
- package/dist/cjs/services/index.js +8 -16
- package/dist/cjs/state/RootStateManager.js +86 -0
- package/dist/cjs/state/rootEventBus.js +65 -0
- package/dist/cjs/utils/CollabClient.js +157 -0
- package/dist/cjs/utils/TokenManager.js +409 -0
- package/dist/cjs/utils/basedQuerys.js +120 -0
- package/dist/cjs/utils/jsonDiff.js +103 -0
- package/dist/cjs/utils/permission.js +4 -4
- package/dist/cjs/utils/services.js +133 -69
- package/dist/cjs/utils/symstoryClient.js +33 -2
- package/dist/esm/config/environment.js +32 -42
- package/dist/esm/index.js +20586 -11525
- package/dist/esm/services/AIService.js +3 -3
- package/dist/esm/services/AuthService.js +48 -7
- package/dist/esm/services/BasedService.js +676 -65
- package/dist/esm/services/CollabService.js +18028 -0
- package/dist/esm/services/CoreService.js +2827 -0
- package/dist/esm/services/SocketService.js +323 -58
- package/dist/esm/services/SymstoryService.js +287 -111
- package/dist/esm/services/index.js +20456 -11470
- package/dist/esm/state/RootStateManager.js +102 -0
- package/dist/esm/state/rootEventBus.js +47 -0
- package/dist/esm/utils/CollabClient.js +17483 -0
- package/dist/esm/utils/TokenManager.js +395 -0
- package/dist/esm/utils/basedQuerys.js +120 -0
- package/dist/esm/utils/jsonDiff.js +6096 -0
- package/dist/esm/utils/permission.js +4 -4
- package/dist/esm/utils/services.js +133 -69
- package/dist/esm/utils/symstoryClient.js +63 -43
- package/dist/esm/utils/validation.js +89 -19
- package/dist/node/config/environment.js +32 -42
- package/dist/node/index.js +37 -28
- package/dist/node/services/AIService.js +3 -3
- package/dist/node/services/AuthService.js +44 -3
- package/dist/node/services/BasedService.js +531 -25
- package/dist/node/services/CollabService.js +401 -0
- package/dist/node/services/CoreService.js +2266 -0
- package/dist/node/services/SocketService.js +197 -59
- package/dist/node/services/SymstoryService.js +135 -49
- package/dist/node/services/index.js +8 -16
- package/dist/node/state/RootStateManager.js +57 -0
- package/dist/node/state/rootEventBus.js +46 -0
- package/dist/node/utils/CollabClient.js +128 -0
- package/dist/node/utils/TokenManager.js +390 -0
- package/dist/node/utils/basedQuerys.js +120 -0
- package/dist/node/utils/jsonDiff.js +74 -0
- package/dist/node/utils/permission.js +4 -4
- package/dist/node/utils/services.js +133 -69
- package/dist/node/utils/symstoryClient.js +33 -2
- package/package.json +23 -14
- package/src/config/environment.js +33 -42
- package/src/index.js +45 -28
- package/src/services/AIService.js +3 -3
- package/src/services/AuthService.js +52 -3
- package/src/services/BasedService.js +603 -23
- package/src/services/CollabService.js +491 -0
- package/src/services/CoreService.js +2548 -0
- package/src/services/SocketService.js +227 -59
- package/src/services/SymstoryService.js +150 -64
- package/src/services/index.js +7 -14
- package/src/state/RootStateManager.js +71 -0
- package/src/state/rootEventBus.js +48 -0
- package/src/utils/CollabClient.js +161 -0
- package/src/utils/TokenManager.js +462 -0
- package/src/utils/basedQuerys.js +123 -0
- package/src/utils/jsonDiff.js +109 -0
- package/src/utils/permission.js +4 -4
- package/src/utils/services.js +144 -69
- package/src/utils/symstoryClient.js +36 -2
- package/dist/cjs/services/SocketIOService.js +0 -309
- package/dist/esm/services/SocketIOService.js +0 -467
- package/dist/node/services/SocketIOService.js +0 -280
- package/src/services/SocketIOService.js +0 -356
|
@@ -1,4 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { connect, send, disconnect } from '@symbo.ls/socket/client.js'
|
|
2
|
+
import { BaseService } from './BaseService.js'
|
|
3
|
+
|
|
4
|
+
import * as utils from '@domql/utils'
|
|
5
|
+
import { router } from '@symbo.ls/router'
|
|
6
|
+
import environment from '../config/environment.js'
|
|
7
|
+
|
|
8
|
+
const { deepStringify, deepDestringify, isString } = utils.default || utils
|
|
2
9
|
|
|
3
10
|
export class SocketService extends BaseService {
|
|
4
11
|
constructor (config) {
|
|
@@ -8,14 +15,31 @@ export class SocketService extends BaseService {
|
|
|
8
15
|
this._maxReconnectAttempts = config?.maxReconnectAttempts || 5
|
|
9
16
|
this._reconnectDelay = config?.reconnectDelay || 1000
|
|
10
17
|
this._handlers = new Map()
|
|
18
|
+
this._sessionId = Math.random()
|
|
19
|
+
|
|
20
|
+
this._ignoreSync = [
|
|
21
|
+
'userId',
|
|
22
|
+
'username',
|
|
23
|
+
'usersName',
|
|
24
|
+
'email',
|
|
25
|
+
'projects',
|
|
26
|
+
'feedbacks',
|
|
27
|
+
'userRoles',
|
|
28
|
+
'loading',
|
|
29
|
+
'appKey',
|
|
30
|
+
'projectName',
|
|
31
|
+
'followingUser',
|
|
32
|
+
'activeProject',
|
|
33
|
+
'user',
|
|
34
|
+
'sessionId',
|
|
35
|
+
'clients'
|
|
36
|
+
]
|
|
11
37
|
}
|
|
12
38
|
|
|
13
|
-
|
|
39
|
+
init () {
|
|
14
40
|
try {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
const { authToken } = context
|
|
18
|
-
const { socketUrl } = context.socket || {}
|
|
41
|
+
const { _context, _options } = this
|
|
42
|
+
const socketUrl = environment.socketUrl || _options.socketUrl
|
|
19
43
|
|
|
20
44
|
if (!socketUrl) {
|
|
21
45
|
throw new Error('Socket URL is required')
|
|
@@ -24,12 +48,11 @@ export class SocketService extends BaseService {
|
|
|
24
48
|
this._info = {
|
|
25
49
|
config: {
|
|
26
50
|
url: socketUrl,
|
|
27
|
-
hasToken: Boolean(authToken),
|
|
51
|
+
hasToken: Boolean(_context.authToken),
|
|
28
52
|
status: 'initializing'
|
|
29
53
|
}
|
|
30
54
|
}
|
|
31
55
|
|
|
32
|
-
await this.connect()
|
|
33
56
|
this._setReady()
|
|
34
57
|
} catch (error) {
|
|
35
58
|
this._setError(error)
|
|
@@ -39,93 +62,233 @@ export class SocketService extends BaseService {
|
|
|
39
62
|
|
|
40
63
|
connect () {
|
|
41
64
|
try {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
65
|
+
// Check if already connected or connecting
|
|
66
|
+
if (
|
|
67
|
+
this._socket &&
|
|
68
|
+
['connected', 'connecting'].includes(this._info?.config?.status)
|
|
69
|
+
) {
|
|
70
|
+
console.warn(
|
|
71
|
+
'Socket connection already exists:',
|
|
72
|
+
this._info?.config?.status
|
|
73
|
+
)
|
|
74
|
+
return true
|
|
75
|
+
}
|
|
45
76
|
|
|
46
|
-
|
|
47
|
-
this._reconnectAttempts = 0
|
|
48
|
-
this._updateStatus('connected')
|
|
77
|
+
const { _context } = this
|
|
49
78
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
this.send('auth', { token: authToken })
|
|
53
|
-
}
|
|
79
|
+
if (!_context.appKey) {
|
|
80
|
+
throw new Error('App key is required')
|
|
54
81
|
}
|
|
55
82
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
83
|
+
// Update status to connecting before attempting connection
|
|
84
|
+
this._updateStatus('connecting')
|
|
85
|
+
|
|
86
|
+
const config = {
|
|
87
|
+
source: 'platform',
|
|
88
|
+
userId: _context.user?.id,
|
|
89
|
+
socketUrl: this._info.config.url,
|
|
90
|
+
location: window.location.host,
|
|
91
|
+
// onConnect: () => {
|
|
92
|
+
// console.log('waz')
|
|
93
|
+
// },
|
|
94
|
+
onChange: this._handleMessage.bind(this),
|
|
95
|
+
sessionId: this._sessionId,
|
|
96
|
+
usersName: _context.user?.name,
|
|
97
|
+
route: window.location.pathname,
|
|
98
|
+
onDisconnect: this._handleDisconnect.bind(this)
|
|
59
99
|
}
|
|
60
100
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
this.
|
|
101
|
+
// If a previous socket exists but wasn't properly cleaned up, destroy it
|
|
102
|
+
if (this._socket) {
|
|
103
|
+
this.destroy()
|
|
64
104
|
}
|
|
65
105
|
|
|
66
|
-
this._socket
|
|
67
|
-
|
|
106
|
+
this._socket = connect(_context.appKey, config)
|
|
107
|
+
this._updateStatus('connected')
|
|
108
|
+
|
|
109
|
+
if (environment.isDevelopment) {
|
|
110
|
+
console.log('Socket connection established:', {
|
|
111
|
+
appKey: _context.appKey,
|
|
112
|
+
userId: _context.user?.id,
|
|
113
|
+
sessionId: this._sessionId,
|
|
114
|
+
url: this._info.config.url
|
|
115
|
+
})
|
|
68
116
|
}
|
|
117
|
+
|
|
118
|
+
return true
|
|
69
119
|
} catch (error) {
|
|
120
|
+
this._updateStatus('failed')
|
|
121
|
+
console.error('Socket connection failed:', error)
|
|
70
122
|
throw new Error(`Socket connection failed: ${error.message}`)
|
|
71
123
|
}
|
|
72
124
|
}
|
|
73
125
|
|
|
74
|
-
|
|
75
|
-
send (type, data) {
|
|
126
|
+
send (type, data, opts = {}) {
|
|
76
127
|
this._requireReady()
|
|
77
128
|
|
|
78
|
-
if (!this._socket
|
|
129
|
+
if (!this._socket) {
|
|
79
130
|
throw new Error('Socket is not connected')
|
|
80
131
|
}
|
|
81
132
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
if (!this._handlers.has(type)) {
|
|
88
|
-
this._handlers.set(type, new Set())
|
|
133
|
+
const payload = {
|
|
134
|
+
sessionId: this._sessionId,
|
|
135
|
+
userId: this._context.user?.id,
|
|
136
|
+
usersName: this._context.user?.name,
|
|
137
|
+
...data
|
|
89
138
|
}
|
|
90
139
|
|
|
91
|
-
|
|
140
|
+
send.call(
|
|
141
|
+
this._socket,
|
|
142
|
+
type,
|
|
143
|
+
opts.useDeepStringify ? deepStringify(payload) : payload
|
|
144
|
+
)
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
_handleMessage (event, data) {
|
|
148
|
+
try {
|
|
149
|
+
const d = isString(data) ? deepDestringify(JSON.parse(data)) : data
|
|
150
|
+
if (this._sessionId === d.sessionId) {
|
|
151
|
+
return
|
|
152
|
+
}
|
|
92
153
|
|
|
93
|
-
|
|
94
|
-
const handlers = this._handlers.get(type)
|
|
154
|
+
const handlers = this._handlers.get(event)
|
|
95
155
|
if (handlers) {
|
|
96
|
-
handlers.
|
|
97
|
-
if (handlers.size === 0) {
|
|
98
|
-
this._handlers.delete(type)
|
|
99
|
-
}
|
|
156
|
+
handlers.forEach(handler => handler(d))
|
|
100
157
|
}
|
|
158
|
+
|
|
159
|
+
// Handle specific events
|
|
160
|
+
switch (event) {
|
|
161
|
+
case 'change':
|
|
162
|
+
this._handleChangeEvent(d)
|
|
163
|
+
break
|
|
164
|
+
case 'clients':
|
|
165
|
+
this._handleClientsEvent(d)
|
|
166
|
+
break
|
|
167
|
+
case 'route':
|
|
168
|
+
this._handleRouteEvent(d)
|
|
169
|
+
break
|
|
170
|
+
default:
|
|
171
|
+
break
|
|
172
|
+
}
|
|
173
|
+
} catch (error) {
|
|
174
|
+
this._setError(new Error(`Failed to handle message: ${error.message}`))
|
|
101
175
|
}
|
|
102
176
|
}
|
|
103
177
|
|
|
104
|
-
|
|
105
|
-
|
|
178
|
+
_handleChangeEvent (data) {
|
|
179
|
+
const { type, changes, version } = data
|
|
180
|
+
if (version) {
|
|
181
|
+
this._context.state.version = version
|
|
182
|
+
}
|
|
183
|
+
if (changes) {
|
|
184
|
+
window.requestAnimationFrame(async () => {
|
|
185
|
+
await this._context.state.setPathCollection(changes, {
|
|
186
|
+
preventReplace: type === 'canvas',
|
|
187
|
+
preventUpdate: true,
|
|
188
|
+
fromSocket: true,
|
|
189
|
+
userId: data.userId,
|
|
190
|
+
changes
|
|
191
|
+
})
|
|
192
|
+
})
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// monaco updates
|
|
196
|
+
// if (data.canvas) {
|
|
197
|
+
// const { clients } = data.canvas
|
|
198
|
+
// const [firstClientKey] = Object.keys(clients)
|
|
199
|
+
// const monaco =
|
|
200
|
+
// clients && clients[firstClientKey] && clients[firstClientKey].monaco
|
|
201
|
+
// if (monaco) {
|
|
202
|
+
// const Canvas =
|
|
203
|
+
// this._context.element && this._context.element.getCanvas()
|
|
204
|
+
// if (Canvas) {
|
|
205
|
+
// Canvas.Chosen.EditorPanels.update({}, { forceMonacoUpdate: true })
|
|
206
|
+
// }
|
|
207
|
+
// }
|
|
208
|
+
// return
|
|
209
|
+
// }
|
|
106
210
|
}
|
|
107
211
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
try {
|
|
111
|
-
const { type, data } = JSON.parse(rawData)
|
|
112
|
-
const handlers = this._handlers.get(type)
|
|
212
|
+
_handleClientsEvent (data) {
|
|
213
|
+
const { root } = this._context.state
|
|
113
214
|
|
|
114
|
-
|
|
115
|
-
|
|
215
|
+
root.replace(
|
|
216
|
+
{ clients: data },
|
|
217
|
+
{
|
|
218
|
+
fromSocket: true,
|
|
219
|
+
preventUpdate: true
|
|
116
220
|
}
|
|
117
|
-
|
|
118
|
-
|
|
221
|
+
)
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
_handleRouteEvent (data) {
|
|
225
|
+
const { element } = this._context
|
|
226
|
+
const { state } = this._context
|
|
227
|
+
|
|
228
|
+
if (data.userId && data.type === 'routeChanged') {
|
|
229
|
+
const isModalOpen = this.getWindow('modal')
|
|
230
|
+
const isFollowing = state.followingUser === data.userId
|
|
231
|
+
const isRouteSyncEnabled =
|
|
232
|
+
element.getUserSettings('presentMode') && data.userId === state.userId
|
|
233
|
+
|
|
234
|
+
if ((isFollowing || isRouteSyncEnabled) && !isModalOpen) {
|
|
235
|
+
router(
|
|
236
|
+
data.route,
|
|
237
|
+
element.__ref.root,
|
|
238
|
+
{},
|
|
239
|
+
{
|
|
240
|
+
fromSocket: true,
|
|
241
|
+
updateStateOptions: {
|
|
242
|
+
fromSocket: true,
|
|
243
|
+
preventStateUpdateListener: 1 // !isModalRoute(data.route, element)
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
)
|
|
247
|
+
}
|
|
248
|
+
} else if (data.reload) {
|
|
249
|
+
window.location.reload()
|
|
250
|
+
} else if (data.route && data.type === 'routeForced') {
|
|
251
|
+
router(
|
|
252
|
+
data.route,
|
|
253
|
+
element.__ref.root,
|
|
254
|
+
{},
|
|
255
|
+
{
|
|
256
|
+
fromSocket: true,
|
|
257
|
+
updateStateOptions: {
|
|
258
|
+
fromSocket: true
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
)
|
|
262
|
+
} else if (data.componentKey) {
|
|
263
|
+
if (!element.getData('components')[data.componentKey]) {
|
|
264
|
+
return
|
|
265
|
+
}
|
|
266
|
+
element.activateSelected(data.componentKey)
|
|
119
267
|
}
|
|
120
268
|
}
|
|
121
269
|
|
|
270
|
+
_handleDisconnect () {
|
|
271
|
+
this._updateStatus('disconnected')
|
|
272
|
+
this._handleReconnect()
|
|
273
|
+
}
|
|
274
|
+
|
|
122
275
|
_handleReconnect () {
|
|
123
276
|
if (this._reconnectAttempts < this._maxReconnectAttempts) {
|
|
124
277
|
this._reconnectAttempts++
|
|
125
278
|
this._updateStatus('reconnecting')
|
|
126
279
|
|
|
127
280
|
setTimeout(() => {
|
|
128
|
-
|
|
281
|
+
try {
|
|
282
|
+
const connected = this.connect()
|
|
283
|
+
if (connected) {
|
|
284
|
+
this._reconnectAttempts = 0
|
|
285
|
+
} else {
|
|
286
|
+
this._handleReconnect()
|
|
287
|
+
}
|
|
288
|
+
} catch (error) {
|
|
289
|
+
console.error('Reconnection failed:', error)
|
|
290
|
+
this._handleReconnect()
|
|
291
|
+
}
|
|
129
292
|
}, this._reconnectDelay * this._reconnectAttempts)
|
|
130
293
|
} else {
|
|
131
294
|
this._updateStatus('failed')
|
|
@@ -143,19 +306,24 @@ export class SocketService extends BaseService {
|
|
|
143
306
|
}
|
|
144
307
|
}
|
|
145
308
|
|
|
146
|
-
// Cleanup
|
|
147
309
|
destroy () {
|
|
148
310
|
if (this._socket) {
|
|
149
|
-
this._socket
|
|
311
|
+
disconnect.call(this._socket)
|
|
150
312
|
this._socket = null
|
|
151
313
|
}
|
|
152
314
|
this._handlers.clear()
|
|
153
315
|
this._setReady(false)
|
|
154
316
|
}
|
|
155
317
|
|
|
318
|
+
reconnect () {
|
|
319
|
+
this.destroy()
|
|
320
|
+
this.connect()
|
|
321
|
+
}
|
|
322
|
+
|
|
156
323
|
_checkRequiredContext () {
|
|
157
|
-
|
|
158
|
-
|
|
324
|
+
return Boolean(
|
|
325
|
+
this._context?.appKey && this._context?.authToken && this._socket
|
|
326
|
+
)
|
|
159
327
|
}
|
|
160
328
|
|
|
161
329
|
isReady () {
|