olova 2.0.61 → 2.0.63
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/CHANGELOG.md +5 -0
- package/README.md +42 -61
- package/dist/compiler.d.ts +44 -0
- package/dist/compiler.js +2139 -0
- package/dist/compiler.js.map +1 -0
- package/dist/core.d.ts +4 -0
- package/dist/core.js +859 -0
- package/dist/core.js.map +1 -0
- package/dist/global.d.ts +15 -0
- package/dist/global.js +226 -0
- package/dist/global.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2302 -0
- package/dist/index.js.map +1 -0
- package/dist/runtime.d.ts +89 -0
- package/dist/runtime.js +633 -0
- package/dist/runtime.js.map +1 -0
- package/dist/signals-core-BdfWh1Yt.d.ts +43 -0
- package/dist/vite.d.ts +5 -0
- package/dist/vite.js +2302 -0
- package/dist/vite.js.map +1 -0
- package/package.json +83 -65
- package/dist/chunk-D7SIC5TC.js +0 -367
- package/dist/chunk-D7SIC5TC.js.map +0 -1
- package/dist/entry-server.cjs +0 -120
- package/dist/entry-server.cjs.map +0 -1
- package/dist/entry-server.js +0 -115
- package/dist/entry-server.js.map +0 -1
- package/dist/entry-worker.cjs +0 -133
- package/dist/entry-worker.cjs.map +0 -1
- package/dist/entry-worker.js +0 -127
- package/dist/entry-worker.js.map +0 -1
- package/dist/main.cjs +0 -18
- package/dist/main.cjs.map +0 -1
- package/dist/main.js +0 -16
- package/dist/main.js.map +0 -1
- package/dist/olova.cjs +0 -1680
- package/dist/olova.cjs.map +0 -1
- package/dist/olova.d.cts +0 -72
- package/dist/olova.d.ts +0 -72
- package/dist/olova.js +0 -1321
- package/dist/olova.js.map +0 -1
- package/dist/performance.cjs +0 -386
- package/dist/performance.cjs.map +0 -1
- package/dist/performance.js +0 -3
- package/dist/performance.js.map +0 -1
- package/dist/router.cjs +0 -646
- package/dist/router.cjs.map +0 -1
- package/dist/router.d.cts +0 -113
- package/dist/router.d.ts +0 -113
- package/dist/router.js +0 -632
- package/dist/router.js.map +0 -1
- package/main.tsx +0 -76
- package/olova.ts +0 -619
- package/src/entry-server.tsx +0 -165
- package/src/entry-worker.tsx +0 -201
- package/src/generator/index.ts +0 -409
- package/src/hydration/flight.ts +0 -320
- package/src/hydration/index.ts +0 -12
- package/src/hydration/types.ts +0 -225
- package/src/logger.ts +0 -182
- package/src/main.tsx +0 -24
- package/src/performance.ts +0 -488
- package/src/plugin/index.ts +0 -204
- package/src/router/ErrorBoundary.tsx +0 -145
- package/src/router/Link.tsx +0 -117
- package/src/router/OlovaRouter.tsx +0 -354
- package/src/router/Outlet.tsx +0 -8
- package/src/router/context.ts +0 -117
- package/src/router/index.ts +0 -29
- package/src/router/matching.ts +0 -63
- package/src/router/router.tsx +0 -23
- package/src/router/search-params.ts +0 -29
- package/src/scanner/index.ts +0 -114
- package/src/types/index.ts +0 -190
- package/src/utils/export.ts +0 -85
- package/src/utils/index.ts +0 -4
- package/src/utils/naming.ts +0 -54
- package/src/utils/path.ts +0 -45
- package/tsup.config.ts +0 -35
package/dist/runtime.js
ADDED
|
@@ -0,0 +1,633 @@
|
|
|
1
|
+
import { effect as effect$1 } from '@preact/signals-core';
|
|
2
|
+
|
|
3
|
+
// core/signals-core.ts
|
|
4
|
+
var hmrCaptureStack = [];
|
|
5
|
+
function effect(fn, options) {
|
|
6
|
+
const stop = effect$1(() => fn());
|
|
7
|
+
return () => stop();
|
|
8
|
+
}
|
|
9
|
+
function beginHmrStateCapture(restoredValues) {
|
|
10
|
+
const restoredByKey = /* @__PURE__ */ new Map();
|
|
11
|
+
const restoredUnkeyed = [];
|
|
12
|
+
for (const entry of restoredValues ?? []) {
|
|
13
|
+
if (entry.key) {
|
|
14
|
+
restoredByKey.set(entry.key, entry.value);
|
|
15
|
+
continue;
|
|
16
|
+
}
|
|
17
|
+
restoredUnkeyed.push(entry.value);
|
|
18
|
+
}
|
|
19
|
+
hmrCaptureStack.push({
|
|
20
|
+
created: [],
|
|
21
|
+
restoredValues,
|
|
22
|
+
restoredByKey,
|
|
23
|
+
restoredUnkeyed,
|
|
24
|
+
cursor: 0
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
function endHmrStateCapture() {
|
|
28
|
+
const frame = hmrCaptureStack.pop();
|
|
29
|
+
return frame?.created ?? [];
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// runtime/component.ts
|
|
33
|
+
var EMPTY_SLOTS = Object.freeze({});
|
|
34
|
+
var currentSetupContext = null;
|
|
35
|
+
function requireSetupContext(apiName) {
|
|
36
|
+
if (!currentSetupContext) {
|
|
37
|
+
throw new Error(
|
|
38
|
+
`[olova] ${apiName}() can only be used during component setup.`
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
return currentSetupContext;
|
|
42
|
+
}
|
|
43
|
+
function toText(value) {
|
|
44
|
+
if (value === null || value === void 0) {
|
|
45
|
+
return "";
|
|
46
|
+
}
|
|
47
|
+
if (Array.isArray(value)) {
|
|
48
|
+
return value.map(toText).join("");
|
|
49
|
+
}
|
|
50
|
+
return String(value);
|
|
51
|
+
}
|
|
52
|
+
function normalizeClassValue(value) {
|
|
53
|
+
if (value === false || value === null || value === void 0) {
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
if (Array.isArray(value)) {
|
|
57
|
+
const parts = value.map((item) => normalizeClassValue(item)).filter((item) => !!item);
|
|
58
|
+
return parts.length > 0 ? parts.join(" ") : null;
|
|
59
|
+
}
|
|
60
|
+
if (typeof value === "object") {
|
|
61
|
+
const parts = Object.entries(value).filter(([, enabled]) => !!enabled).map(([name]) => name);
|
|
62
|
+
return parts.length > 0 ? parts.join(" ") : null;
|
|
63
|
+
}
|
|
64
|
+
return String(value);
|
|
65
|
+
}
|
|
66
|
+
function toAttr(value) {
|
|
67
|
+
if (value === false || value === null || value === void 0) {
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
if (value === true) {
|
|
71
|
+
return "true";
|
|
72
|
+
}
|
|
73
|
+
return String(value);
|
|
74
|
+
}
|
|
75
|
+
function isDangerousHtml(value) {
|
|
76
|
+
return !!(value && typeof value === "object" && "__dangerousHtml" in value && value.__dangerousHtml === true);
|
|
77
|
+
}
|
|
78
|
+
function sanitizeHtml(html) {
|
|
79
|
+
const template = document.createElement("template");
|
|
80
|
+
template.innerHTML = html;
|
|
81
|
+
const blockedElements = /* @__PURE__ */ new Set(["script", "iframe", "object", "embed"]);
|
|
82
|
+
const walker = document.createTreeWalker(template.content, NodeFilter.SHOW_ELEMENT);
|
|
83
|
+
let current = walker.nextNode();
|
|
84
|
+
while (current) {
|
|
85
|
+
const element = current;
|
|
86
|
+
current = walker.nextNode();
|
|
87
|
+
if (blockedElements.has(element.tagName.toLowerCase())) {
|
|
88
|
+
element.remove();
|
|
89
|
+
continue;
|
|
90
|
+
}
|
|
91
|
+
for (const attr of Array.from(element.attributes)) {
|
|
92
|
+
const attrName = attr.name.toLowerCase();
|
|
93
|
+
const attrValue = attr.value.trim().toLowerCase();
|
|
94
|
+
if (attrName.startsWith("on")) {
|
|
95
|
+
element.removeAttribute(attr.name);
|
|
96
|
+
continue;
|
|
97
|
+
}
|
|
98
|
+
if ((attrName === "href" || attrName === "src" || attrName === "xlink:href") && attrValue.startsWith("javascript:")) {
|
|
99
|
+
element.removeAttribute(attr.name);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
return template.innerHTML;
|
|
104
|
+
}
|
|
105
|
+
function toHtml(value) {
|
|
106
|
+
if (value === null || value === void 0) {
|
|
107
|
+
return "";
|
|
108
|
+
}
|
|
109
|
+
if (Array.isArray(value)) {
|
|
110
|
+
return value.map(toHtml).join("");
|
|
111
|
+
}
|
|
112
|
+
if (isDangerousHtml(value)) {
|
|
113
|
+
return value.value;
|
|
114
|
+
}
|
|
115
|
+
return sanitizeHtml(String(value));
|
|
116
|
+
}
|
|
117
|
+
function shallowEqual(a, b) {
|
|
118
|
+
if (a === b) {
|
|
119
|
+
return true;
|
|
120
|
+
}
|
|
121
|
+
if (!a || !b) {
|
|
122
|
+
return false;
|
|
123
|
+
}
|
|
124
|
+
const aKeys = Object.keys(a);
|
|
125
|
+
const bKeys = Object.keys(b);
|
|
126
|
+
if (aKeys.length !== bKeys.length) {
|
|
127
|
+
return false;
|
|
128
|
+
}
|
|
129
|
+
for (const key of aKeys) {
|
|
130
|
+
if (!Object.is(a[key], b[key])) {
|
|
131
|
+
return false;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
return true;
|
|
135
|
+
}
|
|
136
|
+
function shallowEqualSlots(a, b) {
|
|
137
|
+
if (a === b) {
|
|
138
|
+
return true;
|
|
139
|
+
}
|
|
140
|
+
if (!a || !b) {
|
|
141
|
+
return false;
|
|
142
|
+
}
|
|
143
|
+
const aKeys = Object.keys(a);
|
|
144
|
+
const bKeys = Object.keys(b);
|
|
145
|
+
if (aKeys.length !== bKeys.length) {
|
|
146
|
+
return false;
|
|
147
|
+
}
|
|
148
|
+
for (const key of aKeys) {
|
|
149
|
+
if (!Object.is(a[key], b[key])) {
|
|
150
|
+
return false;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
return true;
|
|
154
|
+
}
|
|
155
|
+
function insertFragmentIntoRange(range, fragment) {
|
|
156
|
+
const nodes = Array.from(fragment.childNodes);
|
|
157
|
+
range.deleteContents();
|
|
158
|
+
if (nodes.length === 0) {
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
range.insertNode(fragment);
|
|
162
|
+
const first = nodes[0];
|
|
163
|
+
const last = nodes[nodes.length - 1];
|
|
164
|
+
range.setStartBefore(first);
|
|
165
|
+
range.setEndAfter(last);
|
|
166
|
+
}
|
|
167
|
+
function bindJsxEventsInRange(range) {
|
|
168
|
+
const root = range.commonAncestorContainer.nodeType === Node.ELEMENT_NODE ? range.commonAncestorContainer : range.commonAncestorContainer.parentNode;
|
|
169
|
+
if (!root) {
|
|
170
|
+
return () => {
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
const globalObj = globalThis;
|
|
174
|
+
const handlers = globalObj.__olovaJsxHandlers;
|
|
175
|
+
if (!handlers) {
|
|
176
|
+
return () => {
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
const listeners = [];
|
|
180
|
+
const walker = document.createTreeWalker(root, NodeFilter.SHOW_ELEMENT);
|
|
181
|
+
let current = walker.currentNode;
|
|
182
|
+
while (current) {
|
|
183
|
+
let intersects = false;
|
|
184
|
+
try {
|
|
185
|
+
intersects = range.intersectsNode(current);
|
|
186
|
+
} catch {
|
|
187
|
+
intersects = false;
|
|
188
|
+
}
|
|
189
|
+
if (intersects) {
|
|
190
|
+
const element = current;
|
|
191
|
+
for (const attr of Array.from(current.attributes)) {
|
|
192
|
+
if (!attr.name.startsWith("data-o-jsx-")) {
|
|
193
|
+
continue;
|
|
194
|
+
}
|
|
195
|
+
const eventName = attr.name.slice("data-o-jsx-".length);
|
|
196
|
+
const handlerId = attr.value;
|
|
197
|
+
const listener = (event) => {
|
|
198
|
+
const handler = handlers.get(handlerId);
|
|
199
|
+
if (typeof handler === "function") {
|
|
200
|
+
handler(event);
|
|
201
|
+
}
|
|
202
|
+
};
|
|
203
|
+
element.addEventListener(eventName, listener);
|
|
204
|
+
element.removeAttribute(`on${eventName}`);
|
|
205
|
+
listeners.push(() => element.removeEventListener(eventName, listener));
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
current = walker.nextNode();
|
|
209
|
+
}
|
|
210
|
+
return () => {
|
|
211
|
+
for (const cleanup of listeners) {
|
|
212
|
+
cleanup();
|
|
213
|
+
}
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
function replaceTokenWithTextNode(root, token) {
|
|
217
|
+
const walker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT);
|
|
218
|
+
let current = walker.nextNode();
|
|
219
|
+
while (current) {
|
|
220
|
+
const textNode = current;
|
|
221
|
+
const index = textNode.data.indexOf(token);
|
|
222
|
+
if (index >= 0) {
|
|
223
|
+
const remainder = textNode.splitText(index);
|
|
224
|
+
const after = remainder.splitText(token.length);
|
|
225
|
+
const parent = remainder.parentNode;
|
|
226
|
+
if (!parent) {
|
|
227
|
+
return null;
|
|
228
|
+
}
|
|
229
|
+
const dynamic = document.createTextNode("");
|
|
230
|
+
parent.insertBefore(dynamic, after);
|
|
231
|
+
parent.removeChild(remainder);
|
|
232
|
+
return dynamic;
|
|
233
|
+
}
|
|
234
|
+
current = walker.nextNode();
|
|
235
|
+
}
|
|
236
|
+
return null;
|
|
237
|
+
}
|
|
238
|
+
function createRangeAtToken(root, token) {
|
|
239
|
+
const walker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT);
|
|
240
|
+
let current = walker.nextNode();
|
|
241
|
+
while (current) {
|
|
242
|
+
const textNode = current;
|
|
243
|
+
const index = textNode.data.indexOf(token);
|
|
244
|
+
if (index >= 0) {
|
|
245
|
+
const marker = textNode.splitText(index);
|
|
246
|
+
const after = marker.splitText(token.length);
|
|
247
|
+
const range = document.createRange();
|
|
248
|
+
range.setStartBefore(marker);
|
|
249
|
+
range.setEndBefore(marker);
|
|
250
|
+
marker.parentNode?.removeChild(marker);
|
|
251
|
+
if (after.data.length === 0) {
|
|
252
|
+
after.parentNode?.removeChild(after);
|
|
253
|
+
}
|
|
254
|
+
return range;
|
|
255
|
+
}
|
|
256
|
+
current = walker.nextNode();
|
|
257
|
+
}
|
|
258
|
+
return null;
|
|
259
|
+
}
|
|
260
|
+
function createRangeAtTokenWithinRange(hostRange, token) {
|
|
261
|
+
const root = hostRange.commonAncestorContainer;
|
|
262
|
+
const walker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT);
|
|
263
|
+
let current = walker.nextNode();
|
|
264
|
+
while (current) {
|
|
265
|
+
const textNode = current;
|
|
266
|
+
const index = textNode.data.indexOf(token);
|
|
267
|
+
if (index < 0) {
|
|
268
|
+
current = walker.nextNode();
|
|
269
|
+
continue;
|
|
270
|
+
}
|
|
271
|
+
let intersects = false;
|
|
272
|
+
try {
|
|
273
|
+
intersects = hostRange.intersectsNode(textNode);
|
|
274
|
+
} catch {
|
|
275
|
+
intersects = false;
|
|
276
|
+
}
|
|
277
|
+
if (!intersects) {
|
|
278
|
+
current = walker.nextNode();
|
|
279
|
+
continue;
|
|
280
|
+
}
|
|
281
|
+
const marker = textNode.splitText(index);
|
|
282
|
+
const after = marker.splitText(token.length);
|
|
283
|
+
const range = document.createRange();
|
|
284
|
+
range.setStartBefore(marker);
|
|
285
|
+
range.setEndBefore(marker);
|
|
286
|
+
marker.parentNode?.removeChild(marker);
|
|
287
|
+
if (after.data.length === 0) {
|
|
288
|
+
after.parentNode?.removeChild(after);
|
|
289
|
+
}
|
|
290
|
+
return range;
|
|
291
|
+
}
|
|
292
|
+
return null;
|
|
293
|
+
}
|
|
294
|
+
function resolveTokenRange(target, token) {
|
|
295
|
+
return target instanceof HTMLElement ? createRangeAtToken(target, token) : createRangeAtTokenWithinRange(target, token);
|
|
296
|
+
}
|
|
297
|
+
function mountDescriptor(descriptor, target, slots, context) {
|
|
298
|
+
let fragment;
|
|
299
|
+
let nodes = null;
|
|
300
|
+
if (descriptor.build) {
|
|
301
|
+
const buildResult = descriptor.build();
|
|
302
|
+
fragment = buildResult.fragment;
|
|
303
|
+
nodes = buildResult.nodes;
|
|
304
|
+
} else {
|
|
305
|
+
const template = document.createElement("template");
|
|
306
|
+
template.innerHTML = descriptor.template ? descriptor.template.trim() : "";
|
|
307
|
+
fragment = template.content;
|
|
308
|
+
}
|
|
309
|
+
const cleanups = [];
|
|
310
|
+
for (const binding of descriptor.textBindings) {
|
|
311
|
+
const token = `__O_TEXT_${binding.id}__`;
|
|
312
|
+
const textNode = nodes && nodes[binding.id] ? nodes[binding.id] : replaceTokenWithTextNode(fragment, token);
|
|
313
|
+
if (!textNode) {
|
|
314
|
+
continue;
|
|
315
|
+
}
|
|
316
|
+
const stop = effect(() => {
|
|
317
|
+
textNode.data = toText(binding.get());
|
|
318
|
+
});
|
|
319
|
+
cleanups.push(stop);
|
|
320
|
+
}
|
|
321
|
+
for (const binding of descriptor.attrBindings) {
|
|
322
|
+
const token = `__O_ATTR_${binding.id}__`;
|
|
323
|
+
const elements = nodes && nodes[binding.id] ? [nodes[binding.id]] : Array.from(fragment.querySelectorAll("*")).filter(
|
|
324
|
+
(element) => element.getAttribute(binding.attr) === token
|
|
325
|
+
);
|
|
326
|
+
for (const element of elements) {
|
|
327
|
+
const stop = effect(() => {
|
|
328
|
+
const next = binding.attr === "class" ? normalizeClassValue(binding.get()) : toAttr(binding.get());
|
|
329
|
+
if (next === null) {
|
|
330
|
+
element.removeAttribute(binding.attr);
|
|
331
|
+
return;
|
|
332
|
+
}
|
|
333
|
+
element.setAttribute(binding.attr, next);
|
|
334
|
+
});
|
|
335
|
+
cleanups.push(stop);
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
for (const binding of descriptor.eventBindings) {
|
|
339
|
+
const selector = `[data-o-on-${binding.event}="${binding.id}"]`;
|
|
340
|
+
const element = nodes && nodes[binding.id] ? nodes[binding.id] : fragment.querySelector(selector);
|
|
341
|
+
if (!element) {
|
|
342
|
+
continue;
|
|
343
|
+
}
|
|
344
|
+
if (!nodes) element.removeAttribute(`data-o-on-${binding.event}`);
|
|
345
|
+
let currentHandler;
|
|
346
|
+
const stop = effect(() => {
|
|
347
|
+
currentHandler = binding.get();
|
|
348
|
+
});
|
|
349
|
+
const listener = (event) => {
|
|
350
|
+
if (typeof currentHandler === "function") {
|
|
351
|
+
currentHandler(event);
|
|
352
|
+
}
|
|
353
|
+
};
|
|
354
|
+
element.addEventListener(binding.event, listener);
|
|
355
|
+
cleanups.push(() => {
|
|
356
|
+
stop();
|
|
357
|
+
element.removeEventListener(binding.event, listener);
|
|
358
|
+
});
|
|
359
|
+
}
|
|
360
|
+
if (target instanceof HTMLElement) {
|
|
361
|
+
target.replaceChildren(fragment);
|
|
362
|
+
} else {
|
|
363
|
+
insertFragmentIntoRange(target, fragment);
|
|
364
|
+
}
|
|
365
|
+
for (const binding of descriptor.htmlBindings) {
|
|
366
|
+
const token = `__O_HTML_${binding.id}__`;
|
|
367
|
+
let range = null;
|
|
368
|
+
if (nodes && nodes[binding.id]) {
|
|
369
|
+
range = document.createRange();
|
|
370
|
+
range.setStartBefore(nodes[binding.id]);
|
|
371
|
+
range.setEndBefore(nodes[binding.id]);
|
|
372
|
+
nodes[binding.id].parentNode?.removeChild(nodes[binding.id]);
|
|
373
|
+
} else {
|
|
374
|
+
range = resolveTokenRange(target, token);
|
|
375
|
+
}
|
|
376
|
+
if (!range) {
|
|
377
|
+
continue;
|
|
378
|
+
}
|
|
379
|
+
let lastHtml = "__OLOVA_INIT__";
|
|
380
|
+
let cleanupJsxEvents = () => {
|
|
381
|
+
};
|
|
382
|
+
const stop = effect(() => {
|
|
383
|
+
const nextHtml = toHtml(binding.get());
|
|
384
|
+
if (nextHtml === lastHtml) {
|
|
385
|
+
return;
|
|
386
|
+
}
|
|
387
|
+
lastHtml = nextHtml;
|
|
388
|
+
cleanupJsxEvents();
|
|
389
|
+
const htmlTemplate = document.createElement("template");
|
|
390
|
+
htmlTemplate.innerHTML = nextHtml;
|
|
391
|
+
insertFragmentIntoRange(range, htmlTemplate.content);
|
|
392
|
+
cleanupJsxEvents = bindJsxEventsInRange(range);
|
|
393
|
+
});
|
|
394
|
+
cleanups.push(() => {
|
|
395
|
+
cleanupJsxEvents();
|
|
396
|
+
stop();
|
|
397
|
+
});
|
|
398
|
+
}
|
|
399
|
+
for (const binding of descriptor.slotBindings) {
|
|
400
|
+
const token = `__O_SLOT_${binding.id}__`;
|
|
401
|
+
let range = null;
|
|
402
|
+
if (nodes && nodes[binding.id]) {
|
|
403
|
+
range = document.createRange();
|
|
404
|
+
range.setStartBefore(nodes[binding.id]);
|
|
405
|
+
range.setEndBefore(nodes[binding.id]);
|
|
406
|
+
nodes[binding.id].parentNode?.removeChild(nodes[binding.id]);
|
|
407
|
+
} else {
|
|
408
|
+
range = resolveTokenRange(target, token);
|
|
409
|
+
}
|
|
410
|
+
if (!range) {
|
|
411
|
+
continue;
|
|
412
|
+
}
|
|
413
|
+
const slotFactory = slots[binding.name];
|
|
414
|
+
if (!slotFactory) {
|
|
415
|
+
range.deleteContents();
|
|
416
|
+
continue;
|
|
417
|
+
}
|
|
418
|
+
const slotDescriptor = slotFactory();
|
|
419
|
+
const disposeSlot = mountDescriptor(slotDescriptor, range, slots, context);
|
|
420
|
+
cleanups.push(disposeSlot);
|
|
421
|
+
}
|
|
422
|
+
for (const binding of descriptor.componentBindings) {
|
|
423
|
+
const token = `__O_COMP_${binding.id}__`;
|
|
424
|
+
let range = null;
|
|
425
|
+
if (nodes && nodes[binding.id]) {
|
|
426
|
+
range = document.createRange();
|
|
427
|
+
range.setStartBefore(nodes[binding.id]);
|
|
428
|
+
range.setEndBefore(nodes[binding.id]);
|
|
429
|
+
nodes[binding.id].parentNode?.removeChild(nodes[binding.id]);
|
|
430
|
+
} else {
|
|
431
|
+
range = resolveTokenRange(target, token);
|
|
432
|
+
}
|
|
433
|
+
if (!range) {
|
|
434
|
+
continue;
|
|
435
|
+
}
|
|
436
|
+
let disposeChild = () => {
|
|
437
|
+
};
|
|
438
|
+
let lastComponent = null;
|
|
439
|
+
let lastProps;
|
|
440
|
+
let lastSlots;
|
|
441
|
+
const stop = effect(() => {
|
|
442
|
+
const nextComponent = binding.getComponent();
|
|
443
|
+
const nextProps = binding.getProps();
|
|
444
|
+
const nextSlots = binding.getSlots ? binding.getSlots() : EMPTY_SLOTS;
|
|
445
|
+
if (lastComponent === nextComponent && shallowEqual(lastProps, nextProps) && shallowEqualSlots(lastSlots, nextSlots)) {
|
|
446
|
+
return;
|
|
447
|
+
}
|
|
448
|
+
disposeChild();
|
|
449
|
+
disposeChild = mount(nextComponent, range, nextProps, nextSlots, context);
|
|
450
|
+
lastComponent = nextComponent;
|
|
451
|
+
lastProps = { ...nextProps };
|
|
452
|
+
lastSlots = nextSlots;
|
|
453
|
+
});
|
|
454
|
+
cleanups.push(() => {
|
|
455
|
+
stop();
|
|
456
|
+
disposeChild();
|
|
457
|
+
});
|
|
458
|
+
}
|
|
459
|
+
if (descriptor.ifBindings) {
|
|
460
|
+
for (const binding of descriptor.ifBindings) {
|
|
461
|
+
const token = `__O_IF_${binding.id}__`;
|
|
462
|
+
let range = null;
|
|
463
|
+
if (nodes && nodes[binding.id]) {
|
|
464
|
+
range = document.createRange();
|
|
465
|
+
range.setStartBefore(nodes[binding.id]);
|
|
466
|
+
range.setEndBefore(nodes[binding.id]);
|
|
467
|
+
nodes[binding.id].parentNode?.removeChild(nodes[binding.id]);
|
|
468
|
+
} else {
|
|
469
|
+
range = resolveTokenRange(target, token);
|
|
470
|
+
}
|
|
471
|
+
if (!range) {
|
|
472
|
+
continue;
|
|
473
|
+
}
|
|
474
|
+
let disposeBranch = () => {
|
|
475
|
+
};
|
|
476
|
+
let lastCondition = void 0;
|
|
477
|
+
const stop = effect(() => {
|
|
478
|
+
const condition = !!binding.get();
|
|
479
|
+
if (condition === lastCondition) {
|
|
480
|
+
return;
|
|
481
|
+
}
|
|
482
|
+
disposeBranch();
|
|
483
|
+
if (condition) {
|
|
484
|
+
const branchDescriptor = binding.trueBranch();
|
|
485
|
+
disposeBranch = mountDescriptor(branchDescriptor, range, slots, context);
|
|
486
|
+
} else if (binding.falseBranch) {
|
|
487
|
+
const branchDescriptor = binding.falseBranch();
|
|
488
|
+
disposeBranch = mountDescriptor(branchDescriptor, range, slots, context);
|
|
489
|
+
} else {
|
|
490
|
+
range.deleteContents();
|
|
491
|
+
disposeBranch = () => {
|
|
492
|
+
};
|
|
493
|
+
}
|
|
494
|
+
lastCondition = condition;
|
|
495
|
+
});
|
|
496
|
+
cleanups.push(() => {
|
|
497
|
+
stop();
|
|
498
|
+
disposeBranch();
|
|
499
|
+
});
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
return () => {
|
|
503
|
+
for (const cleanup of cleanups) {
|
|
504
|
+
cleanup();
|
|
505
|
+
}
|
|
506
|
+
if (target instanceof HTMLElement) {
|
|
507
|
+
target.replaceChildren();
|
|
508
|
+
return;
|
|
509
|
+
}
|
|
510
|
+
target.deleteContents();
|
|
511
|
+
};
|
|
512
|
+
}
|
|
513
|
+
function registerMountedInstance(instance) {
|
|
514
|
+
const instances = instance.component.__hmrInstances ?? (instance.component.__hmrInstances = /* @__PURE__ */ new Set());
|
|
515
|
+
instances.add(instance);
|
|
516
|
+
}
|
|
517
|
+
function unregisterMountedInstance(instance) {
|
|
518
|
+
instance.component.__hmrInstances?.delete(instance);
|
|
519
|
+
}
|
|
520
|
+
function renderMountedInstance(instance, restoredValues) {
|
|
521
|
+
const context = new Map(instance.parentContext ?? []);
|
|
522
|
+
const previousContext = currentSetupContext;
|
|
523
|
+
currentSetupContext = context;
|
|
524
|
+
beginHmrStateCapture(restoredValues);
|
|
525
|
+
try {
|
|
526
|
+
const descriptor = instance.component.setup(instance.props, instance.slots);
|
|
527
|
+
instance.disposeDescriptor = mountDescriptor(
|
|
528
|
+
descriptor,
|
|
529
|
+
instance.target,
|
|
530
|
+
instance.slots,
|
|
531
|
+
context
|
|
532
|
+
);
|
|
533
|
+
instance.hmrSignals = endHmrStateCapture();
|
|
534
|
+
} catch (error) {
|
|
535
|
+
endHmrStateCapture();
|
|
536
|
+
throw error;
|
|
537
|
+
} finally {
|
|
538
|
+
currentSetupContext = previousContext;
|
|
539
|
+
}
|
|
540
|
+
}
|
|
541
|
+
function collectHmrSignalValues(instance) {
|
|
542
|
+
return instance.hmrSignals.map(({ key, signal }) => ({
|
|
543
|
+
key,
|
|
544
|
+
value: signal.peek()
|
|
545
|
+
}));
|
|
546
|
+
}
|
|
547
|
+
function replaceComponent(current, next) {
|
|
548
|
+
const instances = current.__hmrInstances;
|
|
549
|
+
if (!instances || instances.size === 0) {
|
|
550
|
+
current.setup = next.setup;
|
|
551
|
+
next.__hmrInstances = instances;
|
|
552
|
+
current.__hmrInstances = void 0;
|
|
553
|
+
return;
|
|
554
|
+
}
|
|
555
|
+
const snapshots = Array.from(instances, (instance) => ({
|
|
556
|
+
instance,
|
|
557
|
+
restoredValues: collectHmrSignalValues(instance)
|
|
558
|
+
}));
|
|
559
|
+
next.__hmrInstances = instances;
|
|
560
|
+
current.__hmrInstances = void 0;
|
|
561
|
+
try {
|
|
562
|
+
for (const { instance, restoredValues } of snapshots) {
|
|
563
|
+
instance.component = next;
|
|
564
|
+
instance.disposeDescriptor();
|
|
565
|
+
renderMountedInstance(instance, restoredValues);
|
|
566
|
+
}
|
|
567
|
+
} catch (error) {
|
|
568
|
+
next.__hmrInstances = void 0;
|
|
569
|
+
current.__hmrInstances = instances;
|
|
570
|
+
for (const { instance, restoredValues } of snapshots) {
|
|
571
|
+
instance.component = current;
|
|
572
|
+
instance.disposeDescriptor();
|
|
573
|
+
renderMountedInstance(instance, restoredValues);
|
|
574
|
+
}
|
|
575
|
+
console.error("[olova] HMR update failed. Restored previous component.", error);
|
|
576
|
+
return;
|
|
577
|
+
}
|
|
578
|
+
}
|
|
579
|
+
function defineComponent(setup, hmrId) {
|
|
580
|
+
return { setup, __hmrId: hmrId };
|
|
581
|
+
}
|
|
582
|
+
function dangerouslySetHtml(value) {
|
|
583
|
+
return {
|
|
584
|
+
__dangerousHtml: true,
|
|
585
|
+
value: toText(value)
|
|
586
|
+
};
|
|
587
|
+
}
|
|
588
|
+
function setContext(key, value) {
|
|
589
|
+
const context = requireSetupContext("setContext");
|
|
590
|
+
context.set(key, value);
|
|
591
|
+
return value;
|
|
592
|
+
}
|
|
593
|
+
function getContext(key) {
|
|
594
|
+
const context = requireSetupContext("getContext");
|
|
595
|
+
return context.get(key);
|
|
596
|
+
}
|
|
597
|
+
function hasContext(key) {
|
|
598
|
+
const context = requireSetupContext("hasContext");
|
|
599
|
+
return context.has(key);
|
|
600
|
+
}
|
|
601
|
+
function mount(component, target, props = {}, slots = EMPTY_SLOTS, parentContext) {
|
|
602
|
+
const instance = {
|
|
603
|
+
component,
|
|
604
|
+
target,
|
|
605
|
+
props,
|
|
606
|
+
slots,
|
|
607
|
+
parentContext,
|
|
608
|
+
disposeDescriptor: () => {
|
|
609
|
+
},
|
|
610
|
+
hmrSignals: []
|
|
611
|
+
};
|
|
612
|
+
registerMountedInstance(instance);
|
|
613
|
+
renderMountedInstance(instance);
|
|
614
|
+
return () => {
|
|
615
|
+
unregisterMountedInstance(instance);
|
|
616
|
+
instance.disposeDescriptor();
|
|
617
|
+
};
|
|
618
|
+
}
|
|
619
|
+
function createApp(root) {
|
|
620
|
+
return {
|
|
621
|
+
mount(target) {
|
|
622
|
+
const element = typeof target === "string" ? document.querySelector(target) : target;
|
|
623
|
+
if (!element) {
|
|
624
|
+
throw new Error(`Target not found: ${String(target)}`);
|
|
625
|
+
}
|
|
626
|
+
return mount(root, element);
|
|
627
|
+
}
|
|
628
|
+
};
|
|
629
|
+
}
|
|
630
|
+
|
|
631
|
+
export { createApp, dangerouslySetHtml, defineComponent, getContext, hasContext, mount, replaceComponent, setContext };
|
|
632
|
+
//# sourceMappingURL=runtime.js.map
|
|
633
|
+
//# sourceMappingURL=runtime.js.map
|