@ecopages/ecopages-jsx 0.2.0-rc.3 → 0.2.0-rc.5

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/README.md CHANGED
@@ -100,7 +100,7 @@ Ecopages JSX can own the outer page shell or just a nested foreign subtree. When
100
100
 
101
101
  Important:
102
102
 
103
- - Cross-integration JSX children must use `EcoEmbed`. Opaque plain objects fail fast at core foreign-child queue boundaries; they are not coerced with `String(object)`.
103
+ - Cross-integration shell stacks should use `EcoEmbed` from `@ecopages/ecopages-jsx/eco-embed` (or the matching integration adapter). Plain opaque objects fail fast at core foreign-subtree queue boundaries; they are not coerced with `String(object)`. Pass already-serialized HTML when `EcoEmbed` is not needed.
104
104
  - Components that may render foreign children must declare those children in `config.dependencies.components`.
105
105
  - Ecopages validates mixed-renderer ownership from declared dependencies during render preparation. It does not treat rendered HTML alone as the source of truth.
106
106
  - Ecopages JSX keeps raw-markup preservation and asset collection inside the JSX renderer.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ecopages/ecopages-jsx",
3
- "version": "0.2.0-rc.3",
3
+ "version": "0.2.0-rc.5",
4
4
  "description": "JSX integration plugin for Ecopages",
5
5
  "keywords": [
6
6
  "ecopages",
@@ -11,6 +11,9 @@
11
11
  "main": "./src/ecopages-jsx.plugin.js",
12
12
  "types": "./src/ecopages-jsx.plugin.d.ts",
13
13
  "type": "module",
14
+ "publishConfig": {
15
+ "access": "public"
16
+ },
14
17
  "exports": {
15
18
  ".": {
16
19
  "default": "./src/ecopages-jsx.plugin.js",
@@ -31,13 +34,13 @@
31
34
  "directory": "packages/integrations/ecopages-jsx"
32
35
  },
33
36
  "dependencies": {
34
- "@ecopages/mdx": "0.2.0-rc.3",
37
+ "@ecopages/mdx": "0.2.0-rc.5",
35
38
  "@mdx-js/mdx": "^3.1.1",
36
39
  "vfile": "^6.0.3"
37
40
  },
38
41
  "peerDependencies": {
39
- "@ecopages/core": "0.2.0-rc.3",
42
+ "@ecopages/core": "0.2.0-rc.5",
40
43
  "@ecopages/jsx": "^0.3.0-rc.2",
41
44
  "@ecopages/radiant": "^0.3.0-rc.2"
42
45
  }
43
- }
46
+ }
@@ -13,7 +13,12 @@ export type EcopagesJsxMdxPageModule = EcoPageFile<{
13
13
  }>;
14
14
  export { appendMdxExtensions, createMdxExtensionFilter };
15
15
  export declare const resolveMdxCompilerOptions: (mdxOptions: EcopagesJsxMdxOptions) => ResolvedMdxCompileOptions;
16
- export declare const createMdxLoaderPlugin: (compilerOptions: ResolvedMdxCompileOptions, extensions: string[]) => EcoBuildPlugin;
17
- export declare const registerBunMdxPlugin: (compilerOptions: ResolvedMdxCompileOptions, extensions: string[]) => Promise<void>;
16
+ export interface CreateEcopagesJsxMdxLoaderPluginOptions {
17
+ compilerOptions: ResolvedMdxCompileOptions;
18
+ extensions: string[];
19
+ projectRoot: string;
20
+ }
21
+ export declare const createMdxLoaderPlugin: (options: CreateEcopagesJsxMdxLoaderPluginOptions) => EcoBuildPlugin;
22
+ export declare const registerBunMdxPlugin: (options: CreateEcopagesJsxMdxLoaderPluginOptions) => Promise<void>;
18
23
  export declare const isMdxFile: (filePath: string, extensions: string[]) => boolean;
19
24
  export declare const normalizeMdxPageModule: (file: string, module: EcopagesJsxMdxPageModule) => EcopagesJsxMdxPageModule;
@@ -1,8 +1,5 @@
1
- import { readFile } from 'node:fs/promises';
2
1
  import { ensurePageConfigLayouts } from '@ecopages/core/eco/page-layout-normalization';
3
- import { rapidhash } from '@ecopages/core/hash';
4
2
  import { appendMdxExtensions, createMdxExtensionFilter, createMdxLoaderPlugin as createMdxLoaderPluginCore, resolveMdxCompilerOptions as resolveMdxCompilerOptionsCore, } from '@ecopages/mdx/core';
5
- import { VFile } from 'vfile';
6
3
  import { ECOPAGES_JSX_PLUGIN_NAME } from './ecopages-jsx.constants.js';
7
4
  export { appendMdxExtensions, createMdxExtensionFilter };
8
5
  export const resolveMdxCompilerOptions = (mdxOptions) => resolveMdxCompilerOptionsCore(mdxOptions, {
@@ -12,27 +9,24 @@ export const resolveMdxCompilerOptions = (mdxOptions) => resolveMdxCompilerOptio
12
9
  outputFormat: 'program',
13
10
  },
14
11
  });
15
- export const createMdxLoaderPlugin = (compilerOptions, extensions) => createMdxLoaderPluginCore({
12
+ export const createMdxLoaderPlugin = (options) => createMdxLoaderPluginCore({
16
13
  name: 'ecopages-jsx-mdx-loader',
17
- compilerOptions,
18
- extensions,
14
+ integrationName: ECOPAGES_JSX_PLUGIN_NAME,
15
+ compilerOptions: options.compilerOptions,
16
+ extensions: options.extensions,
19
17
  includeSourceMap: false,
20
18
  loader: 'js',
19
+ projectRoot: options.projectRoot,
21
20
  });
22
- export const registerBunMdxPlugin = async (compilerOptions, extensions) => {
21
+ export const registerBunMdxPlugin = async (options) => {
23
22
  if (typeof Bun === 'undefined') {
24
23
  return;
25
24
  }
26
- const filter = createMdxExtensionFilter(extensions);
25
+ const plugin = createMdxLoaderPlugin(options);
27
26
  Bun.plugin({
28
- name: 'ecopages-jsx-mdx',
27
+ name: plugin.name,
29
28
  setup(build) {
30
- build.onLoad({ filter }, async (args) => {
31
- const { compile } = await import('@mdx-js/mdx');
32
- const source = await readFile(args.path, 'utf-8');
33
- const compiled = await compile(new VFile({ value: source, path: args.path }), compilerOptions);
34
- return { contents: String(compiled.value), loader: 'js' };
35
- });
29
+ return plugin.setup(build);
36
30
  },
37
31
  });
38
32
  };
@@ -44,27 +38,22 @@ export const normalizeMdxPageModule = (file, module) => {
44
38
  throw new TypeError('MDX file must export a callable default component.');
45
39
  }
46
40
  const Page = module.default;
47
- const normalizedConfig = {
48
- ...(module.config ?? Page.config ?? {}),
49
- identity: module.config?.identity ??
50
- Page.config?.identity ?? {
51
- id: String(rapidhash(file)),
52
- file,
53
- integration: ECOPAGES_JSX_PLUGIN_NAME,
54
- },
55
- };
56
- if (module.layout && !(normalizedConfig.layouts && normalizedConfig.layouts.length > 0)) {
57
- normalizedConfig.layout = module.layout;
41
+ const attributedConfig = module.config ?? Page.config;
42
+ if (!attributedConfig?.identity) {
43
+ throw new Error(`[ecopages] MDX page "${file}" is missing component identity; the MDX loader must attribute it.`);
44
+ }
45
+ if (module.layout && !(attributedConfig.layouts && attributedConfig.layouts.length > 0)) {
46
+ attributedConfig.layout = module.layout;
58
47
  }
59
- ensurePageConfigLayouts(normalizedConfig);
48
+ ensurePageConfigLayouts(attributedConfig);
60
49
  const wrappedPage = async (props) => await Page(props);
61
- wrappedPage.config = normalizedConfig;
50
+ wrappedPage.config = attributedConfig;
62
51
  if (module.getMetadata ?? Page.metadata) {
63
52
  wrappedPage.metadata = module.getMetadata ?? Page.metadata;
64
53
  }
65
54
  return {
66
55
  ...module,
67
56
  default: wrappedPage,
68
- config: normalizedConfig,
57
+ config: attributedConfig,
69
58
  };
70
59
  };
@@ -150,7 +150,14 @@ export class EcopagesJsxPlugin extends IntegrationPlugin {
150
150
  if (!this.mdxEnabled || !this.mdxCompilerOptions || this.mdxLoaderPlugin) {
151
151
  return;
152
152
  }
153
- this.mdxLoaderPlugin = createMdxLoaderPlugin(this.mdxCompilerOptions, this.mdxExtensions);
153
+ if (!this.appConfig?.rootDir) {
154
+ throw new Error('[EcopagesJsxPlugin] Cannot create MDX loader: appConfig.rootDir is required.');
155
+ }
156
+ this.mdxLoaderPlugin = createMdxLoaderPlugin({
157
+ compilerOptions: this.mdxCompilerOptions,
158
+ extensions: this.mdxExtensions,
159
+ projectRoot: this.appConfig.rootDir,
160
+ });
154
161
  }
155
162
  /**
156
163
  * Registers Bun's MDX loader at runtime setup time.
@@ -162,7 +169,14 @@ export class EcopagesJsxPlugin extends IntegrationPlugin {
162
169
  if (typeof Bun === 'undefined' || !this.mdxCompilerOptions) {
163
170
  return;
164
171
  }
165
- await registerBunMdxPlugin(this.mdxCompilerOptions, this.mdxExtensions);
172
+ if (!this.appConfig) {
173
+ throw new Error('[EcopagesJsxPlugin] Cannot register Bun MDX plugin: appConfig is not set');
174
+ }
175
+ await registerBunMdxPlugin({
176
+ compilerOptions: this.mdxCompilerOptions,
177
+ extensions: this.mdxExtensions,
178
+ projectRoot: this.appConfig.rootDir,
179
+ });
166
180
  }
167
181
  }
168
182
  /**