cindel 1.0.0 → 1.0.1

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/client.js CHANGED
@@ -1547,6 +1547,7 @@ var FileLoader = class {
1547
1547
  constructor(httpUrl) {
1548
1548
  this.httpUrl = httpUrl;
1549
1549
  this.loadQueue = /* @__PURE__ */ new Map();
1550
+ this.versions = /* @__PURE__ */ new Map();
1550
1551
  }
1551
1552
  async loadFile(path) {
1552
1553
  const isCSS = path.endsWith(".css");
@@ -1577,22 +1578,10 @@ var FileLoader = class {
1577
1578
  document.head.appendChild(link);
1578
1579
  });
1579
1580
  }
1580
- // Replace the existing module script with a cache busted URL.
1581
- // Changing the URL makes the browser treat it as a new module
1582
- // and execute it from scratch.
1583
1581
  async loadModule(path) {
1584
1582
  const url = this.makeUrl(path);
1585
- const existing = document.querySelector(`script[data-file="${path}"]`);
1586
- if (existing) existing.remove();
1587
- const script = document.createElement("script");
1588
- script.type = "module";
1589
- script.src = url;
1590
- script.setAttribute("data-file", path);
1591
- return new Promise((resolve, reject) => {
1592
- script.onload = () => resolve(true);
1593
- script.onerror = () => reject(new Error(`Failed to execute module: ${path}`));
1594
- document.head.appendChild(script);
1595
- });
1583
+ await import(url);
1584
+ return true;
1596
1585
  }
1597
1586
  async loadScript(path) {
1598
1587
  const url = this.makeUrl(path);
@@ -1648,11 +1637,13 @@ var FileLoader = class {
1648
1637
  el.remove();
1649
1638
  await new Promise((r) => setTimeout(r, 0));
1650
1639
  }
1640
+ this.versions.delete(path);
1651
1641
  }
1652
- // Cache bust with timestamp + random to avoid duplicate URLs on rapid reloads.
1642
+ // Increment the version counter for individual files and return a versioned URL
1653
1643
  makeUrl(path) {
1654
- const cb = `${Date.now()}-${Math.random().toString(36).slice(2, 11)}`;
1655
- return `${this.httpUrl}${path}?cb=${cb}`;
1644
+ const v = (this.versions.get(path) ?? 0) + 1;
1645
+ this.versions.set(path, v);
1646
+ return `${this.httpUrl}${path}?v=${v}`;
1656
1647
  }
1657
1648
  };
1658
1649
 
@@ -1750,6 +1741,7 @@ var HMRClient = class {
1750
1741
  * @param {boolean} [options.autoReconnect=true] - Reconnect on disconnect with exponential backoff.
1751
1742
  * @param {number} [options.reconnectDelay=2000] - Base reconnect delay in ms
1752
1743
  * @param {number} [options.maxReconnectDelay=30000] - Maximum reconnect delay cap in ms
1744
+ * @param {boolean} [options.skipOnReconnect=true] - Skip files already present in the page on reconnect, preventing them from being loaded again.
1753
1745
  * @param {string[]} [options.skip] - Glob patterns for files that should never be loaded (e.g. `['_*\/**']`)
1754
1746
  * @param {function(string, string[]): boolean} [options.filterSkip] - Custom skip logic. Receives `(filePath, allFiles)`. Combined with `skip` via OR.
1755
1747
  * @param {string[]} [options.cold] - Glob patterns for files that require a full page reload. Merged with the server's `cold` config on connect. A `cold` event is emitted instead of hot reloading.
@@ -1769,6 +1761,7 @@ var HMRClient = class {
1769
1761
  this.autoReconnect = this._autoReconnectDefault;
1770
1762
  this.reconnectDelay = opts.reconnectDelay || 2e3;
1771
1763
  this.maxReconnectDelay = opts.maxReconnectDelay || 3e4;
1764
+ this.skipOnReconnect = opts.skipOnReconnect !== false;
1772
1765
  this._coldPatterns = opts.cold || null;
1773
1766
  this._filterCold = opts.filterCold || null;
1774
1767
  this.shouldSkipFile = this.makeFilter(opts.skip || null, opts.filterSkip || null);
@@ -1916,7 +1909,19 @@ var HMRClient = class {
1916
1909
  skipped.forEach((f) => console.log(` \u2514\u2500 ${getFileName(f)}`));
1917
1910
  console.groupEnd();
1918
1911
  }
1919
- const withOverrides = this.buildOverrideMap(filtered);
1912
+ let toLoad = filtered;
1913
+ if (this.skipOnReconnect) {
1914
+ const alreadyLoaded = [];
1915
+ toLoad = [];
1916
+ for (const f of filtered) {
1917
+ const isLoaded = this.fileLoader.versions.has(f) || document.querySelector(`[data-file="${f}"]`);
1918
+ (isLoaded ? alreadyLoaded : toLoad).push(f);
1919
+ }
1920
+ if (alreadyLoaded.length > 0) {
1921
+ this.log("info", `Server reconnected - skipping ${alreadyLoaded.length} existing file${alreadyLoaded.length !== 1 ? "s" : ""}`);
1922
+ }
1923
+ }
1924
+ const withOverrides = this.buildOverrideMap(toLoad);
1920
1925
  const sorted2 = this.sortFiles(withOverrides);
1921
1926
  this.logInitFileGroup(sorted2, this.overrideMap, this.isColdFile.bind(this));
1922
1927
  for (const file of sorted2) {