@ecopages/ecopages-jsx 0.2.0-beta.18 → 0.2.0-beta.19

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ecopages/ecopages-jsx",
3
- "version": "0.2.0-beta.18",
3
+ "version": "0.2.0-beta.19",
4
4
  "description": "JSX integration plugin for Ecopages",
5
5
  "keywords": [
6
6
  "ecopages",
@@ -31,12 +31,12 @@
31
31
  "directory": "packages/integrations/ecopages-jsx"
32
32
  },
33
33
  "dependencies": {
34
- "@ecopages/mdx": "0.2.0-beta.18",
34
+ "@ecopages/mdx": "0.2.0-beta.19",
35
35
  "@mdx-js/mdx": "^3.1.1",
36
36
  "vfile": "^6.0.3"
37
37
  },
38
38
  "peerDependencies": {
39
- "@ecopages/core": "0.2.0-beta.18",
39
+ "@ecopages/core": "0.2.0-beta.19",
40
40
  "@ecopages/jsx": "0.3.0-beta.0",
41
41
  "@ecopages/radiant": "0.3.0-beta.0"
42
42
  }
@@ -9,10 +9,11 @@ class EcopagesJsxHmrStrategy extends HmrStrategy {
9
9
  this.context = context;
10
10
  }
11
11
  matches(filePath) {
12
- if (this.context.getWatchedFiles().has(filePath)) {
12
+ const resolvedPath = path.resolve(filePath);
13
+ const watchedFiles = this.context.getWatchedFiles();
14
+ if (watchedFiles.has(resolvedPath) || [...watchedFiles.keys()].some((key) => path.resolve(key) === resolvedPath)) {
13
15
  return false;
14
16
  }
15
- const resolvedPath = path.resolve(filePath);
16
17
  const srcDir = path.resolve(this.context.getSrcDir());
17
18
  if (!resolvedPath.startsWith(`${srcDir}${path.sep}`) && resolvedPath !== srcDir) {
18
19
  return false;
@@ -1,5 +1,6 @@
1
1
  import { IntegrationPlugin, type EcoBuildPlugin } from '@ecopages/core/plugins/integration-plugin';
2
2
  import type { HmrStrategy } from '@ecopages/core/hmr/hmr-strategy';
3
+ import type { IHmrManager } from '@ecopages/core';
3
4
  import type { JsxRenderable } from '@ecopages/jsx';
4
5
  import { EcopagesJsxRenderer } from './ecopages-jsx-renderer.js';
5
6
  import type { EcopagesJsxPluginOptions } from './ecopages-jsx.types.js';
@@ -22,6 +23,8 @@ export declare class EcopagesJsxPlugin extends IntegrationPlugin<JsxRenderable>
22
23
  private getDependencies;
23
24
  /** Ensures MDX build hooks are ready before Ecopages collects contributions. */
24
25
  prepareBuildContributions(): Promise<void>;
26
+ /** Registers JSX HMR strategy and Radiant SSR invalidation hooks. */
27
+ setHmrManager(hmrManager: IHmrManager): void;
25
28
  /**
26
29
  * Returns the JSX-integration HMR strategy.
27
30
  *
@@ -12,6 +12,7 @@ import {
12
12
  } from "./ecopages-jsx-mdx.js";
13
13
  import { EcopagesJsxRenderer } from "./ecopages-jsx-renderer.js";
14
14
  import { EcopagesJsxHmrStrategy } from "./ecopages-jsx-hmr-strategy.js";
15
+ import { invalidateRadiantRegisteredScriptSsrRegistration } from "./radiant-registered-script-ssr-invalidation.js";
15
16
  const RADIANT_HYDRATOR_SCRIPT_ID = "ecopages-jsx-radiant-hydrator";
16
17
  const resolvePluginOptions = (options) => {
17
18
  const { extensions: userExtensions, radiant, mdx, ...baseConfig } = options ?? {};
@@ -86,6 +87,17 @@ class EcopagesJsxPlugin extends IntegrationPlugin {
86
87
  async prepareBuildContributions() {
87
88
  this.ensureMdxLoaderPlugin();
88
89
  }
90
+ /** Registers JSX HMR strategy and Radiant SSR invalidation hooks. */
91
+ setHmrManager(hmrManager) {
92
+ super.setHmrManager(hmrManager);
93
+ if (!this.includeRadiant || !this.appConfig) {
94
+ return;
95
+ }
96
+ const runtime = this.appConfig.runtime ?? {};
97
+ this.appConfig.runtime = runtime;
98
+ runtime.registeredScriptEntrypointChangeHandlers ??= [];
99
+ runtime.registeredScriptEntrypointChangeHandlers.push(invalidateRadiantRegisteredScriptSsrRegistration);
100
+ }
89
101
  /**
90
102
  * Returns the JSX-integration HMR strategy.
91
103
  *
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Reads the custom-element tag name from a registered script module source file.
3
+ */
4
+ export declare function resolveRadiantCustomElementTag(scriptPath: string): string | undefined;
5
+ /**
6
+ * Removes one custom-element definition from the active runtime registry.
7
+ *
8
+ * @remarks
9
+ * Radiant's `@customElement` decorator and the SSR light-DOM shim both skip
10
+ * re-registration when a tag is already defined. During dev, server requests
11
+ * reuse the same process-global registry, so script edits would otherwise keep
12
+ * serving stale SSR markup until a full dev-server restart.
13
+ */
14
+ export declare function clearRadiantCustomElementDefinition(tagName: string): void;
15
+ /**
16
+ * Clears the SSR custom-element registry entry for one registered Radiant script module.
17
+ */
18
+ export declare function invalidateRadiantRegisteredScriptSsrRegistration(scriptPath: string): void;
@@ -0,0 +1,36 @@
1
+ import { existsSync, readFileSync } from "node:fs";
2
+ const CUSTOM_ELEMENT_TAG_PATTERN = /@customElement\s*\(\s*['"`]([^'"`]+)['"`]/u;
3
+ function resolveRadiantCustomElementTag(scriptPath) {
4
+ if (!existsSync(scriptPath)) {
5
+ return void 0;
6
+ }
7
+ const content = readFileSync(scriptPath, "utf8");
8
+ const match = content.match(CUSTOM_ELEMENT_TAG_PATTERN);
9
+ return match?.[1];
10
+ }
11
+ function clearRadiantCustomElementDefinition(tagName) {
12
+ const registry = globalThis.customElements;
13
+ if (!registry) {
14
+ return;
15
+ }
16
+ if (typeof registry.delete === "function") {
17
+ registry.delete(tagName);
18
+ return;
19
+ }
20
+ const definitions = registry.definitions;
21
+ if (definitions instanceof Map && definitions.has(tagName)) {
22
+ definitions.delete(tagName);
23
+ }
24
+ }
25
+ function invalidateRadiantRegisteredScriptSsrRegistration(scriptPath) {
26
+ const tagName = resolveRadiantCustomElementTag(scriptPath);
27
+ if (!tagName) {
28
+ return;
29
+ }
30
+ clearRadiantCustomElementDefinition(tagName);
31
+ }
32
+ export {
33
+ clearRadiantCustomElementDefinition,
34
+ invalidateRadiantRegisteredScriptSsrRegistration,
35
+ resolveRadiantCustomElementTag
36
+ };