@ripple-ts/vite-plugin 0.3.5 → 0.3.7

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/CHANGELOG.md CHANGED
@@ -1,5 +1,34 @@
1
1
  # @ripple-ts/vite-plugin
2
2
 
3
+ ## 0.3.7
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies []:
8
+ - @ripple-ts/adapter@0.3.7
9
+
10
+ ## 0.3.6
11
+
12
+ ### Patch Changes
13
+
14
+ - [#819](https://github.com/Ripple-TS/ripple/pull/819)
15
+ [`472c4c4`](https://github.com/Ripple-TS/ripple/commit/472c4c4b80a69ed22a258a3f3c03c4ca2d20a95b)
16
+ Thanks [@trueadm](https://github.com/trueadm)! - Fix HMR update causing
17
+ component styling to disappear
18
+
19
+ When editing a component's scoped CSS, the CSS hash changes but the virtual CSS
20
+ module was not being invalidated or included in the HMR update. This caused the
21
+ browser to keep stale CSS selectors that no longer matched the component's new
22
+ hash-scoped class names, making all styling disappear until a full dev server
23
+ restart.
24
+
25
+ The fix eagerly re-compiles the `.ripple` file in the `hotUpdate` hook to update
26
+ the CSS cache, then invalidates and includes the virtual CSS module in the HMR
27
+ update so the browser receives fresh CSS in sync with the re-rendered component.
28
+
29
+ - Updated dependencies []:
30
+ - @ripple-ts/adapter@0.3.6
31
+
3
32
  ## 0.3.5
4
33
 
5
34
  ### Patch Changes
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "description": "Vite plugin for Ripple",
4
4
  "license": "MIT",
5
5
  "author": "Dominic Gannaway",
6
- "version": "0.3.5",
6
+ "version": "0.3.7",
7
7
  "type": "module",
8
8
  "module": "src/index.js",
9
9
  "main": "src/index.js",
@@ -32,13 +32,13 @@
32
32
  "url": "https://github.com/Ripple-TS/ripple/issues"
33
33
  },
34
34
  "dependencies": {
35
- "@ripple-ts/adapter": "0.3.5"
35
+ "@ripple-ts/adapter": "0.3.7"
36
36
  },
37
37
  "devDependencies": {
38
38
  "@types/node": "^24.3.0",
39
39
  "type-fest": "^5.4.4",
40
40
  "vite": "^8.0.0",
41
- "ripple": "0.3.5"
41
+ "ripple": "0.3.7"
42
42
  },
43
43
  "publishConfig": {
44
44
  "access": "public"
package/src/index.js CHANGED
@@ -608,48 +608,76 @@ export function ripple(inlineOptions = {}) {
608
608
  },
609
609
 
610
610
  /**
611
- * Handle HMR for files that Vite's default module HMR can't
612
- * properly refresh.
611
+ * Handle HMR for .ripple files.
613
612
  *
614
- * .ripple components self-accept HMR and swap their component
615
- * function. For changes to their OWN code this works perfectly.
616
- * But for changes to DEPENDENCIES (e.g. .md files imported via
617
- * import.meta.glob), the self-accept handler can't refresh
618
- * static imports cached in the browser's ESM module registry.
613
+ * Inspired by vite-plugin-svelte's approach: instead of manually
614
+ * re-compiling in hotUpdate, we use `transformRequest` to run the
615
+ * full Vite pipeline (load transform). This updates cssCache
616
+ * via the existing transform hook and avoids double-compilation.
619
617
  *
620
- * Strategy:
621
- * - If all changed modules self-accept they can hot-replace
622
- * themselves (e.g. .ripple components, CSS). Let Vite handle.
623
- * - Otherwise, check the SSR module graph. If the file is there,
624
- * invalidate SSR cache and trigger a full page reload.
618
+ * After the .ripple file is re-transformed, we invalidate and
619
+ * include the virtual CSS module in the HMR update so the browser
620
+ * receives fresh CSS in sync with the re-rendered component.
621
+ *
622
+ * For non-.ripple files that don't self-accept, we invalidate
623
+ * SSR modules and trigger a full reload.
625
624
  */
626
- hotUpdate({ file, modules, server }) {
627
- if (this.environment.name !== 'client') return;
628
-
629
- // If all changed modules self-accept, they can hot-replace
630
- // themselves (.ripple components, CSS modules). Let Vite
631
- // handle without intervention.
632
- if (modules.length > 0 && modules.every((m) => m.isSelfAccepting)) {
633
- return;
634
- }
625
+ hotUpdate: {
626
+ order: 'pre',
627
+ async handler({ file, modules, server }) {
628
+ if (this.environment.name !== 'client') return;
635
629
 
636
- // Check if this file is part of the SSR module graph.
637
- const ssr = server.environments.ssr;
638
- if (!ssr) return;
630
+ let updated_modules = modules;
639
631
 
640
- const ssr_modules = ssr.moduleGraph.getModulesByFile(file);
641
- if (!ssr_modules || ssr_modules.size === 0) return;
632
+ if (file.endsWith('.ripple')) {
633
+ const filename = file.replace(root, '');
634
+ const cssId = createVirtualImportId(filename, root, 'style');
642
635
 
643
- // Invalidate SSR modules so the server re-reads the file
644
- // on next request instead of serving stale cached content.
645
- for (const mod of ssr_modules) {
646
- ssr.moduleGraph.invalidateModule(mod);
647
- }
636
+ // Snapshot current cached CSS for comparison
637
+ const prev_css = cssCache.get(cssId);
648
638
 
649
- // Full reload the only reliable way to pick up the change
650
- // for files that don't self-accept but are consumed by the app.
651
- this.environment.hot.send({ type: 'full-reload' });
652
- return [];
639
+ // Use transformRequest to run the standard Vite pipeline.
640
+ // This triggers our transform hook which re-compiles the
641
+ // .ripple file and updates cssCache as a side-effect.
642
+ try {
643
+ await this.environment.transformRequest(filename);
644
+ } catch {
645
+ // Compile errors during partial edits are expected
646
+ }
647
+
648
+ const next_css = cssCache.get(cssId);
649
+ const css_changed = prev_css !== next_css;
650
+
651
+ // If CSS changed, invalidate and include the virtual CSS
652
+ // module so the browser fetches the updated stylesheet.
653
+ if (css_changed) {
654
+ const css_module = this.environment.moduleGraph.getModuleById(cssId);
655
+ if (css_module && !modules.includes(css_module)) {
656
+ this.environment.moduleGraph.invalidateModule(css_module);
657
+ updated_modules = [...modules, css_module];
658
+ }
659
+ }
660
+ }
661
+
662
+ // Non-.ripple files: if all modules self-accept, let Vite
663
+ // handle. Otherwise invalidate SSR and full-reload.
664
+ if (modules.length > 0 && modules.every((m) => m.isSelfAccepting)) {
665
+ return updated_modules === modules ? undefined : updated_modules;
666
+ }
667
+
668
+ const ssr = server.environments.ssr;
669
+ if (!ssr) return;
670
+
671
+ const ssr_modules = ssr.moduleGraph.getModulesByFile(file);
672
+ if (!ssr_modules || ssr_modules.size === 0) return;
673
+
674
+ for (const mod of ssr_modules) {
675
+ ssr.moduleGraph.invalidateModule(mod);
676
+ }
677
+
678
+ this.environment.hot.send({ type: 'full-reload' });
679
+ return [];
680
+ },
653
681
  },
654
682
 
655
683
  /**