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