@servlyadmin/runtime-core 0.1.0 → 0.1.2
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/chunk-CIUQK4GA.js +182 -0
- package/dist/index.cjs +637 -149
- package/dist/index.d.cts +198 -5
- package/dist/index.d.ts +198 -5
- package/dist/index.js +441 -149
- package/dist/registry-GCCVK65D.js +16 -0
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -3,6 +3,9 @@ var __defProp = Object.defineProperty;
|
|
|
3
3
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
4
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
5
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __esm = (fn, res) => function __init() {
|
|
7
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
8
|
+
};
|
|
6
9
|
var __export = (target, all) => {
|
|
7
10
|
for (var name in all)
|
|
8
11
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
@@ -17,27 +20,224 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
17
20
|
};
|
|
18
21
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
22
|
|
|
23
|
+
// src/registry.ts
|
|
24
|
+
var registry_exports = {};
|
|
25
|
+
__export(registry_exports, {
|
|
26
|
+
buildRegistryFromBundle: () => buildRegistryFromBundle,
|
|
27
|
+
collectAllDependencies: () => collectAllDependencies,
|
|
28
|
+
createRegistry: () => createRegistry,
|
|
29
|
+
detectCircularDependencies: () => detectCircularDependencies,
|
|
30
|
+
extractDependencies: () => extractDependencies,
|
|
31
|
+
extractDependenciesFromCode: () => extractDependenciesFromCode
|
|
32
|
+
});
|
|
33
|
+
function createRegistry() {
|
|
34
|
+
const components = /* @__PURE__ */ new Map();
|
|
35
|
+
return {
|
|
36
|
+
get(id, version) {
|
|
37
|
+
if (version) {
|
|
38
|
+
const key = `${id}@${version}`;
|
|
39
|
+
if (components.has(key)) {
|
|
40
|
+
return components.get(key);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
for (const [key, component] of components) {
|
|
44
|
+
if (key.startsWith(`${id}@`)) {
|
|
45
|
+
return component;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return components.get(id);
|
|
49
|
+
},
|
|
50
|
+
has(id, version) {
|
|
51
|
+
if (version) {
|
|
52
|
+
return components.has(`${id}@${version}`);
|
|
53
|
+
}
|
|
54
|
+
for (const key of components.keys()) {
|
|
55
|
+
if (key.startsWith(`${id}@`) || key === id) {
|
|
56
|
+
return true;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return false;
|
|
60
|
+
},
|
|
61
|
+
set(id, version, component) {
|
|
62
|
+
components.set(`${id}@${version}`, component);
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
function buildRegistryFromBundle(data) {
|
|
67
|
+
const registry = createRegistry();
|
|
68
|
+
registry.set(data.id, data.version, {
|
|
69
|
+
layout: data.layout,
|
|
70
|
+
propsInterface: data.propsInterface
|
|
71
|
+
});
|
|
72
|
+
if (data.bundle) {
|
|
73
|
+
for (const [key, component] of Object.entries(data.bundle)) {
|
|
74
|
+
const [id, version] = key.split("@");
|
|
75
|
+
if (id && version) {
|
|
76
|
+
registry.set(id, version, component);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
return registry;
|
|
81
|
+
}
|
|
82
|
+
function extractDependencies(elements) {
|
|
83
|
+
const dependencies = [];
|
|
84
|
+
for (const element of elements) {
|
|
85
|
+
const config = element.configuration;
|
|
86
|
+
if (!config) continue;
|
|
87
|
+
if (config.componentViewRef) {
|
|
88
|
+
dependencies.push({
|
|
89
|
+
id: config.componentViewRef,
|
|
90
|
+
version: config.componentViewVersion,
|
|
91
|
+
type: "viewRef",
|
|
92
|
+
elementId: element.i
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
if (config.blueprint) {
|
|
96
|
+
dependencies.push({
|
|
97
|
+
id: config.blueprint,
|
|
98
|
+
version: config.blueprintVersion,
|
|
99
|
+
type: "blueprint",
|
|
100
|
+
elementId: element.i
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
return dependencies;
|
|
105
|
+
}
|
|
106
|
+
function extractDependenciesFromCode(code) {
|
|
107
|
+
const dependencies = [];
|
|
108
|
+
const pattern = /renderDynamicList\s*\(\s*\{[^}]*blueprint\s*:\s*["']([^"']+)["']/g;
|
|
109
|
+
let match;
|
|
110
|
+
while ((match = pattern.exec(code)) !== null) {
|
|
111
|
+
dependencies.push({
|
|
112
|
+
id: match[1],
|
|
113
|
+
type: "blueprint"
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
return dependencies;
|
|
117
|
+
}
|
|
118
|
+
async function collectAllDependencies(rootId, rootVersion, fetchComponent2, maxDepth = 10) {
|
|
119
|
+
const manifest = {};
|
|
120
|
+
const visited = /* @__PURE__ */ new Set();
|
|
121
|
+
async function collect(id, version, via, depth) {
|
|
122
|
+
if (depth > maxDepth) {
|
|
123
|
+
console.warn(`Max dependency depth (${maxDepth}) reached for ${id}`);
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
const key = `${id}@${version || "latest"}`;
|
|
127
|
+
if (visited.has(key)) {
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
visited.add(key);
|
|
131
|
+
try {
|
|
132
|
+
const component = await fetchComponent2(id, version);
|
|
133
|
+
if (!component) {
|
|
134
|
+
console.warn(`Dependency not found: ${id}@${version || "latest"}`);
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
manifest[id] = {
|
|
138
|
+
version: version || "latest",
|
|
139
|
+
resolved: component.version,
|
|
140
|
+
type: via ? "viewRef" : "viewRef",
|
|
141
|
+
// Will be set by caller
|
|
142
|
+
via
|
|
143
|
+
};
|
|
144
|
+
const nestedDeps = extractDependencies(component.layout);
|
|
145
|
+
for (const dep of nestedDeps) {
|
|
146
|
+
await collect(dep.id, dep.version, id, depth + 1);
|
|
147
|
+
}
|
|
148
|
+
} catch (error) {
|
|
149
|
+
console.error(`Failed to fetch dependency ${id}:`, error);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
const rootComponent = await fetchComponent2(rootId, rootVersion);
|
|
153
|
+
if (rootComponent) {
|
|
154
|
+
const rootDeps = extractDependencies(rootComponent.layout);
|
|
155
|
+
for (const dep of rootDeps) {
|
|
156
|
+
manifest[dep.id] = {
|
|
157
|
+
version: dep.version || "latest",
|
|
158
|
+
resolved: "",
|
|
159
|
+
// Will be filled when fetched
|
|
160
|
+
type: dep.type
|
|
161
|
+
};
|
|
162
|
+
await collect(dep.id, dep.version, void 0, 1);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
return manifest;
|
|
166
|
+
}
|
|
167
|
+
function detectCircularDependencies(manifest) {
|
|
168
|
+
const graph = /* @__PURE__ */ new Map();
|
|
169
|
+
for (const [id, entry] of Object.entries(manifest)) {
|
|
170
|
+
if (entry.via) {
|
|
171
|
+
const deps = graph.get(entry.via) || [];
|
|
172
|
+
deps.push(id);
|
|
173
|
+
graph.set(entry.via, deps);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
const visited = /* @__PURE__ */ new Set();
|
|
177
|
+
const stack = /* @__PURE__ */ new Set();
|
|
178
|
+
const path = [];
|
|
179
|
+
function dfs(node) {
|
|
180
|
+
if (stack.has(node)) {
|
|
181
|
+
const cycleStart = path.indexOf(node);
|
|
182
|
+
return [...path.slice(cycleStart), node];
|
|
183
|
+
}
|
|
184
|
+
if (visited.has(node)) {
|
|
185
|
+
return null;
|
|
186
|
+
}
|
|
187
|
+
visited.add(node);
|
|
188
|
+
stack.add(node);
|
|
189
|
+
path.push(node);
|
|
190
|
+
const neighbors = graph.get(node) || [];
|
|
191
|
+
for (const neighbor of neighbors) {
|
|
192
|
+
const cycle = dfs(neighbor);
|
|
193
|
+
if (cycle) return cycle;
|
|
194
|
+
}
|
|
195
|
+
stack.delete(node);
|
|
196
|
+
path.pop();
|
|
197
|
+
return null;
|
|
198
|
+
}
|
|
199
|
+
for (const node of graph.keys()) {
|
|
200
|
+
const cycle = dfs(node);
|
|
201
|
+
if (cycle) return cycle;
|
|
202
|
+
}
|
|
203
|
+
return null;
|
|
204
|
+
}
|
|
205
|
+
var init_registry = __esm({
|
|
206
|
+
"src/registry.ts"() {
|
|
207
|
+
"use strict";
|
|
208
|
+
}
|
|
209
|
+
});
|
|
210
|
+
|
|
20
211
|
// src/index.ts
|
|
21
212
|
var index_exports = {};
|
|
22
213
|
__export(index_exports, {
|
|
23
214
|
DEFAULT_CACHE_CONFIG: () => DEFAULT_CACHE_CONFIG,
|
|
24
215
|
DEFAULT_RETRY_CONFIG: () => DEFAULT_RETRY_CONFIG,
|
|
25
216
|
applyStyles: () => applyStyles,
|
|
217
|
+
batchFetchComponents: () => batchFetchComponents,
|
|
26
218
|
buildClassName: () => buildClassName,
|
|
27
219
|
buildElementStyles: () => buildElementStyles,
|
|
220
|
+
buildRegistryFromBundle: () => buildRegistryFromBundle,
|
|
28
221
|
bumpVersion: () => bumpVersion,
|
|
29
222
|
camelToKebab: () => camelToKebab,
|
|
30
223
|
clearAllCaches: () => clearAllCaches,
|
|
31
224
|
clearLocalStorageCache: () => clearLocalStorageCache,
|
|
32
225
|
clearMemoryCache: () => clearMemoryCache,
|
|
33
226
|
clearStyles: () => clearStyles,
|
|
227
|
+
collectAllDependencies: () => collectAllDependencies,
|
|
34
228
|
compareVersions: () => compareVersions,
|
|
229
|
+
createRegistry: () => createRegistry,
|
|
230
|
+
detectCircularDependencies: () => detectCircularDependencies,
|
|
35
231
|
extractBindingKeys: () => extractBindingKeys,
|
|
232
|
+
extractDependencies: () => extractDependencies,
|
|
233
|
+
extractDependenciesFromCode: () => extractDependenciesFromCode,
|
|
36
234
|
fetchComponent: () => fetchComponent,
|
|
235
|
+
fetchComponentWithDependencies: () => fetchComponentWithDependencies,
|
|
37
236
|
formatStyleValue: () => formatStyleValue,
|
|
38
237
|
formatVersion: () => formatVersion,
|
|
39
238
|
generateTestCases: () => generateTestCases,
|
|
40
239
|
getCacheKey: () => getCacheKey,
|
|
240
|
+
getDependencyTree: () => getDependencyTree,
|
|
41
241
|
getFromCache: () => getFromCache,
|
|
42
242
|
getMemoryCacheSize: () => getMemoryCacheSize,
|
|
43
243
|
getRegistryUrl: () => getRegistryUrl,
|
|
@@ -49,6 +249,7 @@ __export(index_exports, {
|
|
|
49
249
|
prefetchComponents: () => prefetchComponents,
|
|
50
250
|
processStyles: () => processStyles,
|
|
51
251
|
render: () => render,
|
|
252
|
+
renderDynamicList: () => renderDynamicList,
|
|
52
253
|
resolveBindingPath: () => resolveBindingPath,
|
|
53
254
|
resolveTemplate: () => resolveTemplate,
|
|
54
255
|
resolveTemplateValue: () => resolveTemplateValue,
|
|
@@ -361,17 +562,39 @@ function applyStyles(element, styles) {
|
|
|
361
562
|
}
|
|
362
563
|
}
|
|
363
564
|
}
|
|
565
|
+
var CANVAS_ONLY_STYLES = /* @__PURE__ */ new Set([
|
|
566
|
+
"transform",
|
|
567
|
+
"--translate-x",
|
|
568
|
+
"--translate-y",
|
|
569
|
+
"--width",
|
|
570
|
+
"--height",
|
|
571
|
+
"z-index",
|
|
572
|
+
"zIndex"
|
|
573
|
+
]);
|
|
574
|
+
function filterCanvasStyles(style) {
|
|
575
|
+
const filtered = {};
|
|
576
|
+
for (const [key, value] of Object.entries(style)) {
|
|
577
|
+
if (CANVAS_ONLY_STYLES.has(key)) {
|
|
578
|
+
continue;
|
|
579
|
+
}
|
|
580
|
+
if (key === "transform" && typeof value === "string" && value.includes("translate(")) {
|
|
581
|
+
continue;
|
|
582
|
+
}
|
|
583
|
+
filtered[key] = value;
|
|
584
|
+
}
|
|
585
|
+
return filtered;
|
|
586
|
+
}
|
|
364
587
|
function buildElementStyles(element, context) {
|
|
365
588
|
const config = element.configuration || {};
|
|
366
589
|
const combined = {};
|
|
367
590
|
if (element.style) {
|
|
368
|
-
Object.assign(combined, element.style);
|
|
591
|
+
Object.assign(combined, filterCanvasStyles(element.style));
|
|
369
592
|
}
|
|
370
593
|
if (config.style) {
|
|
371
|
-
Object.assign(combined, config.style);
|
|
594
|
+
Object.assign(combined, filterCanvasStyles(config.style));
|
|
372
595
|
}
|
|
373
596
|
if (config.cssVariables) {
|
|
374
|
-
Object.assign(combined, config.cssVariables);
|
|
597
|
+
Object.assign(combined, filterCanvasStyles(config.cssVariables));
|
|
375
598
|
}
|
|
376
599
|
return processStyles(combined, context);
|
|
377
600
|
}
|
|
@@ -594,18 +817,84 @@ function createElement(element, context, eventHandlers) {
|
|
|
594
817
|
attachEventHandlers(domElement, element.i, eventHandlers, elementState);
|
|
595
818
|
return elementState;
|
|
596
819
|
}
|
|
597
|
-
|
|
820
|
+
var globalRenderingStack = /* @__PURE__ */ new Set();
|
|
821
|
+
function renderComponentRef(element, container, context, state) {
|
|
822
|
+
const config = element.configuration;
|
|
823
|
+
if (!config?.componentViewRef) return void 0;
|
|
824
|
+
const refId = config.componentViewRef;
|
|
825
|
+
const refVersion = config.componentViewVersion;
|
|
826
|
+
if (globalRenderingStack.has(refId)) {
|
|
827
|
+
console.warn(`Circular dependency detected: ${refId} is already being rendered`);
|
|
828
|
+
const placeholder = document.createElement("div");
|
|
829
|
+
placeholder.setAttribute("data-servly-circular", refId);
|
|
830
|
+
placeholder.textContent = `[Circular: ${refId}]`;
|
|
831
|
+
container.appendChild(placeholder);
|
|
832
|
+
return void 0;
|
|
833
|
+
}
|
|
834
|
+
let component;
|
|
835
|
+
if (state.componentRegistry) {
|
|
836
|
+
component = state.componentRegistry.get(refId, refVersion);
|
|
837
|
+
}
|
|
838
|
+
if (!component) {
|
|
839
|
+
const placeholder = document.createElement("div");
|
|
840
|
+
placeholder.setAttribute("data-servly-loading", refId);
|
|
841
|
+
placeholder.className = "servly-loading";
|
|
842
|
+
container.appendChild(placeholder);
|
|
843
|
+
if (state.onDependencyNeeded) {
|
|
844
|
+
state.onDependencyNeeded(refId, refVersion).then((loaded) => {
|
|
845
|
+
if (loaded && state.componentRegistry) {
|
|
846
|
+
state.componentRegistry.set(refId, refVersion || "latest", loaded);
|
|
847
|
+
container.innerHTML = "";
|
|
848
|
+
renderComponentRef(element, container, context, state);
|
|
849
|
+
}
|
|
850
|
+
}).catch((err) => {
|
|
851
|
+
console.error(`Failed to load dependency ${refId}:`, err);
|
|
852
|
+
placeholder.textContent = `[Failed to load: ${refId}]`;
|
|
853
|
+
placeholder.className = "servly-error";
|
|
854
|
+
});
|
|
855
|
+
}
|
|
856
|
+
return void 0;
|
|
857
|
+
}
|
|
858
|
+
const refProps = config.componentViewProps ? resolveTemplatesDeep(config.componentViewProps, context) : {};
|
|
859
|
+
globalRenderingStack.add(refId);
|
|
860
|
+
const refContext = {
|
|
861
|
+
props: refProps,
|
|
862
|
+
state: context.state,
|
|
863
|
+
context: context.context
|
|
864
|
+
};
|
|
865
|
+
try {
|
|
866
|
+
const result = render({
|
|
867
|
+
container,
|
|
868
|
+
elements: component.layout,
|
|
869
|
+
context: refContext,
|
|
870
|
+
componentRegistry: state.componentRegistry,
|
|
871
|
+
onDependencyNeeded: state.onDependencyNeeded
|
|
872
|
+
});
|
|
873
|
+
return result;
|
|
874
|
+
} finally {
|
|
875
|
+
globalRenderingStack.delete(refId);
|
|
876
|
+
}
|
|
877
|
+
}
|
|
878
|
+
function renderElement(element, tree, context, eventHandlers, elementStates, state) {
|
|
598
879
|
const elementState = createElement(element, context, eventHandlers);
|
|
599
880
|
elementStates.set(element.i, elementState);
|
|
881
|
+
const config = element.configuration;
|
|
882
|
+
if (config?.componentViewRef) {
|
|
883
|
+
const nestedResult = renderComponentRef(element, elementState.domElement, context, state);
|
|
884
|
+
if (nestedResult) {
|
|
885
|
+
elementState.nestedRender = nestedResult;
|
|
886
|
+
}
|
|
887
|
+
return elementState.domElement;
|
|
888
|
+
}
|
|
600
889
|
const children = tree.get(element.i) || [];
|
|
601
890
|
for (const child of children) {
|
|
602
|
-
const childElement = renderElement(child, tree, context, eventHandlers, elementStates);
|
|
891
|
+
const childElement = renderElement(child, tree, context, eventHandlers, elementStates, state);
|
|
603
892
|
elementState.domElement.appendChild(childElement);
|
|
604
893
|
}
|
|
605
894
|
return elementState.domElement;
|
|
606
895
|
}
|
|
607
896
|
function render(options) {
|
|
608
|
-
const { container, elements, context, eventHandlers } = options;
|
|
897
|
+
const { container, elements, context, eventHandlers, componentRegistry, onDependencyNeeded } = options;
|
|
609
898
|
const tree = buildTree(elements);
|
|
610
899
|
const rootElements = elements.filter((el) => !el.parent || el.parent === null);
|
|
611
900
|
const state = {
|
|
@@ -614,7 +903,10 @@ function render(options) {
|
|
|
614
903
|
context,
|
|
615
904
|
eventHandlers,
|
|
616
905
|
elementStates: /* @__PURE__ */ new Map(),
|
|
617
|
-
rootElement: null
|
|
906
|
+
rootElement: null,
|
|
907
|
+
componentRegistry,
|
|
908
|
+
onDependencyNeeded,
|
|
909
|
+
renderingStack: /* @__PURE__ */ new Set()
|
|
618
910
|
};
|
|
619
911
|
container.innerHTML = "";
|
|
620
912
|
if (rootElements.length === 0) {
|
|
@@ -630,14 +922,15 @@ function render(options) {
|
|
|
630
922
|
tree,
|
|
631
923
|
context,
|
|
632
924
|
eventHandlers,
|
|
633
|
-
state.elementStates
|
|
925
|
+
state.elementStates,
|
|
926
|
+
state
|
|
634
927
|
);
|
|
635
928
|
container.appendChild(state.rootElement);
|
|
636
929
|
} else {
|
|
637
930
|
const wrapper = document.createElement("div");
|
|
638
931
|
wrapper.setAttribute("data-servly-wrapper", "true");
|
|
639
932
|
for (const root of rootElements) {
|
|
640
|
-
const rootElement = renderElement(root, tree, context, eventHandlers, state.elementStates);
|
|
933
|
+
const rootElement = renderElement(root, tree, context, eventHandlers, state.elementStates, state);
|
|
641
934
|
wrapper.appendChild(rootElement);
|
|
642
935
|
}
|
|
643
936
|
state.rootElement = wrapper;
|
|
@@ -675,6 +968,9 @@ function update(state, newContext) {
|
|
|
675
968
|
function destroy(state) {
|
|
676
969
|
for (const elementState of state.elementStates.values()) {
|
|
677
970
|
detachEventHandlers(elementState);
|
|
971
|
+
if (elementState.nestedRender) {
|
|
972
|
+
elementState.nestedRender.destroy();
|
|
973
|
+
}
|
|
678
974
|
}
|
|
679
975
|
state.elementStates.clear();
|
|
680
976
|
if (state.rootElement && state.rootElement.parentNode) {
|
|
@@ -682,6 +978,66 @@ function destroy(state) {
|
|
|
682
978
|
}
|
|
683
979
|
state.rootElement = null;
|
|
684
980
|
}
|
|
981
|
+
function renderDynamicList(options) {
|
|
982
|
+
const {
|
|
983
|
+
targetContainer,
|
|
984
|
+
blueprint,
|
|
985
|
+
blueprintVersion,
|
|
986
|
+
data,
|
|
987
|
+
renderType = "renderInto",
|
|
988
|
+
itemKey = "item",
|
|
989
|
+
indexKey = "index",
|
|
990
|
+
componentRegistry,
|
|
991
|
+
context = { props: {} }
|
|
992
|
+
} = options;
|
|
993
|
+
let container;
|
|
994
|
+
if (typeof targetContainer === "string") {
|
|
995
|
+
container = document.querySelector(targetContainer);
|
|
996
|
+
} else {
|
|
997
|
+
container = targetContainer;
|
|
998
|
+
}
|
|
999
|
+
if (!container) {
|
|
1000
|
+
console.error(`renderDynamicList: Container not found: ${targetContainer}`);
|
|
1001
|
+
return [];
|
|
1002
|
+
}
|
|
1003
|
+
const blueprintComponent = componentRegistry.get(blueprint, blueprintVersion);
|
|
1004
|
+
if (!blueprintComponent) {
|
|
1005
|
+
console.error(`renderDynamicList: Blueprint not found: ${blueprint}`);
|
|
1006
|
+
return [];
|
|
1007
|
+
}
|
|
1008
|
+
if (renderType === "renderInto") {
|
|
1009
|
+
container.innerHTML = "";
|
|
1010
|
+
}
|
|
1011
|
+
const results = [];
|
|
1012
|
+
const fragment = document.createDocumentFragment();
|
|
1013
|
+
data.forEach((item, index) => {
|
|
1014
|
+
const itemContainer = document.createElement("div");
|
|
1015
|
+
itemContainer.setAttribute("data-servly-list-item", String(index));
|
|
1016
|
+
const itemContext = {
|
|
1017
|
+
props: {
|
|
1018
|
+
...context.props,
|
|
1019
|
+
[itemKey]: item,
|
|
1020
|
+
[indexKey]: index
|
|
1021
|
+
},
|
|
1022
|
+
state: context.state,
|
|
1023
|
+
context: context.context
|
|
1024
|
+
};
|
|
1025
|
+
const result = render({
|
|
1026
|
+
container: itemContainer,
|
|
1027
|
+
elements: blueprintComponent.layout,
|
|
1028
|
+
context: itemContext,
|
|
1029
|
+
componentRegistry
|
|
1030
|
+
});
|
|
1031
|
+
results.push(result);
|
|
1032
|
+
fragment.appendChild(itemContainer);
|
|
1033
|
+
});
|
|
1034
|
+
if (renderType === "prepend") {
|
|
1035
|
+
container.insertBefore(fragment, container.firstChild);
|
|
1036
|
+
} else {
|
|
1037
|
+
container.appendChild(fragment);
|
|
1038
|
+
}
|
|
1039
|
+
return results;
|
|
1040
|
+
}
|
|
685
1041
|
|
|
686
1042
|
// src/cache.ts
|
|
687
1043
|
var DEFAULT_CACHE_CONFIG = {
|
|
@@ -927,126 +1283,15 @@ function invalidateCache(id, version, config = DEFAULT_CACHE_CONFIG) {
|
|
|
927
1283
|
}
|
|
928
1284
|
}
|
|
929
1285
|
|
|
930
|
-
// src/version.ts
|
|
931
|
-
function parseVersion(version) {
|
|
932
|
-
const match = version.match(/^(\d+)\.(\d+)\.(\d+)$/);
|
|
933
|
-
if (!match) return null;
|
|
934
|
-
return {
|
|
935
|
-
major: parseInt(match[1], 10),
|
|
936
|
-
minor: parseInt(match[2], 10),
|
|
937
|
-
patch: parseInt(match[3], 10)
|
|
938
|
-
};
|
|
939
|
-
}
|
|
940
|
-
function compareVersions(a, b) {
|
|
941
|
-
const parsedA = parseVersion(a);
|
|
942
|
-
const parsedB = parseVersion(b);
|
|
943
|
-
if (!parsedA || !parsedB) return 0;
|
|
944
|
-
if (parsedA.major !== parsedB.major) {
|
|
945
|
-
return parsedA.major > parsedB.major ? 1 : -1;
|
|
946
|
-
}
|
|
947
|
-
if (parsedA.minor !== parsedB.minor) {
|
|
948
|
-
return parsedA.minor > parsedB.minor ? 1 : -1;
|
|
949
|
-
}
|
|
950
|
-
if (parsedA.patch !== parsedB.patch) {
|
|
951
|
-
return parsedA.patch > parsedB.patch ? 1 : -1;
|
|
952
|
-
}
|
|
953
|
-
return 0;
|
|
954
|
-
}
|
|
955
|
-
function satisfiesVersion(version, specifier) {
|
|
956
|
-
if (specifier === "latest" || specifier === "*") {
|
|
957
|
-
return true;
|
|
958
|
-
}
|
|
959
|
-
const parsed = parseVersion(version);
|
|
960
|
-
if (!parsed) return false;
|
|
961
|
-
if (/^\d+\.\d+\.\d+$/.test(specifier)) {
|
|
962
|
-
return version === specifier;
|
|
963
|
-
}
|
|
964
|
-
if (specifier.startsWith("^")) {
|
|
965
|
-
const specParsed = parseVersion(specifier.slice(1));
|
|
966
|
-
if (!specParsed) return false;
|
|
967
|
-
if (parsed.major !== specParsed.major) return false;
|
|
968
|
-
if (parsed.major === 0) {
|
|
969
|
-
return parsed.minor === specParsed.minor && parsed.patch >= specParsed.patch;
|
|
970
|
-
}
|
|
971
|
-
return compareVersions(version, specifier.slice(1)) >= 0;
|
|
972
|
-
}
|
|
973
|
-
if (specifier.startsWith("~")) {
|
|
974
|
-
const specParsed = parseVersion(specifier.slice(1));
|
|
975
|
-
if (!specParsed) return false;
|
|
976
|
-
return parsed.major === specParsed.major && parsed.minor === specParsed.minor && parsed.patch >= specParsed.patch;
|
|
977
|
-
}
|
|
978
|
-
if (specifier.startsWith(">=")) {
|
|
979
|
-
return compareVersions(version, specifier.slice(2)) >= 0;
|
|
980
|
-
}
|
|
981
|
-
if (specifier.startsWith(">")) {
|
|
982
|
-
return compareVersions(version, specifier.slice(1)) > 0;
|
|
983
|
-
}
|
|
984
|
-
if (specifier.startsWith("<=")) {
|
|
985
|
-
return compareVersions(version, specifier.slice(2)) <= 0;
|
|
986
|
-
}
|
|
987
|
-
if (specifier.startsWith("<")) {
|
|
988
|
-
return compareVersions(version, specifier.slice(1)) < 0;
|
|
989
|
-
}
|
|
990
|
-
return false;
|
|
991
|
-
}
|
|
992
|
-
function resolveVersion(versions, specifier = "latest") {
|
|
993
|
-
if (versions.length === 0) {
|
|
994
|
-
return null;
|
|
995
|
-
}
|
|
996
|
-
const sorted = [...versions].sort((a, b) => compareVersions(b, a));
|
|
997
|
-
if (specifier === "latest" || specifier === "*") {
|
|
998
|
-
return sorted[0];
|
|
999
|
-
}
|
|
1000
|
-
if (/^\d+\.\d+\.\d+$/.test(specifier)) {
|
|
1001
|
-
return versions.includes(specifier) ? specifier : null;
|
|
1002
|
-
}
|
|
1003
|
-
for (const version of sorted) {
|
|
1004
|
-
if (satisfiesVersion(version, specifier)) {
|
|
1005
|
-
return version;
|
|
1006
|
-
}
|
|
1007
|
-
}
|
|
1008
|
-
return null;
|
|
1009
|
-
}
|
|
1010
|
-
function bumpVersion(currentVersion, bumpType) {
|
|
1011
|
-
const parsed = parseVersion(currentVersion);
|
|
1012
|
-
if (!parsed) return "1.0.0";
|
|
1013
|
-
switch (bumpType) {
|
|
1014
|
-
case "major":
|
|
1015
|
-
return `${parsed.major + 1}.0.0`;
|
|
1016
|
-
case "minor":
|
|
1017
|
-
return `${parsed.major}.${parsed.minor + 1}.0`;
|
|
1018
|
-
case "patch":
|
|
1019
|
-
return `${parsed.major}.${parsed.minor}.${parsed.patch + 1}`;
|
|
1020
|
-
default:
|
|
1021
|
-
return currentVersion;
|
|
1022
|
-
}
|
|
1023
|
-
}
|
|
1024
|
-
function isValidSpecifier(specifier) {
|
|
1025
|
-
if (specifier === "latest" || specifier === "*") {
|
|
1026
|
-
return true;
|
|
1027
|
-
}
|
|
1028
|
-
if (/^\d+\.\d+\.\d+$/.test(specifier)) {
|
|
1029
|
-
return true;
|
|
1030
|
-
}
|
|
1031
|
-
if (/^[\^~><]=?\d+\.\d+\.\d+$/.test(specifier)) {
|
|
1032
|
-
return true;
|
|
1033
|
-
}
|
|
1034
|
-
return false;
|
|
1035
|
-
}
|
|
1036
|
-
function formatVersion(version) {
|
|
1037
|
-
const parsed = parseVersion(version);
|
|
1038
|
-
if (!parsed) return version;
|
|
1039
|
-
return `v${parsed.major}.${parsed.minor}.${parsed.patch}`;
|
|
1040
|
-
}
|
|
1041
|
-
|
|
1042
1286
|
// src/fetcher.ts
|
|
1287
|
+
init_registry();
|
|
1043
1288
|
var DEFAULT_RETRY_CONFIG = {
|
|
1044
1289
|
maxRetries: 3,
|
|
1045
1290
|
initialDelay: 1e3,
|
|
1046
1291
|
maxDelay: 1e4,
|
|
1047
1292
|
backoffMultiplier: 2
|
|
1048
1293
|
};
|
|
1049
|
-
var registryBaseUrl = "/api/
|
|
1294
|
+
var registryBaseUrl = "/api/views/registry";
|
|
1050
1295
|
function setRegistryUrl(url) {
|
|
1051
1296
|
registryBaseUrl = url;
|
|
1052
1297
|
}
|
|
@@ -1080,19 +1325,15 @@ async function resolveVersionFromApi(id, specifier, apiKey) {
|
|
|
1080
1325
|
}
|
|
1081
1326
|
try {
|
|
1082
1327
|
const response = await fetch(
|
|
1083
|
-
`${baseUrl}/${id}/
|
|
1328
|
+
`${baseUrl}/${id}/resolve?specifier=${encodeURIComponent(specifier)}`,
|
|
1084
1329
|
{ headers }
|
|
1085
1330
|
);
|
|
1086
1331
|
if (!response.ok) {
|
|
1087
1332
|
throw new Error(`Failed to resolve version: ${response.statusText}`);
|
|
1088
1333
|
}
|
|
1089
1334
|
const data = await response.json();
|
|
1090
|
-
if (data.success && data.data?.
|
|
1091
|
-
return data.data.
|
|
1092
|
-
}
|
|
1093
|
-
if (data.data?.versions) {
|
|
1094
|
-
const resolved = resolveVersion(data.data.versions, specifier);
|
|
1095
|
-
if (resolved) return resolved;
|
|
1335
|
+
if (data.success && data.data?.resolved) {
|
|
1336
|
+
return data.data.resolved;
|
|
1096
1337
|
}
|
|
1097
1338
|
throw new Error(data.error || "Failed to resolve version");
|
|
1098
1339
|
} catch (error) {
|
|
@@ -1100,7 +1341,7 @@ async function resolveVersionFromApi(id, specifier, apiKey) {
|
|
|
1100
1341
|
return "latest";
|
|
1101
1342
|
}
|
|
1102
1343
|
}
|
|
1103
|
-
async function fetchFromRegistry(id, version, apiKey) {
|
|
1344
|
+
async function fetchFromRegistry(id, version, apiKey, includeBundle) {
|
|
1104
1345
|
const baseUrl = getRegistryUrl();
|
|
1105
1346
|
const headers = {
|
|
1106
1347
|
"Content-Type": "application/json"
|
|
@@ -1108,25 +1349,39 @@ async function fetchFromRegistry(id, version, apiKey) {
|
|
|
1108
1349
|
if (apiKey) {
|
|
1109
1350
|
headers["Authorization"] = `Bearer ${apiKey}`;
|
|
1110
1351
|
}
|
|
1111
|
-
|
|
1352
|
+
let url;
|
|
1353
|
+
if (version && version !== "latest" && /^\d+\.\d+\.\d+/.test(version)) {
|
|
1354
|
+
url = `${baseUrl}/${id}/versions/${version}`;
|
|
1355
|
+
} else if (version && version !== "latest") {
|
|
1356
|
+
url = `${baseUrl}/${id}?version=${encodeURIComponent(version)}`;
|
|
1357
|
+
} else {
|
|
1358
|
+
url = `${baseUrl}/${id}`;
|
|
1359
|
+
}
|
|
1360
|
+
if (includeBundle) {
|
|
1361
|
+
url += (url.includes("?") ? "&" : "?") + "bundle=true";
|
|
1362
|
+
}
|
|
1112
1363
|
const response = await fetch(url, { headers });
|
|
1113
1364
|
if (!response.ok) {
|
|
1114
1365
|
if (response.status === 404) {
|
|
1115
|
-
throw new Error(`
|
|
1366
|
+
throw new Error(`View not found: ${id}@${version}`);
|
|
1116
1367
|
}
|
|
1117
1368
|
if (response.status === 401) {
|
|
1118
1369
|
throw new Error("Unauthorized: Invalid or missing API key");
|
|
1119
1370
|
}
|
|
1120
1371
|
if (response.status === 403) {
|
|
1121
|
-
throw new Error("Forbidden: Access denied to this
|
|
1372
|
+
throw new Error("Forbidden: Access denied to this view");
|
|
1122
1373
|
}
|
|
1123
|
-
throw new Error(`Failed to fetch
|
|
1374
|
+
throw new Error(`Failed to fetch view: ${response.statusText}`);
|
|
1124
1375
|
}
|
|
1125
1376
|
const data = await response.json();
|
|
1126
1377
|
if (!data.success || !data.data) {
|
|
1127
|
-
throw new Error(data.error || "Failed to fetch
|
|
1378
|
+
throw new Error(data.error || "Failed to fetch view data");
|
|
1128
1379
|
}
|
|
1129
|
-
|
|
1380
|
+
const result = data.data;
|
|
1381
|
+
if (result.viewId && !result.id) {
|
|
1382
|
+
result.id = result.viewId;
|
|
1383
|
+
}
|
|
1384
|
+
return result;
|
|
1130
1385
|
}
|
|
1131
1386
|
async function fetchComponent(id, options = {}) {
|
|
1132
1387
|
const {
|
|
@@ -1136,7 +1391,9 @@ async function fetchComponent(id, options = {}) {
|
|
|
1136
1391
|
cacheConfig = DEFAULT_CACHE_CONFIG,
|
|
1137
1392
|
retryConfig = {},
|
|
1138
1393
|
forceRefresh = false,
|
|
1139
|
-
signal
|
|
1394
|
+
signal,
|
|
1395
|
+
bundleStrategy = "eager",
|
|
1396
|
+
includeBundle = true
|
|
1140
1397
|
} = options;
|
|
1141
1398
|
const fullRetryConfig = {
|
|
1142
1399
|
...DEFAULT_RETRY_CONFIG,
|
|
@@ -1145,10 +1402,15 @@ async function fetchComponent(id, options = {}) {
|
|
|
1145
1402
|
if (!forceRefresh) {
|
|
1146
1403
|
const cached = getFromCache(id, version, cacheStrategy, cacheConfig);
|
|
1147
1404
|
if (cached) {
|
|
1405
|
+
let registry;
|
|
1406
|
+
if (cached.bundle) {
|
|
1407
|
+
registry = buildRegistryFromBundle(cached);
|
|
1408
|
+
}
|
|
1148
1409
|
return {
|
|
1149
1410
|
data: cached,
|
|
1150
1411
|
fromCache: true,
|
|
1151
|
-
version: cached.version
|
|
1412
|
+
version: cached.version,
|
|
1413
|
+
registry
|
|
1152
1414
|
};
|
|
1153
1415
|
}
|
|
1154
1416
|
}
|
|
@@ -1156,28 +1418,46 @@ async function fetchComponent(id, options = {}) {
|
|
|
1156
1418
|
if (!forceRefresh && resolvedVersion !== version) {
|
|
1157
1419
|
const cached = getFromCache(id, resolvedVersion, cacheStrategy, cacheConfig);
|
|
1158
1420
|
if (cached) {
|
|
1421
|
+
let registry;
|
|
1422
|
+
if (cached.bundle) {
|
|
1423
|
+
registry = buildRegistryFromBundle(cached);
|
|
1424
|
+
}
|
|
1159
1425
|
return {
|
|
1160
1426
|
data: cached,
|
|
1161
1427
|
fromCache: true,
|
|
1162
|
-
version: resolvedVersion
|
|
1428
|
+
version: resolvedVersion,
|
|
1429
|
+
registry
|
|
1163
1430
|
};
|
|
1164
1431
|
}
|
|
1165
1432
|
}
|
|
1166
1433
|
let lastError = null;
|
|
1434
|
+
const shouldIncludeBundle = bundleStrategy !== "none" && includeBundle;
|
|
1167
1435
|
for (let attempt = 0; attempt <= fullRetryConfig.maxRetries; attempt++) {
|
|
1168
1436
|
if (signal?.aborted) {
|
|
1169
1437
|
throw new Error("Fetch aborted");
|
|
1170
1438
|
}
|
|
1171
1439
|
try {
|
|
1172
|
-
const data = await fetchFromRegistry(id, resolvedVersion, apiKey);
|
|
1440
|
+
const data = await fetchFromRegistry(id, resolvedVersion, apiKey, shouldIncludeBundle);
|
|
1173
1441
|
setInCache(id, resolvedVersion, data, cacheStrategy, cacheConfig);
|
|
1174
1442
|
if (version !== resolvedVersion) {
|
|
1175
1443
|
setInCache(id, version, data, cacheStrategy, cacheConfig);
|
|
1176
1444
|
}
|
|
1445
|
+
let registry;
|
|
1446
|
+
let pendingDependencies;
|
|
1447
|
+
if (data.bundle) {
|
|
1448
|
+
registry = buildRegistryFromBundle(data);
|
|
1449
|
+
} else if (data.dependencies && bundleStrategy === "lazy") {
|
|
1450
|
+
pendingDependencies = Object.entries(data.dependencies).map(([depId, entry]) => ({
|
|
1451
|
+
id: depId,
|
|
1452
|
+
version: entry.resolved || entry.version
|
|
1453
|
+
}));
|
|
1454
|
+
}
|
|
1177
1455
|
return {
|
|
1178
1456
|
data,
|
|
1179
1457
|
fromCache: false,
|
|
1180
|
-
version: resolvedVersion
|
|
1458
|
+
version: resolvedVersion,
|
|
1459
|
+
registry,
|
|
1460
|
+
pendingDependencies
|
|
1181
1461
|
};
|
|
1182
1462
|
} catch (error) {
|
|
1183
1463
|
lastError = error instanceof Error ? error : new Error(String(error));
|
|
@@ -1192,10 +1472,60 @@ async function fetchComponent(id, options = {}) {
|
|
|
1192
1472
|
}
|
|
1193
1473
|
throw lastError || new Error("Failed to fetch component");
|
|
1194
1474
|
}
|
|
1475
|
+
async function fetchComponentWithDependencies(id, options = {}) {
|
|
1476
|
+
const result = await fetchComponent(id, { ...options, includeBundle: true });
|
|
1477
|
+
if (result.pendingDependencies && result.pendingDependencies.length > 0) {
|
|
1478
|
+
const { createRegistry: createRegistry2 } = await Promise.resolve().then(() => (init_registry(), registry_exports));
|
|
1479
|
+
const registry = result.registry || createRegistry2();
|
|
1480
|
+
await Promise.all(
|
|
1481
|
+
result.pendingDependencies.map(async (dep) => {
|
|
1482
|
+
try {
|
|
1483
|
+
const depResult = await fetchComponent(dep.id, {
|
|
1484
|
+
...options,
|
|
1485
|
+
version: dep.version,
|
|
1486
|
+
bundleStrategy: "none"
|
|
1487
|
+
// Don't recursively bundle
|
|
1488
|
+
});
|
|
1489
|
+
registry.set(dep.id, depResult.version, {
|
|
1490
|
+
layout: depResult.data.layout,
|
|
1491
|
+
propsInterface: depResult.data.propsInterface
|
|
1492
|
+
});
|
|
1493
|
+
} catch (err) {
|
|
1494
|
+
console.warn(`Failed to fetch dependency ${dep.id}:`, err);
|
|
1495
|
+
}
|
|
1496
|
+
})
|
|
1497
|
+
);
|
|
1498
|
+
result.registry = registry;
|
|
1499
|
+
result.pendingDependencies = void 0;
|
|
1500
|
+
}
|
|
1501
|
+
return result;
|
|
1502
|
+
}
|
|
1503
|
+
async function batchFetchComponents(components, options = {}) {
|
|
1504
|
+
const baseUrl = getRegistryUrl();
|
|
1505
|
+
const headers = {
|
|
1506
|
+
"Content-Type": "application/json"
|
|
1507
|
+
};
|
|
1508
|
+
if (options.apiKey) {
|
|
1509
|
+
headers["Authorization"] = `Bearer ${options.apiKey}`;
|
|
1510
|
+
}
|
|
1511
|
+
const response = await fetch(`${baseUrl}/batch`, {
|
|
1512
|
+
method: "POST",
|
|
1513
|
+
headers,
|
|
1514
|
+
body: JSON.stringify({ components })
|
|
1515
|
+
});
|
|
1516
|
+
if (!response.ok) {
|
|
1517
|
+
throw new Error(`Batch fetch failed: ${response.statusText}`);
|
|
1518
|
+
}
|
|
1519
|
+
const data = await response.json();
|
|
1520
|
+
if (!data.success || !data.data) {
|
|
1521
|
+
throw new Error(data.error || "Batch fetch failed");
|
|
1522
|
+
}
|
|
1523
|
+
return data.data;
|
|
1524
|
+
}
|
|
1195
1525
|
async function prefetchComponents(ids, options = {}) {
|
|
1196
1526
|
const promises = ids.map(
|
|
1197
1527
|
({ id, version }) => fetchComponent(id, { ...options, version }).catch((error) => {
|
|
1198
|
-
console.warn(`Failed to prefetch
|
|
1528
|
+
console.warn(`Failed to prefetch view ${id}:`, error);
|
|
1199
1529
|
})
|
|
1200
1530
|
);
|
|
1201
1531
|
await Promise.all(promises);
|
|
@@ -1204,19 +1534,164 @@ async function isComponentAvailable(id, version = "latest", options = {}) {
|
|
|
1204
1534
|
const { cacheStrategy = "memory", cacheConfig = DEFAULT_CACHE_CONFIG } = options;
|
|
1205
1535
|
const cached = getFromCache(id, version, cacheStrategy, cacheConfig);
|
|
1206
1536
|
if (cached) {
|
|
1207
|
-
return { available: true, cached: true };
|
|
1537
|
+
return { available: true, cached: true, version: cached.version };
|
|
1538
|
+
}
|
|
1539
|
+
const baseUrl = getRegistryUrl();
|
|
1540
|
+
const headers = {
|
|
1541
|
+
"Content-Type": "application/json"
|
|
1542
|
+
};
|
|
1543
|
+
if (options.apiKey) {
|
|
1544
|
+
headers["Authorization"] = `Bearer ${options.apiKey}`;
|
|
1208
1545
|
}
|
|
1209
1546
|
try {
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
}
|
|
1215
|
-
|
|
1547
|
+
const url = version && version !== "latest" ? `${baseUrl}/${id}/available?version=${encodeURIComponent(version)}` : `${baseUrl}/${id}/available`;
|
|
1548
|
+
const response = await fetch(url, { headers });
|
|
1549
|
+
if (!response.ok) {
|
|
1550
|
+
return { available: false, cached: false };
|
|
1551
|
+
}
|
|
1552
|
+
const data = await response.json();
|
|
1553
|
+
if (data.success && data.data) {
|
|
1554
|
+
return data.data;
|
|
1555
|
+
}
|
|
1556
|
+
return { available: false, cached: false };
|
|
1216
1557
|
} catch {
|
|
1217
1558
|
return { available: false, cached: false };
|
|
1218
1559
|
}
|
|
1219
1560
|
}
|
|
1561
|
+
async function getDependencyTree(id, options = {}) {
|
|
1562
|
+
const baseUrl = getRegistryUrl();
|
|
1563
|
+
const headers = {
|
|
1564
|
+
"Content-Type": "application/json"
|
|
1565
|
+
};
|
|
1566
|
+
if (options.apiKey) {
|
|
1567
|
+
headers["Authorization"] = `Bearer ${options.apiKey}`;
|
|
1568
|
+
}
|
|
1569
|
+
const params = new URLSearchParams();
|
|
1570
|
+
if (options.version) params.set("version", options.version);
|
|
1571
|
+
if (options.depth) params.set("depth", String(options.depth));
|
|
1572
|
+
const url = `${baseUrl}/${id}/dependencies${params.toString() ? "?" + params.toString() : ""}`;
|
|
1573
|
+
const response = await fetch(url, { headers });
|
|
1574
|
+
if (!response.ok) {
|
|
1575
|
+
throw new Error(`Failed to get dependency tree: ${response.statusText}`);
|
|
1576
|
+
}
|
|
1577
|
+
const data = await response.json();
|
|
1578
|
+
if (!data.success || !data.data) {
|
|
1579
|
+
throw new Error(data.error || "Failed to get dependency tree");
|
|
1580
|
+
}
|
|
1581
|
+
return data.data;
|
|
1582
|
+
}
|
|
1583
|
+
|
|
1584
|
+
// src/version.ts
|
|
1585
|
+
function parseVersion(version) {
|
|
1586
|
+
const match = version.match(/^(\d+)\.(\d+)\.(\d+)$/);
|
|
1587
|
+
if (!match) return null;
|
|
1588
|
+
return {
|
|
1589
|
+
major: parseInt(match[1], 10),
|
|
1590
|
+
minor: parseInt(match[2], 10),
|
|
1591
|
+
patch: parseInt(match[3], 10)
|
|
1592
|
+
};
|
|
1593
|
+
}
|
|
1594
|
+
function compareVersions(a, b) {
|
|
1595
|
+
const parsedA = parseVersion(a);
|
|
1596
|
+
const parsedB = parseVersion(b);
|
|
1597
|
+
if (!parsedA || !parsedB) return 0;
|
|
1598
|
+
if (parsedA.major !== parsedB.major) {
|
|
1599
|
+
return parsedA.major > parsedB.major ? 1 : -1;
|
|
1600
|
+
}
|
|
1601
|
+
if (parsedA.minor !== parsedB.minor) {
|
|
1602
|
+
return parsedA.minor > parsedB.minor ? 1 : -1;
|
|
1603
|
+
}
|
|
1604
|
+
if (parsedA.patch !== parsedB.patch) {
|
|
1605
|
+
return parsedA.patch > parsedB.patch ? 1 : -1;
|
|
1606
|
+
}
|
|
1607
|
+
return 0;
|
|
1608
|
+
}
|
|
1609
|
+
function satisfiesVersion(version, specifier) {
|
|
1610
|
+
if (specifier === "latest" || specifier === "*") {
|
|
1611
|
+
return true;
|
|
1612
|
+
}
|
|
1613
|
+
const parsed = parseVersion(version);
|
|
1614
|
+
if (!parsed) return false;
|
|
1615
|
+
if (/^\d+\.\d+\.\d+$/.test(specifier)) {
|
|
1616
|
+
return version === specifier;
|
|
1617
|
+
}
|
|
1618
|
+
if (specifier.startsWith("^")) {
|
|
1619
|
+
const specParsed = parseVersion(specifier.slice(1));
|
|
1620
|
+
if (!specParsed) return false;
|
|
1621
|
+
if (parsed.major !== specParsed.major) return false;
|
|
1622
|
+
if (parsed.major === 0) {
|
|
1623
|
+
return parsed.minor === specParsed.minor && parsed.patch >= specParsed.patch;
|
|
1624
|
+
}
|
|
1625
|
+
return compareVersions(version, specifier.slice(1)) >= 0;
|
|
1626
|
+
}
|
|
1627
|
+
if (specifier.startsWith("~")) {
|
|
1628
|
+
const specParsed = parseVersion(specifier.slice(1));
|
|
1629
|
+
if (!specParsed) return false;
|
|
1630
|
+
return parsed.major === specParsed.major && parsed.minor === specParsed.minor && parsed.patch >= specParsed.patch;
|
|
1631
|
+
}
|
|
1632
|
+
if (specifier.startsWith(">=")) {
|
|
1633
|
+
return compareVersions(version, specifier.slice(2)) >= 0;
|
|
1634
|
+
}
|
|
1635
|
+
if (specifier.startsWith(">")) {
|
|
1636
|
+
return compareVersions(version, specifier.slice(1)) > 0;
|
|
1637
|
+
}
|
|
1638
|
+
if (specifier.startsWith("<=")) {
|
|
1639
|
+
return compareVersions(version, specifier.slice(2)) <= 0;
|
|
1640
|
+
}
|
|
1641
|
+
if (specifier.startsWith("<")) {
|
|
1642
|
+
return compareVersions(version, specifier.slice(1)) < 0;
|
|
1643
|
+
}
|
|
1644
|
+
return false;
|
|
1645
|
+
}
|
|
1646
|
+
function resolveVersion(versions, specifier = "latest") {
|
|
1647
|
+
if (versions.length === 0) {
|
|
1648
|
+
return null;
|
|
1649
|
+
}
|
|
1650
|
+
const sorted = [...versions].sort((a, b) => compareVersions(b, a));
|
|
1651
|
+
if (specifier === "latest" || specifier === "*") {
|
|
1652
|
+
return sorted[0];
|
|
1653
|
+
}
|
|
1654
|
+
if (/^\d+\.\d+\.\d+$/.test(specifier)) {
|
|
1655
|
+
return versions.includes(specifier) ? specifier : null;
|
|
1656
|
+
}
|
|
1657
|
+
for (const version of sorted) {
|
|
1658
|
+
if (satisfiesVersion(version, specifier)) {
|
|
1659
|
+
return version;
|
|
1660
|
+
}
|
|
1661
|
+
}
|
|
1662
|
+
return null;
|
|
1663
|
+
}
|
|
1664
|
+
function bumpVersion(currentVersion, bumpType) {
|
|
1665
|
+
const parsed = parseVersion(currentVersion);
|
|
1666
|
+
if (!parsed) return "1.0.0";
|
|
1667
|
+
switch (bumpType) {
|
|
1668
|
+
case "major":
|
|
1669
|
+
return `${parsed.major + 1}.0.0`;
|
|
1670
|
+
case "minor":
|
|
1671
|
+
return `${parsed.major}.${parsed.minor + 1}.0`;
|
|
1672
|
+
case "patch":
|
|
1673
|
+
return `${parsed.major}.${parsed.minor}.${parsed.patch + 1}`;
|
|
1674
|
+
default:
|
|
1675
|
+
return currentVersion;
|
|
1676
|
+
}
|
|
1677
|
+
}
|
|
1678
|
+
function isValidSpecifier(specifier) {
|
|
1679
|
+
if (specifier === "latest" || specifier === "*") {
|
|
1680
|
+
return true;
|
|
1681
|
+
}
|
|
1682
|
+
if (/^\d+\.\d+\.\d+$/.test(specifier)) {
|
|
1683
|
+
return true;
|
|
1684
|
+
}
|
|
1685
|
+
if (/^[\^~><]=?\d+\.\d+\.\d+$/.test(specifier)) {
|
|
1686
|
+
return true;
|
|
1687
|
+
}
|
|
1688
|
+
return false;
|
|
1689
|
+
}
|
|
1690
|
+
function formatVersion(version) {
|
|
1691
|
+
const parsed = parseVersion(version);
|
|
1692
|
+
if (!parsed) return version;
|
|
1693
|
+
return `v${parsed.major}.${parsed.minor}.${parsed.patch}`;
|
|
1694
|
+
}
|
|
1220
1695
|
|
|
1221
1696
|
// src/testRunner.ts
|
|
1222
1697
|
function runTestCase(elements, testCase, container) {
|
|
@@ -1472,26 +1947,38 @@ function getSampleValue(def) {
|
|
|
1472
1947
|
return def.defaultValue;
|
|
1473
1948
|
}
|
|
1474
1949
|
}
|
|
1950
|
+
|
|
1951
|
+
// src/index.ts
|
|
1952
|
+
init_registry();
|
|
1475
1953
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1476
1954
|
0 && (module.exports = {
|
|
1477
1955
|
DEFAULT_CACHE_CONFIG,
|
|
1478
1956
|
DEFAULT_RETRY_CONFIG,
|
|
1479
1957
|
applyStyles,
|
|
1958
|
+
batchFetchComponents,
|
|
1480
1959
|
buildClassName,
|
|
1481
1960
|
buildElementStyles,
|
|
1961
|
+
buildRegistryFromBundle,
|
|
1482
1962
|
bumpVersion,
|
|
1483
1963
|
camelToKebab,
|
|
1484
1964
|
clearAllCaches,
|
|
1485
1965
|
clearLocalStorageCache,
|
|
1486
1966
|
clearMemoryCache,
|
|
1487
1967
|
clearStyles,
|
|
1968
|
+
collectAllDependencies,
|
|
1488
1969
|
compareVersions,
|
|
1970
|
+
createRegistry,
|
|
1971
|
+
detectCircularDependencies,
|
|
1489
1972
|
extractBindingKeys,
|
|
1973
|
+
extractDependencies,
|
|
1974
|
+
extractDependenciesFromCode,
|
|
1490
1975
|
fetchComponent,
|
|
1976
|
+
fetchComponentWithDependencies,
|
|
1491
1977
|
formatStyleValue,
|
|
1492
1978
|
formatVersion,
|
|
1493
1979
|
generateTestCases,
|
|
1494
1980
|
getCacheKey,
|
|
1981
|
+
getDependencyTree,
|
|
1495
1982
|
getFromCache,
|
|
1496
1983
|
getMemoryCacheSize,
|
|
1497
1984
|
getRegistryUrl,
|
|
@@ -1503,6 +1990,7 @@ function getSampleValue(def) {
|
|
|
1503
1990
|
prefetchComponents,
|
|
1504
1991
|
processStyles,
|
|
1505
1992
|
render,
|
|
1993
|
+
renderDynamicList,
|
|
1506
1994
|
resolveBindingPath,
|
|
1507
1995
|
resolveTemplate,
|
|
1508
1996
|
resolveTemplateValue,
|