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/index.d.mts CHANGED
@@ -1,5 +1,5 @@
1
- import { M as MindCache, a as MindCacheOptions } from './CloudAdapter-BgpqZE00.mjs';
2
- export { A as AccessLevel, C as CloudAdapter, j as CloudAdapterEvents, h as CloudConfig, i as ConnectionState, D as DEFAULT_KEY_ATTRIBUTES, G as GlobalListener, H as HistoryEntry, e as HistoryOptions, K as KeyAttributes, b as KeyType, L as Listener, f as MindCacheCloudOptions, g as MindCacheIndexedDBOptions, c as STM, d as STMEntry, S as SystemTag } from './CloudAdapter-BgpqZE00.mjs';
1
+ import { M as MindCache, a as MindCacheOptions } from './CloudAdapter-WvuWM4fD.mjs';
2
+ export { A as AccessLevel, C as CloudAdapter, j as CloudAdapterEvents, h as CloudConfig, i as ConnectionState, D as DEFAULT_KEY_ATTRIBUTES, G as GlobalListener, H as HistoryEntry, e as HistoryOptions, K as KeyAttributes, b as KeyType, L as Listener, f as MindCacheCloudOptions, g as MindCacheIndexedDBOptions, c as STM, d as STMEntry, S as SystemTag } from './CloudAdapter-WvuWM4fD.mjs';
3
3
  import 'yjs';
4
4
 
5
5
  interface IndexedDBConfig {
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { M as MindCache, a as MindCacheOptions } from './CloudAdapter-BgpqZE00.js';
2
- export { A as AccessLevel, C as CloudAdapter, j as CloudAdapterEvents, h as CloudConfig, i as ConnectionState, D as DEFAULT_KEY_ATTRIBUTES, G as GlobalListener, H as HistoryEntry, e as HistoryOptions, K as KeyAttributes, b as KeyType, L as Listener, f as MindCacheCloudOptions, g as MindCacheIndexedDBOptions, c as STM, d as STMEntry, S as SystemTag } from './CloudAdapter-BgpqZE00.js';
1
+ import { M as MindCache, a as MindCacheOptions } from './CloudAdapter-WvuWM4fD.js';
2
+ export { A as AccessLevel, C as CloudAdapter, j as CloudAdapterEvents, h as CloudConfig, i as ConnectionState, D as DEFAULT_KEY_ATTRIBUTES, G as GlobalListener, H as HistoryEntry, e as HistoryOptions, K as KeyAttributes, b as KeyType, L as Listener, f as MindCacheCloudOptions, g as MindCacheIndexedDBOptions, c as STM, d as STMEntry, S as SystemTag } from './CloudAdapter-WvuWM4fD.js';
3
3
  import 'yjs';
4
4
 
5
5
  interface IndexedDBConfig {
package/dist/index.js CHANGED
@@ -211,6 +211,7 @@ var init_CloudAdapter = __esm({
211
211
  if (!config.baseUrl) {
212
212
  throw new Error("MindCache Cloud: baseUrl is required. Please provide the cloud API URL in your configuration.");
213
213
  }
214
+ this.setupNetworkDetection();
214
215
  }
215
216
  ws = null;
216
217
  mindcache = null;
@@ -218,8 +219,52 @@ var init_CloudAdapter = __esm({
218
219
  reconnectAttempts = 0;
219
220
  reconnectTimeout = null;
220
221
  _state = "disconnected";
222
+ _isOnline = true;
223
+ // Browser network status
221
224
  listeners = {};
222
225
  token = null;
226
+ handleOnline = null;
227
+ handleOffline = null;
228
+ /** Browser network status - instantly updated via navigator.onLine */
229
+ get isOnline() {
230
+ return this._isOnline;
231
+ }
232
+ setupNetworkDetection() {
233
+ if (typeof window === "undefined" || typeof navigator === "undefined") {
234
+ return;
235
+ }
236
+ this._isOnline = navigator.onLine;
237
+ this.handleOnline = () => {
238
+ console.log("\u2601\uFE0F CloudAdapter: Network is back online");
239
+ this._isOnline = true;
240
+ this.emit("network_online");
241
+ if (this._state === "disconnected" || this._state === "error") {
242
+ this.connect();
243
+ }
244
+ };
245
+ this.handleOffline = () => {
246
+ console.log("\u2601\uFE0F CloudAdapter: Network went offline");
247
+ this._isOnline = false;
248
+ this.emit("network_offline");
249
+ if (this._state === "connected" || this._state === "connecting") {
250
+ this._state = "disconnected";
251
+ this.emit("disconnected");
252
+ }
253
+ };
254
+ window.addEventListener("online", this.handleOnline);
255
+ window.addEventListener("offline", this.handleOffline);
256
+ }
257
+ cleanupNetworkDetection() {
258
+ if (typeof window === "undefined") {
259
+ return;
260
+ }
261
+ if (this.handleOnline) {
262
+ window.removeEventListener("online", this.handleOnline);
263
+ }
264
+ if (this.handleOffline) {
265
+ window.removeEventListener("offline", this.handleOffline);
266
+ }
267
+ }
223
268
  setToken(token) {
224
269
  this.token = token;
225
270
  }
@@ -313,6 +358,7 @@ var init_CloudAdapter = __esm({
313
358
  this.ws.close();
314
359
  this.ws = null;
315
360
  }
361
+ this.cleanupNetworkDetection();
316
362
  this._state = "disconnected";
317
363
  this.emit("disconnected");
318
364
  }
@@ -429,7 +475,7 @@ var MindCache = class {
429
475
  listeners = {};
430
476
  globalListeners = [];
431
477
  // Metadata
432
- version = "3.3.1";
478
+ version = "3.3.2";
433
479
  // Internal flag to prevent sync loops when receiving remote updates
434
480
  // (Less critical with Yjs but kept for API compat)
435
481
  _isRemoteUpdate = false;
@@ -502,14 +548,30 @@ var MindCache = class {
502
548
  break;
503
549
  }
504
550
  }
551
+ } else {
552
+ let current = event.target;
553
+ while (current && current.parent) {
554
+ if (current.parent.parent === this.rootMap) {
555
+ for (const [key, val] of this.rootMap) {
556
+ if (val === current.parent) {
557
+ keysAffected.add(key);
558
+ break;
559
+ }
560
+ }
561
+ break;
562
+ }
563
+ current = current.parent;
564
+ }
505
565
  }
506
566
  });
507
567
  keysAffected.forEach((key) => {
508
568
  const entryMap = this.rootMap.get(key);
509
569
  if (entryMap) {
510
570
  const value = entryMap.get("value");
571
+ const attrs = entryMap.get("attributes");
572
+ const resolvedValue = attrs?.type === "document" && value instanceof Y__namespace.Text ? value.toString() : value;
511
573
  if (this.listeners[key]) {
512
- this.listeners[key].forEach((l) => l(value));
574
+ this.listeners[key].forEach((l) => l(resolvedValue));
513
575
  }
514
576
  } else {
515
577
  if (this.listeners[key]) {
@@ -639,12 +701,19 @@ var MindCache = class {
639
701
  if (event.target === this.rootMap) {
640
702
  const mapEvent = event;
641
703
  mapEvent.keysChanged.forEach((key) => keysAffected.add(key));
642
- } else if (event.target.parent === this.rootMap) {
643
- for (const [key, val] of this.rootMap) {
644
- if (val === event.target) {
645
- keysAffected.add(key);
704
+ } else {
705
+ let current = event.target;
706
+ while (current && current.parent) {
707
+ if (current.parent === this.rootMap) {
708
+ for (const [key, val] of this.rootMap) {
709
+ if (val === current) {
710
+ keysAffected.add(key);
711
+ break;
712
+ }
713
+ }
646
714
  break;
647
715
  }
716
+ current = current.parent;
648
717
  }
649
718
  }
650
719
  });
@@ -784,6 +853,19 @@ var MindCache = class {
784
853
  get isCloud() {
785
854
  return this._cloudConfig !== null;
786
855
  }
856
+ /**
857
+ * Browser network status. Returns true if online or in local-only mode.
858
+ * In cloud mode, this updates instantly when network status changes.
859
+ */
860
+ get isOnline() {
861
+ if (!this._cloudAdapter) {
862
+ if (typeof navigator !== "undefined") {
863
+ return navigator.onLine;
864
+ }
865
+ return true;
866
+ }
867
+ return this._cloudAdapter.isOnline;
868
+ }
787
869
  async waitForSync() {
788
870
  if (this._isLoaded) {
789
871
  return;
@@ -1028,11 +1110,15 @@ var MindCache = class {
1028
1110
  const existingAttrs = existingEntry.get("attributes");
1029
1111
  if (existingAttrs?.type === "document") {
1030
1112
  if (typeof value === "string") {
1031
- this.replace_document_text(key, value);
1113
+ this._replaceDocumentText(key, value);
1032
1114
  }
1033
1115
  return;
1034
1116
  }
1035
1117
  }
1118
+ if (!existingEntry && attributes?.type === "document") {
1119
+ this.set_document(key, typeof value === "string" ? value : "", attributes);
1120
+ return;
1121
+ }
1036
1122
  let entryMap = this.rootMap.get(key);
1037
1123
  const isNewEntry = !entryMap;
1038
1124
  if (isNewEntry) {
@@ -1773,14 +1859,6 @@ var MindCache = class {
1773
1859
  }
1774
1860
  return void 0;
1775
1861
  }
1776
- /**
1777
- * Get plain text content of a document key.
1778
- * For collaborative editing, use get_document() and bind to an editor.
1779
- */
1780
- get_document_text(key) {
1781
- const yText = this.get_document(key);
1782
- return yText?.toString();
1783
- }
1784
1862
  /**
1785
1863
  * Insert text at a position in a document key.
1786
1864
  */
@@ -1800,15 +1878,11 @@ var MindCache = class {
1800
1878
  }
1801
1879
  }
1802
1880
  /**
1803
- * Replace all text in a document key.
1881
+ * Replace all text in a document key (private - use set_value for public API).
1804
1882
  * Uses diff-based updates when changes are < diffThreshold (default 80%).
1805
1883
  * This preserves concurrent edits and provides better undo granularity.
1806
- *
1807
- * @param key - The document key
1808
- * @param newText - The new text content
1809
- * @param diffThreshold - Percentage (0-1) of change above which full replace is used (default: 0.8)
1810
1884
  */
1811
- replace_document_text(key, newText, diffThreshold = 0.8) {
1885
+ _replaceDocumentText(key, newText, diffThreshold = 0.8) {
1812
1886
  const yText = this.get_document(key);
1813
1887
  if (!yText) {
1814
1888
  return;
@@ -1914,7 +1988,7 @@ var MindCache = class {
1914
1988
  },
1915
1989
  execute: async ({ value }) => {
1916
1990
  if (isDocument) {
1917
- this.replace_document_text(key, value);
1991
+ this._replaceDocumentText(key, value);
1918
1992
  } else {
1919
1993
  this.set_value(key, value);
1920
1994
  }
@@ -2070,7 +2144,7 @@ var MindCache = class {
2070
2144
  switch (action) {
2071
2145
  case "write":
2072
2146
  if (isDocument) {
2073
- this.replace_document_text(key, value);
2147
+ this._replaceDocumentText(key, value);
2074
2148
  } else {
2075
2149
  this.set_value(key, value);
2076
2150
  }