mindcache 2.2.0 → 2.3.0
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/cloud/index.d.mts +2 -2
- package/dist/cloud/index.d.ts +2 -2
- package/dist/cloud/index.js +93 -27
- package/dist/cloud/index.js.map +1 -1
- package/dist/cloud/index.mjs +93 -27
- package/dist/cloud/index.mjs.map +1 -1
- package/dist/{index-XM7bmK7C.d.mts → index-DXb0fL3e.d.mts} +30 -3
- package/dist/{index-XM7bmK7C.d.ts → index-DXb0fL3e.d.ts} +30 -3
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +93 -27
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +93 -27
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/cloud/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { M as MindCache, C as CloudConfig, a as CloudAdapter } from '../index-
|
|
2
|
-
export { d as ClearOperation, c as CloudAdapterEvents, b as ConnectionState, D as DeleteOperation, O as Operation, S as SetOperation } from '../index-
|
|
1
|
+
import { M as MindCache, C as CloudConfig, a as CloudAdapter } from '../index-DXb0fL3e.mjs';
|
|
2
|
+
export { d as ClearOperation, c as CloudAdapterEvents, b as ConnectionState, D as DeleteOperation, O as Operation, S as SetOperation } from '../index-DXb0fL3e.mjs';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Connect a MindCache instance to the cloud for real-time sync.
|
package/dist/cloud/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { M as MindCache, C as CloudConfig, a as CloudAdapter } from '../index-
|
|
2
|
-
export { d as ClearOperation, c as CloudAdapterEvents, b as ConnectionState, D as DeleteOperation, O as Operation, S as SetOperation } from '../index-
|
|
1
|
+
import { M as MindCache, C as CloudConfig, a as CloudAdapter } from '../index-DXb0fL3e.js';
|
|
2
|
+
export { d as ClearOperation, c as CloudAdapterEvents, b as ConnectionState, D as DeleteOperation, O as Operation, S as SetOperation } from '../index-DXb0fL3e.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Connect a MindCache instance to the cloud for real-time sync.
|
package/dist/cloud/index.js
CHANGED
|
@@ -17,16 +17,17 @@ var CloudAdapter_exports = {};
|
|
|
17
17
|
__export(CloudAdapter_exports, {
|
|
18
18
|
CloudAdapter: () => exports.CloudAdapter
|
|
19
19
|
});
|
|
20
|
-
var
|
|
20
|
+
var RECONNECT_DELAY, MAX_RECONNECT_DELAY; exports.CloudAdapter = void 0;
|
|
21
21
|
var init_CloudAdapter = __esm({
|
|
22
22
|
"src/cloud/CloudAdapter.ts"() {
|
|
23
|
-
DEFAULT_BASE_URL = "wss://api.mindcache.io";
|
|
24
23
|
RECONNECT_DELAY = 1e3;
|
|
25
24
|
MAX_RECONNECT_DELAY = 3e4;
|
|
26
25
|
exports.CloudAdapter = class {
|
|
27
26
|
constructor(config) {
|
|
28
27
|
this.config = config;
|
|
29
|
-
|
|
28
|
+
if (!config.baseUrl) {
|
|
29
|
+
throw new Error("MindCache Cloud: baseUrl is required. Please provide the cloud API URL in your configuration.");
|
|
30
|
+
}
|
|
30
31
|
}
|
|
31
32
|
ws = null;
|
|
32
33
|
queue = [];
|
|
@@ -87,6 +88,40 @@ var init_CloudAdapter = __esm({
|
|
|
87
88
|
}
|
|
88
89
|
this.mindcache = null;
|
|
89
90
|
}
|
|
91
|
+
/**
|
|
92
|
+
* Fetch a short-lived WebSocket token from the API using the API key.
|
|
93
|
+
* This keeps the API key secure by only using it for a single HTTPS request,
|
|
94
|
+
* then using the short-lived token for the WebSocket connection.
|
|
95
|
+
*
|
|
96
|
+
* Supports two key formats:
|
|
97
|
+
* - API keys: mc_live_xxx or mc_test_xxx → Bearer token
|
|
98
|
+
* - Delegate keys: del_xxx:sec_xxx → ApiKey format
|
|
99
|
+
*/
|
|
100
|
+
async fetchTokenWithApiKey() {
|
|
101
|
+
if (!this.config.apiKey) {
|
|
102
|
+
throw new Error("API key is required to fetch token");
|
|
103
|
+
}
|
|
104
|
+
const httpBaseUrl = this.config.baseUrl.replace("wss://", "https://").replace("ws://", "http://");
|
|
105
|
+
const isDelegate = this.config.apiKey.startsWith("del_") && this.config.apiKey.includes(":");
|
|
106
|
+
const authHeader = isDelegate ? `ApiKey ${this.config.apiKey}` : `Bearer ${this.config.apiKey}`;
|
|
107
|
+
const response = await fetch(`${httpBaseUrl}/api/ws-token`, {
|
|
108
|
+
method: "POST",
|
|
109
|
+
headers: {
|
|
110
|
+
"Content-Type": "application/json",
|
|
111
|
+
"Authorization": authHeader
|
|
112
|
+
},
|
|
113
|
+
body: JSON.stringify({
|
|
114
|
+
instanceId: this.config.instanceId,
|
|
115
|
+
permission: "write"
|
|
116
|
+
})
|
|
117
|
+
});
|
|
118
|
+
if (!response.ok) {
|
|
119
|
+
const error = await response.json().catch(() => ({ error: "Failed to get token" }));
|
|
120
|
+
throw new Error(error.error || `Failed to get WebSocket token: ${response.status}`);
|
|
121
|
+
}
|
|
122
|
+
const data = await response.json();
|
|
123
|
+
return data.token;
|
|
124
|
+
}
|
|
90
125
|
/**
|
|
91
126
|
* Connect to the cloud service
|
|
92
127
|
*/
|
|
@@ -96,13 +131,19 @@ var init_CloudAdapter = __esm({
|
|
|
96
131
|
}
|
|
97
132
|
this._state = "connecting";
|
|
98
133
|
try {
|
|
99
|
-
if (
|
|
100
|
-
|
|
134
|
+
if (!this.token) {
|
|
135
|
+
if (this.config.tokenProvider) {
|
|
136
|
+
this.token = await this.config.tokenProvider();
|
|
137
|
+
} else if (this.config.apiKey) {
|
|
138
|
+
this.token = await this.fetchTokenWithApiKey();
|
|
139
|
+
}
|
|
101
140
|
}
|
|
102
141
|
let url = `${this.config.baseUrl}/sync/${this.config.instanceId}`;
|
|
103
142
|
if (this.token) {
|
|
104
143
|
url += `?token=${encodeURIComponent(this.token)}`;
|
|
105
144
|
this.token = null;
|
|
145
|
+
} else {
|
|
146
|
+
throw new Error("MindCache Cloud: No authentication method available. Provide apiKey or tokenProvider.");
|
|
106
147
|
}
|
|
107
148
|
this.ws = new WebSocket(url);
|
|
108
149
|
this.setupWebSocket();
|
|
@@ -164,12 +205,6 @@ var init_CloudAdapter = __esm({
|
|
|
164
205
|
return;
|
|
165
206
|
}
|
|
166
207
|
this.ws.onopen = () => {
|
|
167
|
-
if (this.config.apiKey) {
|
|
168
|
-
this.ws.send(JSON.stringify({
|
|
169
|
-
type: "auth",
|
|
170
|
-
apiKey: this.config.apiKey
|
|
171
|
-
}));
|
|
172
|
-
}
|
|
173
208
|
};
|
|
174
209
|
this.ws.onmessage = (event) => {
|
|
175
210
|
try {
|
|
@@ -177,6 +212,7 @@ var init_CloudAdapter = __esm({
|
|
|
177
212
|
this.handleMessage(msg);
|
|
178
213
|
} catch (error) {
|
|
179
214
|
console.error("MindCache Cloud: Failed to parse message:", error);
|
|
215
|
+
console.error("Raw message:", typeof event.data === "string" ? event.data.slice(0, 200) : event.data);
|
|
180
216
|
}
|
|
181
217
|
};
|
|
182
218
|
this.ws.onclose = () => {
|
|
@@ -184,10 +220,12 @@ var init_CloudAdapter = __esm({
|
|
|
184
220
|
this.emit("disconnected");
|
|
185
221
|
this.scheduleReconnect();
|
|
186
222
|
};
|
|
187
|
-
this.ws.onerror = (
|
|
223
|
+
this.ws.onerror = () => {
|
|
188
224
|
this._state = "error";
|
|
189
|
-
|
|
190
|
-
console.error(
|
|
225
|
+
const url = `${this.config.baseUrl}/sync/${this.config.instanceId}`;
|
|
226
|
+
console.error(`MindCache Cloud: WebSocket error connecting to ${url}`);
|
|
227
|
+
console.error("Check that the instance ID and API key are correct, and that the server is reachable.");
|
|
228
|
+
this.emit("error", new Error(`WebSocket connection failed to ${url}`));
|
|
191
229
|
};
|
|
192
230
|
}
|
|
193
231
|
handleMessage(msg) {
|
|
@@ -264,15 +302,6 @@ var init_CloudAdapter = __esm({
|
|
|
264
302
|
this.reconnectTimeout = setTimeout(async () => {
|
|
265
303
|
this.reconnectTimeout = null;
|
|
266
304
|
this.reconnectAttempts++;
|
|
267
|
-
if (this.config.tokenProvider) {
|
|
268
|
-
try {
|
|
269
|
-
this.token = await this.config.tokenProvider();
|
|
270
|
-
} catch (error) {
|
|
271
|
-
console.error("MindCache Cloud: Failed to get token for reconnect:", error);
|
|
272
|
-
this.emit("error", error);
|
|
273
|
-
return;
|
|
274
|
-
}
|
|
275
|
-
}
|
|
276
305
|
this.connect();
|
|
277
306
|
}, delay);
|
|
278
307
|
}
|
|
@@ -327,6 +356,7 @@ var MindCache = class {
|
|
|
327
356
|
_cloudConfig = null;
|
|
328
357
|
// Access level for system operations
|
|
329
358
|
_accessLevel = "user";
|
|
359
|
+
_initPromise = null;
|
|
330
360
|
constructor(options) {
|
|
331
361
|
if (options?.accessLevel) {
|
|
332
362
|
this._accessLevel = options.accessLevel;
|
|
@@ -335,7 +365,7 @@ var MindCache = class {
|
|
|
335
365
|
this._cloudConfig = options.cloud;
|
|
336
366
|
this._isLoaded = false;
|
|
337
367
|
this._connectionState = "disconnected";
|
|
338
|
-
this._initCloud();
|
|
368
|
+
this._initPromise = this._initCloud();
|
|
339
369
|
}
|
|
340
370
|
}
|
|
341
371
|
/**
|
|
@@ -355,9 +385,11 @@ var MindCache = class {
|
|
|
355
385
|
return;
|
|
356
386
|
}
|
|
357
387
|
try {
|
|
358
|
-
const
|
|
359
|
-
|
|
360
|
-
|
|
388
|
+
const CloudAdapter2 = await this._getCloudAdapterClass();
|
|
389
|
+
if (!this._cloudConfig.baseUrl) {
|
|
390
|
+
throw new Error("MindCache Cloud: baseUrl is required. Please provide the cloud API URL in your configuration.");
|
|
391
|
+
}
|
|
392
|
+
const baseUrl = this._cloudConfig.baseUrl.replace("https://", "wss://").replace("http://", "ws://");
|
|
361
393
|
const adapter = new CloudAdapter2({
|
|
362
394
|
instanceId: this._cloudConfig.instanceId,
|
|
363
395
|
projectId: this._cloudConfig.projectId || "default",
|
|
@@ -425,12 +457,46 @@ var MindCache = class {
|
|
|
425
457
|
get isLoaded() {
|
|
426
458
|
return this._isLoaded;
|
|
427
459
|
}
|
|
460
|
+
/**
|
|
461
|
+
* Protected method to load CloudAdapter class.
|
|
462
|
+
* Can be overridden/mocked for testing.
|
|
463
|
+
*/
|
|
464
|
+
async _getCloudAdapterClass() {
|
|
465
|
+
const { CloudAdapter: CloudAdapter2 } = await Promise.resolve().then(() => (init_CloudAdapter(), CloudAdapter_exports));
|
|
466
|
+
return CloudAdapter2;
|
|
467
|
+
}
|
|
428
468
|
/**
|
|
429
469
|
* Check if this instance is connected to cloud
|
|
430
470
|
*/
|
|
431
471
|
get isCloud() {
|
|
432
472
|
return this._cloudConfig !== null;
|
|
433
473
|
}
|
|
474
|
+
/**
|
|
475
|
+
* Wait for initial sync to complete (or resolve immediately if already synced/local).
|
|
476
|
+
* Useful for scripts or linear execution flows.
|
|
477
|
+
*/
|
|
478
|
+
async waitForSync() {
|
|
479
|
+
if (this._isLoaded) {
|
|
480
|
+
return;
|
|
481
|
+
}
|
|
482
|
+
if (this._initPromise) {
|
|
483
|
+
await this._initPromise;
|
|
484
|
+
}
|
|
485
|
+
if (this._isLoaded) {
|
|
486
|
+
return;
|
|
487
|
+
}
|
|
488
|
+
return new Promise((resolve) => {
|
|
489
|
+
if (!this._cloudAdapter) {
|
|
490
|
+
resolve();
|
|
491
|
+
return;
|
|
492
|
+
}
|
|
493
|
+
const handler = () => {
|
|
494
|
+
this._cloudAdapter?.off("synced", handler);
|
|
495
|
+
resolve();
|
|
496
|
+
};
|
|
497
|
+
this._cloudAdapter.on("synced", handler);
|
|
498
|
+
});
|
|
499
|
+
}
|
|
434
500
|
/**
|
|
435
501
|
* Disconnect from cloud (if connected)
|
|
436
502
|
*/
|