@symbo.ls/sdk 3.2.3 → 3.2.7
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 +141 -0
- package/dist/cjs/config/environment.js +94 -10
- package/dist/cjs/index.js +152 -12
- package/dist/cjs/services/AdminService.js +351 -0
- package/dist/cjs/services/AuthService.js +738 -305
- package/dist/cjs/services/BaseService.js +158 -6
- package/dist/cjs/services/BranchService.js +484 -0
- package/dist/cjs/services/CollabService.js +439 -116
- package/dist/cjs/services/DnsService.js +340 -0
- package/dist/cjs/services/FeatureFlagService.js +175 -0
- package/dist/cjs/services/FileService.js +201 -0
- package/dist/cjs/services/IntegrationService.js +538 -0
- package/dist/cjs/services/MetricsService.js +62 -0
- package/dist/cjs/services/PaymentService.js +271 -0
- package/dist/cjs/services/PlanService.js +426 -0
- package/dist/cjs/services/ProjectService.js +1207 -0
- package/dist/cjs/services/PullRequestService.js +503 -0
- package/dist/cjs/services/ScreenshotService.js +304 -0
- package/dist/cjs/services/SubscriptionService.js +396 -0
- package/dist/cjs/services/TrackingService.js +661 -0
- package/dist/cjs/services/WaitlistService.js +148 -0
- package/dist/cjs/services/index.js +60 -4
- package/dist/cjs/state/RootStateManager.js +2 -23
- package/dist/cjs/state/rootEventBus.js +9 -0
- package/dist/cjs/utils/CollabClient.js +78 -12
- package/dist/cjs/utils/TokenManager.js +16 -3
- package/dist/cjs/utils/changePreprocessor.js +199 -0
- package/dist/cjs/utils/jsonDiff.js +46 -4
- package/dist/cjs/utils/ordering.js +309 -0
- package/dist/cjs/utils/services.js +285 -128
- package/dist/cjs/utils/validation.js +0 -3
- package/dist/esm/config/environment.js +94 -10
- package/dist/esm/index.js +47862 -18248
- package/dist/esm/services/AdminService.js +1132 -0
- package/dist/esm/services/AuthService.js +1493 -386
- package/dist/esm/services/BaseService.js +757 -6
- package/dist/esm/services/BranchService.js +1265 -0
- package/dist/esm/services/CollabService.js +24956 -16089
- package/dist/esm/services/DnsService.js +1121 -0
- package/dist/esm/services/FeatureFlagService.js +956 -0
- package/dist/esm/services/FileService.js +982 -0
- package/dist/esm/services/IntegrationService.js +1319 -0
- package/dist/esm/services/MetricsService.js +843 -0
- package/dist/esm/services/PaymentService.js +1052 -0
- package/dist/esm/services/PlanService.js +1207 -0
- package/dist/esm/services/ProjectService.js +2526 -0
- package/dist/esm/services/PullRequestService.js +1284 -0
- package/dist/esm/services/ScreenshotService.js +1085 -0
- package/dist/esm/services/SubscriptionService.js +1177 -0
- package/dist/esm/services/TrackingService.js +18454 -0
- package/dist/esm/services/WaitlistService.js +929 -0
- package/dist/esm/services/index.js +47373 -18027
- package/dist/esm/state/RootStateManager.js +11 -23
- package/dist/esm/state/rootEventBus.js +9 -0
- package/dist/esm/utils/CollabClient.js +17526 -16120
- package/dist/esm/utils/TokenManager.js +16 -3
- package/dist/esm/utils/changePreprocessor.js +542 -0
- package/dist/esm/utils/jsonDiff.js +958 -43
- package/dist/esm/utils/ordering.js +291 -0
- package/dist/esm/utils/services.js +285 -128
- package/dist/esm/utils/validation.js +116 -50
- package/dist/node/config/environment.js +94 -10
- package/dist/node/index.js +183 -16
- package/dist/node/services/AdminService.js +332 -0
- package/dist/node/services/AuthService.js +742 -310
- package/dist/node/services/BaseService.js +148 -6
- package/dist/node/services/BranchService.js +465 -0
- package/dist/node/services/CollabService.js +439 -116
- package/dist/node/services/DnsService.js +321 -0
- package/dist/node/services/FeatureFlagService.js +156 -0
- package/dist/node/services/FileService.js +182 -0
- package/dist/node/services/IntegrationService.js +519 -0
- package/dist/node/services/MetricsService.js +43 -0
- package/dist/node/services/PaymentService.js +252 -0
- package/dist/node/services/PlanService.js +407 -0
- package/dist/node/services/ProjectService.js +1188 -0
- package/dist/node/services/PullRequestService.js +484 -0
- package/dist/node/services/ScreenshotService.js +285 -0
- package/dist/node/services/SubscriptionService.js +377 -0
- package/dist/node/services/TrackingService.js +632 -0
- package/dist/node/services/WaitlistService.js +129 -0
- package/dist/node/services/index.js +60 -4
- package/dist/node/state/RootStateManager.js +2 -23
- package/dist/node/state/rootEventBus.js +9 -0
- package/dist/node/utils/CollabClient.js +77 -11
- package/dist/node/utils/TokenManager.js +16 -3
- package/dist/node/utils/changePreprocessor.js +180 -0
- package/dist/node/utils/jsonDiff.js +46 -4
- package/dist/node/utils/ordering.js +290 -0
- package/dist/node/utils/services.js +285 -128
- package/dist/node/utils/validation.js +0 -3
- package/package.json +30 -18
- package/src/config/environment.js +95 -10
- package/src/index.js +190 -23
- package/src/services/AdminService.js +374 -0
- package/src/services/AuthService.js +874 -328
- package/src/services/BaseService.js +166 -6
- package/src/services/BranchService.js +536 -0
- package/src/services/CollabService.js +557 -148
- package/src/services/DnsService.js +366 -0
- package/src/services/FeatureFlagService.js +174 -0
- package/src/services/FileService.js +213 -0
- package/src/services/IntegrationService.js +548 -0
- package/src/services/MetricsService.js +40 -0
- package/src/services/PaymentService.js +287 -0
- package/src/services/PlanService.js +468 -0
- package/src/services/ProjectService.js +1366 -0
- package/src/services/PullRequestService.js +537 -0
- package/src/services/ScreenshotService.js +258 -0
- package/src/services/SubscriptionService.js +425 -0
- package/src/services/TrackingService.js +853 -0
- package/src/services/WaitlistService.js +130 -0
- package/src/services/index.js +79 -5
- package/src/services/tests/BranchService/createBranch.test.js +153 -0
- package/src/services/tests/BranchService/deleteBranch.test.js +173 -0
- package/src/services/tests/BranchService/getBranchChanges.test.js +146 -0
- package/src/services/tests/BranchService/listBranches.test.js +87 -0
- package/src/services/tests/BranchService/mergeBranch.test.js +210 -0
- package/src/services/tests/BranchService/publishVersion.test.js +183 -0
- package/src/services/tests/BranchService/renameBranch.test.js +240 -0
- package/src/services/tests/BranchService/resetBranch.test.js +152 -0
- package/src/services/tests/FeatureFlagService/adminFeatureFlags.test.js +67 -0
- package/src/services/tests/FeatureFlagService/getFeatureFlags.test.js +75 -0
- package/src/services/tests/FileService/createFileFormData.test.js +74 -0
- package/src/services/tests/FileService/getFileUrl.test.js +69 -0
- package/src/services/tests/FileService/updateProjectIcon.test.js +109 -0
- package/src/services/tests/FileService/uploadDocument.test.js +36 -0
- package/src/services/tests/FileService/uploadFile.test.js +78 -0
- package/src/services/tests/FileService/uploadFileWithValidation.test.js +114 -0
- package/src/services/tests/FileService/uploadImage.test.js +36 -0
- package/src/services/tests/FileService/uploadMultipleFiles.test.js +111 -0
- package/src/services/tests/FileService/validateFile.test.js +63 -0
- package/src/services/tests/PlanService/createPlan.test.js +104 -0
- package/src/services/tests/PlanService/createPlanWithValidation.test.js +523 -0
- package/src/services/tests/PlanService/deletePlan.test.js +92 -0
- package/src/services/tests/PlanService/getActivePlans.test.js +123 -0
- package/src/services/tests/PlanService/getAdminPlans.test.js +84 -0
- package/src/services/tests/PlanService/getPlan.test.js +50 -0
- package/src/services/tests/PlanService/getPlanByKey.test.js +109 -0
- package/src/services/tests/PlanService/getPlanWithValidation.test.js +85 -0
- package/src/services/tests/PlanService/getPlans.test.js +53 -0
- package/src/services/tests/PlanService/getPlansByPriceRange.test.js +109 -0
- package/src/services/tests/PlanService/getPlansWithValidation.test.js +48 -0
- package/src/services/tests/PlanService/initializePlans.test.js +75 -0
- package/src/services/tests/PlanService/updatePlan.test.js +111 -0
- package/src/services/tests/PlanService/updatePlanWithValidation.test.js +556 -0
- package/src/state/RootStateManager.js +37 -32
- package/src/state/rootEventBus.js +19 -0
- package/src/utils/CollabClient.js +99 -12
- package/src/utils/TokenManager.js +20 -3
- package/src/utils/changePreprocessor.js +239 -0
- package/src/utils/jsonDiff.js +40 -5
- package/src/utils/ordering.js +271 -0
- package/src/utils/services.js +306 -139
- package/src/utils/validation.js +0 -3
- package/dist/cjs/services/AIService.js +0 -155
- package/dist/cjs/services/BasedService.js +0 -1185
- package/dist/cjs/services/CoreService.js +0 -2295
- package/dist/cjs/services/SocketService.js +0 -309
- package/dist/cjs/services/SymstoryService.js +0 -571
- package/dist/cjs/utils/basedQuerys.js +0 -181
- package/dist/cjs/utils/symstoryClient.js +0 -259
- package/dist/esm/services/AIService.js +0 -185
- package/dist/esm/services/BasedService.js +0 -5262
- package/dist/esm/services/CoreService.js +0 -2827
- package/dist/esm/services/SocketService.js +0 -456
- package/dist/esm/services/SymstoryService.js +0 -7025
- package/dist/esm/utils/basedQuerys.js +0 -163
- package/dist/esm/utils/symstoryClient.js +0 -354
- package/dist/node/services/AIService.js +0 -136
- package/dist/node/services/BasedService.js +0 -1156
- package/dist/node/services/CoreService.js +0 -2266
- package/dist/node/services/SocketService.js +0 -280
- package/dist/node/services/SymstoryService.js +0 -542
- package/dist/node/utils/basedQuerys.js +0 -162
- package/dist/node/utils/symstoryClient.js +0 -230
- package/src/services/AIService.js +0 -150
- package/src/services/BasedService.js +0 -1302
- package/src/services/CoreService.js +0 -2548
- package/src/services/SocketService.js +0 -336
- package/src/services/SymstoryService.js +0 -649
- package/src/utils/basedQuerys.js +0 -164
- package/src/utils/symstoryClient.js +0 -252
|
@@ -24,18 +24,54 @@ var import_BaseService = require("./BaseService.js");
|
|
|
24
24
|
var import_CollabClient = require("../utils/CollabClient.js");
|
|
25
25
|
var import_RootStateManager = require("../state/RootStateManager.js");
|
|
26
26
|
var import_rootEventBus = require("../state/rootEventBus.js");
|
|
27
|
+
var import_validation = require("../utils/validation.js");
|
|
28
|
+
var import_utils = require("@domql/utils");
|
|
29
|
+
var import_changePreprocessor = require("../utils/changePreprocessor.js");
|
|
30
|
+
const FUNCTION_META_KEYS = ["node", "__ref", "__element", "parent", "parse"];
|
|
31
|
+
function stringifyFunctionsForTransport(value, seen = /* @__PURE__ */ new WeakMap()) {
|
|
32
|
+
if (value === null || typeof value !== "object") {
|
|
33
|
+
return typeof value === "function" ? value.toString() : value;
|
|
34
|
+
}
|
|
35
|
+
if (seen.has(value)) {
|
|
36
|
+
return seen.get(value);
|
|
37
|
+
}
|
|
38
|
+
const clone = Array.isArray(value) ? [] : {};
|
|
39
|
+
seen.set(value, clone);
|
|
40
|
+
if (Array.isArray(value)) {
|
|
41
|
+
for (let i = 0; i < value.length; i++) {
|
|
42
|
+
clone[i] = stringifyFunctionsForTransport(value[i], seen);
|
|
43
|
+
}
|
|
44
|
+
return clone;
|
|
45
|
+
}
|
|
46
|
+
const keys = Object.keys(value);
|
|
47
|
+
for (let i = 0; i < keys.length; i++) {
|
|
48
|
+
const key = keys[i];
|
|
49
|
+
if (!FUNCTION_META_KEYS.includes(key)) {
|
|
50
|
+
clone[key] = stringifyFunctionsForTransport(value[key], seen);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return clone;
|
|
54
|
+
}
|
|
27
55
|
class CollabService extends import_BaseService.BaseService {
|
|
28
56
|
constructor(config) {
|
|
29
57
|
super(config);
|
|
30
58
|
this._client = null;
|
|
31
59
|
this._stateManager = null;
|
|
32
60
|
this._connected = false;
|
|
61
|
+
this._connecting = false;
|
|
62
|
+
this._connectPromise = null;
|
|
63
|
+
this._connectionMeta = null;
|
|
64
|
+
this._pendingConnectReject = null;
|
|
33
65
|
this._undoStack = [];
|
|
34
66
|
this._redoStack = [];
|
|
35
67
|
this._isUndoRedo = false;
|
|
36
68
|
this._pendingOps = [];
|
|
69
|
+
this._onSocketConnect = this._onSocketConnect.bind(this);
|
|
70
|
+
this._onSocketDisconnect = this._onSocketDisconnect.bind(this);
|
|
71
|
+
this._onSocketError = this._onSocketError.bind(this);
|
|
37
72
|
}
|
|
38
73
|
init({ context }) {
|
|
74
|
+
super.init({ context });
|
|
39
75
|
if (context == null ? void 0 : context.state) {
|
|
40
76
|
try {
|
|
41
77
|
this._stateManager = new import_RootStateManager.RootStateManager(context.state);
|
|
@@ -63,90 +99,240 @@ class CollabService extends import_BaseService.BaseService {
|
|
|
63
99
|
* caller can react accordingly.
|
|
64
100
|
*/
|
|
65
101
|
_ensureStateManager() {
|
|
66
|
-
var _a;
|
|
102
|
+
var _a, _b;
|
|
67
103
|
if (!this._stateManager) {
|
|
68
104
|
if (!((_a = this._context) == null ? void 0 : _a.state)) {
|
|
69
105
|
throw new Error("[CollabService] Cannot operate without root state");
|
|
70
106
|
}
|
|
71
107
|
this._stateManager = new import_RootStateManager.RootStateManager(this._context.state);
|
|
72
108
|
}
|
|
109
|
+
const root = (_b = this._stateManager) == null ? void 0 : _b.root;
|
|
110
|
+
if (root && !root.__element) {
|
|
111
|
+
root.__element = {
|
|
112
|
+
/**
|
|
113
|
+
* Very small subset of the DOMQL `call` API that we rely on inside the
|
|
114
|
+
* CollabService for browser notifications and data helpers.
|
|
115
|
+
* In a Node.js test context we simply log or return fallbacks.
|
|
116
|
+
*/
|
|
117
|
+
call: (method, ...args) => {
|
|
118
|
+
switch (method) {
|
|
119
|
+
case "openNotification": {
|
|
120
|
+
const [payload = {}] = args;
|
|
121
|
+
const { type = "info", title = "", message = "" } = payload;
|
|
122
|
+
const logger = type === "error" ? console.error : console.log;
|
|
123
|
+
logger(`[Notification] ${title}${message ? ` \u2013 ${message}` : ""}`);
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
case "deepStringifyFunctions": {
|
|
127
|
+
return (0, import_utils.deepStringifyFunctions)(...args);
|
|
128
|
+
}
|
|
129
|
+
default:
|
|
130
|
+
return {};
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
};
|
|
134
|
+
}
|
|
73
135
|
}
|
|
74
136
|
/* ---------- Connection Management ---------- */
|
|
75
137
|
async connect(options = {}) {
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
const {
|
|
79
|
-
authToken: jwt,
|
|
80
|
-
projectId,
|
|
81
|
-
branch = "main",
|
|
82
|
-
pro
|
|
83
|
-
} = {
|
|
84
|
-
...this._context,
|
|
85
|
-
...options
|
|
86
|
-
};
|
|
87
|
-
console.log(jwt, projectId, branch, pro);
|
|
88
|
-
if (!projectId) {
|
|
89
|
-
throw new Error("projectId is required for CollabService connection");
|
|
90
|
-
}
|
|
91
|
-
if (this._client) {
|
|
92
|
-
await this.disconnect();
|
|
138
|
+
if (this._connectPromise) {
|
|
139
|
+
return this._connectPromise;
|
|
93
140
|
}
|
|
94
|
-
|
|
141
|
+
this._connectPromise = (async () => {
|
|
142
|
+
var _a;
|
|
143
|
+
this._connecting = true;
|
|
144
|
+
this._connected = false;
|
|
145
|
+
this._ensureStateManager();
|
|
146
|
+
const mergedOptions = {
|
|
147
|
+
...this._context,
|
|
148
|
+
...options
|
|
149
|
+
};
|
|
150
|
+
let { authToken: jwt } = mergedOptions;
|
|
151
|
+
const { projectId, branch = "main", pro } = mergedOptions;
|
|
152
|
+
if (!jwt && this._tokenManager) {
|
|
153
|
+
try {
|
|
154
|
+
jwt = await this._tokenManager.ensureValidToken();
|
|
155
|
+
} catch (error) {
|
|
156
|
+
console.warn(
|
|
157
|
+
"[CollabService] Failed to obtain auth token from token manager",
|
|
158
|
+
error
|
|
159
|
+
);
|
|
160
|
+
}
|
|
161
|
+
if (!jwt && typeof this._tokenManager.getAccessToken === "function") {
|
|
162
|
+
jwt = this._tokenManager.getAccessToken();
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
if (!jwt) {
|
|
166
|
+
throw new Error("[CollabService] Cannot connect without auth token");
|
|
167
|
+
}
|
|
168
|
+
this._context = {
|
|
169
|
+
...this._context,
|
|
170
|
+
authToken: jwt,
|
|
171
|
+
projectId,
|
|
172
|
+
branch,
|
|
173
|
+
pro
|
|
174
|
+
};
|
|
175
|
+
if (!projectId) {
|
|
176
|
+
const state = (_a = this._stateManager) == null ? void 0 : _a.root;
|
|
177
|
+
const el = state.__element;
|
|
178
|
+
el.call("openNotification", {
|
|
179
|
+
type: "error",
|
|
180
|
+
title: "projectId is required",
|
|
181
|
+
message: "projectId is required for CollabService connection"
|
|
182
|
+
});
|
|
183
|
+
throw new Error("projectId is required for CollabService connection");
|
|
184
|
+
}
|
|
185
|
+
if (this._client) {
|
|
186
|
+
await this.disconnect();
|
|
187
|
+
}
|
|
95
188
|
this._client = new import_CollabClient.CollabClient({
|
|
96
189
|
jwt,
|
|
97
190
|
projectId,
|
|
98
191
|
branch,
|
|
99
192
|
live: Boolean(pro)
|
|
100
193
|
});
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
194
|
+
const { socket } = this._client;
|
|
195
|
+
try {
|
|
196
|
+
await new Promise((resolve, reject) => {
|
|
197
|
+
if (!socket) {
|
|
198
|
+
reject(new Error("[CollabService] Socket instance missing"));
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
if (socket.connected) {
|
|
202
|
+
resolve();
|
|
203
|
+
return;
|
|
204
|
+
}
|
|
205
|
+
const cleanup = () => {
|
|
206
|
+
socket.off("connect", handleConnect);
|
|
207
|
+
socket.off("connect_error", handleError);
|
|
208
|
+
socket.off("error", handleError);
|
|
209
|
+
socket.off("disconnect", handleDisconnect);
|
|
210
|
+
if (this._pendingConnectReject === handleError) {
|
|
211
|
+
this._pendingConnectReject = null;
|
|
212
|
+
}
|
|
213
|
+
};
|
|
214
|
+
const handleConnect = () => {
|
|
215
|
+
cleanup();
|
|
216
|
+
resolve();
|
|
217
|
+
};
|
|
218
|
+
const handleError = (error) => {
|
|
219
|
+
cleanup();
|
|
220
|
+
reject(
|
|
221
|
+
error instanceof Error ? error : new Error(String(error || "Unknown connection error"))
|
|
222
|
+
);
|
|
223
|
+
};
|
|
224
|
+
const handleDisconnect = (reason) => {
|
|
225
|
+
handleError(
|
|
226
|
+
reason instanceof Error ? reason : new Error(
|
|
227
|
+
`[CollabService] Socket disconnected before connect: ${reason || "unknown"}`
|
|
228
|
+
)
|
|
229
|
+
);
|
|
230
|
+
};
|
|
231
|
+
this._pendingConnectReject = handleError;
|
|
232
|
+
socket.once("connect", handleConnect);
|
|
233
|
+
socket.once("connect_error", handleError);
|
|
234
|
+
socket.once("error", handleError);
|
|
235
|
+
socket.once("disconnect", handleDisconnect);
|
|
236
|
+
});
|
|
237
|
+
} catch (error) {
|
|
238
|
+
socket == null ? void 0 : socket.disconnect();
|
|
239
|
+
this._client = null;
|
|
240
|
+
this._connectionMeta = null;
|
|
241
|
+
throw error;
|
|
242
|
+
}
|
|
243
|
+
this._attachSocketLifecycleListeners();
|
|
244
|
+
if (socket == null ? void 0 : socket.connected) {
|
|
245
|
+
this._onSocketConnect();
|
|
246
|
+
}
|
|
247
|
+
socket == null ? void 0 : socket.on("ops", ({ changes }) => {
|
|
111
248
|
console.log(`ops event`);
|
|
112
|
-
console.log(changes);
|
|
113
249
|
this._stateManager.applyChanges(changes, { fromSocket: true });
|
|
114
250
|
});
|
|
115
|
-
|
|
116
|
-
|
|
251
|
+
socket == null ? void 0 : socket.on("commit", ({ version }) => {
|
|
252
|
+
if (version) {
|
|
253
|
+
this._stateManager.setVersion(version);
|
|
254
|
+
}
|
|
117
255
|
import_rootEventBus.rootBus.emit("checkpoint:done", { version, origin: "auto" });
|
|
118
256
|
});
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
257
|
+
socket == null ? void 0 : socket.on("clients", this._handleClientsEvent.bind(this));
|
|
258
|
+
socket == null ? void 0 : socket.on("bundle:done", this._handleBundleDoneEvent.bind(this));
|
|
259
|
+
socket == null ? void 0 : socket.on("bundle:error", this._handleBundleErrorEvent.bind(this));
|
|
122
260
|
if (this._pendingOps.length) {
|
|
123
261
|
console.log(
|
|
124
262
|
`[CollabService] Flushing ${this._pendingOps.length} offline operation batch(es)`
|
|
125
263
|
);
|
|
126
|
-
this._pendingOps.forEach(
|
|
127
|
-
|
|
128
|
-
|
|
264
|
+
this._pendingOps.forEach(
|
|
265
|
+
({ changes, granularChanges, orders, options: opOptions }) => {
|
|
266
|
+
const { message } = opOptions || {};
|
|
267
|
+
const ts = Date.now();
|
|
268
|
+
const payload = {
|
|
269
|
+
changes,
|
|
270
|
+
granularChanges,
|
|
271
|
+
orders,
|
|
272
|
+
ts
|
|
273
|
+
};
|
|
274
|
+
if (message) {
|
|
275
|
+
payload.message = message;
|
|
276
|
+
}
|
|
277
|
+
this.socket.emit("ops", payload);
|
|
278
|
+
}
|
|
279
|
+
);
|
|
129
280
|
this._pendingOps.length = 0;
|
|
130
281
|
}
|
|
131
|
-
this.
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
282
|
+
await this._client.ready;
|
|
283
|
+
this._connectionMeta = {
|
|
284
|
+
projectId,
|
|
285
|
+
branch,
|
|
286
|
+
live: Boolean(pro)
|
|
287
|
+
};
|
|
288
|
+
return this.getConnectionInfo();
|
|
289
|
+
})();
|
|
290
|
+
try {
|
|
291
|
+
return await this._connectPromise;
|
|
292
|
+
} finally {
|
|
293
|
+
this._connecting = false;
|
|
294
|
+
this._connectPromise = null;
|
|
136
295
|
}
|
|
137
296
|
}
|
|
138
297
|
disconnect() {
|
|
139
298
|
var _a;
|
|
140
299
|
if ((_a = this._client) == null ? void 0 : _a.socket) {
|
|
141
|
-
this.
|
|
300
|
+
if (this._pendingConnectReject) {
|
|
301
|
+
this._pendingConnectReject(
|
|
302
|
+
new Error("[CollabService] Connection attempt aborted")
|
|
303
|
+
);
|
|
304
|
+
this._pendingConnectReject = null;
|
|
305
|
+
}
|
|
306
|
+
this._detachSocketLifecycleListeners();
|
|
307
|
+
if (typeof this._client.dispose === "function") {
|
|
308
|
+
this._client.dispose();
|
|
309
|
+
} else {
|
|
310
|
+
this._client.socket.disconnect();
|
|
311
|
+
}
|
|
142
312
|
}
|
|
143
313
|
this._client = null;
|
|
144
314
|
this._connected = false;
|
|
315
|
+
this._connecting = false;
|
|
316
|
+
this._connectionMeta = null;
|
|
317
|
+
this._pendingConnectReject = null;
|
|
145
318
|
console.log("[CollabService] Disconnected");
|
|
146
319
|
}
|
|
147
320
|
isConnected() {
|
|
148
321
|
var _a, _b;
|
|
149
|
-
return this._connected && ((_b = (_a = this._client) == null ? void 0 : _a.socket) == null ? void 0 : _b.connected);
|
|
322
|
+
return Boolean(this._connected && ((_b = (_a = this._client) == null ? void 0 : _a.socket) == null ? void 0 : _b.connected));
|
|
323
|
+
}
|
|
324
|
+
getConnectionInfo() {
|
|
325
|
+
var _a, _b, _c;
|
|
326
|
+
return {
|
|
327
|
+
connected: this.isConnected(),
|
|
328
|
+
connecting: this._connecting,
|
|
329
|
+
projectId: ((_a = this._connectionMeta) == null ? void 0 : _a.projectId) ?? null,
|
|
330
|
+
branch: ((_b = this._connectionMeta) == null ? void 0 : _b.branch) ?? null,
|
|
331
|
+
live: ((_c = this._connectionMeta) == null ? void 0 : _c.live) ?? null,
|
|
332
|
+
pendingOps: this._pendingOps.length,
|
|
333
|
+
undoStackSize: this.getUndoStackSize(),
|
|
334
|
+
redoStackSize: this.getRedoStackSize()
|
|
335
|
+
};
|
|
150
336
|
}
|
|
151
337
|
/* convenient shortcuts */
|
|
152
338
|
get ydoc() {
|
|
@@ -171,20 +357,47 @@ class CollabService extends import_BaseService.BaseService {
|
|
|
171
357
|
}
|
|
172
358
|
/* ---------- data helpers ---------- */
|
|
173
359
|
updateData(tuples, options = {}) {
|
|
174
|
-
var _a;
|
|
360
|
+
var _a, _b;
|
|
175
361
|
this._ensureStateManager();
|
|
176
362
|
const { isUndo = false, isRedo = false } = options;
|
|
177
363
|
if (!isUndo && !isRedo && !this._isUndoRedo) {
|
|
178
364
|
this._trackForUndo(tuples, options);
|
|
179
365
|
}
|
|
366
|
+
const root = (_a = this._stateManager) == null ? void 0 : _a.root;
|
|
367
|
+
const { granularChanges: processedTuples, orders } = (0, import_changePreprocessor.preprocessChanges)(
|
|
368
|
+
root,
|
|
369
|
+
tuples,
|
|
370
|
+
options
|
|
371
|
+
);
|
|
372
|
+
if (options.append && options.append.length) {
|
|
373
|
+
processedTuples.push(...options.append);
|
|
374
|
+
}
|
|
180
375
|
this._stateManager.applyChanges(tuples, { ...options });
|
|
376
|
+
const stringifiedGranularTuples = stringifyFunctionsForTransport(processedTuples);
|
|
377
|
+
const stringifiedTuples = stringifyFunctionsForTransport(tuples);
|
|
378
|
+
const { message } = options;
|
|
181
379
|
if (!this.isConnected()) {
|
|
182
380
|
console.warn("[CollabService] Not connected, queuing real-time update");
|
|
183
|
-
this._pendingOps.push({
|
|
381
|
+
this._pendingOps.push({
|
|
382
|
+
changes: stringifiedTuples,
|
|
383
|
+
granularChanges: stringifiedGranularTuples,
|
|
384
|
+
orders,
|
|
385
|
+
options
|
|
386
|
+
});
|
|
184
387
|
return;
|
|
185
388
|
}
|
|
186
|
-
if ((
|
|
187
|
-
|
|
389
|
+
if ((_b = this.socket) == null ? void 0 : _b.connected) {
|
|
390
|
+
const ts = Date.now();
|
|
391
|
+
const payload = {
|
|
392
|
+
changes: stringifiedTuples,
|
|
393
|
+
granularChanges: stringifiedGranularTuples,
|
|
394
|
+
orders,
|
|
395
|
+
ts
|
|
396
|
+
};
|
|
397
|
+
if (message) {
|
|
398
|
+
payload.message = message;
|
|
399
|
+
}
|
|
400
|
+
this.socket.emit("ops", payload);
|
|
188
401
|
}
|
|
189
402
|
return { success: true };
|
|
190
403
|
}
|
|
@@ -227,7 +440,14 @@ class CollabService extends import_BaseService.BaseService {
|
|
|
227
440
|
}
|
|
228
441
|
}
|
|
229
442
|
undo() {
|
|
443
|
+
var _a;
|
|
230
444
|
if (!this._undoStack.length) {
|
|
445
|
+
const state = (_a = this._stateManager) == null ? void 0 : _a.root;
|
|
446
|
+
const el = state.__element;
|
|
447
|
+
el.call("openNotification", {
|
|
448
|
+
type: "error",
|
|
449
|
+
title: "Nothing to undo"
|
|
450
|
+
});
|
|
231
451
|
throw new Error("Nothing to undo");
|
|
232
452
|
}
|
|
233
453
|
if (!this.isConnected()) {
|
|
@@ -255,7 +475,14 @@ class CollabService extends import_BaseService.BaseService {
|
|
|
255
475
|
return operations;
|
|
256
476
|
}
|
|
257
477
|
redo() {
|
|
478
|
+
var _a;
|
|
258
479
|
if (!this._redoStack.length) {
|
|
480
|
+
const state = (_a = this._stateManager) == null ? void 0 : _a.root;
|
|
481
|
+
const el = state.__element;
|
|
482
|
+
el.call("openNotification", {
|
|
483
|
+
type: "error",
|
|
484
|
+
title: "Nothing to redo"
|
|
485
|
+
});
|
|
259
486
|
throw new Error("Nothing to redo");
|
|
260
487
|
}
|
|
261
488
|
if (!this.isConnected()) {
|
|
@@ -300,47 +527,99 @@ class CollabService extends import_BaseService.BaseService {
|
|
|
300
527
|
this._redoStack.length = 0;
|
|
301
528
|
}
|
|
302
529
|
addItem(type, data, opts = {}) {
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
530
|
+
try {
|
|
531
|
+
import_validation.validateParams.type(type);
|
|
532
|
+
import_validation.validateParams.data(data, type);
|
|
533
|
+
const { value, ...schema } = data;
|
|
534
|
+
const tuples = [
|
|
535
|
+
["update", [type, data.key], value],
|
|
536
|
+
["update", ["schema", type, data.key], schema || {}]
|
|
537
|
+
];
|
|
538
|
+
const updatedOpts = { ...opts, skipComponentsChangedEvent: true };
|
|
539
|
+
return this.updateData(tuples, updatedOpts);
|
|
540
|
+
} catch (error) {
|
|
541
|
+
throw new Error(`Failed to add item: ${error.message}`, { cause: error });
|
|
542
|
+
}
|
|
310
543
|
}
|
|
311
544
|
addMultipleItems(items, opts = {}) {
|
|
545
|
+
var _a;
|
|
312
546
|
const tuples = [];
|
|
313
|
-
|
|
547
|
+
try {
|
|
548
|
+
items.forEach(([type, data]) => {
|
|
549
|
+
import_validation.validateParams.type(type);
|
|
550
|
+
import_validation.validateParams.data(data, type);
|
|
551
|
+
const { value, ...schema } = data;
|
|
552
|
+
tuples.push(
|
|
553
|
+
["update", [type, data.key], value],
|
|
554
|
+
["update", ["schema", type, data.key], schema]
|
|
555
|
+
);
|
|
556
|
+
});
|
|
557
|
+
this.updateData([...tuples, ...opts.append || []], {
|
|
558
|
+
message: `Created ${tuples.length} items`,
|
|
559
|
+
...opts
|
|
560
|
+
});
|
|
561
|
+
return tuples;
|
|
562
|
+
} catch (error) {
|
|
563
|
+
const state = (_a = this._stateManager) == null ? void 0 : _a.root;
|
|
564
|
+
const el = state.__element;
|
|
565
|
+
el.call("openNotification", {
|
|
566
|
+
type: "error",
|
|
567
|
+
title: "Failed to add item",
|
|
568
|
+
message: error.message
|
|
569
|
+
});
|
|
570
|
+
throw new Error(`Failed to add item: ${error.message}`, { cause: error });
|
|
571
|
+
}
|
|
572
|
+
}
|
|
573
|
+
updateItem(type, data, opts = {}) {
|
|
574
|
+
var _a;
|
|
575
|
+
try {
|
|
576
|
+
import_validation.validateParams.type(type);
|
|
577
|
+
import_validation.validateParams.data(data, type);
|
|
314
578
|
const { value, ...schema } = data;
|
|
315
|
-
tuples
|
|
579
|
+
const tuples = [
|
|
316
580
|
["update", [type, data.key], value],
|
|
317
581
|
["update", ["schema", type, data.key], schema]
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
return this.updateData(tuples, opts);
|
|
582
|
+
];
|
|
583
|
+
return this.updateData(tuples, opts);
|
|
584
|
+
} catch (error) {
|
|
585
|
+
const state = (_a = this._stateManager) == null ? void 0 : _a.root;
|
|
586
|
+
const el = state.__element;
|
|
587
|
+
el.call("openNotification", {
|
|
588
|
+
type: "error",
|
|
589
|
+
title: "Failed to update item",
|
|
590
|
+
message: error.message
|
|
591
|
+
});
|
|
592
|
+
throw new Error(`Failed to update item: ${error.message}`, {
|
|
593
|
+
cause: error
|
|
594
|
+
});
|
|
595
|
+
}
|
|
333
596
|
}
|
|
334
597
|
deleteItem(type, key, opts = {}) {
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
598
|
+
var _a;
|
|
599
|
+
try {
|
|
600
|
+
import_validation.validateParams.type(type);
|
|
601
|
+
import_validation.validateParams.key(key, type);
|
|
602
|
+
const tuples = [
|
|
603
|
+
["delete", [type, key]],
|
|
604
|
+
["delete", ["schema", type, key]],
|
|
605
|
+
...opts.append || []
|
|
606
|
+
];
|
|
607
|
+
return this.updateData(tuples, {
|
|
608
|
+
message: `Deleted ${key} from ${type}`,
|
|
609
|
+
...opts
|
|
610
|
+
});
|
|
611
|
+
} catch (error) {
|
|
612
|
+
const state = (_a = this._stateManager) == null ? void 0 : _a.root;
|
|
613
|
+
const el = state.__element;
|
|
614
|
+
el.call("openNotification", {
|
|
615
|
+
type: "error",
|
|
616
|
+
title: "Failed to delete item",
|
|
617
|
+
message: error.message
|
|
618
|
+
});
|
|
619
|
+
throw new Error(`Failed to delete item: ${error.message}`, {
|
|
620
|
+
cause: error
|
|
621
|
+
});
|
|
622
|
+
}
|
|
344
623
|
}
|
|
345
624
|
/* ---------- socket event helpers ---------- */
|
|
346
625
|
/**
|
|
@@ -353,48 +632,92 @@ class CollabService extends import_BaseService.BaseService {
|
|
|
353
632
|
var _a;
|
|
354
633
|
const root = (_a = this._stateManager) == null ? void 0 : _a.root;
|
|
355
634
|
if (root && typeof root.replace === "function") {
|
|
356
|
-
root.
|
|
357
|
-
{ clients: data },
|
|
358
|
-
{
|
|
359
|
-
fromSocket: true,
|
|
360
|
-
preventUpdate: true
|
|
361
|
-
}
|
|
362
|
-
);
|
|
635
|
+
root.clients = data;
|
|
363
636
|
}
|
|
637
|
+
import_rootEventBus.rootBus.emit("clients:updated", data);
|
|
364
638
|
}
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
639
|
+
/* ---------- Dependency bundling events ---------- */
|
|
640
|
+
_handleBundleDoneEvent({
|
|
641
|
+
project,
|
|
642
|
+
ticket,
|
|
643
|
+
dependencies = {},
|
|
644
|
+
schema = {}
|
|
645
|
+
} = {}) {
|
|
646
|
+
var _a;
|
|
647
|
+
console.info("[CollabService] Bundle done", { project, ticket });
|
|
648
|
+
try {
|
|
649
|
+
this._ensureStateManager();
|
|
650
|
+
const { dependencies: schemaDependencies = {} } = schema || {};
|
|
651
|
+
const tuples = [
|
|
652
|
+
["update", ["dependencies"], dependencies],
|
|
653
|
+
["update", ["schema", "dependencies"], schemaDependencies]
|
|
654
|
+
];
|
|
655
|
+
this._stateManager.applyChanges(tuples, {
|
|
656
|
+
fromSocket: true,
|
|
657
|
+
preventFetchDeps: true,
|
|
658
|
+
preventUpdate: ["Iframe"]
|
|
659
|
+
});
|
|
660
|
+
} catch (err) {
|
|
661
|
+
console.error("[CollabService] Failed to update deps after bundle", err);
|
|
374
662
|
}
|
|
375
|
-
const
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
663
|
+
const root = (_a = this._stateManager) == null ? void 0 : _a.root;
|
|
664
|
+
const el = root == null ? void 0 : root.__element;
|
|
665
|
+
if (el == null ? void 0 : el.call) {
|
|
666
|
+
el.call("openNotification", {
|
|
667
|
+
type: "success",
|
|
668
|
+
title: "Dependencies ready",
|
|
669
|
+
message: `Project ${project} dependencies have been bundled successfully.`
|
|
670
|
+
});
|
|
671
|
+
}
|
|
672
|
+
import_rootEventBus.rootBus.emit("bundle:done", { project, ticket });
|
|
673
|
+
}
|
|
674
|
+
_handleBundleErrorEvent({ project, ticket, error } = {}) {
|
|
675
|
+
var _a;
|
|
676
|
+
console.error("[CollabService] Bundle error", { project, ticket, error });
|
|
677
|
+
const root = (_a = this._stateManager) == null ? void 0 : _a.root;
|
|
678
|
+
const el = root == null ? void 0 : root.__element;
|
|
679
|
+
if (el == null ? void 0 : el.call) {
|
|
680
|
+
el.call("openNotification", {
|
|
681
|
+
type: "error",
|
|
682
|
+
title: "Dependency bundle failed",
|
|
683
|
+
message: error || `An error occurred while bundling dependencies for project ${project}.`
|
|
684
|
+
});
|
|
382
685
|
}
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
686
|
+
import_rootEventBus.rootBus.emit("bundle:error", { project, ticket, error });
|
|
687
|
+
}
|
|
688
|
+
/* ---------- Manual checkpoint ---------- */
|
|
689
|
+
_attachSocketLifecycleListeners() {
|
|
690
|
+
var _a;
|
|
691
|
+
const socket = (_a = this._client) == null ? void 0 : _a.socket;
|
|
692
|
+
if (!socket) {
|
|
693
|
+
return;
|
|
389
694
|
}
|
|
390
|
-
|
|
391
|
-
|
|
695
|
+
socket.on("connect", this._onSocketConnect);
|
|
696
|
+
socket.on("disconnect", this._onSocketDisconnect);
|
|
697
|
+
socket.on("connect_error", this._onSocketError);
|
|
698
|
+
}
|
|
699
|
+
_detachSocketLifecycleListeners() {
|
|
700
|
+
var _a;
|
|
701
|
+
const socket = (_a = this._client) == null ? void 0 : _a.socket;
|
|
702
|
+
if (!socket) {
|
|
703
|
+
return;
|
|
392
704
|
}
|
|
393
|
-
|
|
394
|
-
|
|
705
|
+
socket.off("connect", this._onSocketConnect);
|
|
706
|
+
socket.off("disconnect", this._onSocketDisconnect);
|
|
707
|
+
socket.off("connect_error", this._onSocketError);
|
|
708
|
+
}
|
|
709
|
+
_onSocketConnect() {
|
|
710
|
+
this._connected = true;
|
|
711
|
+
}
|
|
712
|
+
_onSocketDisconnect(reason) {
|
|
713
|
+
this._connected = false;
|
|
714
|
+
if (reason && reason !== "io client disconnect") {
|
|
715
|
+
console.warn("[CollabService] Socket disconnected", reason);
|
|
395
716
|
}
|
|
396
717
|
}
|
|
397
|
-
|
|
718
|
+
_onSocketError(error) {
|
|
719
|
+
console.warn("[CollabService] Socket connection error", error);
|
|
720
|
+
}
|
|
398
721
|
/**
|
|
399
722
|
* Manually request a checkpoint / commit of buffered operations on the server.
|
|
400
723
|
* Resolves with the new version number once the backend confirms via the
|