@zeus-js/web-c-runtime 0.1.1-beta.12 → 0.1.1-beta.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/web-c-runtime.d.ts +10 -2
- package/dist/web-c-runtime.esm-bundler.js +82 -20
- package/package.json +2 -2
package/dist/web-c-runtime.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CustomElementPropSchema, CustomElementPropType } from '@zeus-js/runtime-dom';
|
|
1
|
+
import { NormalizedPropChange, CustomElementPropSchema, CustomElementPropType } from '@zeus-js/runtime-dom';
|
|
2
2
|
|
|
3
3
|
export type ZeusPropType = CustomElementPropType;
|
|
4
4
|
export interface ZeusPropMeta extends CustomElementPropSchema {
|
|
@@ -36,10 +36,15 @@ export interface HostRef {
|
|
|
36
36
|
connected: boolean;
|
|
37
37
|
loaded: boolean;
|
|
38
38
|
loading?: Promise<void>;
|
|
39
|
+
readinessError?: Error;
|
|
40
|
+
exposedMethods: Record<string, Function>;
|
|
39
41
|
instance?: ZeusComponentInstance;
|
|
40
42
|
values: Map<string, unknown>;
|
|
43
|
+
propDefinitions: ZeusPropMeta[];
|
|
41
44
|
attributeProps: Set<string>;
|
|
42
45
|
reflectingAttrs: Set<string>;
|
|
46
|
+
preUpgradeAttributes: Map<string, string>;
|
|
47
|
+
pendingAttributes: Map<string, string | null>;
|
|
43
48
|
pendingFormCallbacks: ZeusFormCallback[];
|
|
44
49
|
readyWaiters: Array<{
|
|
45
50
|
resolve(host: HTMLElement): void;
|
|
@@ -49,7 +54,7 @@ export interface HostRef {
|
|
|
49
54
|
export interface ZeusComponentInstance {
|
|
50
55
|
connected?(): void;
|
|
51
56
|
disconnected?(): void;
|
|
52
|
-
propertyChanged?(
|
|
57
|
+
propertyChanged?(change: NormalizedPropChange): void;
|
|
53
58
|
formAssociated?(form: HTMLFormElement | null): void;
|
|
54
59
|
formDisabled?(disabled: boolean): void;
|
|
55
60
|
formReset?(): void;
|
|
@@ -85,4 +90,7 @@ export declare function bootstrapLazy(components: ZeusLazyComponentMeta[], optio
|
|
|
85
90
|
|
|
86
91
|
export declare function createLazyElementClass(meta: ZeusLazyComponentMeta): CustomElementConstructor;
|
|
87
92
|
|
|
93
|
+
/** Replace deferred codec markers with the implementation's real schema. */
|
|
94
|
+
export declare function resolveHostProperties(hostRef: HostRef, definitions: ZeusPropMeta[]): void;
|
|
95
|
+
|
|
88
96
|
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* web-c-runtime v0.1.1-beta.
|
|
2
|
+
* web-c-runtime v0.1.1-beta.14
|
|
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";
|
|
6
|
+
import { coerceCustomElementAttribute, findCustomElementPropByAttribute, getCustomElementAttributeName, getCustomElementObservedAttributes, isWithinRuntimeDomMove, reflectCustomElementProperty } from "@zeus-js/runtime-dom";
|
|
7
7
|
//#region packages/web-c/web-c-runtime/src/form-callbacks.ts
|
|
8
8
|
function invokeFormCallback(hostRef, callback) {
|
|
9
9
|
switch (callback.type) {
|
|
@@ -37,10 +37,14 @@ function registerHost(host, meta) {
|
|
|
37
37
|
connected: false,
|
|
38
38
|
loaded: false,
|
|
39
39
|
values: /* @__PURE__ */ new Map(),
|
|
40
|
+
propDefinitions: [...meta.props],
|
|
40
41
|
attributeProps: /* @__PURE__ */ new Set(),
|
|
41
42
|
reflectingAttrs: /* @__PURE__ */ new Set(),
|
|
43
|
+
preUpgradeAttributes: /* @__PURE__ */ new Map(),
|
|
44
|
+
pendingAttributes: /* @__PURE__ */ new Map(),
|
|
42
45
|
pendingFormCallbacks: [],
|
|
43
|
-
readyWaiters: []
|
|
46
|
+
readyWaiters: [],
|
|
47
|
+
exposedMethods: Object.create(null)
|
|
44
48
|
};
|
|
45
49
|
hostRefs.set(host, hostRef);
|
|
46
50
|
return hostRef;
|
|
@@ -69,10 +73,12 @@ function installPropertyAccessors(proto, props) {
|
|
|
69
73
|
if (Object.getOwnPropertyDescriptor(proto, prop.name)) continue;
|
|
70
74
|
Object.defineProperty(proto, prop.name, {
|
|
71
75
|
get() {
|
|
72
|
-
|
|
76
|
+
const hostRef = requireHostRef(this);
|
|
77
|
+
return getPropValue(hostRef, findProp(hostRef, prop.name));
|
|
73
78
|
},
|
|
74
79
|
set(value) {
|
|
75
|
-
|
|
80
|
+
const hostRef = requireHostRef(this);
|
|
81
|
+
setPropValue(hostRef, findProp(hostRef, prop.name), value);
|
|
76
82
|
},
|
|
77
83
|
configurable: true,
|
|
78
84
|
enumerable: true
|
|
@@ -85,36 +91,56 @@ function getPropValue(hostRef, prop) {
|
|
|
85
91
|
}
|
|
86
92
|
function setPropValue(hostRef, prop, value) {
|
|
87
93
|
const oldValue = getPropValue(hostRef, prop);
|
|
88
|
-
if (Object.is(oldValue, value)) return;
|
|
89
94
|
hostRef.values.set(prop.name, value);
|
|
90
95
|
hostRef.attributeProps.delete(prop.name);
|
|
96
|
+
hostRef.pendingAttributes.delete(prop.name);
|
|
91
97
|
if (prop.reflect) reflectCustomElementProperty(hostRef.host, prop, value, hostRef.reflectingAttrs);
|
|
92
|
-
if (hostRef.loaded) {
|
|
98
|
+
if (hostRef.loaded && !Object.is(oldValue, value)) {
|
|
93
99
|
var _hostRef$instance, _hostRef$instance$pro;
|
|
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,
|
|
100
|
+
(_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, {
|
|
101
|
+
name: prop.name,
|
|
102
|
+
value,
|
|
103
|
+
source: "property"
|
|
104
|
+
});
|
|
95
105
|
}
|
|
96
106
|
}
|
|
97
|
-
function syncAttributeToProperty(hostRef, attrName,
|
|
107
|
+
function syncAttributeToProperty(hostRef, attrName, oldValue, newValue) {
|
|
98
108
|
const normalizedAttrName = normalizeAttrName(attrName);
|
|
99
109
|
if (hostRef.reflectingAttrs.has(normalizedAttrName)) return;
|
|
100
|
-
const
|
|
110
|
+
const initialValue = hostRef.preUpgradeAttributes.get(normalizedAttrName);
|
|
111
|
+
hostRef.preUpgradeAttributes.delete(normalizedAttrName);
|
|
112
|
+
if (oldValue === null && newValue === initialValue) return;
|
|
113
|
+
const prop = findCustomElementPropByAttribute(hostRef.propDefinitions, normalizedAttrName);
|
|
101
114
|
if (!prop) return;
|
|
115
|
+
hostRef.attributeProps.add(prop.name);
|
|
116
|
+
if (prop.deserialize === true) {
|
|
117
|
+
hostRef.pendingAttributes.set(prop.name, newValue);
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
102
120
|
const oldPropValue = getPropValue(hostRef, prop);
|
|
103
121
|
const newPropValue = coerceCustomElementAttribute(prop, newValue);
|
|
104
|
-
if (Object.is(oldPropValue, newPropValue)) return;
|
|
105
122
|
hostRef.values.set(prop.name, newPropValue);
|
|
106
|
-
hostRef.
|
|
107
|
-
if (hostRef.loaded) {
|
|
123
|
+
if (hostRef.loaded && !Object.is(oldPropValue, newPropValue)) {
|
|
108
124
|
var _hostRef$instance2, _hostRef$instance2$pr;
|
|
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,
|
|
125
|
+
(_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, {
|
|
126
|
+
name: prop.name,
|
|
127
|
+
value: newPropValue,
|
|
128
|
+
source: "attribute",
|
|
129
|
+
rawAttributeValue: newValue
|
|
130
|
+
});
|
|
110
131
|
}
|
|
111
132
|
}
|
|
112
133
|
function applyInitialValues(hostRef) {
|
|
113
134
|
const host = hostRef.host;
|
|
114
|
-
for (const prop of hostRef.
|
|
135
|
+
for (const prop of hostRef.propDefinitions) {
|
|
115
136
|
if (hostRef.values.has(prop.name)) continue;
|
|
116
137
|
const attrName = getCustomElementAttributeName(prop);
|
|
117
138
|
if (attrName && host.hasAttribute(attrName)) {
|
|
139
|
+
if (prop.deserialize === true) {
|
|
140
|
+
hostRef.pendingAttributes.set(prop.name, host.getAttribute(attrName));
|
|
141
|
+
hostRef.attributeProps.add(prop.name);
|
|
142
|
+
continue;
|
|
143
|
+
}
|
|
118
144
|
hostRef.values.set(prop.name, coerceCustomElementAttribute(prop, host.getAttribute(attrName)));
|
|
119
145
|
hostRef.attributeProps.add(prop.name);
|
|
120
146
|
continue;
|
|
@@ -122,6 +148,20 @@ function applyInitialValues(hostRef) {
|
|
|
122
148
|
if ("default" in prop) hostRef.values.set(prop.name, prop.default);
|
|
123
149
|
}
|
|
124
150
|
}
|
|
151
|
+
/** Replace deferred codec markers with the implementation's real schema. */
|
|
152
|
+
function resolveHostProperties(hostRef, definitions) {
|
|
153
|
+
for (const previous of hostRef.propDefinitions) {
|
|
154
|
+
if (!hostRef.pendingAttributes.has(previous.name)) continue;
|
|
155
|
+
const definition = definitions.find((prop) => prop.name === previous.name);
|
|
156
|
+
const attrName = definition && getCustomElementAttributeName(definition);
|
|
157
|
+
if (definition && attrName) hostRef.values.set(previous.name, coerceCustomElementAttribute(definition, hostRef.pendingAttributes.get(previous.name)));
|
|
158
|
+
}
|
|
159
|
+
hostRef.propDefinitions = definitions;
|
|
160
|
+
hostRef.pendingAttributes.clear();
|
|
161
|
+
}
|
|
162
|
+
function findProp(hostRef, name) {
|
|
163
|
+
return hostRef.propDefinitions.find((prop) => prop.name === name);
|
|
164
|
+
}
|
|
125
165
|
function getObservedAttributes(props) {
|
|
126
166
|
return getCustomElementObservedAttributes(props);
|
|
127
167
|
}
|
|
@@ -139,6 +179,9 @@ function upgradePreDefinedProperties(host, hostRef) {
|
|
|
139
179
|
const descriptor = Object.getOwnPropertyDescriptor(target, prop.name);
|
|
140
180
|
if ((descriptor === null || descriptor === void 0 ? void 0 : descriptor.configurable) === false) continue;
|
|
141
181
|
const value = target[prop.name];
|
|
182
|
+
const attrName = getCustomElementAttributeName(prop);
|
|
183
|
+
const attrValue = attrName ? host.getAttribute(attrName) : null;
|
|
184
|
+
if (attrName && attrValue !== null) hostRef.preUpgradeAttributes.set(attrName, attrValue);
|
|
142
185
|
delete target[prop.name];
|
|
143
186
|
setPropValue(hostRef, prop, value);
|
|
144
187
|
}
|
|
@@ -177,6 +220,7 @@ function _asyncToGenerator(n) {
|
|
|
177
220
|
const moduleCache = /* @__PURE__ */ new WeakMap();
|
|
178
221
|
function waitForComponentReady(hostRef) {
|
|
179
222
|
if (hostRef.loaded) return Promise.resolve(hostRef.host);
|
|
223
|
+
if (hostRef.readinessError) return Promise.reject(hostRef.readinessError);
|
|
180
224
|
return new Promise((resolve, reject) => {
|
|
181
225
|
hostRef.readyWaiters.push({
|
|
182
226
|
resolve,
|
|
@@ -184,6 +228,11 @@ function waitForComponentReady(hostRef) {
|
|
|
184
228
|
});
|
|
185
229
|
});
|
|
186
230
|
}
|
|
231
|
+
function rejectComponentReady(hostRef, error) {
|
|
232
|
+
hostRef.readinessError = error;
|
|
233
|
+
for (const name of Object.keys(hostRef.exposedMethods)) delete hostRef.exposedMethods[name];
|
|
234
|
+
rejectReadyWaiters(hostRef, error);
|
|
235
|
+
}
|
|
187
236
|
function initializeComponent(_x) {
|
|
188
237
|
return _initializeComponent.apply(this, arguments);
|
|
189
238
|
}
|
|
@@ -197,6 +246,7 @@ function _initializeComponent() {
|
|
|
197
246
|
}
|
|
198
247
|
if (hostRef.loading) {
|
|
199
248
|
yield hostRef.loading;
|
|
249
|
+
if (hostRef.connected && !hostRef.loaded) yield initializeComponent(hostRef);
|
|
200
250
|
return;
|
|
201
251
|
}
|
|
202
252
|
const loading = doInitializeComponent(hostRef);
|
|
@@ -204,7 +254,7 @@ function _initializeComponent() {
|
|
|
204
254
|
try {
|
|
205
255
|
yield loading;
|
|
206
256
|
} catch (error) {
|
|
207
|
-
|
|
257
|
+
rejectComponentReady(hostRef, error instanceof Error ? error : new Error(String(error)));
|
|
208
258
|
throw error;
|
|
209
259
|
} finally {
|
|
210
260
|
if (hostRef.loading === loading) hostRef.loading = void 0;
|
|
@@ -309,16 +359,21 @@ function createLazyElementClass(meta) {
|
|
|
309
359
|
connectedCallback() {
|
|
310
360
|
const hostRef = requireHostRef(this);
|
|
311
361
|
hostRef.connected = true;
|
|
362
|
+
hostRef.readinessError = void 0;
|
|
312
363
|
initializeComponent(hostRef).catch((error) => {
|
|
313
364
|
reportInitializationError(meta.tagName, error);
|
|
314
365
|
});
|
|
315
366
|
}
|
|
316
367
|
disconnectedCallback() {
|
|
368
|
+
if (isWithinRuntimeDomMove(this)) return;
|
|
317
369
|
const hostRef = requireHostRef(this);
|
|
318
370
|
hostRef.connected = false;
|
|
319
|
-
if (hostRef.loaded) {
|
|
371
|
+
if (!hostRef.loaded) rejectComponentReady(hostRef, /* @__PURE__ */ new Error(`[ZEUS_WC_DISCONNECTED_BEFORE_READY] <${meta.tagName}> disconnected before initialization completed.`));
|
|
372
|
+
if (hostRef.loaded) try {
|
|
320
373
|
var _hostRef$instance, _hostRef$instance$dis;
|
|
321
374
|
(_hostRef$instance = hostRef.instance) === null || _hostRef$instance === void 0 || (_hostRef$instance$dis = _hostRef$instance.disconnected) === null || _hostRef$instance$dis === void 0 || _hostRef$instance$dis.call(_hostRef$instance);
|
|
375
|
+
} finally {
|
|
376
|
+
for (const name of Object.keys(hostRef.exposedMethods)) delete hostRef.exposedMethods[name];
|
|
322
377
|
}
|
|
323
378
|
}
|
|
324
379
|
attributeChangedCallback(name, oldValue, newValue) {
|
|
@@ -378,7 +433,8 @@ function installMethodProxies(proto, methods) {
|
|
|
378
433
|
const args = Array.prototype.slice.call(arguments);
|
|
379
434
|
const hostRef = requireHostRef(host);
|
|
380
435
|
return waitForComponentReady(hostRef).then((readyHost) => {
|
|
381
|
-
|
|
436
|
+
if (!hostRef.connected) throw new Error(`[ZEUS_WC_DISCONNECTED_BEFORE_READY] <${hostRef.meta.tagName}> is disconnected.`);
|
|
437
|
+
const method = hostRef.exposedMethods[name];
|
|
382
438
|
if (typeof method !== "function") throw new Error(`[zeus:web-c] Method "${name}" is not exposed on <${hostRef.meta.tagName}>.`);
|
|
383
439
|
return method.apply(readyHost, args);
|
|
384
440
|
});
|
|
@@ -388,15 +444,21 @@ function installMethodProxies(proto, methods) {
|
|
|
388
444
|
}
|
|
389
445
|
//#endregion
|
|
390
446
|
//#region packages/web-c/web-c-runtime/src/bootstrapLazy.ts
|
|
447
|
+
const definitions = /* @__PURE__ */ new WeakMap();
|
|
391
448
|
function bootstrapLazy(components, options = {}) {
|
|
392
449
|
var _options$registry;
|
|
393
450
|
const registry = (_options$registry = options.registry) !== null && _options$registry !== void 0 ? _options$registry : typeof customElements === "undefined" ? void 0 : customElements;
|
|
394
451
|
if (!registry) return;
|
|
395
452
|
for (const meta of components) {
|
|
396
|
-
|
|
453
|
+
const existing = registry.get(meta.tagName);
|
|
454
|
+
if (existing) {
|
|
455
|
+
if (definitions.get(existing) === meta) continue;
|
|
456
|
+
throw new Error(`[ZEUS_WC_DUPLICATE_TAG] <${meta.tagName}> is already registered with a different definition.`);
|
|
457
|
+
}
|
|
397
458
|
const LazyElement = createLazyElementClass(meta);
|
|
398
459
|
registry.define(meta.tagName, LazyElement);
|
|
460
|
+
definitions.set(LazyElement, meta);
|
|
399
461
|
}
|
|
400
462
|
}
|
|
401
463
|
//#endregion
|
|
402
|
-
export { bootstrapLazy, createLazyElementClass };
|
|
464
|
+
export { bootstrapLazy, createLazyElementClass, resolveHostProperties };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zeus-js/web-c-runtime",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.1.1-beta.
|
|
4
|
+
"version": "0.1.1-beta.14",
|
|
5
5
|
"description": "Zeus Web-C lazy-loading runtime",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"repository": {
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"dist"
|
|
27
27
|
],
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@zeus-js/runtime-dom": "0.1.1-beta.
|
|
29
|
+
"@zeus-js/runtime-dom": "0.1.1-beta.14"
|
|
30
30
|
},
|
|
31
31
|
"author": "Baicie",
|
|
32
32
|
"buildOptions": {
|