@symbo.ls/sdk 2.32.22 → 2.32.26
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/dist/cjs/services/AuthService.js +6 -0
- package/dist/cjs/services/BaseService.js +1 -1
- package/dist/cjs/services/CollabService.js +24 -6
- package/dist/cjs/utils/changePreprocessor.js +58 -2
- package/dist/cjs/utils/services.js +1 -0
- package/dist/esm/index.js +90 -9
- package/dist/esm/services/AdminService.js +1 -1
- package/dist/esm/services/AuthService.js +7 -1
- package/dist/esm/services/BaseService.js +1 -1
- package/dist/esm/services/BranchService.js +1 -1
- package/dist/esm/services/CollabService.js +83 -9
- package/dist/esm/services/DnsService.js +1 -1
- package/dist/esm/services/FileService.js +1 -1
- package/dist/esm/services/PaymentService.js +1 -1
- package/dist/esm/services/PlanService.js +1 -1
- package/dist/esm/services/ProjectService.js +59 -3
- package/dist/esm/services/PullRequestService.js +1 -1
- package/dist/esm/services/ScreenshotService.js +1 -1
- package/dist/esm/services/SubscriptionService.js +1 -1
- package/dist/esm/services/TrackingService.js +1 -1
- package/dist/esm/services/index.js +89 -9
- package/dist/esm/utils/changePreprocessor.js +58 -2
- package/dist/esm/utils/services.js +1 -0
- package/dist/node/services/AuthService.js +6 -0
- package/dist/node/services/BaseService.js +1 -1
- package/dist/node/services/CollabService.js +24 -6
- package/dist/node/utils/changePreprocessor.js +58 -2
- package/dist/node/utils/services.js +1 -0
- package/package.json +6 -6
- package/src/services/AuthService.js +7 -0
- package/src/services/BaseService.js +1 -1
- package/src/services/CollabService.js +27 -6
- package/src/utils/changePreprocessor.js +76 -2
- package/src/utils/services.js +1 -0
|
@@ -337,6 +337,12 @@ class AuthService extends import_BaseService.BaseService {
|
|
|
337
337
|
throw new Error(`Failed to get user profile: ${error.message}`, { cause: error });
|
|
338
338
|
}
|
|
339
339
|
}
|
|
340
|
+
getAuthToken() {
|
|
341
|
+
if (!this._tokenManager) {
|
|
342
|
+
return null;
|
|
343
|
+
}
|
|
344
|
+
return this._tokenManager.getAccessToken();
|
|
345
|
+
}
|
|
340
346
|
/**
|
|
341
347
|
* Get stored authentication state (backward compatibility method)
|
|
342
348
|
* Replaces AuthService.getStoredAuthState()
|
|
@@ -243,8 +243,19 @@ class CollabService extends import_BaseService.BaseService {
|
|
|
243
243
|
console.log(
|
|
244
244
|
`[CollabService] Flushing ${this._pendingOps.length} offline operation batch(es)`
|
|
245
245
|
);
|
|
246
|
-
this._pendingOps.forEach(({ changes, granularChanges, orders }) => {
|
|
247
|
-
|
|
246
|
+
this._pendingOps.forEach(({ changes, granularChanges, orders, options: opOptions }) => {
|
|
247
|
+
const { message } = opOptions || {};
|
|
248
|
+
const ts = Date.now();
|
|
249
|
+
const payload = {
|
|
250
|
+
changes,
|
|
251
|
+
granularChanges,
|
|
252
|
+
orders,
|
|
253
|
+
ts
|
|
254
|
+
};
|
|
255
|
+
if (message) {
|
|
256
|
+
payload.message = message;
|
|
257
|
+
}
|
|
258
|
+
this.socket.emit("ops", payload);
|
|
248
259
|
});
|
|
249
260
|
this._pendingOps.length = 0;
|
|
250
261
|
}
|
|
@@ -355,6 +366,7 @@ class CollabService extends import_BaseService.BaseService {
|
|
|
355
366
|
tuples,
|
|
356
367
|
Array.isArray(tuples) ? [] : {}
|
|
357
368
|
) : (0, import_utils.deepStringifyFunctions)(tuples, Array.isArray(tuples) ? [] : {});
|
|
369
|
+
const { message } = options;
|
|
358
370
|
if (!this.isConnected()) {
|
|
359
371
|
console.warn("[CollabService] Not connected, queuing real-time update");
|
|
360
372
|
this._pendingOps.push({
|
|
@@ -366,18 +378,24 @@ class CollabService extends import_BaseService.BaseService {
|
|
|
366
378
|
return;
|
|
367
379
|
}
|
|
368
380
|
if ((_c = this.socket) == null ? void 0 : _c.connected) {
|
|
381
|
+
const ts = Date.now();
|
|
369
382
|
console.log("[CollabService] Sending operations to the backend", {
|
|
370
383
|
changes: stringifiedTuples,
|
|
371
384
|
granularChanges: stringifiedGranularTuples,
|
|
372
385
|
orders,
|
|
373
|
-
ts
|
|
386
|
+
ts,
|
|
387
|
+
message
|
|
374
388
|
});
|
|
375
|
-
|
|
389
|
+
const payload = {
|
|
376
390
|
changes: stringifiedTuples,
|
|
377
391
|
granularChanges: stringifiedGranularTuples,
|
|
378
392
|
orders,
|
|
379
|
-
ts
|
|
380
|
-
}
|
|
393
|
+
ts
|
|
394
|
+
};
|
|
395
|
+
if (message) {
|
|
396
|
+
payload.message = message;
|
|
397
|
+
}
|
|
398
|
+
this.socket.emit("ops", payload);
|
|
381
399
|
}
|
|
382
400
|
return { success: true };
|
|
383
401
|
}
|
|
@@ -35,6 +35,48 @@ function getByPathSafe(root, path) {
|
|
|
35
35
|
return null;
|
|
36
36
|
}
|
|
37
37
|
}
|
|
38
|
+
function resolveNextValueFromTuples(tuples, path) {
|
|
39
|
+
if (!Array.isArray(tuples) || !Array.isArray(path)) {
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
for (let i = tuples.length - 1; i >= 0; i--) {
|
|
43
|
+
const t = tuples[i];
|
|
44
|
+
if (!Array.isArray(t) || t.length < 3) {
|
|
45
|
+
continue;
|
|
46
|
+
}
|
|
47
|
+
const [action, tuplePath, tupleValue] = t;
|
|
48
|
+
if (action !== "update" && action !== "set" || !Array.isArray(tuplePath)) {
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
if (tuplePath.length > path.length) {
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
let isPrefix = true;
|
|
55
|
+
for (let j = 0; j < tuplePath.length; j++) {
|
|
56
|
+
if (tuplePath[j] !== path[j]) {
|
|
57
|
+
isPrefix = false;
|
|
58
|
+
break;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
if (!isPrefix) {
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
if (tuplePath.length === path.length) {
|
|
65
|
+
return tupleValue;
|
|
66
|
+
}
|
|
67
|
+
let current = tupleValue;
|
|
68
|
+
for (let j = tuplePath.length; j < path.length; j++) {
|
|
69
|
+
if (current == null) {
|
|
70
|
+
return null;
|
|
71
|
+
}
|
|
72
|
+
current = current[path[j]];
|
|
73
|
+
}
|
|
74
|
+
if (current !== null) {
|
|
75
|
+
return current;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
38
80
|
function preprocessChanges(root, tuples = [], options = {}) {
|
|
39
81
|
const expandTuple = (t) => {
|
|
40
82
|
const [action, path, value] = t || [];
|
|
@@ -109,7 +151,21 @@ function preprocessChanges(root, tuples = [], options = {}) {
|
|
|
109
151
|
return Array.isArray(tuples) ? tuples.slice() : [];
|
|
110
152
|
}
|
|
111
153
|
})();
|
|
112
|
-
const
|
|
154
|
+
const hydratedGranularChanges = granularChanges.map((t) => {
|
|
155
|
+
if (!Array.isArray(t) || t.length < 3) {
|
|
156
|
+
return t;
|
|
157
|
+
}
|
|
158
|
+
const [action, path] = t;
|
|
159
|
+
if (action !== "update" && action !== "set" || !Array.isArray(path)) {
|
|
160
|
+
return t;
|
|
161
|
+
}
|
|
162
|
+
const nextValue = resolveNextValueFromTuples(tuples, path);
|
|
163
|
+
if (nextValue === null) {
|
|
164
|
+
return t;
|
|
165
|
+
}
|
|
166
|
+
return [action, path, nextValue];
|
|
167
|
+
});
|
|
168
|
+
const baseOrders = (0, import_ordering.computeOrdersForTuples)(root, hydratedGranularChanges);
|
|
113
169
|
const preferOrdersMap = /* @__PURE__ */ new Map();
|
|
114
170
|
for (let i = 0; i < tuples.length; i++) {
|
|
115
171
|
const t = tuples[i];
|
|
@@ -139,5 +195,5 @@ function preprocessChanges(root, tuples = [], options = {}) {
|
|
|
139
195
|
mergedOrders.push(v);
|
|
140
196
|
}
|
|
141
197
|
}
|
|
142
|
-
return { granularChanges, orders: mergedOrders };
|
|
198
|
+
return { granularChanges: hydratedGranularChanges, orders: mergedOrders };
|
|
143
199
|
}
|
package/dist/esm/index.js
CHANGED
|
@@ -31640,7 +31640,7 @@ var BaseService = class {
|
|
|
31640
31640
|
}
|
|
31641
31641
|
}
|
|
31642
31642
|
_requireAuth() {
|
|
31643
|
-
if (!this.
|
|
31643
|
+
if (!this.getAuthToken()) {
|
|
31644
31644
|
throw new Error("Authentication required");
|
|
31645
31645
|
}
|
|
31646
31646
|
}
|
|
@@ -32190,6 +32190,12 @@ var AuthService = class extends BaseService {
|
|
|
32190
32190
|
throw new Error(`Failed to get user profile: ${error.message}`, { cause: error });
|
|
32191
32191
|
}
|
|
32192
32192
|
}
|
|
32193
|
+
getAuthToken() {
|
|
32194
|
+
if (!this._tokenManager) {
|
|
32195
|
+
return null;
|
|
32196
|
+
}
|
|
32197
|
+
return this._tokenManager.getAccessToken();
|
|
32198
|
+
}
|
|
32193
32199
|
/**
|
|
32194
32200
|
* Get stored authentication state (backward compatibility method)
|
|
32195
32201
|
* Replaces AuthService.getStoredAuthState()
|
|
@@ -42896,6 +42902,48 @@ function getByPathSafe(root, path) {
|
|
|
42896
42902
|
return null;
|
|
42897
42903
|
}
|
|
42898
42904
|
}
|
|
42905
|
+
function resolveNextValueFromTuples(tuples, path) {
|
|
42906
|
+
if (!Array.isArray(tuples) || !Array.isArray(path)) {
|
|
42907
|
+
return null;
|
|
42908
|
+
}
|
|
42909
|
+
for (let i3 = tuples.length - 1; i3 >= 0; i3--) {
|
|
42910
|
+
const t4 = tuples[i3];
|
|
42911
|
+
if (!Array.isArray(t4) || t4.length < 3) {
|
|
42912
|
+
continue;
|
|
42913
|
+
}
|
|
42914
|
+
const [action, tuplePath, tupleValue] = t4;
|
|
42915
|
+
if (action !== "update" && action !== "set" || !Array.isArray(tuplePath)) {
|
|
42916
|
+
continue;
|
|
42917
|
+
}
|
|
42918
|
+
if (tuplePath.length > path.length) {
|
|
42919
|
+
continue;
|
|
42920
|
+
}
|
|
42921
|
+
let isPrefix = true;
|
|
42922
|
+
for (let j3 = 0; j3 < tuplePath.length; j3++) {
|
|
42923
|
+
if (tuplePath[j3] !== path[j3]) {
|
|
42924
|
+
isPrefix = false;
|
|
42925
|
+
break;
|
|
42926
|
+
}
|
|
42927
|
+
}
|
|
42928
|
+
if (!isPrefix) {
|
|
42929
|
+
continue;
|
|
42930
|
+
}
|
|
42931
|
+
if (tuplePath.length === path.length) {
|
|
42932
|
+
return tupleValue;
|
|
42933
|
+
}
|
|
42934
|
+
let current2 = tupleValue;
|
|
42935
|
+
for (let j3 = tuplePath.length; j3 < path.length; j3++) {
|
|
42936
|
+
if (current2 == null) {
|
|
42937
|
+
return null;
|
|
42938
|
+
}
|
|
42939
|
+
current2 = current2[path[j3]];
|
|
42940
|
+
}
|
|
42941
|
+
if (current2 !== null) {
|
|
42942
|
+
return current2;
|
|
42943
|
+
}
|
|
42944
|
+
}
|
|
42945
|
+
return null;
|
|
42946
|
+
}
|
|
42899
42947
|
function preprocessChanges(root, tuples = [], options = {}) {
|
|
42900
42948
|
const expandTuple = (t4) => {
|
|
42901
42949
|
const [action, path, value2] = t4 || [];
|
|
@@ -42970,7 +43018,21 @@ function preprocessChanges(root, tuples = [], options = {}) {
|
|
|
42970
43018
|
return Array.isArray(tuples) ? tuples.slice() : [];
|
|
42971
43019
|
}
|
|
42972
43020
|
})();
|
|
42973
|
-
const
|
|
43021
|
+
const hydratedGranularChanges = granularChanges.map((t4) => {
|
|
43022
|
+
if (!Array.isArray(t4) || t4.length < 3) {
|
|
43023
|
+
return t4;
|
|
43024
|
+
}
|
|
43025
|
+
const [action, path] = t4;
|
|
43026
|
+
if (action !== "update" && action !== "set" || !Array.isArray(path)) {
|
|
43027
|
+
return t4;
|
|
43028
|
+
}
|
|
43029
|
+
const nextValue = resolveNextValueFromTuples(tuples, path);
|
|
43030
|
+
if (nextValue === null) {
|
|
43031
|
+
return t4;
|
|
43032
|
+
}
|
|
43033
|
+
return [action, path, nextValue];
|
|
43034
|
+
});
|
|
43035
|
+
const baseOrders = computeOrdersForTuples(root, hydratedGranularChanges);
|
|
42974
43036
|
const preferOrdersMap = /* @__PURE__ */ new Map();
|
|
42975
43037
|
for (let i3 = 0; i3 < tuples.length; i3++) {
|
|
42976
43038
|
const t4 = tuples[i3];
|
|
@@ -43000,7 +43062,7 @@ function preprocessChanges(root, tuples = [], options = {}) {
|
|
|
43000
43062
|
mergedOrders.push(v3);
|
|
43001
43063
|
}
|
|
43002
43064
|
}
|
|
43003
|
-
return { granularChanges, orders: mergedOrders };
|
|
43065
|
+
return { granularChanges: hydratedGranularChanges, orders: mergedOrders };
|
|
43004
43066
|
}
|
|
43005
43067
|
|
|
43006
43068
|
// src/services/CollabService.js
|
|
@@ -43220,8 +43282,19 @@ var CollabService = class extends BaseService {
|
|
|
43220
43282
|
console.log(
|
|
43221
43283
|
`[CollabService] Flushing ${this._pendingOps.length} offline operation batch(es)`
|
|
43222
43284
|
);
|
|
43223
|
-
this._pendingOps.forEach(({ changes, granularChanges, orders }) => {
|
|
43224
|
-
|
|
43285
|
+
this._pendingOps.forEach(({ changes, granularChanges, orders, options: opOptions }) => {
|
|
43286
|
+
const { message } = opOptions || {};
|
|
43287
|
+
const ts = Date.now();
|
|
43288
|
+
const payload = {
|
|
43289
|
+
changes,
|
|
43290
|
+
granularChanges,
|
|
43291
|
+
orders,
|
|
43292
|
+
ts
|
|
43293
|
+
};
|
|
43294
|
+
if (message) {
|
|
43295
|
+
payload.message = message;
|
|
43296
|
+
}
|
|
43297
|
+
this.socket.emit("ops", payload);
|
|
43225
43298
|
});
|
|
43226
43299
|
this._pendingOps.length = 0;
|
|
43227
43300
|
}
|
|
@@ -43332,6 +43405,7 @@ var CollabService = class extends BaseService {
|
|
|
43332
43405
|
tuples,
|
|
43333
43406
|
Array.isArray(tuples) ? [] : {}
|
|
43334
43407
|
) : deepStringifyFunctions(tuples, Array.isArray(tuples) ? [] : {});
|
|
43408
|
+
const { message } = options;
|
|
43335
43409
|
if (!this.isConnected()) {
|
|
43336
43410
|
console.warn("[CollabService] Not connected, queuing real-time update");
|
|
43337
43411
|
this._pendingOps.push({
|
|
@@ -43343,18 +43417,24 @@ var CollabService = class extends BaseService {
|
|
|
43343
43417
|
return;
|
|
43344
43418
|
}
|
|
43345
43419
|
if ((_c = this.socket) == null ? void 0 : _c.connected) {
|
|
43420
|
+
const ts = Date.now();
|
|
43346
43421
|
console.log("[CollabService] Sending operations to the backend", {
|
|
43347
43422
|
changes: stringifiedTuples,
|
|
43348
43423
|
granularChanges: stringifiedGranularTuples,
|
|
43349
43424
|
orders,
|
|
43350
|
-
ts
|
|
43425
|
+
ts,
|
|
43426
|
+
message
|
|
43351
43427
|
});
|
|
43352
|
-
|
|
43428
|
+
const payload = {
|
|
43353
43429
|
changes: stringifiedTuples,
|
|
43354
43430
|
granularChanges: stringifiedGranularTuples,
|
|
43355
43431
|
orders,
|
|
43356
|
-
ts
|
|
43357
|
-
}
|
|
43432
|
+
ts
|
|
43433
|
+
};
|
|
43434
|
+
if (message) {
|
|
43435
|
+
payload.message = message;
|
|
43436
|
+
}
|
|
43437
|
+
this.socket.emit("ops", payload);
|
|
43358
43438
|
}
|
|
43359
43439
|
return { success: true };
|
|
43360
43440
|
}
|
|
@@ -48174,6 +48254,7 @@ var SERVICE_METHODS = {
|
|
|
48174
48254
|
// Core service methods (new - replaces most based/auth functionality)
|
|
48175
48255
|
// Auth methods
|
|
48176
48256
|
getStoredAuthState: "auth",
|
|
48257
|
+
getAuthToken: "auth",
|
|
48177
48258
|
register: "auth",
|
|
48178
48259
|
login: "auth",
|
|
48179
48260
|
logout: "auth",
|
|
@@ -682,7 +682,7 @@ var BaseService = class {
|
|
|
682
682
|
}
|
|
683
683
|
}
|
|
684
684
|
_requireAuth() {
|
|
685
|
-
if (!this.
|
|
685
|
+
if (!this.getAuthToken()) {
|
|
686
686
|
throw new Error("Authentication required");
|
|
687
687
|
}
|
|
688
688
|
}
|
|
@@ -1232,6 +1232,12 @@ var AuthService = class extends BaseService {
|
|
|
1232
1232
|
throw new Error(`Failed to get user profile: ${error.message}`, { cause: error });
|
|
1233
1233
|
}
|
|
1234
1234
|
}
|
|
1235
|
+
getAuthToken() {
|
|
1236
|
+
if (!this._tokenManager) {
|
|
1237
|
+
return null;
|
|
1238
|
+
}
|
|
1239
|
+
return this._tokenManager.getAccessToken();
|
|
1240
|
+
}
|
|
1235
1241
|
/**
|
|
1236
1242
|
* Get stored authentication state (backward compatibility method)
|
|
1237
1243
|
* Replaces AuthService.getStoredAuthState()
|
|
@@ -14765,7 +14765,7 @@ var BaseService = class {
|
|
|
14765
14765
|
}
|
|
14766
14766
|
}
|
|
14767
14767
|
_requireAuth() {
|
|
14768
|
-
if (!this.
|
|
14768
|
+
if (!this.getAuthToken()) {
|
|
14769
14769
|
throw new Error("Authentication required");
|
|
14770
14770
|
}
|
|
14771
14771
|
}
|
|
@@ -24977,6 +24977,48 @@ function getByPathSafe(root, path) {
|
|
|
24977
24977
|
return null;
|
|
24978
24978
|
}
|
|
24979
24979
|
}
|
|
24980
|
+
function resolveNextValueFromTuples(tuples, path) {
|
|
24981
|
+
if (!Array.isArray(tuples) || !Array.isArray(path)) {
|
|
24982
|
+
return null;
|
|
24983
|
+
}
|
|
24984
|
+
for (let i = tuples.length - 1; i >= 0; i--) {
|
|
24985
|
+
const t = tuples[i];
|
|
24986
|
+
if (!Array.isArray(t) || t.length < 3) {
|
|
24987
|
+
continue;
|
|
24988
|
+
}
|
|
24989
|
+
const [action, tuplePath, tupleValue] = t;
|
|
24990
|
+
if (action !== "update" && action !== "set" || !Array.isArray(tuplePath)) {
|
|
24991
|
+
continue;
|
|
24992
|
+
}
|
|
24993
|
+
if (tuplePath.length > path.length) {
|
|
24994
|
+
continue;
|
|
24995
|
+
}
|
|
24996
|
+
let isPrefix = true;
|
|
24997
|
+
for (let j = 0; j < tuplePath.length; j++) {
|
|
24998
|
+
if (tuplePath[j] !== path[j]) {
|
|
24999
|
+
isPrefix = false;
|
|
25000
|
+
break;
|
|
25001
|
+
}
|
|
25002
|
+
}
|
|
25003
|
+
if (!isPrefix) {
|
|
25004
|
+
continue;
|
|
25005
|
+
}
|
|
25006
|
+
if (tuplePath.length === path.length) {
|
|
25007
|
+
return tupleValue;
|
|
25008
|
+
}
|
|
25009
|
+
let current2 = tupleValue;
|
|
25010
|
+
for (let j = tuplePath.length; j < path.length; j++) {
|
|
25011
|
+
if (current2 == null) {
|
|
25012
|
+
return null;
|
|
25013
|
+
}
|
|
25014
|
+
current2 = current2[path[j]];
|
|
25015
|
+
}
|
|
25016
|
+
if (current2 !== null) {
|
|
25017
|
+
return current2;
|
|
25018
|
+
}
|
|
25019
|
+
}
|
|
25020
|
+
return null;
|
|
25021
|
+
}
|
|
24980
25022
|
function preprocessChanges(root, tuples = [], options = {}) {
|
|
24981
25023
|
const expandTuple = (t) => {
|
|
24982
25024
|
const [action, path, value2] = t || [];
|
|
@@ -25051,7 +25093,21 @@ function preprocessChanges(root, tuples = [], options = {}) {
|
|
|
25051
25093
|
return Array.isArray(tuples) ? tuples.slice() : [];
|
|
25052
25094
|
}
|
|
25053
25095
|
})();
|
|
25054
|
-
const
|
|
25096
|
+
const hydratedGranularChanges = granularChanges.map((t) => {
|
|
25097
|
+
if (!Array.isArray(t) || t.length < 3) {
|
|
25098
|
+
return t;
|
|
25099
|
+
}
|
|
25100
|
+
const [action, path] = t;
|
|
25101
|
+
if (action !== "update" && action !== "set" || !Array.isArray(path)) {
|
|
25102
|
+
return t;
|
|
25103
|
+
}
|
|
25104
|
+
const nextValue = resolveNextValueFromTuples(tuples, path);
|
|
25105
|
+
if (nextValue === null) {
|
|
25106
|
+
return t;
|
|
25107
|
+
}
|
|
25108
|
+
return [action, path, nextValue];
|
|
25109
|
+
});
|
|
25110
|
+
const baseOrders = computeOrdersForTuples(root, hydratedGranularChanges);
|
|
25055
25111
|
const preferOrdersMap = /* @__PURE__ */ new Map();
|
|
25056
25112
|
for (let i = 0; i < tuples.length; i++) {
|
|
25057
25113
|
const t = tuples[i];
|
|
@@ -25081,7 +25137,7 @@ function preprocessChanges(root, tuples = [], options = {}) {
|
|
|
25081
25137
|
mergedOrders.push(v);
|
|
25082
25138
|
}
|
|
25083
25139
|
}
|
|
25084
|
-
return { granularChanges, orders: mergedOrders };
|
|
25140
|
+
return { granularChanges: hydratedGranularChanges, orders: mergedOrders };
|
|
25085
25141
|
}
|
|
25086
25142
|
|
|
25087
25143
|
// src/services/CollabService.js
|
|
@@ -25301,8 +25357,19 @@ var CollabService = class extends BaseService {
|
|
|
25301
25357
|
console.log(
|
|
25302
25358
|
`[CollabService] Flushing ${this._pendingOps.length} offline operation batch(es)`
|
|
25303
25359
|
);
|
|
25304
|
-
this._pendingOps.forEach(({ changes, granularChanges, orders }) => {
|
|
25305
|
-
|
|
25360
|
+
this._pendingOps.forEach(({ changes, granularChanges, orders, options: opOptions }) => {
|
|
25361
|
+
const { message } = opOptions || {};
|
|
25362
|
+
const ts = Date.now();
|
|
25363
|
+
const payload = {
|
|
25364
|
+
changes,
|
|
25365
|
+
granularChanges,
|
|
25366
|
+
orders,
|
|
25367
|
+
ts
|
|
25368
|
+
};
|
|
25369
|
+
if (message) {
|
|
25370
|
+
payload.message = message;
|
|
25371
|
+
}
|
|
25372
|
+
this.socket.emit("ops", payload);
|
|
25306
25373
|
});
|
|
25307
25374
|
this._pendingOps.length = 0;
|
|
25308
25375
|
}
|
|
@@ -25413,6 +25480,7 @@ var CollabService = class extends BaseService {
|
|
|
25413
25480
|
tuples,
|
|
25414
25481
|
Array.isArray(tuples) ? [] : {}
|
|
25415
25482
|
) : deepStringifyFunctions(tuples, Array.isArray(tuples) ? [] : {});
|
|
25483
|
+
const { message } = options;
|
|
25416
25484
|
if (!this.isConnected()) {
|
|
25417
25485
|
console.warn("[CollabService] Not connected, queuing real-time update");
|
|
25418
25486
|
this._pendingOps.push({
|
|
@@ -25424,18 +25492,24 @@ var CollabService = class extends BaseService {
|
|
|
25424
25492
|
return;
|
|
25425
25493
|
}
|
|
25426
25494
|
if ((_c = this.socket) == null ? void 0 : _c.connected) {
|
|
25495
|
+
const ts = Date.now();
|
|
25427
25496
|
console.log("[CollabService] Sending operations to the backend", {
|
|
25428
25497
|
changes: stringifiedTuples,
|
|
25429
25498
|
granularChanges: stringifiedGranularTuples,
|
|
25430
25499
|
orders,
|
|
25431
|
-
ts
|
|
25500
|
+
ts,
|
|
25501
|
+
message
|
|
25432
25502
|
});
|
|
25433
|
-
|
|
25503
|
+
const payload = {
|
|
25434
25504
|
changes: stringifiedTuples,
|
|
25435
25505
|
granularChanges: stringifiedGranularTuples,
|
|
25436
25506
|
orders,
|
|
25437
|
-
ts
|
|
25438
|
-
}
|
|
25507
|
+
ts
|
|
25508
|
+
};
|
|
25509
|
+
if (message) {
|
|
25510
|
+
payload.message = message;
|
|
25511
|
+
}
|
|
25512
|
+
this.socket.emit("ops", payload);
|
|
25439
25513
|
}
|
|
25440
25514
|
return { success: true };
|
|
25441
25515
|
}
|
|
@@ -682,7 +682,7 @@ var BaseService = class {
|
|
|
682
682
|
}
|
|
683
683
|
}
|
|
684
684
|
_requireAuth() {
|
|
685
|
-
if (!this.
|
|
685
|
+
if (!this.getAuthToken()) {
|
|
686
686
|
throw new Error("Authentication required");
|
|
687
687
|
}
|
|
688
688
|
}
|
|
@@ -1122,6 +1122,48 @@ function getByPathSafe(root, path) {
|
|
|
1122
1122
|
return null;
|
|
1123
1123
|
}
|
|
1124
1124
|
}
|
|
1125
|
+
function resolveNextValueFromTuples(tuples, path) {
|
|
1126
|
+
if (!Array.isArray(tuples) || !Array.isArray(path)) {
|
|
1127
|
+
return null;
|
|
1128
|
+
}
|
|
1129
|
+
for (let i = tuples.length - 1; i >= 0; i--) {
|
|
1130
|
+
const t = tuples[i];
|
|
1131
|
+
if (!Array.isArray(t) || t.length < 3) {
|
|
1132
|
+
continue;
|
|
1133
|
+
}
|
|
1134
|
+
const [action, tuplePath, tupleValue] = t;
|
|
1135
|
+
if (action !== "update" && action !== "set" || !Array.isArray(tuplePath)) {
|
|
1136
|
+
continue;
|
|
1137
|
+
}
|
|
1138
|
+
if (tuplePath.length > path.length) {
|
|
1139
|
+
continue;
|
|
1140
|
+
}
|
|
1141
|
+
let isPrefix = true;
|
|
1142
|
+
for (let j = 0; j < tuplePath.length; j++) {
|
|
1143
|
+
if (tuplePath[j] !== path[j]) {
|
|
1144
|
+
isPrefix = false;
|
|
1145
|
+
break;
|
|
1146
|
+
}
|
|
1147
|
+
}
|
|
1148
|
+
if (!isPrefix) {
|
|
1149
|
+
continue;
|
|
1150
|
+
}
|
|
1151
|
+
if (tuplePath.length === path.length) {
|
|
1152
|
+
return tupleValue;
|
|
1153
|
+
}
|
|
1154
|
+
let current = tupleValue;
|
|
1155
|
+
for (let j = tuplePath.length; j < path.length; j++) {
|
|
1156
|
+
if (current == null) {
|
|
1157
|
+
return null;
|
|
1158
|
+
}
|
|
1159
|
+
current = current[path[j]];
|
|
1160
|
+
}
|
|
1161
|
+
if (current !== null) {
|
|
1162
|
+
return current;
|
|
1163
|
+
}
|
|
1164
|
+
}
|
|
1165
|
+
return null;
|
|
1166
|
+
}
|
|
1125
1167
|
function preprocessChanges(root, tuples = [], options = {}) {
|
|
1126
1168
|
const expandTuple = (t) => {
|
|
1127
1169
|
const [action, path, value] = t || [];
|
|
@@ -1196,7 +1238,21 @@ function preprocessChanges(root, tuples = [], options = {}) {
|
|
|
1196
1238
|
return Array.isArray(tuples) ? tuples.slice() : [];
|
|
1197
1239
|
}
|
|
1198
1240
|
})();
|
|
1199
|
-
const
|
|
1241
|
+
const hydratedGranularChanges = granularChanges.map((t) => {
|
|
1242
|
+
if (!Array.isArray(t) || t.length < 3) {
|
|
1243
|
+
return t;
|
|
1244
|
+
}
|
|
1245
|
+
const [action, path] = t;
|
|
1246
|
+
if (action !== "update" && action !== "set" || !Array.isArray(path)) {
|
|
1247
|
+
return t;
|
|
1248
|
+
}
|
|
1249
|
+
const nextValue = resolveNextValueFromTuples(tuples, path);
|
|
1250
|
+
if (nextValue === null) {
|
|
1251
|
+
return t;
|
|
1252
|
+
}
|
|
1253
|
+
return [action, path, nextValue];
|
|
1254
|
+
});
|
|
1255
|
+
const baseOrders = computeOrdersForTuples(root, hydratedGranularChanges);
|
|
1200
1256
|
const preferOrdersMap = /* @__PURE__ */ new Map();
|
|
1201
1257
|
for (let i = 0; i < tuples.length; i++) {
|
|
1202
1258
|
const t = tuples[i];
|
|
@@ -1226,7 +1282,7 @@ function preprocessChanges(root, tuples = [], options = {}) {
|
|
|
1226
1282
|
mergedOrders.push(v);
|
|
1227
1283
|
}
|
|
1228
1284
|
}
|
|
1229
|
-
return { granularChanges, orders: mergedOrders };
|
|
1285
|
+
return { granularChanges: hydratedGranularChanges, orders: mergedOrders };
|
|
1230
1286
|
}
|
|
1231
1287
|
|
|
1232
1288
|
// src/services/ProjectService.js
|