@zeus-js/output-wc 0.1.1-beta.2 → 0.1.1-beta.20

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,14 +1,97 @@
1
1
  /**
2
- * output-wc v0.1.1-beta.2
2
+ * output-wc v0.1.1-beta.20
3
3
  * (c) 2026 baicie
4
4
  * Released under the MIT License.
5
5
  **/
6
6
  import path from "node:path";
7
+ import { fileURLToPath } from "node:url";
7
8
  import { resolvePluginDts } from "@zeus-js/bundler-plugin";
8
- import { generateLoaderDts, generateWCDtsFiles, generateWCJsxDts } from "@zeus-js/component-dts";
9
+ import { formatDetailType, generateLoaderDts, generateWCDtsFiles, generateWCJsxDts } from "@zeus-js/component-dts";
10
+ //#region packages/web-c/output-wc/src/generateManifest.ts
11
+ function generateZeusComponentsManifest(manifest) {
12
+ validateComponentManifest(manifest);
13
+ return `${JSON.stringify(manifest, null, 2)}\n`;
14
+ }
15
+ function validateComponentManifest(manifest) {
16
+ if ((manifest === null || manifest === void 0 ? void 0 : manifest.schemaVersion) !== 1) throw new Error("[ZEUS_WC_ABI_VERSION] Component manifest schemaVersion must be 1.");
17
+ if (!Array.isArray(manifest.components)) throw new Error("[ZEUS_WC_INVALID_MANIFEST] Component manifest components must be an array.");
18
+ const tags = /* @__PURE__ */ new Set();
19
+ for (const [componentIndex, component] of manifest.components.entries()) {
20
+ if (!component || typeof component.tag !== "string") throw new Error(`[ZEUS_WC_INVALID_MANIFEST] components[${componentIndex}].tag must be a string.`);
21
+ if (tags.has(component.tag)) throw new Error(`[ZEUS_WC_DUPLICATE_TAG] Component tag "${component.tag}" is declared more than once.`);
22
+ tags.add(component.tag);
23
+ }
24
+ for (const [componentIndex, component] of manifest.components.entries()) {
25
+ var _component$props, _component$events, _component$props2;
26
+ const componentPath = `components[${componentIndex}]`;
27
+ if (!component || typeof component.tag !== "string" || typeof component.exportName !== "string") throw new Error(`[ZEUS_WC_INVALID_MANIFEST] ${componentPath} requires tag and exportName strings.`);
28
+ const attributes = /* @__PURE__ */ new Map();
29
+ for (const [propName, prop] of Object.entries((_component$props = component.props) !== null && _component$props !== void 0 ? _component$props : {})) {
30
+ const attrName = prop.attr === false ? false : typeof prop.attr === "string" ? prop.attr : [
31
+ "string",
32
+ "number",
33
+ "boolean"
34
+ ].includes(prop.type) ? propName.replace(/[A-Z]/g, (match) => `-${match.toLowerCase()}`) : false;
35
+ if (attrName !== false) {
36
+ const previous = attributes.get(attrName);
37
+ if (previous && previous !== propName) throw new Error(`[ZEUS_WC_ATTR_COLLISION] ${componentPath}.props.${propName} and ${previous} both use attribute "${attrName}".`);
38
+ attributes.set(attrName, propName);
39
+ }
40
+ }
41
+ for (const [eventKey, event] of Object.entries((_component$events = component.events) !== null && _component$events !== void 0 ? _component$events : {})) {
42
+ if (event.name !== void 0 && typeof event.name !== "string" || event.reactName !== void 0 && typeof event.reactName !== "string" || event.bubbles !== void 0 && typeof event.bubbles !== "boolean" || event.composed !== void 0 && typeof event.composed !== "boolean" || event.cancelable !== void 0 && typeof event.cancelable !== "boolean") throw new Error(`[ZEUS_WC_EVENT_ABI] ${componentPath}.events.${eventKey} contains invalid names or bubbles/composed/cancelable flags.`);
43
+ const eventPath = `${componentPath}.events.${eventKey}`;
44
+ if (event.detail !== void 0) assertJsonSafe(event.detail, `${eventPath}.detail`);
45
+ if (event.detailOptional !== void 0) assertJsonSafe(event.detailOptional, `${eventPath}.detailOptional`);
46
+ if (event.detail !== void 0 && (event.detail === null || typeof event.detail !== "object" || Array.isArray(event.detail) || Object.values(event.detail).some((type) => typeof type !== "string"))) throw new Error(`[ZEUS_WC_EVENT_ABI] ${eventPath}.detail must map field names to type strings.`);
47
+ if (event.detailOptional !== void 0 && (!Array.isArray(event.detailOptional) || !event.detail || [...event.detailOptional].some((name) => typeof name !== "string" || !Object.prototype.hasOwnProperty.call(event.detail, name)) || new Set(event.detailOptional).size !== event.detailOptional.length)) throw new Error(`[ZEUS_WC_EVENT_ABI] ${eventPath}.detailOptional must contain unique names from detail.`);
48
+ }
49
+ for (const [propName, prop] of Object.entries((_component$props2 = component.props) !== null && _component$props2 !== void 0 ? _component$props2 : {})) {
50
+ if (prop.hasDefault !== void 0 && typeof prop.hasDefault !== "boolean") throw new Error(`[ZEUS_WC_INVALID_DEFAULT_META] ${componentPath}.props.${propName}.hasDefault must be boolean.`);
51
+ if (prop.defaultStrategy !== void 0 && prop.defaultStrategy !== "static" && prop.defaultStrategy !== "factory") throw new Error(`[ZEUS_WC_INVALID_DEFAULT_META] ${componentPath}.props.${propName}.defaultStrategy is invalid.`);
52
+ if (prop.defaultStrategy === "factory" && prop.default !== void 0) throw new Error(`[ZEUS_WC_INVALID_DEFAULT_META] ${componentPath}.props.${propName} factory defaults cannot be serialized as values.`);
53
+ if (prop.defaultStrategy === "static" && !Object.prototype.hasOwnProperty.call(prop, "default")) throw new Error(`[ZEUS_WC_INVALID_DEFAULT_META] ${componentPath}.props.${propName} static defaults require a value.`);
54
+ if (Object.prototype.hasOwnProperty.call(prop, "default")) {
55
+ if (prop.default === void 0) throw new Error(`[ZEUS_WC_INVALID_DEFAULT_META] ${componentPath}.props.${propName}.default cannot be undefined.`);
56
+ assertJsonSafe(prop.default, `${componentPath}.props.${propName}.default`, /* @__PURE__ */ new Set(), "ZEUS_WC_INVALID_DEFAULT_META", true);
57
+ }
58
+ }
59
+ }
60
+ assertJsonSafe(manifest, "manifest");
61
+ }
62
+ function assertJsonSafe(value, path, parents = /* @__PURE__ */ new Set(), code = "ZEUS_WC_INVALID_MANIFEST", rejectUndefined = false) {
63
+ if (value === void 0) {
64
+ if (rejectUndefined) throw invalidManifest(path, "undefined values are not supported", code);
65
+ return;
66
+ }
67
+ if (value === null) return;
68
+ if (typeof value === "string" || typeof value === "boolean") return;
69
+ if (typeof value === "number") {
70
+ if (!Number.isFinite(value) || Object.is(value, -0)) throw invalidManifest(path, "numbers must be finite and cannot be -0", code);
71
+ return;
72
+ }
73
+ if (typeof value === "function" || typeof value === "symbol" || typeof value === "bigint") throw invalidManifest(path, "functions, symbols, and bigint values are not supported", code);
74
+ if (typeof value !== "object") throw invalidManifest(path, "value is not JSON-safe", code);
75
+ if (parents.has(value)) throw invalidManifest(path, "cyclic values are not supported", code);
76
+ const prototype = Object.getPrototypeOf(value);
77
+ if (!Array.isArray(value) && prototype !== Object.prototype && prototype !== null) throw invalidManifest(path, "only plain objects and arrays are supported", code);
78
+ if (Object.getOwnPropertySymbols(value).length > 0) throw invalidManifest(path, "symbol keys are not supported", code);
79
+ parents.add(value);
80
+ for (const [key, descriptor] of Object.entries(Object.getOwnPropertyDescriptors(value))) {
81
+ if ("get" in descriptor || "set" in descriptor) throw invalidManifest(`${path}.${key}`, "accessor properties are not supported", code);
82
+ if (descriptor.value === void 0 && !rejectUndefined) continue;
83
+ assertJsonSafe(descriptor.value, Array.isArray(value) ? `${path}[${key}]` : `${path}.${key}`, parents, code, rejectUndefined);
84
+ }
85
+ parents.delete(value);
86
+ }
87
+ function invalidManifest(path, reason, code) {
88
+ return /* @__PURE__ */ new Error(`[${code}] ${path}: ${reason}.`);
89
+ }
90
+ //#endregion
9
91
  //#region packages/web-c/output-wc/src/generateCustomElementsJson.ts
10
92
  function generateCustomElementsJson(options) {
11
93
  const { manifest, getModulePath } = options;
94
+ validateComponentManifest(manifest);
12
95
  const result = {
13
96
  schemaVersion: "1.0.0",
14
97
  modules: manifest.components.map((component) => {
@@ -70,21 +153,31 @@ function generateMembers(component) {
70
153
  default: prop.default === void 0 ? void 0 : JSON.stringify(prop.default)
71
154
  };
72
155
  });
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
- });
156
+ const methods = Object.entries((_component$methods = component.methods) !== null && _component$methods !== void 0 ? _component$methods : {}).map(([name, method]) => generateMethodMember(name, method));
79
157
  return [...fields, ...methods];
80
158
  }
159
+ function generateMethodMember(name, method) {
160
+ var _method$returns, _method$returns2;
161
+ const member = {
162
+ kind: "method",
163
+ name,
164
+ return: { type: { text: method.async ? `Promise<${(_method$returns = method.returns) !== null && _method$returns !== void 0 ? _method$returns : "unknown"}>` : (_method$returns2 = method.returns) !== null && _method$returns2 !== void 0 ? _method$returns2 : "unknown" } }
165
+ };
166
+ if (method.parameters) member.parameters = method.parameters.map((parameter) => ({
167
+ name: parameter.name,
168
+ type: { text: parameter.type },
169
+ optional: parameter.optional,
170
+ rest: parameter.rest
171
+ }));
172
+ return member;
173
+ }
81
174
  function generateEvents(component) {
82
175
  return Object.entries(component.events).map(([key, event]) => {
83
176
  var _event$name, _event$key;
84
177
  return {
85
178
  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),
86
179
  description: event.description,
87
- type: { text: event.detail ? `CustomEvent<${formatDetailType(event.detail)}>` : "CustomEvent" }
180
+ type: { text: event.detail ? `CustomEvent<${formatDetailType(event.detail, event.detailOptional)}>` : "CustomEvent" }
88
181
  };
89
182
  });
90
183
  }
@@ -120,9 +213,6 @@ function formatPropType(prop) {
120
213
  function isAttributeBackedType$1(type) {
121
214
  return type === "string" || type === "number" || type === "boolean";
122
215
  }
123
- function formatDetailType(detail) {
124
- return `{ ${Object.entries(detail).map(([name, type]) => `${name}: ${type}`).join("; ")} }`;
125
- }
126
216
  function normalizeModulePath(value) {
127
217
  return value.replace(/\\/g, "/");
128
218
  }
@@ -152,6 +242,15 @@ function generateWCEntry(options) {
152
242
  `import { ${component.exportName} } from ${JSON.stringify(source)};`,
153
243
  "",
154
244
  `export { ${component.exportName} };`,
245
+ "",
246
+ `export function defineCustomElement(options = {}) {`,
247
+ ` const registry = options.registry ?? (typeof customElements === 'undefined' ? undefined : customElements);`,
248
+ ` if (!registry) return;`,
249
+ ` const existing = registry.get(${JSON.stringify(component.tag)});`,
250
+ ` if (existing === ${component.exportName}) return;`,
251
+ ` if (existing) throw new Error(${JSON.stringify(`[ZEUS_WC_DUPLICATE_TAG] <${component.tag}> is already registered with a different definition.`)});`,
252
+ ` registry.define(${JSON.stringify(component.tag)}, ${component.exportName});`,
253
+ `}`,
155
254
  ""
156
255
  ].join("\n");
157
256
  }
@@ -177,16 +276,19 @@ function getVirtualIndexId() {
177
276
  //#region packages/web-c/output-wc/src/generateLazyEntry.ts
178
277
  function generateLazyEntry(options) {
179
278
  const { component, outPath, sourceImport } = options;
180
- const source = sourceImport !== null && sourceImport !== void 0 ? sourceImport : toRelativeImport(component.source, outPath);
279
+ const source = `${sourceImport !== null && sourceImport !== void 0 ? sourceImport : toRelativeImport(component.source, outPath)}?zeus-lazy-component=${component.exportName}`;
181
280
  return [
182
- `import { createCustomElementMountLifecycle, mountElementDefinition } from "@zeus-js/runtime-dom";`,
281
+ `import { createCustomElementMountLifecycle, getElementDefinition, mountElementDefinition } from "@zeus-js/runtime-dom";`,
282
+ `import { resolveHostProperties } from "@zeus-js/web-c-runtime";`,
183
283
  `import { ${component.exportName} } from ${JSON.stringify(source)};`,
184
284
  "",
185
285
  `export function createComponent(hostRef) {`,
286
+ ` resolveHostProperties(hostRef, getElementDefinition(${component.exportName}).propDefs);`,
186
287
  ` const mountState = {`,
187
288
  ` attributeProps: hostRef.attributeProps,`,
188
289
  ` internals: hostRef.internals,`,
189
290
  ` reflectingAttrs: hostRef.reflectingAttrs,`,
291
+ ` exposedMethods: hostRef.exposedMethods,`,
190
292
  ` };`,
191
293
  ` const lifecycle = createCustomElementMountLifecycle(() =>`,
192
294
  ` mountElementDefinition(`,
@@ -206,8 +308,8 @@ function generateLazyEntry(options) {
206
308
  ` lifecycle.disconnect();`,
207
309
  ` },`,
208
310
  "",
209
- ` propertyChanged(name, oldValue, newValue) {`,
210
- ` lifecycle.current()?.propertyChanged(name, oldValue, newValue);`,
311
+ ` propertyChanged(change) {`,
312
+ ` lifecycle.current()?.propertyChanged(change);`,
211
313
  ` },`,
212
314
  "",
213
315
  ` formAssociated(form) {`,
@@ -241,6 +343,60 @@ function toRelativeImport(source, outPath) {
241
343
  return [...outParts.slice(common).map(() => ".."), ...sourceParts.slice(common)].join("/");
242
344
  }
243
345
  //#endregion
346
+ //#region packages/web-c/output-wc/src/generateLoader.ts
347
+ function generateLoader() {
348
+ return `import { bootstrapLazy } from "@zeus-js/web-c-runtime";
349
+ import { components } from "./components.manifest.js";
350
+
351
+ const componentsByTagName = new Map(
352
+ components.map(component => [component.tagName, component]),
353
+ );
354
+
355
+ function resolveRegistry(options) {
356
+ return options.registry ??
357
+ (typeof customElements === "undefined" ? undefined : customElements);
358
+ }
359
+
360
+ export function defineCustomElement(tagName, options = {}) {
361
+ const registry = resolveRegistry(options);
362
+
363
+ if (!registry) {
364
+ return;
365
+ }
366
+
367
+ const component = componentsByTagName.get(tagName);
368
+
369
+ if (!component) {
370
+ throw new Error(\`[zeus:web-c] Unknown custom element: <\${tagName}>.\`);
371
+ }
372
+
373
+ bootstrapLazy([component], { registry });
374
+ }
375
+
376
+ export function defineCustomElements(options = {}) {
377
+ for (const component of components) {
378
+ defineCustomElement(component.tagName, options);
379
+ }
380
+ }
381
+
382
+ `;
383
+ }
384
+ function generateAutoEntry() {
385
+ return `import { defineCustomElements } from "./loader.js";
386
+
387
+ defineCustomElements();
388
+
389
+ export {};
390
+ `;
391
+ }
392
+ function generateLazyIndex() {
393
+ return `export {
394
+ defineCustomElement,
395
+ defineCustomElements,
396
+ } from "./loader.js";
397
+ `;
398
+ }
399
+ //#endregion
244
400
  //#region packages/web-c/output-wc/src/generateLazyManifest.ts
245
401
  function generateLazyManifest(options) {
246
402
  const { components, getEntryFileName } = options;
@@ -276,12 +432,28 @@ function generatePropsArray(props) {
276
432
  if (attrName !== toKebabCase(name)) parts.push(`attrName: ${JSON.stringify(attrName)}`);
277
433
  }
278
434
  parts.push(`type: ${JSON.stringify(prop.type)}`);
435
+ if (isJsonSafeDefault(prop.default)) {
436
+ const encoded = JSON.stringify(prop.default);
437
+ parts.push(`default: ${typeof prop.default === "object" && prop.default !== null ? `JSON.parse(${JSON.stringify(encoded)})` : encoded}`);
438
+ }
279
439
  if (prop.reflect && (isAttributeBackedType(prop.type) || Boolean(prop.serialize))) parts.push("reflect: true");
280
440
  if (prop.serialize) parts.push("serialize: true");
281
441
  if (prop.deserialize) parts.push("deserialize: true");
282
442
  return ` { ${parts.join(", ")} }`;
283
443
  }).join(",\n")}\n ]`;
284
444
  }
445
+ function isJsonSafeDefault(value, parents = /* @__PURE__ */ new Set()) {
446
+ if (value === null || typeof value === "string" || typeof value === "boolean") return true;
447
+ if (typeof value === "number") return Number.isFinite(value) && !Object.is(value, -0);
448
+ if (typeof value !== "object" || parents.has(value)) return false;
449
+ if (!Array.isArray(value) && Object.getPrototypeOf(value) !== Object.prototype) return false;
450
+ if (Object.getOwnPropertySymbols(value).length) return false;
451
+ parents.add(value);
452
+ const descriptors = Object.getOwnPropertyDescriptors(value);
453
+ const valid = Array.isArray(value) ? Array.from({ length: value.length }, (_, index) => descriptors[index]).every((descriptor) => descriptor && "value" in descriptor && isJsonSafeDefault(descriptor.value, parents)) : Object.values(descriptors).every((descriptor) => "value" in descriptor && isJsonSafeDefault(descriptor.value, parents));
454
+ parents.delete(value);
455
+ return valid;
456
+ }
285
457
  function isAttributeBackedType(type) {
286
458
  return type === "string" || type === "number" || type === "boolean";
287
459
  }
@@ -289,92 +461,134 @@ function toKebabCase(value) {
289
461
  return value.replace(/[A-Z]/g, (match) => `-${match.toLowerCase()}`);
290
462
  }
291
463
  //#endregion
292
- //#region packages/web-c/output-wc/src/generateLoader.ts
293
- function generateLoader() {
464
+ //#region packages/web-c/output-wc/src/generateRegistration.ts
465
+ function generateLazyRegistration(component, entryFileName) {
294
466
  return `import { bootstrapLazy } from "@zeus-js/web-c-runtime";
295
- import { components } from "./components.manifest.js";
296
-
297
- const componentsByTagName = new Map(
298
- components.map(component => [component.tagName, component]),
299
- );
300
-
301
- const definedTagsByRegistry = new WeakMap();
467
+ ${generateLazyManifest({
468
+ components: [component],
469
+ getEntryFileName: () => entryFileName
470
+ })}
471
+ export const component = components[0];
302
472
 
303
- function resolveRegistry(options) {
304
- return options.registry ??
305
- (typeof customElements === "undefined" ? undefined : customElements);
473
+ export function defineCustomElement(options = {}) {
474
+ bootstrapLazy([component], options);
306
475
  }
307
-
308
- function getDefinedTags(registry) {
309
- let definedTags = definedTagsByRegistry.get(registry);
310
-
311
- if (!definedTags) {
312
- definedTags = new Set();
313
- definedTagsByRegistry.set(registry, definedTags);
314
- }
315
-
316
- return definedTags;
476
+ `;
317
477
  }
318
-
319
- export function defineCustomElement(tagName, options = {}) {
320
- const registry = resolveRegistry(options);
321
-
322
- if (!registry) {
323
- return;
324
- }
325
-
326
- const component = componentsByTagName.get(tagName);
327
-
328
- if (!component) {
329
- throw new Error(\`[zeus:web-c] Unknown custom element: <\${tagName}>.\`);
330
- }
331
-
332
- const definedTags = getDefinedTags(registry);
333
-
334
- if (definedTags.has(tagName) || registry.get(tagName)) {
335
- definedTags.add(tagName);
336
- return;
337
- }
338
-
339
- bootstrapLazy([component], { registry });
340
-
341
- definedTags.add(tagName);
478
+ //#endregion
479
+ //#region \0@oxc-project+runtime@0.137.0/helpers/esm/typeof.js
480
+ function _typeof(o) {
481
+ "@babel/helpers - typeof";
482
+ return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(o) {
483
+ return typeof o;
484
+ } : function(o) {
485
+ return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
486
+ }, _typeof(o);
342
487
  }
343
-
344
- export function defineCustomElements(options = {}) {
345
- for (const component of components) {
346
- defineCustomElement(component.tagName, options);
347
- }
488
+ //#endregion
489
+ //#region \0@oxc-project+runtime@0.137.0/helpers/esm/toPrimitive.js
490
+ function toPrimitive(t, r) {
491
+ if ("object" != _typeof(t) || !t) return t;
492
+ var e = t[Symbol.toPrimitive];
493
+ if (void 0 !== e) {
494
+ var i = e.call(t, r || "default");
495
+ if ("object" != _typeof(i)) return i;
496
+ throw new TypeError("@@toPrimitive must return a primitive value.");
497
+ }
498
+ return ("string" === r ? String : Number)(t);
348
499
  }
349
-
350
- export const defineLazyElement = defineCustomElement;
351
- export const defineLazyElements = defineCustomElements;
352
- `;
500
+ //#endregion
501
+ //#region \0@oxc-project+runtime@0.137.0/helpers/esm/toPropertyKey.js
502
+ function toPropertyKey(t) {
503
+ var i = toPrimitive(t, "string");
504
+ return "symbol" == _typeof(i) ? i : i + "";
353
505
  }
354
- function generateAutoEntry() {
355
- return `import { defineCustomElements } from "./loader.js";
356
-
357
- defineCustomElements();
358
-
359
- export {};
360
- `;
506
+ //#endregion
507
+ //#region \0@oxc-project+runtime@0.137.0/helpers/esm/defineProperty.js
508
+ function _defineProperty(e, r, t) {
509
+ return (r = toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
510
+ value: t,
511
+ enumerable: !0,
512
+ configurable: !0,
513
+ writable: !0
514
+ }) : e[r] = t, e;
361
515
  }
362
- function generateLazyIndex() {
363
- return `export {
364
- defineCustomElement,
365
- defineCustomElements,
366
- defineLazyElement,
367
- defineLazyElements,
368
- } from "./loader.js";
369
- `;
516
+ //#endregion
517
+ //#region \0@oxc-project+runtime@0.137.0/helpers/esm/objectSpread2.js
518
+ function ownKeys(e, r) {
519
+ var t = Object.keys(e);
520
+ if (Object.getOwnPropertySymbols) {
521
+ var o = Object.getOwnPropertySymbols(e);
522
+ r && (o = o.filter(function(r) {
523
+ return Object.getOwnPropertyDescriptor(e, r).enumerable;
524
+ })), t.push.apply(t, o);
525
+ }
526
+ return t;
527
+ }
528
+ function _objectSpread2(e) {
529
+ for (var r = 1; r < arguments.length; r++) {
530
+ var t = null != arguments[r] ? arguments[r] : {};
531
+ r % 2 ? ownKeys(Object(t), !0).forEach(function(r) {
532
+ _defineProperty(e, r, t[r]);
533
+ }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function(r) {
534
+ Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r));
535
+ });
536
+ }
537
+ return e;
370
538
  }
371
539
  //#endregion
372
- //#region packages/web-c/output-wc/src/generateManifest.ts
373
- function generateZeusComponentsManifest(manifest) {
374
- return `${JSON.stringify(manifest, null, 2)}\n`;
540
+ //#region packages/web-c/output-wc/src/generateVSCodeCustomData.ts
541
+ function generateVSCodeCustomData(customElementsJson) {
542
+ let manifest;
543
+ try {
544
+ manifest = JSON.parse(customElementsJson);
545
+ } catch (_unused) {
546
+ throw new Error("[ZEUS_VSCODE_CUSTOM_DATA_INVALID] CEM input is not valid JSON.");
547
+ }
548
+ if ((manifest === null || manifest === void 0 ? void 0 : manifest.schemaVersion) !== "1.0.0" || !Array.isArray(manifest.modules)) throw new Error("[ZEUS_VSCODE_CUSTOM_DATA_INVALID] CEM input must use schemaVersion 1.0.0 and contain modules.");
549
+ const tags = manifest.modules.flatMap((module) => {
550
+ var _module$declarations;
551
+ return ((_module$declarations = module.declarations) !== null && _module$declarations !== void 0 ? _module$declarations : []).filter((declaration) => declaration.kind === "class" && declaration.customElement === true && typeof declaration.tagName === "string").map((declaration) => {
552
+ var _declaration$attribut;
553
+ const tagName = declaration.tagName;
554
+ const attributes = ((_declaration$attribut = declaration.attributes) !== null && _declaration$attribut !== void 0 ? _declaration$attribut : []).map((attribute) => {
555
+ var _attribute$type;
556
+ if (typeof attribute.name !== "string") throw new Error(`[ZEUS_VSCODE_CUSTOM_DATA_INVALID] <${tagName}> contains an attribute without a name.`);
557
+ const values = parseStringLiteralUnion((_attribute$type = attribute.type) === null || _attribute$type === void 0 ? void 0 : _attribute$type.text);
558
+ return _objectSpread2(_objectSpread2({ name: attribute.name }, attribute.description ? { description: attribute.description } : {}), values ? { values: values.map((name) => ({ name })) } : {});
559
+ });
560
+ return _objectSpread2(_objectSpread2({ name: tagName }, declaration.description ? { description: declaration.description } : {}), attributes.length > 0 ? { attributes } : {});
561
+ });
562
+ });
563
+ const names = /* @__PURE__ */ new Set();
564
+ for (const tag of tags) {
565
+ if (names.has(tag.name)) throw new Error(`[ZEUS_VSCODE_CUSTOM_DATA_INVALID] CEM declares <${tag.name}> more than once.`);
566
+ names.add(tag.name);
567
+ }
568
+ return `${JSON.stringify({
569
+ version: 1.1,
570
+ tags
571
+ }, null, 2)}\n`;
572
+ }
573
+ function parseStringLiteralUnion(typeText) {
574
+ if (!typeText) return void 0;
575
+ const parts = typeText.split(/\s+\|\s+/);
576
+ const values = [];
577
+ for (const part of parts) {
578
+ if (!part.startsWith("\"") || !part.endsWith("\"")) return void 0;
579
+ try {
580
+ const value = JSON.parse(part);
581
+ if (typeof value !== "string") return void 0;
582
+ values.push(value);
583
+ } catch (_unused2) {
584
+ return;
585
+ }
586
+ }
587
+ return values.length > 0 ? values : void 0;
375
588
  }
376
589
  //#endregion
377
590
  //#region packages/web-c/output-wc/src/index.ts
591
+ const outputWcModulePath = fileURLToPath(import.meta.url);
378
592
  function wc(options = {}) {
379
593
  var _options$register, _options$outDir, _options$stripPrefix, _options$manifestFile, _options$customElemen, _options$dts, _options$jsxDts, _options$index, _options$warnOnFileNa, _options$auto, _options$entryFileNam;
380
594
  const registerMode = (_options$register = options.register) !== null && _options$register !== void 0 ? _options$register : "lazy";
@@ -449,15 +663,13 @@ function wc(options = {}) {
449
663
  modules.push({
450
664
  id: "zeus:wc:components.manifest",
451
665
  fileName: joinPath("components.manifest.js"),
452
- code: generateLazyManifest({
453
- components: ctx.manifest.components,
454
- getEntryFileName: (tag) => getLazyEntryFileName(normalized.entryFileName, tag)
455
- })
666
+ code: [...ctx.manifest.components.map((component, index) => `import { component as c${index} } from ${JSON.stringify(getVirtualComponentId(component))};`), `export const components = [${ctx.manifest.components.map((_, index) => `c${index}`).join(", ")}];`].join("\n")
456
667
  });
457
668
  modules.push({
458
669
  id: "zeus:wc:loader",
459
670
  fileName: joinPath("loader.js"),
460
- code: generateLoader()
671
+ code: generateLoader(),
672
+ resolveFrom: outputWcModulePath
461
673
  });
462
674
  if (normalized.auto) modules.push({
463
675
  id: "zeus:wc:auto",
@@ -474,13 +686,9 @@ function wc(options = {}) {
474
686
  */
475
687
  modules.push({
476
688
  id: getVirtualComponentId(component),
477
- code: `
478
- import { defineCustomElements } from "zeus:wc:loader";
479
-
480
- defineCustomElements();
481
-
482
- export {};
483
- `.trimStart()
689
+ fileName: joinPath(getFileName(component.tag)),
690
+ code: generateLazyRegistration(component, path.posix.relative(path.posix.dirname(joinPath(getFileName(component.tag))), joinPath(getLazyEntryFileName(normalized.entryFileName, component.tag)))),
691
+ resolveFrom: outputWcModulePath
484
692
  });
485
693
  const fileName = joinPath(getLazyEntryFileName(normalized.entryFileName, component.tag));
486
694
  modules.push({
@@ -490,7 +698,8 @@ export {};
490
698
  component,
491
699
  outPath: fileName,
492
700
  sourceImport: toAbsoluteImportPath(ctx.root, component.source)
493
- })
701
+ }),
702
+ resolveFrom: outputWcModulePath
494
703
  });
495
704
  } else {
496
705
  const fileName = joinPath(getFileName(component.tag));
@@ -535,12 +744,17 @@ export {};
535
744
  const isLazy = normalized.register === "lazy";
536
745
  if (isLazy) {
537
746
  if (dts) {
538
- const loaderDts = generateLoaderDts(ctx.manifest);
747
+ const loaderDts = [...jsxDts ? ["import './types/jsx'", ""] : [], generateLoaderDts(ctx.manifest)].join("\n");
539
748
  files.push({
540
749
  type: "asset",
541
750
  fileName: joinPath("loader.d.ts"),
542
751
  source: loaderDts
543
752
  });
753
+ for (const component of ctx.manifest.components) files.push({
754
+ type: "asset",
755
+ fileName: joinPath(getFileName(component.tag).replace(/\.js$/, ".d.ts")),
756
+ source: "export declare function defineCustomElement(options?: { registry?: CustomElementRegistry }): void\n"
757
+ });
544
758
  if (normalized.index) files.push({
545
759
  type: "asset",
546
760
  fileName: joinPath("index.d.ts"),
@@ -558,14 +772,22 @@ export {};
558
772
  fileName: normalized.manifestFile,
559
773
  source: generateZeusComponentsManifest(ctx.manifest)
560
774
  });
561
- if (normalized.customElementsFile) files.push({
562
- type: "asset",
563
- fileName: normalized.customElementsFile,
564
- source: generateCustomElementsJson({
775
+ if (normalized.customElementsFile) {
776
+ const customElementsJson = generateCustomElementsJson({
565
777
  manifest: ctx.manifest,
566
778
  getModulePath: (component) => isLazy ? joinPath(getLazyEntryFileName(normalized.entryFileName, component.tag)) : joinPath(getFileName(component.tag))
567
- })
568
- });
779
+ });
780
+ files.push({
781
+ type: "asset",
782
+ fileName: normalized.customElementsFile,
783
+ source: customElementsJson
784
+ });
785
+ files.push({
786
+ type: "asset",
787
+ fileName: "vscode.html-custom-data.json",
788
+ source: generateVSCodeCustomData(customElementsJson)
789
+ });
790
+ }
569
791
  if (!isLazy && (dts || jsxDts)) {
570
792
  const dtsFiles = generateWCDtsFiles(ctx.manifest, {
571
793
  outDir: _outDir,