mindcache 3.3.1 → 3.4.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/{CloudAdapter-BgpqZE00.d.mts → CloudAdapter-WvuWM4fD.d.mts} +17 -12
- package/dist/{CloudAdapter-BgpqZE00.d.ts → CloudAdapter-WvuWM4fD.d.ts} +17 -12
- package/dist/cloud/index.d.mts +2 -2
- package/dist/cloud/index.d.ts +2 -2
- package/dist/cloud/index.js +97 -23
- package/dist/cloud/index.js.map +1 -1
- package/dist/cloud/index.mjs +97 -23
- package/dist/cloud/index.mjs.map +1 -1
- package/dist/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +97 -23
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +97 -23
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -183,6 +183,7 @@ var init_CloudAdapter = __esm({
|
|
|
183
183
|
if (!config.baseUrl) {
|
|
184
184
|
throw new Error("MindCache Cloud: baseUrl is required. Please provide the cloud API URL in your configuration.");
|
|
185
185
|
}
|
|
186
|
+
this.setupNetworkDetection();
|
|
186
187
|
}
|
|
187
188
|
ws = null;
|
|
188
189
|
mindcache = null;
|
|
@@ -190,8 +191,52 @@ var init_CloudAdapter = __esm({
|
|
|
190
191
|
reconnectAttempts = 0;
|
|
191
192
|
reconnectTimeout = null;
|
|
192
193
|
_state = "disconnected";
|
|
194
|
+
_isOnline = true;
|
|
195
|
+
// Browser network status
|
|
193
196
|
listeners = {};
|
|
194
197
|
token = null;
|
|
198
|
+
handleOnline = null;
|
|
199
|
+
handleOffline = null;
|
|
200
|
+
/** Browser network status - instantly updated via navigator.onLine */
|
|
201
|
+
get isOnline() {
|
|
202
|
+
return this._isOnline;
|
|
203
|
+
}
|
|
204
|
+
setupNetworkDetection() {
|
|
205
|
+
if (typeof window === "undefined" || typeof navigator === "undefined") {
|
|
206
|
+
return;
|
|
207
|
+
}
|
|
208
|
+
this._isOnline = navigator.onLine;
|
|
209
|
+
this.handleOnline = () => {
|
|
210
|
+
console.log("\u2601\uFE0F CloudAdapter: Network is back online");
|
|
211
|
+
this._isOnline = true;
|
|
212
|
+
this.emit("network_online");
|
|
213
|
+
if (this._state === "disconnected" || this._state === "error") {
|
|
214
|
+
this.connect();
|
|
215
|
+
}
|
|
216
|
+
};
|
|
217
|
+
this.handleOffline = () => {
|
|
218
|
+
console.log("\u2601\uFE0F CloudAdapter: Network went offline");
|
|
219
|
+
this._isOnline = false;
|
|
220
|
+
this.emit("network_offline");
|
|
221
|
+
if (this._state === "connected" || this._state === "connecting") {
|
|
222
|
+
this._state = "disconnected";
|
|
223
|
+
this.emit("disconnected");
|
|
224
|
+
}
|
|
225
|
+
};
|
|
226
|
+
window.addEventListener("online", this.handleOnline);
|
|
227
|
+
window.addEventListener("offline", this.handleOffline);
|
|
228
|
+
}
|
|
229
|
+
cleanupNetworkDetection() {
|
|
230
|
+
if (typeof window === "undefined") {
|
|
231
|
+
return;
|
|
232
|
+
}
|
|
233
|
+
if (this.handleOnline) {
|
|
234
|
+
window.removeEventListener("online", this.handleOnline);
|
|
235
|
+
}
|
|
236
|
+
if (this.handleOffline) {
|
|
237
|
+
window.removeEventListener("offline", this.handleOffline);
|
|
238
|
+
}
|
|
239
|
+
}
|
|
195
240
|
setToken(token) {
|
|
196
241
|
this.token = token;
|
|
197
242
|
}
|
|
@@ -285,6 +330,7 @@ var init_CloudAdapter = __esm({
|
|
|
285
330
|
this.ws.close();
|
|
286
331
|
this.ws = null;
|
|
287
332
|
}
|
|
333
|
+
this.cleanupNetworkDetection();
|
|
288
334
|
this._state = "disconnected";
|
|
289
335
|
this.emit("disconnected");
|
|
290
336
|
}
|
|
@@ -401,7 +447,7 @@ var MindCache = class {
|
|
|
401
447
|
listeners = {};
|
|
402
448
|
globalListeners = [];
|
|
403
449
|
// Metadata
|
|
404
|
-
version = "3.3.
|
|
450
|
+
version = "3.3.2";
|
|
405
451
|
// Internal flag to prevent sync loops when receiving remote updates
|
|
406
452
|
// (Less critical with Yjs but kept for API compat)
|
|
407
453
|
_isRemoteUpdate = false;
|
|
@@ -474,14 +520,30 @@ var MindCache = class {
|
|
|
474
520
|
break;
|
|
475
521
|
}
|
|
476
522
|
}
|
|
523
|
+
} else {
|
|
524
|
+
let current = event.target;
|
|
525
|
+
while (current && current.parent) {
|
|
526
|
+
if (current.parent.parent === this.rootMap) {
|
|
527
|
+
for (const [key, val] of this.rootMap) {
|
|
528
|
+
if (val === current.parent) {
|
|
529
|
+
keysAffected.add(key);
|
|
530
|
+
break;
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
break;
|
|
534
|
+
}
|
|
535
|
+
current = current.parent;
|
|
536
|
+
}
|
|
477
537
|
}
|
|
478
538
|
});
|
|
479
539
|
keysAffected.forEach((key) => {
|
|
480
540
|
const entryMap = this.rootMap.get(key);
|
|
481
541
|
if (entryMap) {
|
|
482
542
|
const value = entryMap.get("value");
|
|
543
|
+
const attrs = entryMap.get("attributes");
|
|
544
|
+
const resolvedValue = attrs?.type === "document" && value instanceof Y.Text ? value.toString() : value;
|
|
483
545
|
if (this.listeners[key]) {
|
|
484
|
-
this.listeners[key].forEach((l) => l(
|
|
546
|
+
this.listeners[key].forEach((l) => l(resolvedValue));
|
|
485
547
|
}
|
|
486
548
|
} else {
|
|
487
549
|
if (this.listeners[key]) {
|
|
@@ -611,12 +673,19 @@ var MindCache = class {
|
|
|
611
673
|
if (event.target === this.rootMap) {
|
|
612
674
|
const mapEvent = event;
|
|
613
675
|
mapEvent.keysChanged.forEach((key) => keysAffected.add(key));
|
|
614
|
-
} else
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
676
|
+
} else {
|
|
677
|
+
let current = event.target;
|
|
678
|
+
while (current && current.parent) {
|
|
679
|
+
if (current.parent === this.rootMap) {
|
|
680
|
+
for (const [key, val] of this.rootMap) {
|
|
681
|
+
if (val === current) {
|
|
682
|
+
keysAffected.add(key);
|
|
683
|
+
break;
|
|
684
|
+
}
|
|
685
|
+
}
|
|
618
686
|
break;
|
|
619
687
|
}
|
|
688
|
+
current = current.parent;
|
|
620
689
|
}
|
|
621
690
|
}
|
|
622
691
|
});
|
|
@@ -756,6 +825,19 @@ var MindCache = class {
|
|
|
756
825
|
get isCloud() {
|
|
757
826
|
return this._cloudConfig !== null;
|
|
758
827
|
}
|
|
828
|
+
/**
|
|
829
|
+
* Browser network status. Returns true if online or in local-only mode.
|
|
830
|
+
* In cloud mode, this updates instantly when network status changes.
|
|
831
|
+
*/
|
|
832
|
+
get isOnline() {
|
|
833
|
+
if (!this._cloudAdapter) {
|
|
834
|
+
if (typeof navigator !== "undefined") {
|
|
835
|
+
return navigator.onLine;
|
|
836
|
+
}
|
|
837
|
+
return true;
|
|
838
|
+
}
|
|
839
|
+
return this._cloudAdapter.isOnline;
|
|
840
|
+
}
|
|
759
841
|
async waitForSync() {
|
|
760
842
|
if (this._isLoaded) {
|
|
761
843
|
return;
|
|
@@ -1000,11 +1082,15 @@ var MindCache = class {
|
|
|
1000
1082
|
const existingAttrs = existingEntry.get("attributes");
|
|
1001
1083
|
if (existingAttrs?.type === "document") {
|
|
1002
1084
|
if (typeof value === "string") {
|
|
1003
|
-
this.
|
|
1085
|
+
this._replaceDocumentText(key, value);
|
|
1004
1086
|
}
|
|
1005
1087
|
return;
|
|
1006
1088
|
}
|
|
1007
1089
|
}
|
|
1090
|
+
if (!existingEntry && attributes?.type === "document") {
|
|
1091
|
+
this.set_document(key, typeof value === "string" ? value : "", attributes);
|
|
1092
|
+
return;
|
|
1093
|
+
}
|
|
1008
1094
|
let entryMap = this.rootMap.get(key);
|
|
1009
1095
|
const isNewEntry = !entryMap;
|
|
1010
1096
|
if (isNewEntry) {
|
|
@@ -1745,14 +1831,6 @@ var MindCache = class {
|
|
|
1745
1831
|
}
|
|
1746
1832
|
return void 0;
|
|
1747
1833
|
}
|
|
1748
|
-
/**
|
|
1749
|
-
* Get plain text content of a document key.
|
|
1750
|
-
* For collaborative editing, use get_document() and bind to an editor.
|
|
1751
|
-
*/
|
|
1752
|
-
get_document_text(key) {
|
|
1753
|
-
const yText = this.get_document(key);
|
|
1754
|
-
return yText?.toString();
|
|
1755
|
-
}
|
|
1756
1834
|
/**
|
|
1757
1835
|
* Insert text at a position in a document key.
|
|
1758
1836
|
*/
|
|
@@ -1772,15 +1850,11 @@ var MindCache = class {
|
|
|
1772
1850
|
}
|
|
1773
1851
|
}
|
|
1774
1852
|
/**
|
|
1775
|
-
* Replace all text in a document key.
|
|
1853
|
+
* Replace all text in a document key (private - use set_value for public API).
|
|
1776
1854
|
* Uses diff-based updates when changes are < diffThreshold (default 80%).
|
|
1777
1855
|
* This preserves concurrent edits and provides better undo granularity.
|
|
1778
|
-
*
|
|
1779
|
-
* @param key - The document key
|
|
1780
|
-
* @param newText - The new text content
|
|
1781
|
-
* @param diffThreshold - Percentage (0-1) of change above which full replace is used (default: 0.8)
|
|
1782
1856
|
*/
|
|
1783
|
-
|
|
1857
|
+
_replaceDocumentText(key, newText, diffThreshold = 0.8) {
|
|
1784
1858
|
const yText = this.get_document(key);
|
|
1785
1859
|
if (!yText) {
|
|
1786
1860
|
return;
|
|
@@ -1886,7 +1960,7 @@ var MindCache = class {
|
|
|
1886
1960
|
},
|
|
1887
1961
|
execute: async ({ value }) => {
|
|
1888
1962
|
if (isDocument) {
|
|
1889
|
-
this.
|
|
1963
|
+
this._replaceDocumentText(key, value);
|
|
1890
1964
|
} else {
|
|
1891
1965
|
this.set_value(key, value);
|
|
1892
1966
|
}
|
|
@@ -2042,7 +2116,7 @@ var MindCache = class {
|
|
|
2042
2116
|
switch (action) {
|
|
2043
2117
|
case "write":
|
|
2044
2118
|
if (isDocument) {
|
|
2045
|
-
this.
|
|
2119
|
+
this._replaceDocumentText(key, value);
|
|
2046
2120
|
} else {
|
|
2047
2121
|
this.set_value(key, value);
|
|
2048
2122
|
}
|