@zeus-js/output-wc 0.1.0-beta.3 → 0.1.0-beta.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.
@@ -1,5 +1,5 @@
1
1
  /**
2
- * output-wc v0.1.0-beta.3
2
+ * output-wc v0.1.0-beta.5
3
3
  * (c) 2026 baicie
4
4
  * Released under the MIT License.
5
5
  **/
@@ -9,7 +9,7 @@ Object.defineProperties(exports, {
9
9
  });
10
10
  const ZEUS_OUTPUT_WC_CAPABILITIES = {
11
11
  packageName: "@zeus-js/output-wc",
12
- version: "0.1.0-beta.3",
12
+ version: "0.1.0-beta.5",
13
13
  output: {
14
14
  webComponent: true,
15
15
  customElements: true,
@@ -1,5 +1,5 @@
1
1
  /**
2
- * output-wc v0.1.0-beta.3
2
+ * output-wc v0.1.0-beta.5
3
3
  * (c) 2026 baicie
4
4
  * Released under the MIT License.
5
5
  **/
@@ -9,7 +9,7 @@ Object.defineProperties(exports, {
9
9
  });
10
10
  const ZEUS_OUTPUT_WC_CAPABILITIES = {
11
11
  packageName: "@zeus-js/output-wc",
12
- version: "0.1.0-beta.3",
12
+ version: "0.1.0-beta.5",
13
13
  output: {
14
14
  webComponent: true,
15
15
  customElements: true,
@@ -1,6 +1,6 @@
1
1
  const ZEUS_OUTPUT_WC_CAPABILITIES = {
2
2
  packageName: "@zeus-js/output-wc",
3
- version: "0.1.0-beta.3",
3
+ version: "0.1.0-beta.5",
4
4
  output: {
5
5
  webComponent: true,
6
6
  customElements: true,
@@ -1,6 +1,6 @@
1
1
  const ZEUS_OUTPUT_WC_CAPABILITIES = {
2
2
  packageName: "@zeus-js/output-wc",
3
- version: "0.1.0-beta.3",
3
+ version: "0.1.0-beta.5",
4
4
  output: {
5
5
  webComponent: true,
6
6
  customElements: true,
@@ -1,5 +1,5 @@
1
1
  /**
2
- * output-wc v0.1.0-beta.3
2
+ * output-wc v0.1.0-beta.5
3
3
  * (c) 2026 baicie
4
4
  * Released under the MIT License.
5
5
  **/
@@ -54,7 +54,10 @@ function generateCustomElementsJson(options) {
54
54
  events: generateEvents(component),
55
55
  slots: generateSlots(component),
56
56
  cssParts: component.cssParts.map((name) => ({ name })),
57
- cssProperties: component.cssVars.map((name) => ({ name }))
57
+ cssProperties: getCssVars(component).map((variable) => ({
58
+ name: variable.name,
59
+ description: variable.description
60
+ }))
58
61
  }],
59
62
  exports: [{
60
63
  kind: "js",
@@ -84,7 +87,8 @@ function generateAttributes(component) {
84
87
  return result;
85
88
  }
86
89
  function generateMembers(component) {
87
- return Object.entries(component.props).map(([name, prop]) => {
90
+ var _component$methods;
91
+ const fields = Object.entries(component.props).map(([name, prop]) => {
88
92
  return {
89
93
  kind: "field",
90
94
  name,
@@ -93,18 +97,28 @@ function generateMembers(component) {
93
97
  default: prop.default === void 0 ? void 0 : JSON.stringify(prop.default)
94
98
  };
95
99
  });
100
+ const methods = Object.keys((_component$methods = component.methods) !== null && _component$methods !== void 0 ? _component$methods : {}).map((name) => {
101
+ return {
102
+ kind: "method",
103
+ name
104
+ };
105
+ });
106
+ return [...fields, ...methods];
96
107
  }
97
108
  function generateEvents(component) {
98
- return Object.entries(component.events).map(([name, event]) => {
109
+ return Object.entries(component.events).map(([key, event]) => {
110
+ var _event$name, _event$key;
99
111
  return {
100
- name,
112
+ name: (_event$name = event.name) !== null && _event$name !== void 0 ? _event$name : toKebabCase$1((_event$key = event.key) !== null && _event$key !== void 0 ? _event$key : key),
101
113
  description: event.description,
102
114
  type: { text: event.detail ? `CustomEvent<${formatDetailType(event.detail)}>` : "CustomEvent" }
103
115
  };
104
116
  });
105
117
  }
106
118
  function generateSlots(component) {
107
- return Object.entries(component.slots).map(([name, slot]) => {
119
+ return Object.entries(component.slots).map(([key, slot]) => {
120
+ var _slot$name;
121
+ const name = (_slot$name = slot.name) !== null && _slot$name !== void 0 ? _slot$name : key;
108
122
  return {
109
123
  name: name === "default" ? "" : name,
110
124
  description: slot.description
@@ -114,6 +128,7 @@ function generateSlots(component) {
114
128
  function getAttributeName(propName, prop) {
115
129
  if (prop.attr === false) return false;
116
130
  if (typeof prop.attr === "string") return prop.attr;
131
+ if (!isAttributeBackedType$1(prop.type)) return false;
117
132
  return propName.replace(/[A-Z]/g, (match) => `-${match.toLowerCase()}`);
118
133
  }
119
134
  function formatPropType(prop) {
@@ -125,15 +140,25 @@ function formatPropType(prop) {
125
140
  case "boolean": return "boolean";
126
141
  case "array": return "unknown[]";
127
142
  case "object": return "Record<string, unknown>";
143
+ case "function": return "Function";
128
144
  default: return "unknown";
129
145
  }
130
146
  }
147
+ function isAttributeBackedType$1(type) {
148
+ return type === "string" || type === "number" || type === "boolean";
149
+ }
131
150
  function formatDetailType(detail) {
132
151
  return `{ ${Object.entries(detail).map(([name, type]) => `${name}: ${type}`).join("; ")} }`;
133
152
  }
134
153
  function normalizeModulePath(value) {
135
154
  return value.replace(/\\/g, "/");
136
155
  }
156
+ function getCssVars(component) {
157
+ return Object.values(component.cssVars);
158
+ }
159
+ function toKebabCase$1(value) {
160
+ return value.replace(/[A-Z]/g, (match) => `-${match.toLowerCase()}`);
161
+ }
137
162
  //#endregion
138
163
  //#region packages/web-c/output-wc/src/imports.ts
139
164
  function toAbsoluteImportPath(root, source) {
@@ -186,7 +211,11 @@ function generateLazyEntry(options) {
186
211
  "",
187
212
  `export function createComponent(hostRef) {`,
188
213
  ` let mounted;`,
189
- ` const mountState = {};`,
214
+ ` const mountState = {`,
215
+ ` attributeProps: hostRef.attributeProps,`,
216
+ ` internals: hostRef.internals,`,
217
+ ` reflectingAttrs: hostRef.reflectingAttrs,`,
218
+ ` };`,
190
219
  "",
191
220
  ` return {`,
192
221
  ` connected() {`,
@@ -208,6 +237,22 @@ function generateLazyEntry(options) {
208
237
  ` propertyChanged(name, oldValue, newValue) {`,
209
238
  ` mounted?.propertyChanged(name, oldValue, newValue);`,
210
239
  ` },`,
240
+ "",
241
+ ` formAssociated(form) {`,
242
+ ` mounted?.formAssociated(form);`,
243
+ ` },`,
244
+ "",
245
+ ` formDisabled(disabled) {`,
246
+ ` mounted?.formDisabled(disabled);`,
247
+ ` },`,
248
+ "",
249
+ ` formReset() {`,
250
+ ` mounted?.formReset();`,
251
+ ` },`,
252
+ "",
253
+ ` formStateRestore(state, mode) {`,
254
+ ` mounted?.formStateRestore(state, mode);`,
255
+ ` },`,
211
256
  ` };`,
212
257
  `}`,
213
258
  "",
@@ -229,15 +274,19 @@ function generateLazyManifest(options) {
229
274
  const { components, getEntryFileName } = options;
230
275
  return `export const components = [
231
276
  ${components.map((component) => {
232
- var _component$runtimePro, _component$meta$shado, _component$meta;
277
+ var _component$runtimePro, _component$methods, _component$meta$shado, _component$meta, _component$meta$formA, _component$meta2;
233
278
  const entryFile = getEntryFileName(component.tag).replace(/\\/g, "/");
234
279
  const props = generatePropsArray((_component$runtimePro = component.runtimeProps) !== null && _component$runtimePro !== void 0 ? _component$runtimePro : component.props);
280
+ const methods = Object.keys((_component$methods = component.methods) !== null && _component$methods !== void 0 ? _component$methods : {});
235
281
  const importPath = entryFile.startsWith(".") ? JSON.stringify(entryFile) : JSON.stringify(`./${entryFile}`);
282
+ const methodLine = methods.length ? ` methods: ${JSON.stringify(methods)},\n` : "";
236
283
  return ` {
237
284
  tagName: ${JSON.stringify(component.tag)},
238
285
  shadow: ${(_component$meta$shado = (_component$meta = component.meta) === null || _component$meta === void 0 ? void 0 : _component$meta.shadow) !== null && _component$meta$shado !== void 0 ? _component$meta$shado : false},
286
+ formAssociated: ${(_component$meta$formA = (_component$meta2 = component.meta) === null || _component$meta2 === void 0 ? void 0 : _component$meta2.formAssociated) !== null && _component$meta$formA !== void 0 ? _component$meta$formA : false},
239
287
  load: () => import(${importPath}),
240
288
  props: ${props},
289
+ ${methodLine}
241
290
  }`;
242
291
  }).join(",\n")}
243
292
  ];
@@ -248,14 +297,16 @@ function generatePropsArray(props) {
248
297
  if (entries.length === 0) return "[]";
249
298
  return `[\n${entries.map(([name, prop]) => {
250
299
  const parts = [`name: ${JSON.stringify(name)}`];
251
- if (!isAttributeBackedType(prop.type) || prop.attr === false) parts.push("attrName: false");
300
+ if (!isAttributeBackedType(prop.type) && !prop.deserialize || prop.attr === false) parts.push("attrName: false");
252
301
  else {
253
302
  var _prop$attr;
254
303
  const attrName = (_prop$attr = prop.attr) !== null && _prop$attr !== void 0 ? _prop$attr : toKebabCase(name);
255
304
  if (attrName !== toKebabCase(name)) parts.push(`attrName: ${JSON.stringify(attrName)}`);
256
305
  }
257
306
  parts.push(`type: ${JSON.stringify(prop.type)}`);
258
- if (prop.reflect && isAttributeBackedType(prop.type)) parts.push("reflect: true");
307
+ if (prop.reflect && (isAttributeBackedType(prop.type) || Boolean(prop.serialize))) parts.push("reflect: true");
308
+ if (prop.serialize) parts.push("serialize: true");
309
+ if (prop.deserialize) parts.push("deserialize: true");
259
310
  return ` { ${parts.join(", ")} }`;
260
311
  }).join(",\n")}\n ]`;
261
312
  }
@@ -271,22 +322,60 @@ function generateLoader() {
271
322
  return `import { bootstrapLazy } from "@zeus-js/web-c-runtime";
272
323
  import { components } from "./components.manifest.js";
273
324
 
274
- let defined = false;
325
+ const componentsByTagName = new Map(
326
+ components.map(component => [component.tagName, component]),
327
+ );
275
328
 
276
- export function defineCustomElements() {
277
- if (defined) {
329
+ const definedTagsByRegistry = new WeakMap();
330
+
331
+ function resolveRegistry(options) {
332
+ return options.registry ??
333
+ (typeof customElements === "undefined" ? undefined : customElements);
334
+ }
335
+
336
+ function getDefinedTags(registry) {
337
+ let definedTags = definedTagsByRegistry.get(registry);
338
+
339
+ if (!definedTags) {
340
+ definedTags = new Set();
341
+ definedTagsByRegistry.set(registry, definedTags);
342
+ }
343
+
344
+ return definedTags;
345
+ }
346
+
347
+ export function defineCustomElement(tagName, options = {}) {
348
+ const registry = resolveRegistry(options);
349
+
350
+ if (!registry) {
278
351
  return;
279
352
  }
280
353
 
281
- if (typeof customElements === "undefined") {
354
+ const component = componentsByTagName.get(tagName);
355
+
356
+ if (!component) {
357
+ throw new Error(\`[zeus:web-c] Unknown custom element: <\${tagName}>.\`);
358
+ }
359
+
360
+ const definedTags = getDefinedTags(registry);
361
+
362
+ if (definedTags.has(tagName) || registry.get(tagName)) {
363
+ definedTags.add(tagName);
282
364
  return;
283
365
  }
284
366
 
285
- bootstrapLazy(components);
367
+ bootstrapLazy([component], { registry });
286
368
 
287
- defined = true;
369
+ definedTags.add(tagName);
288
370
  }
289
371
 
372
+ export function defineCustomElements(options = {}) {
373
+ for (const component of components) {
374
+ defineCustomElement(component.tagName, options);
375
+ }
376
+ }
377
+
378
+ export const defineLazyElement = defineCustomElement;
290
379
  export const defineLazyElements = defineCustomElements;
291
380
  `;
292
381
  }
@@ -300,7 +389,9 @@ export {};
300
389
  }
301
390
  function generateLazyIndex() {
302
391
  return `export {
392
+ defineCustomElement,
303
393
  defineCustomElements,
394
+ defineLazyElement,
304
395
  defineLazyElements,
305
396
  } from "./loader.js";
306
397
  `;
@@ -319,8 +410,8 @@ function wc(options = {}) {
319
410
  outDir: (_options$outDir = options.outDir) !== null && _options$outDir !== void 0 ? _options$outDir : "wc",
320
411
  stripPrefix: (_options$stripPrefix = options.stripPrefix) !== null && _options$stripPrefix !== void 0 ? _options$stripPrefix : false,
321
412
  fileName: options.fileName,
322
- manifestFile: registerMode === "lazy" ? false : (_options$manifestFile = options.manifestFile) !== null && _options$manifestFile !== void 0 ? _options$manifestFile : "zeus.components.json",
323
- customElementsFile: registerMode === "lazy" ? false : (_options$customElemen = options.customElementsFile) !== null && _options$customElemen !== void 0 ? _options$customElemen : "custom-elements.json",
413
+ manifestFile: (_options$manifestFile = options.manifestFile) !== null && _options$manifestFile !== void 0 ? _options$manifestFile : "zeus.components.json",
414
+ customElementsFile: (_options$customElemen = options.customElementsFile) !== null && _options$customElemen !== void 0 ? _options$customElemen : "custom-elements.json",
324
415
  dts: (_options$dts = options.dts) !== null && _options$dts !== void 0 ? _options$dts : true,
325
416
  jsxDts: (_options$jsxDts = options.jsxDts) !== null && _options$jsxDts !== void 0 ? _options$jsxDts : true,
326
417
  index: (_options$index = options.index) !== null && _options$index !== void 0 ? _options$index : true,
@@ -349,15 +440,15 @@ function wc(options = {}) {
349
440
  const runtimeProps = (_component$runtimePro2 = component.runtimeProps) !== null && _component$runtimePro2 !== void 0 ? _component$runtimePro2 : {};
350
441
  for (const [name, prop] of Object.entries(runtimeProps)) {
351
442
  if (isAttributeBackedRuntimeProp(prop.type)) continue;
352
- if (prop.attr !== void 0 && prop.attr !== false) ctx.error([
443
+ if (prop.attr !== void 0 && prop.attr !== false && !prop.deserialize) ctx.error([
353
444
  `[zeus-output-wc] <${component.tag}> prop "${name}" cannot use attr:${JSON.stringify(prop.attr)} with register:"lazy".`,
354
- "Lazy Web-C only supports attributes for string, number and boolean props.",
355
- "Use attr:false and pass object/array/function values as properties instead."
445
+ "Non-primitive lazy attributes require a custom deserialize function.",
446
+ "Add deserialize or use attr:false and pass the value as a property."
356
447
  ].join("\n"));
357
- if (prop.reflect) ctx.error([
448
+ if (prop.reflect && !prop.serialize) ctx.error([
358
449
  `[zeus-output-wc] <${component.tag}> prop "${name}" cannot use reflect:true with register:"lazy".`,
359
- "Lazy Web-C only reflects string, number and boolean props.",
360
- "Use a string/number/boolean prop or remove reflect:true."
450
+ "Non-primitive lazy reflection requires a custom serialize function.",
451
+ "Add serialize or remove reflect:true."
361
452
  ].join("\n"));
362
453
  }
363
454
  }
@@ -404,7 +495,7 @@ function wc(options = {}) {
404
495
  }
405
496
  for (const component of ctx.manifest.components) if (isLazy) {
406
497
  /**
407
- * Compatibility module consumed by Vue / React wrappers.
498
+ * Registration bridge module consumed by Vue / React wrappers.
408
499
  *
409
500
  * It only registers lazy Proxy Elements.
410
501
  * It does not import the real component implementation.
@@ -489,17 +580,18 @@ export {};
489
580
  fileName: joinPath("types/jsx.d.ts"),
490
581
  source: (0, _zeus_js_component_dts.generateWCJsxDts)(ctx.manifest)
491
582
  });
492
- } else if (normalized.manifestFile) files.push({
583
+ }
584
+ if (normalized.manifestFile) files.push({
493
585
  type: "asset",
494
586
  fileName: normalized.manifestFile,
495
587
  source: generateZeusComponentsManifest(ctx.manifest)
496
588
  });
497
- if (!isLazy && normalized.customElementsFile) files.push({
589
+ if (normalized.customElementsFile) files.push({
498
590
  type: "asset",
499
591
  fileName: normalized.customElementsFile,
500
592
  source: generateCustomElementsJson({
501
593
  manifest: ctx.manifest,
502
- getModulePath: (component) => joinPath(getFileName(component.tag))
594
+ getModulePath: (component) => isLazy ? joinPath(getLazyEntryFileName(normalized.entryFileName, component.tag)) : joinPath(getFileName(component.tag))
503
595
  })
504
596
  });
505
597
  if (!isLazy && (dts || jsxDts)) {
@@ -1,5 +1,5 @@
1
1
  /**
2
- * output-wc v0.1.0-beta.3
2
+ * output-wc v0.1.0-beta.5
3
3
  * (c) 2026 baicie
4
4
  * Released under the MIT License.
5
5
  **/
@@ -54,7 +54,10 @@ function generateCustomElementsJson(options) {
54
54
  events: generateEvents(component),
55
55
  slots: generateSlots(component),
56
56
  cssParts: component.cssParts.map((name) => ({ name })),
57
- cssProperties: component.cssVars.map((name) => ({ name }))
57
+ cssProperties: getCssVars(component).map((variable) => ({
58
+ name: variable.name,
59
+ description: variable.description
60
+ }))
58
61
  }],
59
62
  exports: [{
60
63
  kind: "js",
@@ -84,7 +87,8 @@ function generateAttributes(component) {
84
87
  return result;
85
88
  }
86
89
  function generateMembers(component) {
87
- return Object.entries(component.props).map(([name, prop]) => {
90
+ var _component$methods;
91
+ const fields = Object.entries(component.props).map(([name, prop]) => {
88
92
  return {
89
93
  kind: "field",
90
94
  name,
@@ -93,18 +97,28 @@ function generateMembers(component) {
93
97
  default: prop.default === void 0 ? void 0 : JSON.stringify(prop.default)
94
98
  };
95
99
  });
100
+ const methods = Object.keys((_component$methods = component.methods) !== null && _component$methods !== void 0 ? _component$methods : {}).map((name) => {
101
+ return {
102
+ kind: "method",
103
+ name
104
+ };
105
+ });
106
+ return [...fields, ...methods];
96
107
  }
97
108
  function generateEvents(component) {
98
- return Object.entries(component.events).map(([name, event]) => {
109
+ return Object.entries(component.events).map(([key, event]) => {
110
+ var _event$name, _event$key;
99
111
  return {
100
- name,
112
+ name: (_event$name = event.name) !== null && _event$name !== void 0 ? _event$name : toKebabCase$1((_event$key = event.key) !== null && _event$key !== void 0 ? _event$key : key),
101
113
  description: event.description,
102
114
  type: { text: event.detail ? `CustomEvent<${formatDetailType(event.detail)}>` : "CustomEvent" }
103
115
  };
104
116
  });
105
117
  }
106
118
  function generateSlots(component) {
107
- return Object.entries(component.slots).map(([name, slot]) => {
119
+ return Object.entries(component.slots).map(([key, slot]) => {
120
+ var _slot$name;
121
+ const name = (_slot$name = slot.name) !== null && _slot$name !== void 0 ? _slot$name : key;
108
122
  return {
109
123
  name: name === "default" ? "" : name,
110
124
  description: slot.description
@@ -114,6 +128,7 @@ function generateSlots(component) {
114
128
  function getAttributeName(propName, prop) {
115
129
  if (prop.attr === false) return false;
116
130
  if (typeof prop.attr === "string") return prop.attr;
131
+ if (!isAttributeBackedType$1(prop.type)) return false;
117
132
  return propName.replace(/[A-Z]/g, (match) => `-${match.toLowerCase()}`);
118
133
  }
119
134
  function formatPropType(prop) {
@@ -125,15 +140,25 @@ function formatPropType(prop) {
125
140
  case "boolean": return "boolean";
126
141
  case "array": return "unknown[]";
127
142
  case "object": return "Record<string, unknown>";
143
+ case "function": return "Function";
128
144
  default: return "unknown";
129
145
  }
130
146
  }
147
+ function isAttributeBackedType$1(type) {
148
+ return type === "string" || type === "number" || type === "boolean";
149
+ }
131
150
  function formatDetailType(detail) {
132
151
  return `{ ${Object.entries(detail).map(([name, type]) => `${name}: ${type}`).join("; ")} }`;
133
152
  }
134
153
  function normalizeModulePath(value) {
135
154
  return value.replace(/\\/g, "/");
136
155
  }
156
+ function getCssVars(component) {
157
+ return Object.values(component.cssVars);
158
+ }
159
+ function toKebabCase$1(value) {
160
+ return value.replace(/[A-Z]/g, (match) => `-${match.toLowerCase()}`);
161
+ }
137
162
  //#endregion
138
163
  //#region packages/web-c/output-wc/src/imports.ts
139
164
  function toAbsoluteImportPath(root, source) {
@@ -186,7 +211,11 @@ function generateLazyEntry(options) {
186
211
  "",
187
212
  `export function createComponent(hostRef) {`,
188
213
  ` let mounted;`,
189
- ` const mountState = {};`,
214
+ ` const mountState = {`,
215
+ ` attributeProps: hostRef.attributeProps,`,
216
+ ` internals: hostRef.internals,`,
217
+ ` reflectingAttrs: hostRef.reflectingAttrs,`,
218
+ ` };`,
190
219
  "",
191
220
  ` return {`,
192
221
  ` connected() {`,
@@ -208,6 +237,22 @@ function generateLazyEntry(options) {
208
237
  ` propertyChanged(name, oldValue, newValue) {`,
209
238
  ` mounted?.propertyChanged(name, oldValue, newValue);`,
210
239
  ` },`,
240
+ "",
241
+ ` formAssociated(form) {`,
242
+ ` mounted?.formAssociated(form);`,
243
+ ` },`,
244
+ "",
245
+ ` formDisabled(disabled) {`,
246
+ ` mounted?.formDisabled(disabled);`,
247
+ ` },`,
248
+ "",
249
+ ` formReset() {`,
250
+ ` mounted?.formReset();`,
251
+ ` },`,
252
+ "",
253
+ ` formStateRestore(state, mode) {`,
254
+ ` mounted?.formStateRestore(state, mode);`,
255
+ ` },`,
211
256
  ` };`,
212
257
  `}`,
213
258
  "",
@@ -229,15 +274,19 @@ function generateLazyManifest(options) {
229
274
  const { components, getEntryFileName } = options;
230
275
  return `export const components = [
231
276
  ${components.map((component) => {
232
- var _component$runtimePro, _component$meta$shado, _component$meta;
277
+ var _component$runtimePro, _component$methods, _component$meta$shado, _component$meta, _component$meta$formA, _component$meta2;
233
278
  const entryFile = getEntryFileName(component.tag).replace(/\\/g, "/");
234
279
  const props = generatePropsArray((_component$runtimePro = component.runtimeProps) !== null && _component$runtimePro !== void 0 ? _component$runtimePro : component.props);
280
+ const methods = Object.keys((_component$methods = component.methods) !== null && _component$methods !== void 0 ? _component$methods : {});
235
281
  const importPath = entryFile.startsWith(".") ? JSON.stringify(entryFile) : JSON.stringify(`./${entryFile}`);
282
+ const methodLine = methods.length ? ` methods: ${JSON.stringify(methods)},\n` : "";
236
283
  return ` {
237
284
  tagName: ${JSON.stringify(component.tag)},
238
285
  shadow: ${(_component$meta$shado = (_component$meta = component.meta) === null || _component$meta === void 0 ? void 0 : _component$meta.shadow) !== null && _component$meta$shado !== void 0 ? _component$meta$shado : false},
286
+ formAssociated: ${(_component$meta$formA = (_component$meta2 = component.meta) === null || _component$meta2 === void 0 ? void 0 : _component$meta2.formAssociated) !== null && _component$meta$formA !== void 0 ? _component$meta$formA : false},
239
287
  load: () => import(${importPath}),
240
288
  props: ${props},
289
+ ${methodLine}
241
290
  }`;
242
291
  }).join(",\n")}
243
292
  ];
@@ -248,14 +297,16 @@ function generatePropsArray(props) {
248
297
  if (entries.length === 0) return "[]";
249
298
  return `[\n${entries.map(([name, prop]) => {
250
299
  const parts = [`name: ${JSON.stringify(name)}`];
251
- if (!isAttributeBackedType(prop.type) || prop.attr === false) parts.push("attrName: false");
300
+ if (!isAttributeBackedType(prop.type) && !prop.deserialize || prop.attr === false) parts.push("attrName: false");
252
301
  else {
253
302
  var _prop$attr;
254
303
  const attrName = (_prop$attr = prop.attr) !== null && _prop$attr !== void 0 ? _prop$attr : toKebabCase(name);
255
304
  if (attrName !== toKebabCase(name)) parts.push(`attrName: ${JSON.stringify(attrName)}`);
256
305
  }
257
306
  parts.push(`type: ${JSON.stringify(prop.type)}`);
258
- if (prop.reflect && isAttributeBackedType(prop.type)) parts.push("reflect: true");
307
+ if (prop.reflect && (isAttributeBackedType(prop.type) || Boolean(prop.serialize))) parts.push("reflect: true");
308
+ if (prop.serialize) parts.push("serialize: true");
309
+ if (prop.deserialize) parts.push("deserialize: true");
259
310
  return ` { ${parts.join(", ")} }`;
260
311
  }).join(",\n")}\n ]`;
261
312
  }
@@ -271,22 +322,60 @@ function generateLoader() {
271
322
  return `import { bootstrapLazy } from "@zeus-js/web-c-runtime";
272
323
  import { components } from "./components.manifest.js";
273
324
 
274
- let defined = false;
325
+ const componentsByTagName = new Map(
326
+ components.map(component => [component.tagName, component]),
327
+ );
275
328
 
276
- export function defineCustomElements() {
277
- if (defined) {
329
+ const definedTagsByRegistry = new WeakMap();
330
+
331
+ function resolveRegistry(options) {
332
+ return options.registry ??
333
+ (typeof customElements === "undefined" ? undefined : customElements);
334
+ }
335
+
336
+ function getDefinedTags(registry) {
337
+ let definedTags = definedTagsByRegistry.get(registry);
338
+
339
+ if (!definedTags) {
340
+ definedTags = new Set();
341
+ definedTagsByRegistry.set(registry, definedTags);
342
+ }
343
+
344
+ return definedTags;
345
+ }
346
+
347
+ export function defineCustomElement(tagName, options = {}) {
348
+ const registry = resolveRegistry(options);
349
+
350
+ if (!registry) {
278
351
  return;
279
352
  }
280
353
 
281
- if (typeof customElements === "undefined") {
354
+ const component = componentsByTagName.get(tagName);
355
+
356
+ if (!component) {
357
+ throw new Error(\`[zeus:web-c] Unknown custom element: <\${tagName}>.\`);
358
+ }
359
+
360
+ const definedTags = getDefinedTags(registry);
361
+
362
+ if (definedTags.has(tagName) || registry.get(tagName)) {
363
+ definedTags.add(tagName);
282
364
  return;
283
365
  }
284
366
 
285
- bootstrapLazy(components);
367
+ bootstrapLazy([component], { registry });
286
368
 
287
- defined = true;
369
+ definedTags.add(tagName);
288
370
  }
289
371
 
372
+ export function defineCustomElements(options = {}) {
373
+ for (const component of components) {
374
+ defineCustomElement(component.tagName, options);
375
+ }
376
+ }
377
+
378
+ export const defineLazyElement = defineCustomElement;
290
379
  export const defineLazyElements = defineCustomElements;
291
380
  `;
292
381
  }
@@ -300,7 +389,9 @@ export {};
300
389
  }
301
390
  function generateLazyIndex() {
302
391
  return `export {
392
+ defineCustomElement,
303
393
  defineCustomElements,
394
+ defineLazyElement,
304
395
  defineLazyElements,
305
396
  } from "./loader.js";
306
397
  `;
@@ -319,8 +410,8 @@ function wc(options = {}) {
319
410
  outDir: (_options$outDir = options.outDir) !== null && _options$outDir !== void 0 ? _options$outDir : "wc",
320
411
  stripPrefix: (_options$stripPrefix = options.stripPrefix) !== null && _options$stripPrefix !== void 0 ? _options$stripPrefix : false,
321
412
  fileName: options.fileName,
322
- manifestFile: registerMode === "lazy" ? false : (_options$manifestFile = options.manifestFile) !== null && _options$manifestFile !== void 0 ? _options$manifestFile : "zeus.components.json",
323
- customElementsFile: registerMode === "lazy" ? false : (_options$customElemen = options.customElementsFile) !== null && _options$customElemen !== void 0 ? _options$customElemen : "custom-elements.json",
413
+ manifestFile: (_options$manifestFile = options.manifestFile) !== null && _options$manifestFile !== void 0 ? _options$manifestFile : "zeus.components.json",
414
+ customElementsFile: (_options$customElemen = options.customElementsFile) !== null && _options$customElemen !== void 0 ? _options$customElemen : "custom-elements.json",
324
415
  dts: (_options$dts = options.dts) !== null && _options$dts !== void 0 ? _options$dts : true,
325
416
  jsxDts: (_options$jsxDts = options.jsxDts) !== null && _options$jsxDts !== void 0 ? _options$jsxDts : true,
326
417
  index: (_options$index = options.index) !== null && _options$index !== void 0 ? _options$index : true,
@@ -349,15 +440,15 @@ function wc(options = {}) {
349
440
  const runtimeProps = (_component$runtimePro2 = component.runtimeProps) !== null && _component$runtimePro2 !== void 0 ? _component$runtimePro2 : {};
350
441
  for (const [name, prop] of Object.entries(runtimeProps)) {
351
442
  if (isAttributeBackedRuntimeProp(prop.type)) continue;
352
- if (prop.attr !== void 0 && prop.attr !== false) ctx.error([
443
+ if (prop.attr !== void 0 && prop.attr !== false && !prop.deserialize) ctx.error([
353
444
  `[zeus-output-wc] <${component.tag}> prop "${name}" cannot use attr:${JSON.stringify(prop.attr)} with register:"lazy".`,
354
- "Lazy Web-C only supports attributes for string, number and boolean props.",
355
- "Use attr:false and pass object/array/function values as properties instead."
445
+ "Non-primitive lazy attributes require a custom deserialize function.",
446
+ "Add deserialize or use attr:false and pass the value as a property."
356
447
  ].join("\n"));
357
- if (prop.reflect) ctx.error([
448
+ if (prop.reflect && !prop.serialize) ctx.error([
358
449
  `[zeus-output-wc] <${component.tag}> prop "${name}" cannot use reflect:true with register:"lazy".`,
359
- "Lazy Web-C only reflects string, number and boolean props.",
360
- "Use a string/number/boolean prop or remove reflect:true."
450
+ "Non-primitive lazy reflection requires a custom serialize function.",
451
+ "Add serialize or remove reflect:true."
361
452
  ].join("\n"));
362
453
  }
363
454
  }
@@ -404,7 +495,7 @@ function wc(options = {}) {
404
495
  }
405
496
  for (const component of ctx.manifest.components) if (isLazy) {
406
497
  /**
407
- * Compatibility module consumed by Vue / React wrappers.
498
+ * Registration bridge module consumed by Vue / React wrappers.
408
499
  *
409
500
  * It only registers lazy Proxy Elements.
410
501
  * It does not import the real component implementation.
@@ -489,17 +580,18 @@ export {};
489
580
  fileName: joinPath("types/jsx.d.ts"),
490
581
  source: (0, _zeus_js_component_dts.generateWCJsxDts)(ctx.manifest)
491
582
  });
492
- } else if (normalized.manifestFile) files.push({
583
+ }
584
+ if (normalized.manifestFile) files.push({
493
585
  type: "asset",
494
586
  fileName: normalized.manifestFile,
495
587
  source: generateZeusComponentsManifest(ctx.manifest)
496
588
  });
497
- if (!isLazy && normalized.customElementsFile) files.push({
589
+ if (normalized.customElementsFile) files.push({
498
590
  type: "asset",
499
591
  fileName: normalized.customElementsFile,
500
592
  source: generateCustomElementsJson({
501
593
  manifest: ctx.manifest,
502
- getModulePath: (component) => joinPath(getFileName(component.tag))
594
+ getModulePath: (component) => isLazy ? joinPath(getLazyEntryFileName(normalized.entryFileName, component.tag)) : joinPath(getFileName(component.tag))
503
595
  })
504
596
  });
505
597
  if (!isLazy && (dts || jsxDts)) {
@@ -65,7 +65,6 @@ export interface OutputWCOptions {
65
65
  *
66
66
  * side-effect:
67
67
  * Immediately registers full components on import.
68
- * Compatible with legacy behavior; not recommended as default.
69
68
  */
70
69
  register?: WebCRegisterMode;
71
70
  /**
@@ -1,5 +1,5 @@
1
1
  /**
2
- * output-wc v0.1.0-beta.3
2
+ * output-wc v0.1.0-beta.5
3
3
  * (c) 2026 baicie
4
4
  * Released under the MIT License.
5
5
  **/
@@ -27,7 +27,10 @@ function generateCustomElementsJson(options) {
27
27
  events: generateEvents(component),
28
28
  slots: generateSlots(component),
29
29
  cssParts: component.cssParts.map((name) => ({ name })),
30
- cssProperties: component.cssVars.map((name) => ({ name }))
30
+ cssProperties: getCssVars(component).map((variable) => ({
31
+ name: variable.name,
32
+ description: variable.description
33
+ }))
31
34
  }],
32
35
  exports: [{
33
36
  kind: "js",
@@ -57,7 +60,8 @@ function generateAttributes(component) {
57
60
  return result;
58
61
  }
59
62
  function generateMembers(component) {
60
- return Object.entries(component.props).map(([name, prop]) => {
63
+ var _component$methods;
64
+ const fields = Object.entries(component.props).map(([name, prop]) => {
61
65
  return {
62
66
  kind: "field",
63
67
  name,
@@ -66,18 +70,28 @@ function generateMembers(component) {
66
70
  default: prop.default === void 0 ? void 0 : JSON.stringify(prop.default)
67
71
  };
68
72
  });
73
+ const methods = Object.keys((_component$methods = component.methods) !== null && _component$methods !== void 0 ? _component$methods : {}).map((name) => {
74
+ return {
75
+ kind: "method",
76
+ name
77
+ };
78
+ });
79
+ return [...fields, ...methods];
69
80
  }
70
81
  function generateEvents(component) {
71
- return Object.entries(component.events).map(([name, event]) => {
82
+ return Object.entries(component.events).map(([key, event]) => {
83
+ var _event$name, _event$key;
72
84
  return {
73
- name,
85
+ name: (_event$name = event.name) !== null && _event$name !== void 0 ? _event$name : toKebabCase$1((_event$key = event.key) !== null && _event$key !== void 0 ? _event$key : key),
74
86
  description: event.description,
75
87
  type: { text: event.detail ? `CustomEvent<${formatDetailType(event.detail)}>` : "CustomEvent" }
76
88
  };
77
89
  });
78
90
  }
79
91
  function generateSlots(component) {
80
- return Object.entries(component.slots).map(([name, slot]) => {
92
+ return Object.entries(component.slots).map(([key, slot]) => {
93
+ var _slot$name;
94
+ const name = (_slot$name = slot.name) !== null && _slot$name !== void 0 ? _slot$name : key;
81
95
  return {
82
96
  name: name === "default" ? "" : name,
83
97
  description: slot.description
@@ -87,6 +101,7 @@ function generateSlots(component) {
87
101
  function getAttributeName(propName, prop) {
88
102
  if (prop.attr === false) return false;
89
103
  if (typeof prop.attr === "string") return prop.attr;
104
+ if (!isAttributeBackedType$1(prop.type)) return false;
90
105
  return propName.replace(/[A-Z]/g, (match) => `-${match.toLowerCase()}`);
91
106
  }
92
107
  function formatPropType(prop) {
@@ -98,15 +113,25 @@ function formatPropType(prop) {
98
113
  case "boolean": return "boolean";
99
114
  case "array": return "unknown[]";
100
115
  case "object": return "Record<string, unknown>";
116
+ case "function": return "Function";
101
117
  default: return "unknown";
102
118
  }
103
119
  }
120
+ function isAttributeBackedType$1(type) {
121
+ return type === "string" || type === "number" || type === "boolean";
122
+ }
104
123
  function formatDetailType(detail) {
105
124
  return `{ ${Object.entries(detail).map(([name, type]) => `${name}: ${type}`).join("; ")} }`;
106
125
  }
107
126
  function normalizeModulePath(value) {
108
127
  return value.replace(/\\/g, "/");
109
128
  }
129
+ function getCssVars(component) {
130
+ return Object.values(component.cssVars);
131
+ }
132
+ function toKebabCase$1(value) {
133
+ return value.replace(/[A-Z]/g, (match) => `-${match.toLowerCase()}`);
134
+ }
110
135
  //#endregion
111
136
  //#region packages/web-c/output-wc/src/imports.ts
112
137
  function toAbsoluteImportPath(root, source) {
@@ -159,7 +184,11 @@ function generateLazyEntry(options) {
159
184
  "",
160
185
  `export function createComponent(hostRef) {`,
161
186
  ` let mounted;`,
162
- ` const mountState = {};`,
187
+ ` const mountState = {`,
188
+ ` attributeProps: hostRef.attributeProps,`,
189
+ ` internals: hostRef.internals,`,
190
+ ` reflectingAttrs: hostRef.reflectingAttrs,`,
191
+ ` };`,
163
192
  "",
164
193
  ` return {`,
165
194
  ` connected() {`,
@@ -181,6 +210,22 @@ function generateLazyEntry(options) {
181
210
  ` propertyChanged(name, oldValue, newValue) {`,
182
211
  ` mounted?.propertyChanged(name, oldValue, newValue);`,
183
212
  ` },`,
213
+ "",
214
+ ` formAssociated(form) {`,
215
+ ` mounted?.formAssociated(form);`,
216
+ ` },`,
217
+ "",
218
+ ` formDisabled(disabled) {`,
219
+ ` mounted?.formDisabled(disabled);`,
220
+ ` },`,
221
+ "",
222
+ ` formReset() {`,
223
+ ` mounted?.formReset();`,
224
+ ` },`,
225
+ "",
226
+ ` formStateRestore(state, mode) {`,
227
+ ` mounted?.formStateRestore(state, mode);`,
228
+ ` },`,
184
229
  ` };`,
185
230
  `}`,
186
231
  "",
@@ -202,15 +247,19 @@ function generateLazyManifest(options) {
202
247
  const { components, getEntryFileName } = options;
203
248
  return `export const components = [
204
249
  ${components.map((component) => {
205
- var _component$runtimePro, _component$meta$shado, _component$meta;
250
+ var _component$runtimePro, _component$methods, _component$meta$shado, _component$meta, _component$meta$formA, _component$meta2;
206
251
  const entryFile = getEntryFileName(component.tag).replace(/\\/g, "/");
207
252
  const props = generatePropsArray((_component$runtimePro = component.runtimeProps) !== null && _component$runtimePro !== void 0 ? _component$runtimePro : component.props);
253
+ const methods = Object.keys((_component$methods = component.methods) !== null && _component$methods !== void 0 ? _component$methods : {});
208
254
  const importPath = entryFile.startsWith(".") ? JSON.stringify(entryFile) : JSON.stringify(`./${entryFile}`);
255
+ const methodLine = methods.length ? ` methods: ${JSON.stringify(methods)},\n` : "";
209
256
  return ` {
210
257
  tagName: ${JSON.stringify(component.tag)},
211
258
  shadow: ${(_component$meta$shado = (_component$meta = component.meta) === null || _component$meta === void 0 ? void 0 : _component$meta.shadow) !== null && _component$meta$shado !== void 0 ? _component$meta$shado : false},
259
+ formAssociated: ${(_component$meta$formA = (_component$meta2 = component.meta) === null || _component$meta2 === void 0 ? void 0 : _component$meta2.formAssociated) !== null && _component$meta$formA !== void 0 ? _component$meta$formA : false},
212
260
  load: () => import(${importPath}),
213
261
  props: ${props},
262
+ ${methodLine}
214
263
  }`;
215
264
  }).join(",\n")}
216
265
  ];
@@ -221,14 +270,16 @@ function generatePropsArray(props) {
221
270
  if (entries.length === 0) return "[]";
222
271
  return `[\n${entries.map(([name, prop]) => {
223
272
  const parts = [`name: ${JSON.stringify(name)}`];
224
- if (!isAttributeBackedType(prop.type) || prop.attr === false) parts.push("attrName: false");
273
+ if (!isAttributeBackedType(prop.type) && !prop.deserialize || prop.attr === false) parts.push("attrName: false");
225
274
  else {
226
275
  var _prop$attr;
227
276
  const attrName = (_prop$attr = prop.attr) !== null && _prop$attr !== void 0 ? _prop$attr : toKebabCase(name);
228
277
  if (attrName !== toKebabCase(name)) parts.push(`attrName: ${JSON.stringify(attrName)}`);
229
278
  }
230
279
  parts.push(`type: ${JSON.stringify(prop.type)}`);
231
- if (prop.reflect && isAttributeBackedType(prop.type)) parts.push("reflect: true");
280
+ if (prop.reflect && (isAttributeBackedType(prop.type) || Boolean(prop.serialize))) parts.push("reflect: true");
281
+ if (prop.serialize) parts.push("serialize: true");
282
+ if (prop.deserialize) parts.push("deserialize: true");
232
283
  return ` { ${parts.join(", ")} }`;
233
284
  }).join(",\n")}\n ]`;
234
285
  }
@@ -244,22 +295,60 @@ function generateLoader() {
244
295
  return `import { bootstrapLazy } from "@zeus-js/web-c-runtime";
245
296
  import { components } from "./components.manifest.js";
246
297
 
247
- let defined = false;
298
+ const componentsByTagName = new Map(
299
+ components.map(component => [component.tagName, component]),
300
+ );
248
301
 
249
- export function defineCustomElements() {
250
- if (defined) {
302
+ const definedTagsByRegistry = new WeakMap();
303
+
304
+ function resolveRegistry(options) {
305
+ return options.registry ??
306
+ (typeof customElements === "undefined" ? undefined : customElements);
307
+ }
308
+
309
+ function getDefinedTags(registry) {
310
+ let definedTags = definedTagsByRegistry.get(registry);
311
+
312
+ if (!definedTags) {
313
+ definedTags = new Set();
314
+ definedTagsByRegistry.set(registry, definedTags);
315
+ }
316
+
317
+ return definedTags;
318
+ }
319
+
320
+ export function defineCustomElement(tagName, options = {}) {
321
+ const registry = resolveRegistry(options);
322
+
323
+ if (!registry) {
251
324
  return;
252
325
  }
253
326
 
254
- if (typeof customElements === "undefined") {
327
+ const component = componentsByTagName.get(tagName);
328
+
329
+ if (!component) {
330
+ throw new Error(\`[zeus:web-c] Unknown custom element: <\${tagName}>.\`);
331
+ }
332
+
333
+ const definedTags = getDefinedTags(registry);
334
+
335
+ if (definedTags.has(tagName) || registry.get(tagName)) {
336
+ definedTags.add(tagName);
255
337
  return;
256
338
  }
257
339
 
258
- bootstrapLazy(components);
340
+ bootstrapLazy([component], { registry });
259
341
 
260
- defined = true;
342
+ definedTags.add(tagName);
261
343
  }
262
344
 
345
+ export function defineCustomElements(options = {}) {
346
+ for (const component of components) {
347
+ defineCustomElement(component.tagName, options);
348
+ }
349
+ }
350
+
351
+ export const defineLazyElement = defineCustomElement;
263
352
  export const defineLazyElements = defineCustomElements;
264
353
  `;
265
354
  }
@@ -273,7 +362,9 @@ export {};
273
362
  }
274
363
  function generateLazyIndex() {
275
364
  return `export {
365
+ defineCustomElement,
276
366
  defineCustomElements,
367
+ defineLazyElement,
277
368
  defineLazyElements,
278
369
  } from "./loader.js";
279
370
  `;
@@ -292,8 +383,8 @@ function wc(options = {}) {
292
383
  outDir: (_options$outDir = options.outDir) !== null && _options$outDir !== void 0 ? _options$outDir : "wc",
293
384
  stripPrefix: (_options$stripPrefix = options.stripPrefix) !== null && _options$stripPrefix !== void 0 ? _options$stripPrefix : false,
294
385
  fileName: options.fileName,
295
- manifestFile: registerMode === "lazy" ? false : (_options$manifestFile = options.manifestFile) !== null && _options$manifestFile !== void 0 ? _options$manifestFile : "zeus.components.json",
296
- customElementsFile: registerMode === "lazy" ? false : (_options$customElemen = options.customElementsFile) !== null && _options$customElemen !== void 0 ? _options$customElemen : "custom-elements.json",
386
+ manifestFile: (_options$manifestFile = options.manifestFile) !== null && _options$manifestFile !== void 0 ? _options$manifestFile : "zeus.components.json",
387
+ customElementsFile: (_options$customElemen = options.customElementsFile) !== null && _options$customElemen !== void 0 ? _options$customElemen : "custom-elements.json",
297
388
  dts: (_options$dts = options.dts) !== null && _options$dts !== void 0 ? _options$dts : true,
298
389
  jsxDts: (_options$jsxDts = options.jsxDts) !== null && _options$jsxDts !== void 0 ? _options$jsxDts : true,
299
390
  index: (_options$index = options.index) !== null && _options$index !== void 0 ? _options$index : true,
@@ -322,15 +413,15 @@ function wc(options = {}) {
322
413
  const runtimeProps = (_component$runtimePro2 = component.runtimeProps) !== null && _component$runtimePro2 !== void 0 ? _component$runtimePro2 : {};
323
414
  for (const [name, prop] of Object.entries(runtimeProps)) {
324
415
  if (isAttributeBackedRuntimeProp(prop.type)) continue;
325
- if (prop.attr !== void 0 && prop.attr !== false) ctx.error([
416
+ if (prop.attr !== void 0 && prop.attr !== false && !prop.deserialize) ctx.error([
326
417
  `[zeus-output-wc] <${component.tag}> prop "${name}" cannot use attr:${JSON.stringify(prop.attr)} with register:"lazy".`,
327
- "Lazy Web-C only supports attributes for string, number and boolean props.",
328
- "Use attr:false and pass object/array/function values as properties instead."
418
+ "Non-primitive lazy attributes require a custom deserialize function.",
419
+ "Add deserialize or use attr:false and pass the value as a property."
329
420
  ].join("\n"));
330
- if (prop.reflect) ctx.error([
421
+ if (prop.reflect && !prop.serialize) ctx.error([
331
422
  `[zeus-output-wc] <${component.tag}> prop "${name}" cannot use reflect:true with register:"lazy".`,
332
- "Lazy Web-C only reflects string, number and boolean props.",
333
- "Use a string/number/boolean prop or remove reflect:true."
423
+ "Non-primitive lazy reflection requires a custom serialize function.",
424
+ "Add serialize or remove reflect:true."
334
425
  ].join("\n"));
335
426
  }
336
427
  }
@@ -377,7 +468,7 @@ function wc(options = {}) {
377
468
  }
378
469
  for (const component of ctx.manifest.components) if (isLazy) {
379
470
  /**
380
- * Compatibility module consumed by Vue / React wrappers.
471
+ * Registration bridge module consumed by Vue / React wrappers.
381
472
  *
382
473
  * It only registers lazy Proxy Elements.
383
474
  * It does not import the real component implementation.
@@ -462,17 +553,18 @@ export {};
462
553
  fileName: joinPath("types/jsx.d.ts"),
463
554
  source: generateWCJsxDts(ctx.manifest)
464
555
  });
465
- } else if (normalized.manifestFile) files.push({
556
+ }
557
+ if (normalized.manifestFile) files.push({
466
558
  type: "asset",
467
559
  fileName: normalized.manifestFile,
468
560
  source: generateZeusComponentsManifest(ctx.manifest)
469
561
  });
470
- if (!isLazy && normalized.customElementsFile) files.push({
562
+ if (normalized.customElementsFile) files.push({
471
563
  type: "asset",
472
564
  fileName: normalized.customElementsFile,
473
565
  source: generateCustomElementsJson({
474
566
  manifest: ctx.manifest,
475
- getModulePath: (component) => joinPath(getFileName(component.tag))
567
+ getModulePath: (component) => isLazy ? joinPath(getLazyEntryFileName(normalized.entryFileName, component.tag)) : joinPath(getFileName(component.tag))
476
568
  })
477
569
  });
478
570
  if (!isLazy && (dts || jsxDts)) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zeus-js/output-wc",
3
- "version": "0.1.0-beta.3",
3
+ "version": "0.1.0-beta.5",
4
4
  "description": "Zeus Web Component output plugin",
5
5
  "type": "module",
6
6
  "main": "index.js",
@@ -52,11 +52,11 @@
52
52
  ]
53
53
  },
54
54
  "dependencies": {
55
- "@zeus-js/bundler-plugin": "0.1.0-beta.3",
56
- "@zeus-js/component-analyzer": "0.1.0-beta.3",
57
- "@zeus-js/runtime-dom": "0.1.0-beta.3",
58
- "@zeus-js/component-dts": "0.1.0-beta.3",
59
- "@zeus-js/web-c-runtime": "0.1.0"
55
+ "@zeus-js/bundler-plugin": "0.1.0-beta.5",
56
+ "@zeus-js/component-analyzer": "0.1.0-beta.5",
57
+ "@zeus-js/runtime-dom": "0.1.0-beta.5",
58
+ "@zeus-js/web-c-runtime": "0.2.0",
59
+ "@zeus-js/component-dts": "0.1.0-beta.5"
60
60
  },
61
61
  "peerDependencies": {
62
62
  "rollup": "^4.0.0"