@symbo.ls/sdk 2.32.6 → 2.32.8
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/config/environment.js +19 -0
- package/dist/cjs/services/AuthService.js +4 -2
- package/dist/cjs/services/CollabService.js +214 -64
- package/dist/cjs/services/ProjectService.js +19 -10
- package/dist/cjs/utils/CollabClient.js +46 -9
- package/dist/esm/config/environment.js +19 -0
- package/dist/esm/index.js +302 -85
- package/dist/esm/services/AdminService.js +19 -0
- package/dist/esm/services/AuthService.js +23 -2
- package/dist/esm/services/BaseService.js +19 -0
- package/dist/esm/services/BranchService.js +19 -0
- package/dist/esm/services/CollabService.js +279 -73
- package/dist/esm/services/CoreService.js +19 -0
- package/dist/esm/services/DnsService.js +19 -0
- package/dist/esm/services/FileService.js +19 -0
- package/dist/esm/services/PaymentService.js +19 -0
- package/dist/esm/services/PlanService.js +19 -0
- package/dist/esm/services/ProjectService.js +38 -10
- package/dist/esm/services/PullRequestService.js +19 -0
- package/dist/esm/services/ScreenshotService.js +19 -0
- package/dist/esm/services/SubscriptionService.js +19 -0
- package/dist/esm/services/index.js +302 -85
- package/dist/esm/utils/CollabClient.js +65 -9
- package/dist/node/config/environment.js +19 -0
- package/dist/node/services/AuthService.js +4 -2
- package/dist/node/services/CollabService.js +214 -64
- package/dist/node/services/ProjectService.js +19 -10
- package/dist/node/utils/CollabClient.js +46 -9
- package/package.json +6 -6
- package/src/config/environment.js +20 -1
- package/src/services/AuthService.js +7 -2
- package/src/services/CollabService.js +258 -77
- package/src/services/ProjectService.js +19 -10
- package/src/utils/CollabClient.js +51 -8
|
@@ -17490,6 +17490,9 @@ var CONFIG = {
|
|
|
17490
17490
|
// For based api
|
|
17491
17491
|
githubClientId: "Ov23liAFrsR0StbAO6PO",
|
|
17492
17492
|
// For github api
|
|
17493
|
+
grafanaUrl: "https://faro-collector-prod-us-east-0.grafana.net/collect/aef64330db80bdfeaac084317bf72f99",
|
|
17494
|
+
// For grafana tracing
|
|
17495
|
+
grafanaAppName: "Localhost Symbols",
|
|
17493
17496
|
// Environment-specific feature toggles (override common)
|
|
17494
17497
|
features: {
|
|
17495
17498
|
betaFeatures: true
|
|
@@ -17505,6 +17508,9 @@ var CONFIG = {
|
|
|
17505
17508
|
socketUrl: "https://dev.api.symbols.app",
|
|
17506
17509
|
apiUrl: "https://dev.api.symbols.app",
|
|
17507
17510
|
githubClientId: "Ov23liHxyWFBxS8f1gnF",
|
|
17511
|
+
grafanaUrl: "https://faro-collector-prod-us-east-0.grafana.net/collect/7a3ba473cee2025c68513667024316b8",
|
|
17512
|
+
// For grafana tracing
|
|
17513
|
+
grafanaAppName: "Symbols Dev",
|
|
17508
17514
|
typesenseCollectionName: "docs",
|
|
17509
17515
|
typesenseApiKey: "awmcVpbWqZi9IUgmvslp1C5LKDU8tMjA",
|
|
17510
17516
|
typesenseHost: "tl2qpnwxev4cjm36p-1.a1.typesense.net",
|
|
@@ -17518,6 +17524,9 @@ var CONFIG = {
|
|
|
17518
17524
|
basedProject: "platform-v2-sm",
|
|
17519
17525
|
basedOrg: "symbols",
|
|
17520
17526
|
githubClientId: "Ov23liHxyWFBxS8f1gnF",
|
|
17527
|
+
grafanaUrl: "https://faro-collector-prod-us-east-0.grafana.net/collect/7a3ba473cee2025c68513667024316b8",
|
|
17528
|
+
// For grafana tracing
|
|
17529
|
+
grafanaAppName: "Symbols Test",
|
|
17521
17530
|
typesenseCollectionName: "docs",
|
|
17522
17531
|
typesenseApiKey: "awmcVpbWqZi9IUgmvslp1C5LKDU8tMjA",
|
|
17523
17532
|
typesenseHost: "tl2qpnwxev4cjm36p-1.a1.typesense.net",
|
|
@@ -17528,6 +17537,9 @@ var CONFIG = {
|
|
|
17528
17537
|
socketUrl: "https://upcoming.api.symbols.app",
|
|
17529
17538
|
apiUrl: "https://upcoming.api.symbols.app",
|
|
17530
17539
|
githubClientId: "Ov23liWF7NvdZ056RV5J",
|
|
17540
|
+
grafanaUrl: "https://faro-collector-prod-us-east-0.grafana.net/collect/7a3ba473cee2025c68513667024316b8",
|
|
17541
|
+
// For grafana tracing
|
|
17542
|
+
grafanaAppName: "Symbols Upcoming",
|
|
17531
17543
|
typesenseCollectionName: "docs",
|
|
17532
17544
|
typesenseApiKey: "awmcVpbWqZi9IUgmvslp1C5LKDU8tMjA",
|
|
17533
17545
|
typesenseHost: "tl2qpnwxev4cjm36p-1.a1.typesense.net",
|
|
@@ -17541,6 +17553,9 @@ var CONFIG = {
|
|
|
17541
17553
|
basedProject: "platform-v2-sm",
|
|
17542
17554
|
basedOrg: "symbols",
|
|
17543
17555
|
githubClientId: "Ov23ligwZDQVD0VfuWNa",
|
|
17556
|
+
grafanaUrl: "https://faro-collector-prod-us-east-0.grafana.net/collect/7a3ba473cee2025c68513667024316b8",
|
|
17557
|
+
// For grafana tracing
|
|
17558
|
+
grafanaAppName: "Symbols Staging",
|
|
17544
17559
|
typesenseCollectionName: "docs",
|
|
17545
17560
|
typesenseApiKey: "awmcVpbWqZi9IUgmvslp1C5LKDU8tMjA",
|
|
17546
17561
|
typesenseHost: "tl2qpnwxev4cjm36p-1.a1.typesense.net",
|
|
@@ -17554,6 +17569,9 @@ var CONFIG = {
|
|
|
17554
17569
|
basedProject: "platform-v2-sm",
|
|
17555
17570
|
basedOrg: "symbols",
|
|
17556
17571
|
githubClientId: "Ov23liFAlOEIXtX3dBtR",
|
|
17572
|
+
grafanaUrl: "https://faro-collector-prod-us-east-0.grafana.net/collect/5c1089f3c3eea4ec5658e05c3f53baae",
|
|
17573
|
+
// For grafana tracing
|
|
17574
|
+
grafanaAppName: "Symbols",
|
|
17557
17575
|
typesenseCollectionName: "docs",
|
|
17558
17576
|
typesenseApiKey: "awmcVpbWqZi9IUgmvslp1C5LKDU8tMjA",
|
|
17559
17577
|
typesenseHost: "tl2qpnwxev4cjm36p-1.a1.typesense.net",
|
|
@@ -17580,6 +17598,7 @@ var getConfig = () => {
|
|
|
17580
17598
|
basedProject: process.env.SYMBOLS_APP_BASED_PROJECT || envConfig.basedProject,
|
|
17581
17599
|
basedOrg: process.env.SYMBOLS_APP_BASED_ORG || envConfig.basedOrg,
|
|
17582
17600
|
githubClientId: process.env.SYMBOLS_APP_GITHUB_CLIENT_ID || envConfig.githubClientId,
|
|
17601
|
+
grafanaUrl: process.env.SYMBOLS_APP_GRAFANA_URL || envConfig.grafanaUrl,
|
|
17583
17602
|
typesenseCollectionName: process.env.TYPESENSE_COLLECTION_NAME || envConfig.typesenseCollectionName,
|
|
17584
17603
|
typesenseApiKey: process.env.TYPESENSE_API_KEY || envConfig.typesenseApiKey,
|
|
17585
17604
|
typesenseHost: process.env.TYPESENSE_HOST || envConfig.typesenseHost,
|
|
@@ -17750,8 +17769,8 @@ var CollabClient = class {
|
|
|
17750
17769
|
__publicField(this, "_buffer", []);
|
|
17751
17770
|
__publicField(this, "_flushTimer", null);
|
|
17752
17771
|
__publicField(this, "_clientId", nanoid());
|
|
17753
|
-
__publicField(this, "_outboxStore",
|
|
17754
|
-
// Dexie table
|
|
17772
|
+
__publicField(this, "_outboxStore", createMemoryOutbox());
|
|
17773
|
+
// Dexie table fallback
|
|
17755
17774
|
__publicField(this, "_readyResolve");
|
|
17756
17775
|
__publicField(this, "ready", new Promise((res) => this._readyResolve = res));
|
|
17757
17776
|
/* ---------- private handlers ---------- */
|
|
@@ -17793,6 +17812,12 @@ var CollabClient = class {
|
|
|
17793
17812
|
await this._outboxStore.clear();
|
|
17794
17813
|
}
|
|
17795
17814
|
});
|
|
17815
|
+
__publicField(this, "_onLiveMode", (flag) => {
|
|
17816
|
+
this.live = flag;
|
|
17817
|
+
});
|
|
17818
|
+
__publicField(this, "_onError", (e) => {
|
|
17819
|
+
console.warn("[collab] socket error", e);
|
|
17820
|
+
});
|
|
17796
17821
|
Object.assign(this, { jwt, projectId, branch, live });
|
|
17797
17822
|
this.ydoc = new Doc();
|
|
17798
17823
|
const hasIndexedDB = typeof globalThis.indexedDB !== "undefined";
|
|
@@ -17805,14 +17830,11 @@ var CollabClient = class {
|
|
|
17805
17830
|
console.warn("[CollabClient] Failed to load IndexeddbPersistence:", err);
|
|
17806
17831
|
});
|
|
17807
17832
|
}
|
|
17808
|
-
if (typeof window
|
|
17809
|
-
this._outboxStore = createMemoryOutbox();
|
|
17810
|
-
} else {
|
|
17833
|
+
if (typeof window !== "undefined" && hasIndexedDB) {
|
|
17811
17834
|
createDexieOutbox(`${projectId}:${branch}`).then((outboxStore) => {
|
|
17812
17835
|
this._outboxStore = outboxStore;
|
|
17813
17836
|
}).catch((err) => {
|
|
17814
17837
|
console.warn("[CollabClient] Failed to load Dexie:", err);
|
|
17815
|
-
this._outboxStore = createMemoryOutbox();
|
|
17816
17838
|
});
|
|
17817
17839
|
}
|
|
17818
17840
|
this.socket = lookup2(environment_default.socketUrl, {
|
|
@@ -17822,9 +17844,7 @@ var CollabClient = class {
|
|
|
17822
17844
|
reconnectionAttempts: Infinity,
|
|
17823
17845
|
reconnectionDelayMax: 4e3
|
|
17824
17846
|
});
|
|
17825
|
-
this.socket.on("snapshot", this._onSnapshot).on("ops", this._onOps).on("commit", this._onCommit).on("liveMode", (
|
|
17826
|
-
this.live = flag;
|
|
17827
|
-
}).on("connect", this._onConnect).on("error", (e) => console.warn("[collab] socket error", e));
|
|
17847
|
+
this.socket.on("snapshot", this._onSnapshot).on("ops", this._onOps).on("commit", this._onCommit).on("liveMode", this._onLiveMode).on("connect", this._onConnect).on("error", this._onError);
|
|
17828
17848
|
this._prevJson = this.ydoc.getMap("root").toJSON();
|
|
17829
17849
|
this.ydoc.on("afterTransaction", (tr) => {
|
|
17830
17850
|
if (tr.origin === "remote") {
|
|
@@ -17871,6 +17891,42 @@ var CollabClient = class {
|
|
|
17871
17891
|
});
|
|
17872
17892
|
this._buffer.length = 0;
|
|
17873
17893
|
}
|
|
17894
|
+
dispose() {
|
|
17895
|
+
var _a;
|
|
17896
|
+
clearTimeout(this._flushTimer);
|
|
17897
|
+
this._flushTimer = null;
|
|
17898
|
+
this._buffer.length = 0;
|
|
17899
|
+
if ((_a = this._outboxStore) == null ? void 0 : _a.clear) {
|
|
17900
|
+
try {
|
|
17901
|
+
const result = this._outboxStore.clear();
|
|
17902
|
+
if (result && typeof result.catch === "function") {
|
|
17903
|
+
result.catch(() => {
|
|
17904
|
+
});
|
|
17905
|
+
}
|
|
17906
|
+
} catch (error) {
|
|
17907
|
+
console.warn("[CollabClient] Failed to clear outbox store during dispose:", error);
|
|
17908
|
+
}
|
|
17909
|
+
}
|
|
17910
|
+
if (this.socket) {
|
|
17911
|
+
this.socket.off("snapshot", this._onSnapshot);
|
|
17912
|
+
this.socket.off("ops", this._onOps);
|
|
17913
|
+
this.socket.off("commit", this._onCommit);
|
|
17914
|
+
this.socket.off("liveMode", this._onLiveMode);
|
|
17915
|
+
this.socket.off("connect", this._onConnect);
|
|
17916
|
+
this.socket.off("error", this._onError);
|
|
17917
|
+
this.socket.removeAllListeners();
|
|
17918
|
+
this.socket.disconnect();
|
|
17919
|
+
this.socket = null;
|
|
17920
|
+
}
|
|
17921
|
+
if (this.ydoc) {
|
|
17922
|
+
this.ydoc.destroy();
|
|
17923
|
+
this.ydoc = null;
|
|
17924
|
+
}
|
|
17925
|
+
if (typeof this._readyResolve === "function") {
|
|
17926
|
+
this._readyResolve();
|
|
17927
|
+
this._readyResolve = null;
|
|
17928
|
+
}
|
|
17929
|
+
}
|
|
17874
17930
|
};
|
|
17875
17931
|
function createMemoryOutbox() {
|
|
17876
17932
|
const store = /* @__PURE__ */ new Map();
|
|
@@ -25,6 +25,9 @@ const CONFIG = {
|
|
|
25
25
|
// For based api
|
|
26
26
|
githubClientId: "Ov23liAFrsR0StbAO6PO",
|
|
27
27
|
// For github api
|
|
28
|
+
grafanaUrl: "https://faro-collector-prod-us-east-0.grafana.net/collect/aef64330db80bdfeaac084317bf72f99",
|
|
29
|
+
// For grafana tracing
|
|
30
|
+
grafanaAppName: "Localhost Symbols",
|
|
28
31
|
// Environment-specific feature toggles (override common)
|
|
29
32
|
features: {
|
|
30
33
|
betaFeatures: true
|
|
@@ -40,6 +43,9 @@ const CONFIG = {
|
|
|
40
43
|
socketUrl: "https://dev.api.symbols.app",
|
|
41
44
|
apiUrl: "https://dev.api.symbols.app",
|
|
42
45
|
githubClientId: "Ov23liHxyWFBxS8f1gnF",
|
|
46
|
+
grafanaUrl: "https://faro-collector-prod-us-east-0.grafana.net/collect/7a3ba473cee2025c68513667024316b8",
|
|
47
|
+
// For grafana tracing
|
|
48
|
+
grafanaAppName: "Symbols Dev",
|
|
43
49
|
typesenseCollectionName: "docs",
|
|
44
50
|
typesenseApiKey: "awmcVpbWqZi9IUgmvslp1C5LKDU8tMjA",
|
|
45
51
|
typesenseHost: "tl2qpnwxev4cjm36p-1.a1.typesense.net",
|
|
@@ -53,6 +59,9 @@ const CONFIG = {
|
|
|
53
59
|
basedProject: "platform-v2-sm",
|
|
54
60
|
basedOrg: "symbols",
|
|
55
61
|
githubClientId: "Ov23liHxyWFBxS8f1gnF",
|
|
62
|
+
grafanaUrl: "https://faro-collector-prod-us-east-0.grafana.net/collect/7a3ba473cee2025c68513667024316b8",
|
|
63
|
+
// For grafana tracing
|
|
64
|
+
grafanaAppName: "Symbols Test",
|
|
56
65
|
typesenseCollectionName: "docs",
|
|
57
66
|
typesenseApiKey: "awmcVpbWqZi9IUgmvslp1C5LKDU8tMjA",
|
|
58
67
|
typesenseHost: "tl2qpnwxev4cjm36p-1.a1.typesense.net",
|
|
@@ -63,6 +72,9 @@ const CONFIG = {
|
|
|
63
72
|
socketUrl: "https://upcoming.api.symbols.app",
|
|
64
73
|
apiUrl: "https://upcoming.api.symbols.app",
|
|
65
74
|
githubClientId: "Ov23liWF7NvdZ056RV5J",
|
|
75
|
+
grafanaUrl: "https://faro-collector-prod-us-east-0.grafana.net/collect/7a3ba473cee2025c68513667024316b8",
|
|
76
|
+
// For grafana tracing
|
|
77
|
+
grafanaAppName: "Symbols Upcoming",
|
|
66
78
|
typesenseCollectionName: "docs",
|
|
67
79
|
typesenseApiKey: "awmcVpbWqZi9IUgmvslp1C5LKDU8tMjA",
|
|
68
80
|
typesenseHost: "tl2qpnwxev4cjm36p-1.a1.typesense.net",
|
|
@@ -76,6 +88,9 @@ const CONFIG = {
|
|
|
76
88
|
basedProject: "platform-v2-sm",
|
|
77
89
|
basedOrg: "symbols",
|
|
78
90
|
githubClientId: "Ov23ligwZDQVD0VfuWNa",
|
|
91
|
+
grafanaUrl: "https://faro-collector-prod-us-east-0.grafana.net/collect/7a3ba473cee2025c68513667024316b8",
|
|
92
|
+
// For grafana tracing
|
|
93
|
+
grafanaAppName: "Symbols Staging",
|
|
79
94
|
typesenseCollectionName: "docs",
|
|
80
95
|
typesenseApiKey: "awmcVpbWqZi9IUgmvslp1C5LKDU8tMjA",
|
|
81
96
|
typesenseHost: "tl2qpnwxev4cjm36p-1.a1.typesense.net",
|
|
@@ -89,6 +104,9 @@ const CONFIG = {
|
|
|
89
104
|
basedProject: "platform-v2-sm",
|
|
90
105
|
basedOrg: "symbols",
|
|
91
106
|
githubClientId: "Ov23liFAlOEIXtX3dBtR",
|
|
107
|
+
grafanaUrl: "https://faro-collector-prod-us-east-0.grafana.net/collect/5c1089f3c3eea4ec5658e05c3f53baae",
|
|
108
|
+
// For grafana tracing
|
|
109
|
+
grafanaAppName: "Symbols",
|
|
92
110
|
typesenseCollectionName: "docs",
|
|
93
111
|
typesenseApiKey: "awmcVpbWqZi9IUgmvslp1C5LKDU8tMjA",
|
|
94
112
|
typesenseHost: "tl2qpnwxev4cjm36p-1.a1.typesense.net",
|
|
@@ -116,6 +134,7 @@ const getConfig = () => {
|
|
|
116
134
|
basedProject: process.env.SYMBOLS_APP_BASED_PROJECT || envConfig.basedProject,
|
|
117
135
|
basedOrg: process.env.SYMBOLS_APP_BASED_ORG || envConfig.basedOrg,
|
|
118
136
|
githubClientId: process.env.SYMBOLS_APP_GITHUB_CLIENT_ID || envConfig.githubClientId,
|
|
137
|
+
grafanaUrl: process.env.SYMBOLS_APP_GRAFANA_URL || envConfig.grafanaUrl,
|
|
119
138
|
typesenseCollectionName: process.env.TYPESENSE_COLLECTION_NAME || envConfig.typesenseCollectionName,
|
|
120
139
|
typesenseApiKey: process.env.TYPESENSE_API_KEY || envConfig.typesenseApiKey,
|
|
121
140
|
typesenseHost: process.env.TYPESENSE_HOST || envConfig.typesenseHost,
|
|
@@ -302,10 +302,12 @@ class AuthService extends BaseService {
|
|
|
302
302
|
throw new Error(`Password change confirmation failed: ${error.message}`, { cause: error });
|
|
303
303
|
}
|
|
304
304
|
}
|
|
305
|
-
async getMe() {
|
|
305
|
+
async getMe(options = {}) {
|
|
306
306
|
this._requireReady("getMe");
|
|
307
307
|
try {
|
|
308
|
-
const
|
|
308
|
+
const session = this._resolvePluginSession(options.session);
|
|
309
|
+
const endpoint = session ? `/auth/me?session=${encodeURIComponent(session)}` : "/auth/me";
|
|
310
|
+
const response = await this._request(endpoint, {
|
|
309
311
|
method: "GET",
|
|
310
312
|
methodName: "getMe"
|
|
311
313
|
});
|
|
@@ -11,12 +11,20 @@ class CollabService extends BaseService {
|
|
|
11
11
|
this._client = null;
|
|
12
12
|
this._stateManager = null;
|
|
13
13
|
this._connected = false;
|
|
14
|
+
this._connecting = false;
|
|
15
|
+
this._connectPromise = null;
|
|
16
|
+
this._connectionMeta = null;
|
|
17
|
+
this._pendingConnectReject = null;
|
|
14
18
|
this._undoStack = [];
|
|
15
19
|
this._redoStack = [];
|
|
16
20
|
this._isUndoRedo = false;
|
|
17
21
|
this._pendingOps = [];
|
|
22
|
+
this._onSocketConnect = this._onSocketConnect.bind(this);
|
|
23
|
+
this._onSocketDisconnect = this._onSocketDisconnect.bind(this);
|
|
24
|
+
this._onSocketError = this._onSocketError.bind(this);
|
|
18
25
|
}
|
|
19
26
|
init({ context }) {
|
|
27
|
+
super.init({ context });
|
|
20
28
|
if (context == null ? void 0 : context.state) {
|
|
21
29
|
try {
|
|
22
30
|
this._stateManager = new RootStateManager(context.state);
|
|
@@ -80,86 +88,196 @@ class CollabService extends BaseService {
|
|
|
80
88
|
}
|
|
81
89
|
/* ---------- Connection Management ---------- */
|
|
82
90
|
async connect(options = {}) {
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
const {
|
|
86
|
-
authToken: jwt,
|
|
87
|
-
projectId,
|
|
88
|
-
branch = "main",
|
|
89
|
-
pro
|
|
90
|
-
} = {
|
|
91
|
-
...this._context,
|
|
92
|
-
...options
|
|
93
|
-
};
|
|
94
|
-
if (!projectId) {
|
|
95
|
-
const state = (_a = this._stateManager) == null ? void 0 : _a.root;
|
|
96
|
-
const el = state.__element;
|
|
97
|
-
el.call("openNotification", {
|
|
98
|
-
type: "error",
|
|
99
|
-
title: "projectId is required",
|
|
100
|
-
message: "projectId is required for CollabService connection"
|
|
101
|
-
});
|
|
102
|
-
throw new Error("projectId is required for CollabService connection");
|
|
103
|
-
}
|
|
104
|
-
if (this._client) {
|
|
105
|
-
await this.disconnect();
|
|
91
|
+
if (this._connectPromise) {
|
|
92
|
+
return this._connectPromise;
|
|
106
93
|
}
|
|
107
|
-
this.
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
94
|
+
this._connectPromise = (async () => {
|
|
95
|
+
var _a;
|
|
96
|
+
this._connecting = true;
|
|
97
|
+
this._connected = false;
|
|
98
|
+
this._ensureStateManager();
|
|
99
|
+
const mergedOptions = {
|
|
100
|
+
...this._context,
|
|
101
|
+
...options
|
|
102
|
+
};
|
|
103
|
+
let { authToken: jwt } = mergedOptions;
|
|
104
|
+
const {
|
|
105
|
+
projectId,
|
|
106
|
+
branch = "main",
|
|
107
|
+
pro
|
|
108
|
+
} = mergedOptions;
|
|
109
|
+
if (!jwt && this._tokenManager) {
|
|
110
|
+
try {
|
|
111
|
+
jwt = await this._tokenManager.ensureValidToken();
|
|
112
|
+
} catch (error) {
|
|
113
|
+
console.warn("[CollabService] Failed to obtain auth token from token manager", error);
|
|
114
|
+
}
|
|
115
|
+
if (!jwt && typeof this._tokenManager.getAccessToken === "function") {
|
|
116
|
+
jwt = this._tokenManager.getAccessToken();
|
|
117
|
+
}
|
|
119
118
|
}
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
console.log(`ops event`);
|
|
123
|
-
this._stateManager.applyChanges(changes, { fromSocket: true });
|
|
124
|
-
});
|
|
125
|
-
(_c = this._client.socket) == null ? void 0 : _c.on("commit", ({ version }) => {
|
|
126
|
-
if (version) {
|
|
127
|
-
this._stateManager.setVersion(version);
|
|
119
|
+
if (!jwt) {
|
|
120
|
+
throw new Error("[CollabService] Cannot connect without auth token");
|
|
128
121
|
}
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
122
|
+
this._context = {
|
|
123
|
+
...this._context,
|
|
124
|
+
authToken: jwt,
|
|
125
|
+
projectId,
|
|
126
|
+
branch,
|
|
127
|
+
pro
|
|
128
|
+
};
|
|
129
|
+
if (!projectId) {
|
|
130
|
+
const state = (_a = this._stateManager) == null ? void 0 : _a.root;
|
|
131
|
+
const el = state.__element;
|
|
132
|
+
el.call("openNotification", {
|
|
133
|
+
type: "error",
|
|
134
|
+
title: "projectId is required",
|
|
135
|
+
message: "projectId is required for CollabService connection"
|
|
136
|
+
});
|
|
137
|
+
throw new Error("projectId is required for CollabService connection");
|
|
138
|
+
}
|
|
139
|
+
if (this._client) {
|
|
140
|
+
await this.disconnect();
|
|
141
|
+
}
|
|
142
|
+
this._client = new CollabClient({
|
|
143
|
+
jwt,
|
|
144
|
+
projectId,
|
|
145
|
+
branch,
|
|
146
|
+
live: Boolean(pro)
|
|
147
|
+
});
|
|
148
|
+
const { socket } = this._client;
|
|
149
|
+
try {
|
|
150
|
+
await new Promise((resolve, reject) => {
|
|
151
|
+
if (!socket) {
|
|
152
|
+
reject(new Error("[CollabService] Socket instance missing"));
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
if (socket.connected) {
|
|
156
|
+
resolve();
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
const cleanup = () => {
|
|
160
|
+
socket.off("connect", handleConnect);
|
|
161
|
+
socket.off("connect_error", handleError);
|
|
162
|
+
socket.off("error", handleError);
|
|
163
|
+
socket.off("disconnect", handleDisconnect);
|
|
164
|
+
if (this._pendingConnectReject === handleError) {
|
|
165
|
+
this._pendingConnectReject = null;
|
|
166
|
+
}
|
|
167
|
+
};
|
|
168
|
+
const handleConnect = () => {
|
|
169
|
+
cleanup();
|
|
170
|
+
resolve();
|
|
171
|
+
};
|
|
172
|
+
const handleError = (error) => {
|
|
173
|
+
cleanup();
|
|
174
|
+
reject(
|
|
175
|
+
error instanceof Error ? error : new Error(String(error || "Unknown connection error"))
|
|
176
|
+
);
|
|
177
|
+
};
|
|
178
|
+
const handleDisconnect = (reason) => {
|
|
179
|
+
handleError(
|
|
180
|
+
reason instanceof Error ? reason : new Error(
|
|
181
|
+
`[CollabService] Socket disconnected before connect: ${reason || "unknown"}`
|
|
182
|
+
)
|
|
183
|
+
);
|
|
184
|
+
};
|
|
185
|
+
this._pendingConnectReject = handleError;
|
|
186
|
+
socket.once("connect", handleConnect);
|
|
187
|
+
socket.once("connect_error", handleError);
|
|
188
|
+
socket.once("error", handleError);
|
|
189
|
+
socket.once("disconnect", handleDisconnect);
|
|
190
|
+
});
|
|
191
|
+
} catch (error) {
|
|
192
|
+
socket == null ? void 0 : socket.disconnect();
|
|
193
|
+
this._client = null;
|
|
194
|
+
this._connectionMeta = null;
|
|
195
|
+
throw error;
|
|
196
|
+
}
|
|
197
|
+
this._attachSocketLifecycleListeners();
|
|
198
|
+
if (socket == null ? void 0 : socket.connected) {
|
|
199
|
+
this._onSocketConnect();
|
|
200
|
+
}
|
|
201
|
+
socket == null ? void 0 : socket.on("ops", ({ changes }) => {
|
|
202
|
+
console.log(`ops event`);
|
|
203
|
+
this._stateManager.applyChanges(changes, { fromSocket: true });
|
|
146
204
|
});
|
|
147
|
-
|
|
205
|
+
socket == null ? void 0 : socket.on("commit", ({ version }) => {
|
|
206
|
+
if (version) {
|
|
207
|
+
this._stateManager.setVersion(version);
|
|
208
|
+
}
|
|
209
|
+
rootBus.emit("checkpoint:done", { version, origin: "auto" });
|
|
210
|
+
});
|
|
211
|
+
socket == null ? void 0 : socket.on("clients", this._handleClientsEvent.bind(this));
|
|
212
|
+
socket == null ? void 0 : socket.on(
|
|
213
|
+
"bundle:done",
|
|
214
|
+
this._handleBundleDoneEvent.bind(this)
|
|
215
|
+
);
|
|
216
|
+
socket == null ? void 0 : socket.on(
|
|
217
|
+
"bundle:error",
|
|
218
|
+
this._handleBundleErrorEvent.bind(this)
|
|
219
|
+
);
|
|
220
|
+
if (this._pendingOps.length) {
|
|
221
|
+
console.log(
|
|
222
|
+
`[CollabService] Flushing ${this._pendingOps.length} offline operation batch(es)`
|
|
223
|
+
);
|
|
224
|
+
this._pendingOps.forEach(({ changes, granularChanges, orders }) => {
|
|
225
|
+
this.socket.emit("ops", { changes, granularChanges, orders, ts: Date.now() });
|
|
226
|
+
});
|
|
227
|
+
this._pendingOps.length = 0;
|
|
228
|
+
}
|
|
229
|
+
await this._client.ready;
|
|
230
|
+
this._connectionMeta = {
|
|
231
|
+
projectId,
|
|
232
|
+
branch,
|
|
233
|
+
live: Boolean(pro)
|
|
234
|
+
};
|
|
235
|
+
return this.getConnectionInfo();
|
|
236
|
+
})();
|
|
237
|
+
try {
|
|
238
|
+
return await this._connectPromise;
|
|
239
|
+
} finally {
|
|
240
|
+
this._connecting = false;
|
|
241
|
+
this._connectPromise = null;
|
|
148
242
|
}
|
|
149
|
-
this._connected = true;
|
|
150
243
|
}
|
|
151
244
|
disconnect() {
|
|
152
245
|
var _a;
|
|
153
246
|
if ((_a = this._client) == null ? void 0 : _a.socket) {
|
|
154
|
-
this.
|
|
247
|
+
if (this._pendingConnectReject) {
|
|
248
|
+
this._pendingConnectReject(new Error("[CollabService] Connection attempt aborted"));
|
|
249
|
+
this._pendingConnectReject = null;
|
|
250
|
+
}
|
|
251
|
+
this._detachSocketLifecycleListeners();
|
|
252
|
+
if (typeof this._client.dispose === "function") {
|
|
253
|
+
this._client.dispose();
|
|
254
|
+
} else {
|
|
255
|
+
this._client.socket.disconnect();
|
|
256
|
+
}
|
|
155
257
|
}
|
|
156
258
|
this._client = null;
|
|
157
259
|
this._connected = false;
|
|
260
|
+
this._connecting = false;
|
|
261
|
+
this._connectionMeta = null;
|
|
262
|
+
this._pendingConnectReject = null;
|
|
158
263
|
console.log("[CollabService] Disconnected");
|
|
159
264
|
}
|
|
160
265
|
isConnected() {
|
|
161
266
|
var _a, _b;
|
|
162
|
-
return this._connected && ((_b = (_a = this._client) == null ? void 0 : _a.socket) == null ? void 0 : _b.connected);
|
|
267
|
+
return Boolean(this._connected && ((_b = (_a = this._client) == null ? void 0 : _a.socket) == null ? void 0 : _b.connected));
|
|
268
|
+
}
|
|
269
|
+
getConnectionInfo() {
|
|
270
|
+
var _a, _b, _c;
|
|
271
|
+
return {
|
|
272
|
+
connected: this.isConnected(),
|
|
273
|
+
connecting: this._connecting,
|
|
274
|
+
projectId: ((_a = this._connectionMeta) == null ? void 0 : _a.projectId) ?? null,
|
|
275
|
+
branch: ((_b = this._connectionMeta) == null ? void 0 : _b.branch) ?? null,
|
|
276
|
+
live: ((_c = this._connectionMeta) == null ? void 0 : _c.live) ?? null,
|
|
277
|
+
pendingOps: this._pendingOps.length,
|
|
278
|
+
undoStackSize: this.getUndoStackSize(),
|
|
279
|
+
redoStackSize: this.getRedoStackSize()
|
|
280
|
+
};
|
|
163
281
|
}
|
|
164
282
|
/* convenient shortcuts */
|
|
165
283
|
get ydoc() {
|
|
@@ -526,6 +644,38 @@ class CollabService extends BaseService {
|
|
|
526
644
|
rootBus.emit("bundle:error", { project, ticket, error });
|
|
527
645
|
}
|
|
528
646
|
/* ---------- Manual checkpoint ---------- */
|
|
647
|
+
_attachSocketLifecycleListeners() {
|
|
648
|
+
var _a;
|
|
649
|
+
const socket = (_a = this._client) == null ? void 0 : _a.socket;
|
|
650
|
+
if (!socket) {
|
|
651
|
+
return;
|
|
652
|
+
}
|
|
653
|
+
socket.on("connect", this._onSocketConnect);
|
|
654
|
+
socket.on("disconnect", this._onSocketDisconnect);
|
|
655
|
+
socket.on("connect_error", this._onSocketError);
|
|
656
|
+
}
|
|
657
|
+
_detachSocketLifecycleListeners() {
|
|
658
|
+
var _a;
|
|
659
|
+
const socket = (_a = this._client) == null ? void 0 : _a.socket;
|
|
660
|
+
if (!socket) {
|
|
661
|
+
return;
|
|
662
|
+
}
|
|
663
|
+
socket.off("connect", this._onSocketConnect);
|
|
664
|
+
socket.off("disconnect", this._onSocketDisconnect);
|
|
665
|
+
socket.off("connect_error", this._onSocketError);
|
|
666
|
+
}
|
|
667
|
+
_onSocketConnect() {
|
|
668
|
+
this._connected = true;
|
|
669
|
+
}
|
|
670
|
+
_onSocketDisconnect(reason) {
|
|
671
|
+
this._connected = false;
|
|
672
|
+
if (reason && reason !== "io client disconnect") {
|
|
673
|
+
console.warn("[CollabService] Socket disconnected", reason);
|
|
674
|
+
}
|
|
675
|
+
}
|
|
676
|
+
_onSocketError(error) {
|
|
677
|
+
console.warn("[CollabService] Socket connection error", error);
|
|
678
|
+
}
|
|
529
679
|
/**
|
|
530
680
|
* Manually request a checkpoint / commit of buffered operations on the server.
|
|
531
681
|
* Resolves with the new version number once the backend confirms via the
|
|
@@ -154,7 +154,8 @@ class ProjectService extends BaseService {
|
|
|
154
154
|
const {
|
|
155
155
|
branch = "main",
|
|
156
156
|
version = "latest",
|
|
157
|
-
includeHistory = false
|
|
157
|
+
includeHistory = false,
|
|
158
|
+
headers
|
|
158
159
|
} = options;
|
|
159
160
|
const queryParams = new URLSearchParams({
|
|
160
161
|
branch,
|
|
@@ -166,7 +167,8 @@ class ProjectService extends BaseService {
|
|
|
166
167
|
`/projects/key/${key}/data?${queryParams}`,
|
|
167
168
|
{
|
|
168
169
|
method: "GET",
|
|
169
|
-
methodName: "getProjectDataByKey"
|
|
170
|
+
methodName: "getProjectDataByKey",
|
|
171
|
+
...headers ? { headers } : {}
|
|
170
172
|
}
|
|
171
173
|
);
|
|
172
174
|
if (response.success) {
|
|
@@ -357,7 +359,7 @@ class ProjectService extends BaseService {
|
|
|
357
359
|
if (!projectId || !email || !role) {
|
|
358
360
|
throw new Error("Project ID, email, and role are required");
|
|
359
361
|
}
|
|
360
|
-
const { name, callbackUrl } = options;
|
|
362
|
+
const { name, callbackUrl, headers } = options;
|
|
361
363
|
const defaultCallbackUrl = typeof window === "undefined" ? "https://app.symbols.com/accept-invite" : `${window.location.origin}/accept-invite`;
|
|
362
364
|
try {
|
|
363
365
|
const requestBody = {
|
|
@@ -371,6 +373,7 @@ class ProjectService extends BaseService {
|
|
|
371
373
|
const response = await this._request(`/projects/${projectId}/invite`, {
|
|
372
374
|
method: "POST",
|
|
373
375
|
body: JSON.stringify(requestBody),
|
|
376
|
+
...headers ? { headers } : {},
|
|
374
377
|
methodName: "inviteMember"
|
|
375
378
|
});
|
|
376
379
|
if (response.success) {
|
|
@@ -532,7 +535,7 @@ class ProjectService extends BaseService {
|
|
|
532
535
|
if (!Array.isArray(changes)) {
|
|
533
536
|
throw new Error("Changes must be an array");
|
|
534
537
|
}
|
|
535
|
-
const { message, branch = "main", type = "patch" } = options;
|
|
538
|
+
const { message, branch = "main", type = "patch", headers } = options;
|
|
536
539
|
const state = this._context && this._context.state;
|
|
537
540
|
const { granularChanges, orders: preprocessorOrders } = preprocessChanges(state, changes, options);
|
|
538
541
|
const derivedOrders = options.orders || (preprocessorOrders && preprocessorOrders.length ? preprocessorOrders : state ? computeOrdersForTuples(state, granularChanges) : []);
|
|
@@ -548,6 +551,7 @@ class ProjectService extends BaseService {
|
|
|
548
551
|
type,
|
|
549
552
|
...derivedOrders && derivedOrders.length ? { orders: derivedOrders } : {}
|
|
550
553
|
}),
|
|
554
|
+
...headers ? { headers } : {},
|
|
551
555
|
methodName: "applyProjectChanges"
|
|
552
556
|
});
|
|
553
557
|
if (response.success) {
|
|
@@ -570,7 +574,8 @@ class ProjectService extends BaseService {
|
|
|
570
574
|
const {
|
|
571
575
|
branch = "main",
|
|
572
576
|
version = "latest",
|
|
573
|
-
includeHistory = false
|
|
577
|
+
includeHistory = false,
|
|
578
|
+
headers
|
|
574
579
|
} = options;
|
|
575
580
|
const queryParams = new URLSearchParams({
|
|
576
581
|
branch,
|
|
@@ -582,7 +587,8 @@ class ProjectService extends BaseService {
|
|
|
582
587
|
`/projects/${projectId}/data?${queryParams}`,
|
|
583
588
|
{
|
|
584
589
|
method: "GET",
|
|
585
|
-
methodName: "getProjectData"
|
|
590
|
+
methodName: "getProjectData",
|
|
591
|
+
...headers ? { headers } : {}
|
|
586
592
|
}
|
|
587
593
|
);
|
|
588
594
|
if (response.success) {
|
|
@@ -601,7 +607,7 @@ class ProjectService extends BaseService {
|
|
|
601
607
|
if (!projectId) {
|
|
602
608
|
throw new Error("Project ID is required");
|
|
603
609
|
}
|
|
604
|
-
const { branch = "main", page = 1, limit = 50 } = options;
|
|
610
|
+
const { branch = "main", page = 1, limit = 50, headers } = options;
|
|
605
611
|
const queryParams = new URLSearchParams({
|
|
606
612
|
branch,
|
|
607
613
|
page: page.toString(),
|
|
@@ -612,7 +618,8 @@ class ProjectService extends BaseService {
|
|
|
612
618
|
`/projects/${projectId}/versions?${queryParams}`,
|
|
613
619
|
{
|
|
614
620
|
method: "GET",
|
|
615
|
-
methodName: "getProjectVersions"
|
|
621
|
+
methodName: "getProjectVersions",
|
|
622
|
+
...headers ? { headers } : {}
|
|
616
623
|
}
|
|
617
624
|
);
|
|
618
625
|
if (response.success) {
|
|
@@ -635,7 +642,7 @@ class ProjectService extends BaseService {
|
|
|
635
642
|
if (!version) {
|
|
636
643
|
throw new Error("Version is required");
|
|
637
644
|
}
|
|
638
|
-
const { message, branch = "main", type = "patch" } = options;
|
|
645
|
+
const { message, branch = "main", type = "patch", headers } = options;
|
|
639
646
|
try {
|
|
640
647
|
const response = await this._request(`/projects/${projectId}/restore`, {
|
|
641
648
|
method: "POST",
|
|
@@ -645,6 +652,7 @@ class ProjectService extends BaseService {
|
|
|
645
652
|
branch,
|
|
646
653
|
type
|
|
647
654
|
}),
|
|
655
|
+
...headers ? { headers } : {},
|
|
648
656
|
methodName: "restoreProjectVersion"
|
|
649
657
|
});
|
|
650
658
|
if (response.success) {
|
|
@@ -794,7 +802,7 @@ class ProjectService extends BaseService {
|
|
|
794
802
|
// ==================== RECENT PROJECT METHODS ====================
|
|
795
803
|
async getRecentProjects(options = {}) {
|
|
796
804
|
this._requireReady("getRecentProjects");
|
|
797
|
-
const { limit = 20 } = options;
|
|
805
|
+
const { limit = 20, headers } = options;
|
|
798
806
|
const queryString = new URLSearchParams({
|
|
799
807
|
limit: limit.toString()
|
|
800
808
|
}).toString();
|
|
@@ -802,6 +810,7 @@ class ProjectService extends BaseService {
|
|
|
802
810
|
try {
|
|
803
811
|
const response = await this._request(url, {
|
|
804
812
|
method: "GET",
|
|
813
|
+
...headers ? { headers } : {},
|
|
805
814
|
methodName: "getRecentProjects"
|
|
806
815
|
});
|
|
807
816
|
if (response.success) {
|