@zeus-js/web-c-runtime 0.1.0 → 0.1.1-beta.1

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,9 +1,7 @@
1
- export type ZeusPropType = 'string' | 'number' | 'boolean' | 'object' | 'array' | 'function' | 'unknown';
2
- export interface ZeusPropMeta {
3
- name: string;
4
- attrName?: string | false;
5
- type: ZeusPropType;
6
- reflect?: boolean;
1
+ import { CustomElementPropSchema, CustomElementPropType } from '@zeus-js/runtime-dom';
2
+
3
+ export type ZeusPropType = CustomElementPropType;
4
+ export interface ZeusPropMeta extends CustomElementPropSchema {
7
5
  default?: unknown;
8
6
  }
9
7
  export interface ZeusLazyComponentMeta {
@@ -17,22 +15,32 @@ export interface ZeusLazyComponentMeta {
17
15
  default: ZeusComponentModule;
18
16
  }>;
19
17
  props: ZeusPropMeta[];
18
+ methods?: string[];
20
19
  /**
21
20
  * Whether to render into a ShadowRoot.
22
21
  *
23
22
  * @default false
24
23
  */
25
24
  shadow?: boolean;
25
+ /**
26
+ * Whether the proxy class participates in browser form association.
27
+ *
28
+ * @default false
29
+ */
30
+ formAssociated?: boolean;
26
31
  }
27
32
  export interface HostRef {
28
33
  host: HTMLElement;
29
34
  meta: ZeusLazyComponentMeta;
35
+ internals?: ElementInternals;
30
36
  connected: boolean;
31
37
  loaded: boolean;
32
38
  loading?: Promise<void>;
33
39
  instance?: ZeusComponentInstance;
34
40
  values: Map<string, unknown>;
41
+ attributeProps: Set<string>;
35
42
  reflectingAttrs: Set<string>;
43
+ pendingFormCallbacks: ZeusFormCallback[];
36
44
  readyWaiters: Array<{
37
45
  resolve(host: HTMLElement): void;
38
46
  reject(error: unknown): void;
@@ -42,6 +50,10 @@ export interface ZeusComponentInstance {
42
50
  connected?(): void;
43
51
  disconnected?(): void;
44
52
  propertyChanged?(name: string, oldValue: unknown, newValue: unknown): void;
53
+ formAssociated?(form: HTMLFormElement | null): void;
54
+ formDisabled?(disabled: boolean): void;
55
+ formReset?(): void;
56
+ formStateRestore?(state: File | FormData | string | null, mode: 'restore' | 'autocomplete'): void;
45
57
  /**
46
58
  * Can return Node / Node[] / string.
47
59
  * If the component completes rendering itself, it can also return void.
@@ -49,11 +61,27 @@ export interface ZeusComponentInstance {
49
61
  render?(): void | string | Node | Node[];
50
62
  dispose?(): void;
51
63
  }
64
+ type ZeusFormCallback = {
65
+ type: 'associated';
66
+ form: HTMLFormElement | null;
67
+ } | {
68
+ type: 'disabled';
69
+ disabled: boolean;
70
+ } | {
71
+ type: 'reset';
72
+ } | {
73
+ type: 'stateRestore';
74
+ state: File | FormData | string | null;
75
+ mode: 'restore' | 'autocomplete';
76
+ };
52
77
  export interface ZeusComponentModule {
53
78
  createComponent(hostRef: HostRef): ZeusComponentInstance;
54
79
  }
55
80
 
56
- export declare function bootstrapLazy(components: ZeusLazyComponentMeta[]): void;
81
+ export interface BootstrapLazyOptions {
82
+ registry?: CustomElementRegistry;
83
+ }
84
+ export declare function bootstrapLazy(components: ZeusLazyComponentMeta[], options?: BootstrapLazyOptions): void;
57
85
 
58
86
  export declare function createLazyElementClass(meta: ZeusLazyComponentMeta): CustomElementConstructor;
59
87
 
@@ -1,8 +1,30 @@
1
1
  /**
2
- * web-c-runtime v0.1.0
2
+ * web-c-runtime v0.1.1-beta.1
3
3
  * (c) 2026 baicie
4
4
  * Released under the MIT License.
5
5
  **/
6
+ import { coerceCustomElementAttribute, findCustomElementPropByAttribute, getCustomElementAttributeName, getCustomElementObservedAttributes, reflectCustomElementProperty } from "@zeus-js/runtime-dom";
7
+ //#region packages/web-c/web-c-runtime/src/form-callbacks.ts
8
+ function invokeFormCallback(hostRef, callback) {
9
+ switch (callback.type) {
10
+ case "associated":
11
+ var _hostRef$instance, _hostRef$instance$for;
12
+ (_hostRef$instance = hostRef.instance) === null || _hostRef$instance === void 0 || (_hostRef$instance$for = _hostRef$instance.formAssociated) === null || _hostRef$instance$for === void 0 || _hostRef$instance$for.call(_hostRef$instance, callback.form);
13
+ return;
14
+ case "disabled":
15
+ var _hostRef$instance2, _hostRef$instance2$fo;
16
+ (_hostRef$instance2 = hostRef.instance) === null || _hostRef$instance2 === void 0 || (_hostRef$instance2$fo = _hostRef$instance2.formDisabled) === null || _hostRef$instance2$fo === void 0 || _hostRef$instance2$fo.call(_hostRef$instance2, callback.disabled);
17
+ return;
18
+ case "reset":
19
+ var _hostRef$instance3, _hostRef$instance3$fo;
20
+ (_hostRef$instance3 = hostRef.instance) === null || _hostRef$instance3 === void 0 || (_hostRef$instance3$fo = _hostRef$instance3.formReset) === null || _hostRef$instance3$fo === void 0 || _hostRef$instance3$fo.call(_hostRef$instance3);
21
+ return;
22
+ case "stateRestore":
23
+ var _hostRef$instance4, _hostRef$instance4$fo;
24
+ (_hostRef$instance4 = hostRef.instance) === null || _hostRef$instance4 === void 0 || (_hostRef$instance4$fo = _hostRef$instance4.formStateRestore) === null || _hostRef$instance4$fo === void 0 || _hostRef$instance4$fo.call(_hostRef$instance4, callback.state, callback.mode);
25
+ }
26
+ }
27
+ //#endregion
6
28
  //#region packages/web-c/web-c-runtime/src/host-ref.ts
7
29
  const hostRefs = /* @__PURE__ */ new WeakMap();
8
30
  function registerHost(host, meta) {
@@ -11,15 +33,27 @@ function registerHost(host, meta) {
11
33
  const hostRef = {
12
34
  host,
13
35
  meta,
36
+ internals: meta.formAssociated ? attachElementInternals(host) : void 0,
14
37
  connected: false,
15
38
  loaded: false,
16
39
  values: /* @__PURE__ */ new Map(),
40
+ attributeProps: /* @__PURE__ */ new Set(),
17
41
  reflectingAttrs: /* @__PURE__ */ new Set(),
42
+ pendingFormCallbacks: [],
18
43
  readyWaiters: []
19
44
  };
20
45
  hostRefs.set(host, hostRef);
21
46
  return hostRef;
22
47
  }
48
+ function attachElementInternals(host) {
49
+ if (typeof host.attachInternals !== "function") return;
50
+ try {
51
+ return host.attachInternals();
52
+ } catch (error) {
53
+ console.warn("[zeus:web-c] Failed to attach ElementInternals.", error);
54
+ return;
55
+ }
56
+ }
23
57
  function getHostRef(host) {
24
58
  return hostRefs.get(host);
25
59
  }
@@ -53,7 +87,8 @@ function setPropValue(hostRef, prop, value) {
53
87
  const oldValue = getPropValue(hostRef, prop);
54
88
  if (Object.is(oldValue, value)) return;
55
89
  hostRef.values.set(prop.name, value);
56
- if (prop.reflect) reflectPropertyToAttribute(hostRef, prop, value);
90
+ hostRef.attributeProps.delete(prop.name);
91
+ if (prop.reflect) reflectCustomElementProperty(hostRef.host, prop, value, hostRef.reflectingAttrs);
57
92
  if (hostRef.loaded) {
58
93
  var _hostRef$instance, _hostRef$instance$pro;
59
94
  (_hostRef$instance = hostRef.instance) === null || _hostRef$instance === void 0 || (_hostRef$instance$pro = _hostRef$instance.propertyChanged) === null || _hostRef$instance$pro === void 0 || _hostRef$instance$pro.call(_hostRef$instance, prop.name, oldValue, value);
@@ -62,12 +97,13 @@ function setPropValue(hostRef, prop, value) {
62
97
  function syncAttributeToProperty(hostRef, attrName, _oldValue, newValue) {
63
98
  const normalizedAttrName = normalizeAttrName(attrName);
64
99
  if (hostRef.reflectingAttrs.has(normalizedAttrName)) return;
65
- const prop = findPropByAttrName(hostRef, normalizedAttrName);
100
+ const prop = findCustomElementPropByAttribute(hostRef.meta.props, normalizedAttrName);
66
101
  if (!prop) return;
67
102
  const oldPropValue = getPropValue(hostRef, prop);
68
- const newPropValue = parseAttributeValue(prop, newValue);
103
+ const newPropValue = coerceCustomElementAttribute(prop, newValue);
69
104
  if (Object.is(oldPropValue, newPropValue)) return;
70
105
  hostRef.values.set(prop.name, newPropValue);
106
+ hostRef.attributeProps.add(prop.name);
71
107
  if (hostRef.loaded) {
72
108
  var _hostRef$instance2, _hostRef$instance2$pr;
73
109
  (_hostRef$instance2 = hostRef.instance) === null || _hostRef$instance2 === void 0 || (_hostRef$instance2$pr = _hostRef$instance2.propertyChanged) === null || _hostRef$instance2$pr === void 0 || _hostRef$instance2$pr.call(_hostRef$instance2, prop.name, oldPropValue, newPropValue);
@@ -77,21 +113,17 @@ function applyInitialValues(hostRef) {
77
113
  const host = hostRef.host;
78
114
  for (const prop of hostRef.meta.props) {
79
115
  if (hostRef.values.has(prop.name)) continue;
80
- const attrName = getAttrName(prop);
116
+ const attrName = getCustomElementAttributeName(prop);
81
117
  if (attrName && host.hasAttribute(attrName)) {
82
- hostRef.values.set(prop.name, parseAttributeValue(prop, host.getAttribute(attrName)));
118
+ hostRef.values.set(prop.name, coerceCustomElementAttribute(prop, host.getAttribute(attrName)));
119
+ hostRef.attributeProps.add(prop.name);
83
120
  continue;
84
121
  }
85
122
  if ("default" in prop) hostRef.values.set(prop.name, prop.default);
86
123
  }
87
124
  }
88
125
  function getObservedAttributes(props) {
89
- const attrs = [];
90
- for (const prop of props) {
91
- const attrName = getAttrName(prop);
92
- if (attrName) attrs.push(attrName);
93
- }
94
- return attrs;
126
+ return getCustomElementObservedAttributes(props);
95
127
  }
96
128
  /**
97
129
  * Upgrades properties that were written on an element instance before its
@@ -111,57 +143,11 @@ function upgradePreDefinedProperties(host, hostRef) {
111
143
  setPropValue(hostRef, prop, value);
112
144
  }
113
145
  }
114
- function findPropByAttrName(hostRef, attrName) {
115
- return hostRef.meta.props.find((prop) => {
116
- return getAttrName(prop) === attrName;
117
- });
118
- }
119
- function getAttrName(prop) {
120
- var _prop$attrName;
121
- if (prop.attrName === false) return;
122
- if (!isAttributeBackedType(prop.type)) return;
123
- return normalizeAttrName((_prop$attrName = prop.attrName) !== null && _prop$attrName !== void 0 ? _prop$attrName : toKebabCase(prop.name));
124
- }
125
- function isAttributeBackedType(type) {
126
- return type === "string" || type === "number" || type === "boolean";
127
- }
128
146
  function normalizeAttrName(value) {
129
147
  return value.toLowerCase();
130
148
  }
131
- function parseAttributeValue(prop, value) {
132
- switch (prop.type) {
133
- case "boolean": return value !== null;
134
- case "number":
135
- if (value === null) return;
136
- return Number(value);
137
- case "string": return value !== null && value !== void 0 ? value : void 0;
138
- default: return value;
139
- }
140
- }
141
- function reflectPropertyToAttribute(hostRef, prop, value) {
142
- const host = hostRef.host;
143
- const attrName = getAttrName(prop);
144
- if (!attrName) return;
145
- hostRef.reflectingAttrs.add(attrName);
146
- try {
147
- if (prop.type === "boolean") {
148
- host.toggleAttribute(attrName, Boolean(value));
149
- return;
150
- }
151
- if (value === null || value === void 0 || value === false) {
152
- host.removeAttribute(attrName);
153
- return;
154
- }
155
- if (prop.type === "string" || prop.type === "number") host.setAttribute(attrName, String(value));
156
- } finally {
157
- hostRef.reflectingAttrs.delete(attrName);
158
- }
159
- }
160
- function toKebabCase(value) {
161
- return value.replace(/[A-Z]/g, (match) => `-${match.toLowerCase()}`);
162
- }
163
149
  //#endregion
164
- //#region \0@oxc-project+runtime@0.134.0/helpers/esm/asyncToGenerator.js
150
+ //#region \0@oxc-project+runtime@0.137.0/helpers/esm/asyncToGenerator.js
165
151
  function asyncGeneratorStep(n, t, e, r, o, a, c) {
166
152
  try {
167
153
  var i = n[a](c), u = i.value;
@@ -206,6 +192,7 @@ function _initializeComponent() {
206
192
  if (hostRef.loaded) {
207
193
  var _hostRef$instance, _hostRef$instance$con;
208
194
  (_hostRef$instance = hostRef.instance) === null || _hostRef$instance === void 0 || (_hostRef$instance$con = _hostRef$instance.connected) === null || _hostRef$instance$con === void 0 || _hostRef$instance$con.call(_hostRef$instance);
195
+ flushPendingFormCallbacks(hostRef);
209
196
  return;
210
197
  }
211
198
  if (hostRef.loading) {
@@ -238,6 +225,7 @@ function _doInitializeComponent() {
238
225
  try {
239
226
  var _instance$connected, _instance$render;
240
227
  (_instance$connected = instance.connected) === null || _instance$connected === void 0 || _instance$connected.call(instance);
228
+ flushPendingFormCallbacks(hostRef);
241
229
  const rendered = (_instance$render = instance.render) === null || _instance$render === void 0 ? void 0 : _instance$render.call(instance);
242
230
  if (rendered !== void 0) mountRenderedOutput(hostRef, rendered);
243
231
  hostRef.loaded = true;
@@ -252,6 +240,12 @@ function _doInitializeComponent() {
252
240
  });
253
241
  return _doInitializeComponent.apply(this, arguments);
254
242
  }
243
+ function flushPendingFormCallbacks(hostRef) {
244
+ while (hostRef.pendingFormCallbacks.length > 0) {
245
+ invokeFormCallback(hostRef, hostRef.pendingFormCallbacks[0]);
246
+ hostRef.pendingFormCallbacks.shift();
247
+ }
248
+ }
255
249
  function loadComponentModule(_x3) {
256
250
  return _loadComponentModule.apply(this, arguments);
257
251
  }
@@ -331,6 +325,28 @@ function createLazyElementClass(meta) {
331
325
  if (oldValue === newValue) return;
332
326
  syncAttributeToProperty(requireHostRef(this), name, oldValue, newValue);
333
327
  }
328
+ formAssociatedCallback(form) {
329
+ dispatchFormCallback(requireHostRef(this), {
330
+ type: "associated",
331
+ form
332
+ });
333
+ }
334
+ formDisabledCallback(disabled) {
335
+ dispatchFormCallback(requireHostRef(this), {
336
+ type: "disabled",
337
+ disabled
338
+ });
339
+ }
340
+ formResetCallback() {
341
+ dispatchFormCallback(requireHostRef(this), { type: "reset" });
342
+ }
343
+ formStateRestoreCallback(state, mode) {
344
+ dispatchFormCallback(requireHostRef(this), {
345
+ type: "stateRestore",
346
+ state,
347
+ mode
348
+ });
349
+ }
334
350
  componentOnReady() {
335
351
  const hostRef = requireHostRef(this);
336
352
  if (hostRef.connected && !hostRef.loaded && !hostRef.loading) initializeComponent(hostRef).catch((error) => {
@@ -339,13 +355,42 @@ function createLazyElementClass(meta) {
339
355
  return waitForComponentReady(hostRef);
340
356
  }
341
357
  }
358
+ ZeusLazyElement.formAssociated = Boolean(meta.formAssociated);
342
359
  installPropertyAccessors(ZeusLazyElement.prototype, meta.props);
360
+ installMethodProxies(ZeusLazyElement.prototype, meta.methods);
343
361
  return ZeusLazyElement;
344
362
  }
363
+ function dispatchFormCallback(hostRef, callback) {
364
+ if (!hostRef.instance || !hostRef.connected) {
365
+ hostRef.pendingFormCallbacks.push(callback);
366
+ return;
367
+ }
368
+ invokeFormCallback(hostRef, callback);
369
+ }
370
+ function installMethodProxies(proto, methods) {
371
+ if (!methods) return;
372
+ for (const name of methods) {
373
+ if (name in proto) continue;
374
+ Object.defineProperty(proto, name, {
375
+ configurable: true,
376
+ value: function() {
377
+ const host = this;
378
+ const args = Array.prototype.slice.call(arguments);
379
+ const hostRef = requireHostRef(host);
380
+ return waitForComponentReady(hostRef).then((readyHost) => {
381
+ const method = readyHost[name];
382
+ if (typeof method !== "function") throw new Error(`[zeus:web-c] Method "${name}" is not exposed on <${hostRef.meta.tagName}>.`);
383
+ return method.apply(readyHost, args);
384
+ });
385
+ }
386
+ });
387
+ }
388
+ }
345
389
  //#endregion
346
390
  //#region packages/web-c/web-c-runtime/src/bootstrapLazy.ts
347
- function bootstrapLazy(components) {
348
- const registry = typeof customElements === "undefined" ? void 0 : customElements;
391
+ function bootstrapLazy(components, options = {}) {
392
+ var _options$registry;
393
+ const registry = (_options$registry = options.registry) !== null && _options$registry !== void 0 ? _options$registry : typeof customElements === "undefined" ? void 0 : customElements;
349
394
  if (!registry) return;
350
395
  for (const meta of components) {
351
396
  if (registry.get(meta.tagName)) continue;
package/package.json CHANGED
@@ -1,14 +1,19 @@
1
1
  {
2
2
  "name": "@zeus-js/web-c-runtime",
3
- "version": "0.1.0",
4
- "description": "Zeus Web-C lazy-loading runtime",
5
3
  "type": "module",
6
- "main": "./dist/web-c-runtime.esm-bundler.js",
7
- "module": "./dist/web-c-runtime.esm-bundler.js",
8
- "types": "./dist/web-c-runtime.d.ts",
9
- "files": [
10
- "dist"
11
- ],
4
+ "version": "0.1.1-beta.1",
5
+ "description": "Zeus Web-C lazy-loading runtime",
6
+ "license": "MIT",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "https://github.com/baicie/zeus.git",
10
+ "directory": "packages/web-c/web-c-runtime"
11
+ },
12
+ "publishConfig": {
13
+ "access": "public",
14
+ "provenance": true
15
+ },
16
+ "sideEffects": false,
12
17
  "exports": {
13
18
  ".": {
14
19
  "types": "./dist/web-c-runtime.d.ts",
@@ -17,11 +22,13 @@
17
22
  "default": "./dist/web-c-runtime.esm-bundler.js"
18
23
  }
19
24
  },
20
- "sideEffects": false,
21
- "repository": {
22
- "type": "git",
23
- "url": "https://github.com/baicie/zeus"
25
+ "files": [
26
+ "dist"
27
+ ],
28
+ "dependencies": {
29
+ "@zeus-js/runtime-dom": "0.1.1-beta.1"
24
30
  },
31
+ "author": "Baicie",
25
32
  "buildOptions": {
26
33
  "name": "ZeusWebCRuntime",
27
34
  "formats": [
@@ -33,6 +40,7 @@
33
40
  "web-components",
34
41
  "custom-elements"
35
42
  ],
36
- "author": "Baicie",
37
- "license": "MIT"
43
+ "main": "./dist/web-c-runtime.esm-bundler.js",
44
+ "module": "./dist/web-c-runtime.esm-bundler.js",
45
+ "types": "./dist/web-c-runtime.d.ts"
38
46
  }