sinwan 0.1.0 → 1.0.0
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/README.md +66 -39
- package/dist/cjs/index.development.js +1624 -961
- package/dist/cjs/index.development.js.map +21 -18
- package/dist/cjs/index.production.min.js +2 -2
- package/dist/cjs/index.production.min.js.map +21 -18
- package/dist/cjs/jsx/jsx-dev-runtime.development.js +6 -16
- package/dist/cjs/jsx/jsx-dev-runtime.development.js.map +3 -3
- package/dist/cjs/jsx/jsx-dev-runtime.production.min.js +2 -2
- package/dist/cjs/jsx/jsx-dev-runtime.production.min.js.map +3 -3
- package/dist/cjs/jsx/jsx-runtime.development.js +6 -16
- package/dist/cjs/jsx/jsx-runtime.development.js.map +3 -3
- package/dist/cjs/jsx/jsx-runtime.production.min.js +2 -2
- package/dist/cjs/jsx/jsx-runtime.production.min.js.map +3 -3
- package/dist/cjs/renderer/index.development.js +1175 -0
- package/dist/cjs/renderer/index.development.js.map +24 -0
- package/dist/cjs/renderer/index.production.min.js +3 -0
- package/dist/cjs/renderer/index.production.min.js.map +24 -0
- package/dist/cjs/server/index.development.js +665 -329
- package/dist/cjs/server/index.development.js.map +11 -10
- package/dist/cjs/server/index.production.min.js +2 -2
- package/dist/cjs/server/index.production.min.js.map +11 -10
- package/dist/component/control-flow.d.ts +18 -0
- package/dist/component/control-flow.d.ts.map +1 -0
- package/dist/component/index.d.ts +3 -1
- package/dist/component/index.d.ts.map +1 -1
- package/dist/component/instance.d.ts +7 -1
- package/dist/component/instance.d.ts.map +1 -1
- package/dist/component/lifecycle.d.ts +2 -1
- package/dist/component/lifecycle.d.ts.map +1 -1
- package/dist/component/provide-inject.d.ts +11 -5
- package/dist/component/provide-inject.d.ts.map +1 -1
- package/dist/esm/index.development.js +1301 -660
- package/dist/esm/index.development.js.map +21 -18
- package/dist/esm/index.production.min.js +2 -2
- package/dist/esm/index.production.min.js.map +21 -18
- package/dist/esm/jsx/jsx-dev-runtime.development.js +6 -16
- package/dist/esm/jsx/jsx-dev-runtime.development.js.map +3 -3
- package/dist/esm/jsx/jsx-dev-runtime.production.min.js +2 -2
- package/dist/esm/jsx/jsx-dev-runtime.production.min.js.map +3 -3
- package/dist/esm/jsx/jsx-runtime.development.js +6 -16
- package/dist/esm/jsx/jsx-runtime.development.js.map +3 -3
- package/dist/esm/jsx/jsx-runtime.production.min.js +2 -2
- package/dist/esm/jsx/jsx-runtime.production.min.js.map +3 -3
- package/dist/esm/renderer/index.development.js +1124 -0
- package/dist/esm/renderer/index.development.js.map +24 -0
- package/dist/esm/renderer/index.production.min.js +4 -0
- package/dist/esm/renderer/index.production.min.js.map +24 -0
- package/dist/esm/server/index.development.js +665 -329
- package/dist/esm/server/index.development.js.map +11 -10
- package/dist/esm/server/index.production.min.js +2 -2
- package/dist/esm/server/index.production.min.js.map +11 -10
- package/dist/hydration/walk.d.ts.map +1 -1
- package/dist/index.d.ts +6 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/jsx/jsx-runtime.d.ts +13 -0
- package/dist/jsx/jsx-runtime.d.ts.map +1 -1
- package/dist/jsx/jsx-types.d.ts +122 -57
- package/dist/jsx/jsx-types.d.ts.map +1 -1
- package/dist/renderer/attributes.d.ts.map +1 -1
- package/dist/renderer/dom-ops.d.ts +4 -1
- package/dist/renderer/dom-ops.d.ts.map +1 -1
- package/dist/renderer/index.d.ts +1 -1
- package/dist/renderer/index.d.ts.map +1 -1
- package/dist/renderer/mount.d.ts +2 -5
- package/dist/renderer/mount.d.ts.map +1 -1
- package/dist/renderer/render-children.d.ts +2 -2
- package/dist/renderer/render-children.d.ts.map +1 -1
- package/dist/renderer/render-control-flow.d.ts +13 -0
- package/dist/renderer/render-control-flow.d.ts.map +1 -0
- package/dist/renderer/render-element.d.ts +1 -1
- package/dist/renderer/render-element.d.ts.map +1 -1
- package/dist/renderer/types.d.ts +2 -0
- package/dist/renderer/types.d.ts.map +1 -1
- package/dist/renderer/unmount.d.ts +20 -0
- package/dist/renderer/unmount.d.ts.map +1 -0
- package/dist/renderer.d.ts +1 -0
- package/dist/renderer.js +7 -0
- package/dist/renderer.mjs +4 -0
- package/dist/server/hydration-markers.d.ts.map +1 -1
- package/dist/server/index.d.ts +1 -1
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/renderer.d.ts.map +1 -1
- package/dist/server/stream.d.ts +9 -1
- package/dist/server/stream.d.ts.map +1 -1
- package/dist/types.d.ts +8 -2
- package/dist/types.d.ts.map +1 -1
- package/package.json +15 -1
|
@@ -0,0 +1,1124 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
// src/jsx/jsx-runtime.ts
|
|
3
|
+
var Fragment = Symbol("Fragment");
|
|
4
|
+
|
|
5
|
+
class HtmlEscapedString extends String {
|
|
6
|
+
value;
|
|
7
|
+
constructor(value) {
|
|
8
|
+
super(value);
|
|
9
|
+
this.value = value;
|
|
10
|
+
}
|
|
11
|
+
toString() {
|
|
12
|
+
return this.value;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
var raw = (str) => new HtmlEscapedString(str);
|
|
16
|
+
var VOID_ELEMENTS = new Set([
|
|
17
|
+
"area",
|
|
18
|
+
"base",
|
|
19
|
+
"br",
|
|
20
|
+
"col",
|
|
21
|
+
"embed",
|
|
22
|
+
"hr",
|
|
23
|
+
"img",
|
|
24
|
+
"input",
|
|
25
|
+
"link",
|
|
26
|
+
"meta",
|
|
27
|
+
"param",
|
|
28
|
+
"source",
|
|
29
|
+
"track",
|
|
30
|
+
"wbr"
|
|
31
|
+
]);
|
|
32
|
+
function normalizeChildren(children) {
|
|
33
|
+
if (children == null || typeof children === "boolean")
|
|
34
|
+
return [];
|
|
35
|
+
if (Array.isArray(children))
|
|
36
|
+
return children.flat(Infinity);
|
|
37
|
+
return [children];
|
|
38
|
+
}
|
|
39
|
+
function buildElement(type, props, children) {
|
|
40
|
+
if (type === Fragment) {
|
|
41
|
+
return { tag: "", props: {}, children };
|
|
42
|
+
}
|
|
43
|
+
if (typeof type === "function" || typeof type === "string") {
|
|
44
|
+
const finalProps = props ?? {};
|
|
45
|
+
if (children.length > 0 && finalProps.children === undefined) {
|
|
46
|
+
finalProps.children = children.length === 1 ? children[0] : children;
|
|
47
|
+
}
|
|
48
|
+
return { tag: type, props: finalProps, children };
|
|
49
|
+
}
|
|
50
|
+
return { tag: "", props: {}, children };
|
|
51
|
+
}
|
|
52
|
+
function jsx(type, props, key) {
|
|
53
|
+
return buildElement(type, props, normalizeChildren(props?.children));
|
|
54
|
+
}
|
|
55
|
+
function jsxs(type, props, key) {
|
|
56
|
+
const children = props?.children;
|
|
57
|
+
return buildElement(type, props, Array.isArray(children) ? children.flat(Infinity) : normalizeChildren(children));
|
|
58
|
+
}
|
|
59
|
+
function jsxDEV(type, props, key, isStaticChildren, source, self) {
|
|
60
|
+
const children = isStaticChildren ? Array.isArray(props?.children) ? props.children.flat(Infinity) : normalizeChildren(props?.children) : normalizeChildren(props?.children);
|
|
61
|
+
const element = buildElement(type, props, children);
|
|
62
|
+
if (source) {
|
|
63
|
+
element.__source = source;
|
|
64
|
+
}
|
|
65
|
+
return element;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// src/renderer/dom-ops.ts
|
|
69
|
+
function createDefaultDOMOps() {
|
|
70
|
+
return {
|
|
71
|
+
createElement(tag) {
|
|
72
|
+
return document.createElement(tag);
|
|
73
|
+
},
|
|
74
|
+
createElementNS(namespace, tag) {
|
|
75
|
+
return document.createElementNS(namespace, tag);
|
|
76
|
+
},
|
|
77
|
+
createTextNode(text) {
|
|
78
|
+
return document.createTextNode(text);
|
|
79
|
+
},
|
|
80
|
+
createComment(text) {
|
|
81
|
+
return document.createComment(text);
|
|
82
|
+
},
|
|
83
|
+
setAttribute(el, key, value) {
|
|
84
|
+
el.setAttribute(key, value);
|
|
85
|
+
},
|
|
86
|
+
removeAttribute(el, key) {
|
|
87
|
+
el.removeAttribute(key);
|
|
88
|
+
},
|
|
89
|
+
setProperty(el, key, value) {
|
|
90
|
+
el[key] = value;
|
|
91
|
+
},
|
|
92
|
+
insertBefore(parent, child, anchor) {
|
|
93
|
+
parent.insertBefore(child, anchor);
|
|
94
|
+
},
|
|
95
|
+
appendChild(parent, child) {
|
|
96
|
+
parent.appendChild(child);
|
|
97
|
+
},
|
|
98
|
+
remove(node) {
|
|
99
|
+
node.parentNode?.removeChild(node);
|
|
100
|
+
},
|
|
101
|
+
setTextContent(node, text) {
|
|
102
|
+
node.data = text;
|
|
103
|
+
},
|
|
104
|
+
addEventListener(el, event, handler) {
|
|
105
|
+
el.addEventListener(event, handler);
|
|
106
|
+
},
|
|
107
|
+
removeEventListener(el, event, handler) {
|
|
108
|
+
el.removeEventListener(event, handler);
|
|
109
|
+
},
|
|
110
|
+
parentNode(node) {
|
|
111
|
+
return node.parentNode;
|
|
112
|
+
},
|
|
113
|
+
nextSibling(node) {
|
|
114
|
+
return node.nextSibling;
|
|
115
|
+
}
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
var defaultDOMOps = createDefaultDOMOps();
|
|
119
|
+
var domOps = { ...defaultDOMOps };
|
|
120
|
+
function setDOMOps(overrides) {
|
|
121
|
+
Object.assign(domOps, overrides);
|
|
122
|
+
}
|
|
123
|
+
function resetDOMOps() {
|
|
124
|
+
for (const key of Object.keys(domOps)) {
|
|
125
|
+
delete domOps[key];
|
|
126
|
+
}
|
|
127
|
+
Object.assign(domOps, defaultDOMOps);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// src/reactivity/scheduler.ts
|
|
131
|
+
var pendingEffects = new Set;
|
|
132
|
+
var flushScheduled = false;
|
|
133
|
+
var isFlushing = false;
|
|
134
|
+
var pendingCallbacks = [];
|
|
135
|
+
function scheduleEffect(effect) {
|
|
136
|
+
if (!effect.active)
|
|
137
|
+
return;
|
|
138
|
+
pendingEffects.add(effect);
|
|
139
|
+
scheduleFlush();
|
|
140
|
+
}
|
|
141
|
+
function unscheduleEffect(effect) {
|
|
142
|
+
pendingEffects.delete(effect);
|
|
143
|
+
}
|
|
144
|
+
function scheduleFlush() {
|
|
145
|
+
if (!flushScheduled) {
|
|
146
|
+
flushScheduled = true;
|
|
147
|
+
queueMicrotask(flush);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
function flush() {
|
|
151
|
+
isFlushing = true;
|
|
152
|
+
const sorted = [...pendingEffects].sort((a, b) => a.id - b.id);
|
|
153
|
+
pendingEffects.clear();
|
|
154
|
+
for (const effect of sorted) {
|
|
155
|
+
if (effect.active) {
|
|
156
|
+
effect.run();
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
let safety = 10;
|
|
160
|
+
while (pendingEffects.size > 0 && safety-- > 0) {
|
|
161
|
+
const next = [...pendingEffects].sort((a, b) => a.id - b.id);
|
|
162
|
+
pendingEffects.clear();
|
|
163
|
+
for (const effect of next) {
|
|
164
|
+
if (effect.active) {
|
|
165
|
+
effect.run();
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
flushScheduled = false;
|
|
170
|
+
isFlushing = false;
|
|
171
|
+
const cbs = pendingCallbacks.splice(0);
|
|
172
|
+
for (const cb of cbs) {
|
|
173
|
+
cb();
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
function nextTick(fn) {
|
|
177
|
+
return new Promise((resolve) => {
|
|
178
|
+
const callback = () => {
|
|
179
|
+
fn?.();
|
|
180
|
+
resolve();
|
|
181
|
+
};
|
|
182
|
+
if (flushScheduled || isFlushing) {
|
|
183
|
+
pendingCallbacks.push(callback);
|
|
184
|
+
} else {
|
|
185
|
+
queueMicrotask(callback);
|
|
186
|
+
}
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
function flushSync() {
|
|
190
|
+
if (flushScheduled) {
|
|
191
|
+
flushScheduled = false;
|
|
192
|
+
flush();
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// src/reactivity/effect.ts
|
|
197
|
+
var activeEffect = null;
|
|
198
|
+
var effectStack = [];
|
|
199
|
+
var effectIdCounter = 0;
|
|
200
|
+
|
|
201
|
+
class ReactiveEffect {
|
|
202
|
+
id;
|
|
203
|
+
active = true;
|
|
204
|
+
fn;
|
|
205
|
+
cleanup = undefined;
|
|
206
|
+
deps = new Set;
|
|
207
|
+
constructor(fn) {
|
|
208
|
+
this.id = effectIdCounter++;
|
|
209
|
+
this.fn = fn;
|
|
210
|
+
}
|
|
211
|
+
run() {
|
|
212
|
+
if (!this.active)
|
|
213
|
+
return;
|
|
214
|
+
if (effectStack.includes(this))
|
|
215
|
+
return;
|
|
216
|
+
this.cleanupDeps();
|
|
217
|
+
if (this.cleanup) {
|
|
218
|
+
this.cleanup();
|
|
219
|
+
this.cleanup = undefined;
|
|
220
|
+
}
|
|
221
|
+
effectStack.push(this);
|
|
222
|
+
const prevEffect = activeEffect;
|
|
223
|
+
activeEffect = this;
|
|
224
|
+
try {
|
|
225
|
+
const result = this.fn();
|
|
226
|
+
if (typeof result === "function") {
|
|
227
|
+
this.cleanup = result;
|
|
228
|
+
}
|
|
229
|
+
} finally {
|
|
230
|
+
activeEffect = prevEffect;
|
|
231
|
+
effectStack.pop();
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
cleanupDeps() {
|
|
235
|
+
for (const dep of this.deps) {
|
|
236
|
+
dep.subscribers.delete(this);
|
|
237
|
+
}
|
|
238
|
+
this.deps.clear();
|
|
239
|
+
}
|
|
240
|
+
notify() {
|
|
241
|
+
scheduleEffect(this);
|
|
242
|
+
}
|
|
243
|
+
dispose() {
|
|
244
|
+
if (!this.active)
|
|
245
|
+
return;
|
|
246
|
+
this.active = false;
|
|
247
|
+
if (this.cleanup) {
|
|
248
|
+
this.cleanup();
|
|
249
|
+
this.cleanup = undefined;
|
|
250
|
+
}
|
|
251
|
+
this.cleanupDeps();
|
|
252
|
+
unscheduleEffect(this);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
function effect(fn) {
|
|
256
|
+
const e = new ReactiveEffect(fn);
|
|
257
|
+
e.run();
|
|
258
|
+
return () => e.dispose();
|
|
259
|
+
}
|
|
260
|
+
function track(dep) {
|
|
261
|
+
if (activeEffect) {
|
|
262
|
+
dep.subscribers.add(activeEffect);
|
|
263
|
+
activeEffect.deps.add(dep);
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
function trigger(dep) {
|
|
267
|
+
const effects = [...dep.subscribers];
|
|
268
|
+
for (const effect2 of effects) {
|
|
269
|
+
effect2.notify();
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
// src/reactivity/signal.ts
|
|
274
|
+
var SIGNAL_BRAND = Symbol("Sinwan:signal");
|
|
275
|
+
|
|
276
|
+
class SignalImpl {
|
|
277
|
+
[SIGNAL_BRAND] = true;
|
|
278
|
+
subscribers = new Set;
|
|
279
|
+
_value;
|
|
280
|
+
_manualSubs = new Set;
|
|
281
|
+
constructor(initial) {
|
|
282
|
+
this._value = initial;
|
|
283
|
+
}
|
|
284
|
+
get value() {
|
|
285
|
+
track(this);
|
|
286
|
+
return this._value;
|
|
287
|
+
}
|
|
288
|
+
set value(newValue) {
|
|
289
|
+
if (Object.is(this._value, newValue))
|
|
290
|
+
return;
|
|
291
|
+
this._value = newValue;
|
|
292
|
+
trigger(this);
|
|
293
|
+
for (const fn of this._manualSubs) {
|
|
294
|
+
fn(newValue);
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
peek() {
|
|
298
|
+
return this._value;
|
|
299
|
+
}
|
|
300
|
+
subscribe(fn) {
|
|
301
|
+
this._manualSubs.add(fn);
|
|
302
|
+
return () => {
|
|
303
|
+
this._manualSubs.delete(fn);
|
|
304
|
+
};
|
|
305
|
+
}
|
|
306
|
+
toString() {
|
|
307
|
+
return String(this.value);
|
|
308
|
+
}
|
|
309
|
+
valueOf() {
|
|
310
|
+
return this.value;
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
function signal(initial) {
|
|
314
|
+
return new SignalImpl(initial);
|
|
315
|
+
}
|
|
316
|
+
function isSignal(value) {
|
|
317
|
+
return value != null && typeof value === "object" && SIGNAL_BRAND in value;
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
// src/reactivity/computed.ts
|
|
321
|
+
var COMPUTED_BRAND = Symbol("Sinwan:computed");
|
|
322
|
+
|
|
323
|
+
class ComputedImpl {
|
|
324
|
+
[COMPUTED_BRAND] = true;
|
|
325
|
+
subscribers = new Set;
|
|
326
|
+
_value;
|
|
327
|
+
_dirty = true;
|
|
328
|
+
_effect;
|
|
329
|
+
constructor(getter) {
|
|
330
|
+
const self = this;
|
|
331
|
+
this._effect = new ReactiveEffect(() => {
|
|
332
|
+
self._value = getter();
|
|
333
|
+
});
|
|
334
|
+
this._effect.notify = function() {
|
|
335
|
+
if (!self._dirty) {
|
|
336
|
+
self._dirty = true;
|
|
337
|
+
trigger(self);
|
|
338
|
+
}
|
|
339
|
+
};
|
|
340
|
+
this._effect.run();
|
|
341
|
+
this._dirty = false;
|
|
342
|
+
}
|
|
343
|
+
get value() {
|
|
344
|
+
track(this);
|
|
345
|
+
if (this._dirty) {
|
|
346
|
+
this._effect.run();
|
|
347
|
+
this._dirty = false;
|
|
348
|
+
}
|
|
349
|
+
return this._value;
|
|
350
|
+
}
|
|
351
|
+
peek() {
|
|
352
|
+
if (this._dirty) {
|
|
353
|
+
this._effect.run();
|
|
354
|
+
this._dirty = false;
|
|
355
|
+
}
|
|
356
|
+
return this._value;
|
|
357
|
+
}
|
|
358
|
+
toString() {
|
|
359
|
+
return String(this.value);
|
|
360
|
+
}
|
|
361
|
+
valueOf() {
|
|
362
|
+
return this.value;
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
function computed(getter) {
|
|
366
|
+
return new ComputedImpl(getter);
|
|
367
|
+
}
|
|
368
|
+
function isComputed(value) {
|
|
369
|
+
return value != null && typeof value === "object" && COMPUTED_BRAND in value;
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
// src/renderer/events.ts
|
|
373
|
+
function isEventProp(key) {
|
|
374
|
+
return key.length > 2 && key[0] === "o" && key[1] === "n" && key[2] >= "A" && key[2] <= "Z";
|
|
375
|
+
}
|
|
376
|
+
function toEventName(key) {
|
|
377
|
+
return key.slice(2).toLowerCase();
|
|
378
|
+
}
|
|
379
|
+
function bindEvent(el, eventName, handler) {
|
|
380
|
+
domOps.addEventListener(el, eventName, handler);
|
|
381
|
+
return () => {
|
|
382
|
+
domOps.removeEventListener(el, eventName, handler);
|
|
383
|
+
};
|
|
384
|
+
}
|
|
385
|
+
function bindEvents(el, props) {
|
|
386
|
+
const cleanups = [];
|
|
387
|
+
for (const key of Object.keys(props)) {
|
|
388
|
+
if (isEventProp(key)) {
|
|
389
|
+
const handler = props[key];
|
|
390
|
+
if (typeof handler === "function") {
|
|
391
|
+
const eventName = toEventName(key);
|
|
392
|
+
cleanups.push(bindEvent(el, eventName, handler));
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
return cleanups;
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
// src/component/instance.ts
|
|
400
|
+
var uidCounter = 0;
|
|
401
|
+
function createComponentInstance(component, props, parent) {
|
|
402
|
+
return {
|
|
403
|
+
uid: uidCounter++,
|
|
404
|
+
component,
|
|
405
|
+
props,
|
|
406
|
+
element: null,
|
|
407
|
+
parent,
|
|
408
|
+
children: [],
|
|
409
|
+
effects: [],
|
|
410
|
+
_mountedHooks: [],
|
|
411
|
+
_unmountedHooks: [],
|
|
412
|
+
_updatedHooks: [],
|
|
413
|
+
_errorHooks: [],
|
|
414
|
+
provides: parent ? Object.create(parent.provides) : Object.create(null),
|
|
415
|
+
isMounted: false,
|
|
416
|
+
isUnmounted: false
|
|
417
|
+
};
|
|
418
|
+
}
|
|
419
|
+
var currentInstance = null;
|
|
420
|
+
function getCurrentInstance() {
|
|
421
|
+
return currentInstance;
|
|
422
|
+
}
|
|
423
|
+
function setCurrentInstance(instance) {
|
|
424
|
+
const prev = currentInstance;
|
|
425
|
+
currentInstance = instance;
|
|
426
|
+
return prev;
|
|
427
|
+
}
|
|
428
|
+
function withInstance(instance, fn) {
|
|
429
|
+
const prev = setCurrentInstance(instance);
|
|
430
|
+
try {
|
|
431
|
+
return fn();
|
|
432
|
+
} finally {
|
|
433
|
+
setCurrentInstance(prev);
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
function fireMountedHooks(instance) {
|
|
437
|
+
if (instance.isUnmounted) {
|
|
438
|
+
return;
|
|
439
|
+
}
|
|
440
|
+
for (const child of instance.children) {
|
|
441
|
+
fireMountedHooks(child);
|
|
442
|
+
}
|
|
443
|
+
if (!instance.isMounted) {
|
|
444
|
+
instance.isMounted = true;
|
|
445
|
+
for (const hook of instance._mountedHooks) {
|
|
446
|
+
hook();
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
function fireUnmountedHooks(instance) {
|
|
451
|
+
for (const child of instance.children) {
|
|
452
|
+
fireUnmountedHooks(child);
|
|
453
|
+
}
|
|
454
|
+
if (instance.isMounted && !instance.isUnmounted) {
|
|
455
|
+
instance.isUnmounted = true;
|
|
456
|
+
instance.isMounted = false;
|
|
457
|
+
for (const hook of instance._unmountedHooks) {
|
|
458
|
+
hook();
|
|
459
|
+
}
|
|
460
|
+
for (const dispose of instance.effects) {
|
|
461
|
+
dispose();
|
|
462
|
+
}
|
|
463
|
+
instance.effects.length = 0;
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
function fireUpdatedHooks(instance) {
|
|
467
|
+
for (const hook of instance._updatedHooks) {
|
|
468
|
+
hook();
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
var queuedUpdatedHooks = new Set;
|
|
472
|
+
function queueUpdatedHooks(instance) {
|
|
473
|
+
if (!instance || !instance.isMounted || instance.isUnmounted || instance._updatedHooks.length === 0 || queuedUpdatedHooks.has(instance)) {
|
|
474
|
+
return;
|
|
475
|
+
}
|
|
476
|
+
queuedUpdatedHooks.add(instance);
|
|
477
|
+
nextTick(() => {
|
|
478
|
+
queuedUpdatedHooks.delete(instance);
|
|
479
|
+
if (instance.isMounted && !instance.isUnmounted) {
|
|
480
|
+
fireUpdatedHooks(instance);
|
|
481
|
+
}
|
|
482
|
+
});
|
|
483
|
+
}
|
|
484
|
+
function handleComponentError(instance, err) {
|
|
485
|
+
let current = instance;
|
|
486
|
+
while (current) {
|
|
487
|
+
if (current._errorHooks.length > 0) {
|
|
488
|
+
for (const hook of current._errorHooks) {
|
|
489
|
+
hook(err);
|
|
490
|
+
}
|
|
491
|
+
return;
|
|
492
|
+
}
|
|
493
|
+
current = current.parent;
|
|
494
|
+
}
|
|
495
|
+
console.error("[Sinwan] Unhandled component error:", err);
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
// src/renderer/attributes.ts
|
|
499
|
+
var SKIP_PROPS = new Set(["children", "key", "ref", "dangerouslySetInnerHTML"]);
|
|
500
|
+
var DOM_PROPERTIES = new Set(["value", "checked", "selected", "disabled", "readOnly", "multiple", "indeterminate"]);
|
|
501
|
+
var PROP_ALIASES = {
|
|
502
|
+
className: "class",
|
|
503
|
+
htmlFor: "for",
|
|
504
|
+
tabIndex: "tabindex",
|
|
505
|
+
crossOrigin: "crossorigin"
|
|
506
|
+
};
|
|
507
|
+
function applyAttributes(el, props) {
|
|
508
|
+
const disposers = [];
|
|
509
|
+
const owner = getCurrentInstance();
|
|
510
|
+
for (const [key, value] of Object.entries(props)) {
|
|
511
|
+
if (SKIP_PROPS.has(key) || isEventProp(key))
|
|
512
|
+
continue;
|
|
513
|
+
if (isSignal(value) || isComputed(value)) {
|
|
514
|
+
let initialized = false;
|
|
515
|
+
const dispose = effect(() => {
|
|
516
|
+
setSingleAttribute(el, key, value.value);
|
|
517
|
+
if (initialized) {
|
|
518
|
+
queueUpdatedHooks(owner);
|
|
519
|
+
}
|
|
520
|
+
initialized = true;
|
|
521
|
+
});
|
|
522
|
+
disposers.push(dispose);
|
|
523
|
+
} else {
|
|
524
|
+
setSingleAttribute(el, key, value);
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
return disposers;
|
|
528
|
+
}
|
|
529
|
+
function setSingleAttribute(el, key, value) {
|
|
530
|
+
const attrName = PROP_ALIASES[key] ?? key;
|
|
531
|
+
if (attrName === "style" && typeof value === "object" && value !== null) {
|
|
532
|
+
applyStyle(el, value);
|
|
533
|
+
return;
|
|
534
|
+
}
|
|
535
|
+
if (attrName === "class" && typeof value === "object" && value !== null) {
|
|
536
|
+
applyClass(el, value);
|
|
537
|
+
return;
|
|
538
|
+
}
|
|
539
|
+
if (value == null || value === false) {
|
|
540
|
+
domOps.removeAttribute(el, attrName);
|
|
541
|
+
if (DOM_PROPERTIES.has(attrName)) {
|
|
542
|
+
domOps.setProperty(el, attrName, attrName === "value" ? "" : false);
|
|
543
|
+
}
|
|
544
|
+
return;
|
|
545
|
+
}
|
|
546
|
+
if (value === true) {
|
|
547
|
+
domOps.setAttribute(el, attrName, "");
|
|
548
|
+
if (DOM_PROPERTIES.has(attrName)) {
|
|
549
|
+
domOps.setProperty(el, attrName, true);
|
|
550
|
+
}
|
|
551
|
+
return;
|
|
552
|
+
}
|
|
553
|
+
if (DOM_PROPERTIES.has(attrName)) {
|
|
554
|
+
domOps.setProperty(el, attrName, value);
|
|
555
|
+
return;
|
|
556
|
+
}
|
|
557
|
+
domOps.setAttribute(el, attrName, String(value));
|
|
558
|
+
}
|
|
559
|
+
function applyStyle(el, styles) {
|
|
560
|
+
for (const [prop, val] of Object.entries(styles)) {
|
|
561
|
+
if (prop.includes("-")) {
|
|
562
|
+
el.style.setProperty(prop, val);
|
|
563
|
+
} else {
|
|
564
|
+
el.style[prop] = val;
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
function applyClass(el, value) {
|
|
569
|
+
let classStr;
|
|
570
|
+
if (Array.isArray(value)) {
|
|
571
|
+
classStr = value.filter(Boolean).join(" ");
|
|
572
|
+
} else if (typeof value === "object" && value !== null) {
|
|
573
|
+
classStr = Object.entries(value).filter(([, v]) => Boolean(v)).map(([k]) => k).join(" ");
|
|
574
|
+
} else {
|
|
575
|
+
classStr = String(value);
|
|
576
|
+
}
|
|
577
|
+
domOps.setAttribute(el, "class", classStr);
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
// src/component/control-flow.ts
|
|
581
|
+
var SHOW_TYPE = Symbol.for("Sinwan.Show");
|
|
582
|
+
var FOR_TYPE = Symbol.for("Sinwan.For");
|
|
583
|
+
function Show(props) {
|
|
584
|
+
return {
|
|
585
|
+
tag: SHOW_TYPE,
|
|
586
|
+
props,
|
|
587
|
+
children: []
|
|
588
|
+
};
|
|
589
|
+
}
|
|
590
|
+
function For(props) {
|
|
591
|
+
return {
|
|
592
|
+
tag: FOR_TYPE,
|
|
593
|
+
props,
|
|
594
|
+
children: []
|
|
595
|
+
};
|
|
596
|
+
}
|
|
597
|
+
function isShowElement(element) {
|
|
598
|
+
return element.tag === SHOW_TYPE;
|
|
599
|
+
}
|
|
600
|
+
function isForElement(element) {
|
|
601
|
+
return element.tag === FOR_TYPE;
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
// src/renderer/unmount.ts
|
|
605
|
+
function getMountedDomNodes(node) {
|
|
606
|
+
switch (node.type) {
|
|
607
|
+
case "text":
|
|
608
|
+
case "reactive-text":
|
|
609
|
+
return [node.node];
|
|
610
|
+
case "element":
|
|
611
|
+
return [node.node];
|
|
612
|
+
case "fragment":
|
|
613
|
+
return [
|
|
614
|
+
node.anchor,
|
|
615
|
+
...node.children.flatMap((child) => getMountedDomNodes(child))
|
|
616
|
+
];
|
|
617
|
+
case "reactive-block":
|
|
618
|
+
return [
|
|
619
|
+
node.startAnchor,
|
|
620
|
+
...node.children.flatMap((child) => getMountedDomNodes(child)),
|
|
621
|
+
node.endAnchor
|
|
622
|
+
];
|
|
623
|
+
case "component":
|
|
624
|
+
return node.children.flatMap((child) => getMountedDomNodes(child));
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
function unmountNode(node) {
|
|
628
|
+
switch (node.type) {
|
|
629
|
+
case "text":
|
|
630
|
+
break;
|
|
631
|
+
case "reactive-text":
|
|
632
|
+
node.dispose();
|
|
633
|
+
break;
|
|
634
|
+
case "element":
|
|
635
|
+
for (const dispose of node.attrDisposers) {
|
|
636
|
+
dispose();
|
|
637
|
+
}
|
|
638
|
+
for (const cleanup of node.eventCleanups) {
|
|
639
|
+
cleanup();
|
|
640
|
+
}
|
|
641
|
+
node.refCleanup?.();
|
|
642
|
+
for (const child of node.children) {
|
|
643
|
+
unmountNode(child);
|
|
644
|
+
}
|
|
645
|
+
break;
|
|
646
|
+
case "fragment":
|
|
647
|
+
for (const child of node.children) {
|
|
648
|
+
unmountNode(child);
|
|
649
|
+
}
|
|
650
|
+
break;
|
|
651
|
+
case "reactive-block":
|
|
652
|
+
node.dispose();
|
|
653
|
+
for (const child of node.children) {
|
|
654
|
+
unmountNode(child);
|
|
655
|
+
}
|
|
656
|
+
break;
|
|
657
|
+
case "component":
|
|
658
|
+
if (node.instance) {
|
|
659
|
+
fireUnmountedHooks(node.instance);
|
|
660
|
+
} else {
|
|
661
|
+
for (const dispose of node.disposers) {
|
|
662
|
+
dispose();
|
|
663
|
+
}
|
|
664
|
+
}
|
|
665
|
+
for (const child of node.children) {
|
|
666
|
+
unmountNode(child);
|
|
667
|
+
}
|
|
668
|
+
break;
|
|
669
|
+
}
|
|
670
|
+
}
|
|
671
|
+
function removeMountedNode(node) {
|
|
672
|
+
const domNodes = getMountedDomNodes(node);
|
|
673
|
+
unmountNode(node);
|
|
674
|
+
for (const domNode of domNodes) {
|
|
675
|
+
if (domNode.parentNode) {
|
|
676
|
+
domOps.remove(domNode);
|
|
677
|
+
}
|
|
678
|
+
}
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
// src/renderer/render-control-flow.ts
|
|
682
|
+
function renderControlFlowToDOM(element, parent, anchor, namespace) {
|
|
683
|
+
const startAnchor = domOps.createComment("Sinwan-b");
|
|
684
|
+
const endAnchor = domOps.createComment("/Sinwan-b");
|
|
685
|
+
insertNode(parent, startAnchor, anchor);
|
|
686
|
+
insertNode(parent, endAnchor, anchor);
|
|
687
|
+
const owner = getCurrentInstance();
|
|
688
|
+
let disposeEffect = () => {};
|
|
689
|
+
const block = {
|
|
690
|
+
type: "reactive-block",
|
|
691
|
+
dispose: () => disposeEffect(),
|
|
692
|
+
children: [],
|
|
693
|
+
startAnchor,
|
|
694
|
+
endAnchor
|
|
695
|
+
};
|
|
696
|
+
if (isShowElement(element)) {
|
|
697
|
+
disposeEffect = renderShowBlock(element, block, parent, namespace, owner);
|
|
698
|
+
} else if (isForElement(element)) {
|
|
699
|
+
disposeEffect = renderForBlock(element, block, parent, namespace, owner);
|
|
700
|
+
}
|
|
701
|
+
return block;
|
|
702
|
+
}
|
|
703
|
+
function renderShowBlock(element, block, parent, namespace, owner) {
|
|
704
|
+
let initialized = false;
|
|
705
|
+
return effect(() => {
|
|
706
|
+
clearChildren(block);
|
|
707
|
+
const when = readReactive(element.props.when);
|
|
708
|
+
const content = withOptionalInstance(owner, () => when ? resolveShowChildren(element, when) : element.props.fallback);
|
|
709
|
+
block.children = renderBlockContent(content, parent, block.endAnchor, namespace, owner);
|
|
710
|
+
if (initialized) {
|
|
711
|
+
fireMountedAndQueueUpdated(owner);
|
|
712
|
+
}
|
|
713
|
+
initialized = true;
|
|
714
|
+
});
|
|
715
|
+
}
|
|
716
|
+
function renderForBlock(element, block, parent, namespace, owner) {
|
|
717
|
+
let initialized = false;
|
|
718
|
+
let records = [];
|
|
719
|
+
return effect(() => {
|
|
720
|
+
const props = element.props;
|
|
721
|
+
const items = readReactive(props.each);
|
|
722
|
+
const list = Array.isArray(items) ? items : [];
|
|
723
|
+
const renderChild = props.children;
|
|
724
|
+
if (typeof renderChild !== "function") {
|
|
725
|
+
clearChildren(block);
|
|
726
|
+
records = [];
|
|
727
|
+
if (initialized) {
|
|
728
|
+
queueUpdatedHooks(owner);
|
|
729
|
+
}
|
|
730
|
+
initialized = true;
|
|
731
|
+
return;
|
|
732
|
+
}
|
|
733
|
+
const oldByKey = new Map;
|
|
734
|
+
for (const record of records) {
|
|
735
|
+
oldByKey.set(record.key, record);
|
|
736
|
+
}
|
|
737
|
+
const nextRecords = [];
|
|
738
|
+
list.forEach((item, index) => {
|
|
739
|
+
const key = props.key ? props.key(item, index) : item;
|
|
740
|
+
const old = oldByKey.get(key);
|
|
741
|
+
if (old && old.item === item) {
|
|
742
|
+
old.index = index;
|
|
743
|
+
moveBeforeEnd(parent, old.mounted, block.endAnchor);
|
|
744
|
+
nextRecords.push(old);
|
|
745
|
+
oldByKey.delete(key);
|
|
746
|
+
return;
|
|
747
|
+
}
|
|
748
|
+
if (old) {
|
|
749
|
+
removeMountedNode(old.mounted);
|
|
750
|
+
oldByKey.delete(key);
|
|
751
|
+
}
|
|
752
|
+
const record = {
|
|
753
|
+
key,
|
|
754
|
+
item,
|
|
755
|
+
index,
|
|
756
|
+
mounted: { type: "text", node: domOps.createTextNode("") }
|
|
757
|
+
};
|
|
758
|
+
record.mounted = withOptionalInstance(owner, () => renderNodeToDOM(renderChild(item, () => record.index), parent, block.endAnchor, namespace));
|
|
759
|
+
nextRecords.push(record);
|
|
760
|
+
});
|
|
761
|
+
for (const record of oldByKey.values()) {
|
|
762
|
+
removeMountedNode(record.mounted);
|
|
763
|
+
}
|
|
764
|
+
records = nextRecords;
|
|
765
|
+
block.children = nextRecords.map((record) => record.mounted);
|
|
766
|
+
if (initialized) {
|
|
767
|
+
fireMountedAndQueueUpdated(owner);
|
|
768
|
+
}
|
|
769
|
+
initialized = true;
|
|
770
|
+
});
|
|
771
|
+
}
|
|
772
|
+
function resolveShowChildren(element, value) {
|
|
773
|
+
const children = element.props.children ?? element.children;
|
|
774
|
+
if (typeof children === "function") {
|
|
775
|
+
return children(value);
|
|
776
|
+
}
|
|
777
|
+
return children;
|
|
778
|
+
}
|
|
779
|
+
function renderBlockContent(content, parent, anchor, namespace, owner) {
|
|
780
|
+
if (content == null || typeof content === "boolean") {
|
|
781
|
+
return [];
|
|
782
|
+
}
|
|
783
|
+
const nodes = Array.isArray(content) ? content : [content];
|
|
784
|
+
return nodes.map((node) => withOptionalInstance(owner, () => renderNodeToDOM(node, parent, anchor, namespace)));
|
|
785
|
+
}
|
|
786
|
+
function clearChildren(block) {
|
|
787
|
+
for (const child of block.children) {
|
|
788
|
+
removeMountedNode(child);
|
|
789
|
+
}
|
|
790
|
+
block.children = [];
|
|
791
|
+
}
|
|
792
|
+
function moveBeforeEnd(parent, mounted, endAnchor) {
|
|
793
|
+
for (const node of getMountedDomNodes(mounted)) {
|
|
794
|
+
domOps.insertBefore(parent, node, endAnchor);
|
|
795
|
+
}
|
|
796
|
+
}
|
|
797
|
+
function fireMountedAndQueueUpdated(owner) {
|
|
798
|
+
if (owner) {
|
|
799
|
+
fireMountedHooks(owner);
|
|
800
|
+
}
|
|
801
|
+
queueUpdatedHooks(owner);
|
|
802
|
+
}
|
|
803
|
+
function withOptionalInstance(owner, fn) {
|
|
804
|
+
return owner ? withInstance(owner, fn) : fn();
|
|
805
|
+
}
|
|
806
|
+
function readReactive(value) {
|
|
807
|
+
return isSignal(value) || isComputed(value) ? value.value : value;
|
|
808
|
+
}
|
|
809
|
+
function insertNode(parent, child, anchor) {
|
|
810
|
+
if (anchor) {
|
|
811
|
+
domOps.insertBefore(parent, child, anchor);
|
|
812
|
+
} else {
|
|
813
|
+
domOps.appendChild(parent, child);
|
|
814
|
+
}
|
|
815
|
+
}
|
|
816
|
+
|
|
817
|
+
// src/renderer/render-element.ts
|
|
818
|
+
var VOID_ELEMENTS2 = new Set([
|
|
819
|
+
"area",
|
|
820
|
+
"base",
|
|
821
|
+
"br",
|
|
822
|
+
"col",
|
|
823
|
+
"embed",
|
|
824
|
+
"hr",
|
|
825
|
+
"img",
|
|
826
|
+
"input",
|
|
827
|
+
"link",
|
|
828
|
+
"meta",
|
|
829
|
+
"param",
|
|
830
|
+
"source",
|
|
831
|
+
"track",
|
|
832
|
+
"wbr"
|
|
833
|
+
]);
|
|
834
|
+
var SVG_NS = "http://www.w3.org/2000/svg";
|
|
835
|
+
var MATH_NS = "http://www.w3.org/1998/Math/MathML";
|
|
836
|
+
function renderElementToDOM(element, parent, anchor = null, namespace = null) {
|
|
837
|
+
const { tag, props, children } = element;
|
|
838
|
+
if (tag === "" || tag === Fragment) {
|
|
839
|
+
return renderFragmentToDOM(children, parent, anchor, namespace);
|
|
840
|
+
}
|
|
841
|
+
if (tag === Show || tag === For) {
|
|
842
|
+
return renderElementToDOM(tag(props), parent, anchor, namespace);
|
|
843
|
+
}
|
|
844
|
+
if (isShowElement(element) || isForElement(element)) {
|
|
845
|
+
return renderControlFlowToDOM(element, parent, anchor, namespace);
|
|
846
|
+
}
|
|
847
|
+
if (typeof tag === "function") {
|
|
848
|
+
return renderComponentToDOM(tag, props, parent, anchor, namespace);
|
|
849
|
+
}
|
|
850
|
+
if (typeof tag === "string") {
|
|
851
|
+
return renderIntrinsicToDOM(tag, props, children, parent, anchor, namespace);
|
|
852
|
+
}
|
|
853
|
+
return renderFragmentToDOM(children, parent, anchor, namespace);
|
|
854
|
+
}
|
|
855
|
+
function renderIntrinsicToDOM(tag, props, children, parent, anchor, parentNamespace) {
|
|
856
|
+
const namespace = getElementNamespace(tag, parentNamespace);
|
|
857
|
+
const el = namespace ? domOps.createElementNS(namespace, tag) : domOps.createElement(tag);
|
|
858
|
+
const attrDisposers = applyAttributes(el, props);
|
|
859
|
+
const eventCleanups = bindEvents(el, props);
|
|
860
|
+
let mountedChildren = [];
|
|
861
|
+
if (!VOID_ELEMENTS2.has(tag)) {
|
|
862
|
+
const dangerous = props.dangerouslySetInnerHTML;
|
|
863
|
+
if (dangerous && typeof dangerous.__html === "string") {
|
|
864
|
+
el.innerHTML = dangerous.__html;
|
|
865
|
+
} else {
|
|
866
|
+
mountedChildren = renderChildrenToDOM(children, el, getChildNamespace(tag, namespace));
|
|
867
|
+
}
|
|
868
|
+
}
|
|
869
|
+
if (anchor) {
|
|
870
|
+
domOps.insertBefore(parent, el, anchor);
|
|
871
|
+
} else {
|
|
872
|
+
domOps.appendChild(parent, el);
|
|
873
|
+
}
|
|
874
|
+
const refCleanup = applyRef(el, props.ref);
|
|
875
|
+
return {
|
|
876
|
+
type: "element",
|
|
877
|
+
node: el,
|
|
878
|
+
children: mountedChildren,
|
|
879
|
+
eventCleanups,
|
|
880
|
+
attrDisposers,
|
|
881
|
+
refCleanup
|
|
882
|
+
};
|
|
883
|
+
}
|
|
884
|
+
function renderComponentToDOM(component, props, parent, anchor, namespace) {
|
|
885
|
+
const parentInstance = getCurrentInstance();
|
|
886
|
+
const instance = createComponentInstance(component, props, parentInstance);
|
|
887
|
+
if (parentInstance) {
|
|
888
|
+
parentInstance.children.push(instance);
|
|
889
|
+
}
|
|
890
|
+
const prevInstance = setCurrentInstance(instance);
|
|
891
|
+
let result;
|
|
892
|
+
let child;
|
|
893
|
+
try {
|
|
894
|
+
result = component(props);
|
|
895
|
+
if (result && typeof result === "object" && "tag" in result) {
|
|
896
|
+
child = renderElementToDOM(result, parent, anchor, namespace);
|
|
897
|
+
} else {
|
|
898
|
+
child = renderNodeToDOM(result, parent, anchor, namespace);
|
|
899
|
+
}
|
|
900
|
+
} catch (err) {
|
|
901
|
+
setCurrentInstance(prevInstance);
|
|
902
|
+
handleComponentError(instance, err);
|
|
903
|
+
const text = domOps.createTextNode("");
|
|
904
|
+
if (anchor) {
|
|
905
|
+
domOps.insertBefore(parent, text, anchor);
|
|
906
|
+
} else {
|
|
907
|
+
domOps.appendChild(parent, text);
|
|
908
|
+
}
|
|
909
|
+
return {
|
|
910
|
+
type: "component",
|
|
911
|
+
children: [{ type: "text", node: text }],
|
|
912
|
+
disposers: [],
|
|
913
|
+
instance
|
|
914
|
+
};
|
|
915
|
+
}
|
|
916
|
+
setCurrentInstance(prevInstance);
|
|
917
|
+
instance.element = child;
|
|
918
|
+
return {
|
|
919
|
+
type: "component",
|
|
920
|
+
children: [child],
|
|
921
|
+
disposers: instance.effects,
|
|
922
|
+
instance
|
|
923
|
+
};
|
|
924
|
+
}
|
|
925
|
+
function renderFragmentToDOM(children, parent, anchor, namespace) {
|
|
926
|
+
const anchorComment = domOps.createComment("Sinwan-f");
|
|
927
|
+
if (anchor) {
|
|
928
|
+
domOps.insertBefore(parent, anchorComment, anchor);
|
|
929
|
+
} else {
|
|
930
|
+
domOps.appendChild(parent, anchorComment);
|
|
931
|
+
}
|
|
932
|
+
const mounted = [];
|
|
933
|
+
for (const child of children) {
|
|
934
|
+
mounted.push(renderNodeToDOM(child, parent, anchor, namespace));
|
|
935
|
+
}
|
|
936
|
+
return { type: "fragment", children: mounted, anchor: anchorComment };
|
|
937
|
+
}
|
|
938
|
+
function getElementNamespace(tag, parentNamespace) {
|
|
939
|
+
if (tag === "svg")
|
|
940
|
+
return SVG_NS;
|
|
941
|
+
if (tag === "math")
|
|
942
|
+
return MATH_NS;
|
|
943
|
+
return parentNamespace;
|
|
944
|
+
}
|
|
945
|
+
function getChildNamespace(tag, namespace) {
|
|
946
|
+
if (namespace === SVG_NS && tag === "foreignObject") {
|
|
947
|
+
return null;
|
|
948
|
+
}
|
|
949
|
+
return namespace;
|
|
950
|
+
}
|
|
951
|
+
function applyRef(el, ref) {
|
|
952
|
+
const value = ref;
|
|
953
|
+
if (!value) {
|
|
954
|
+
return null;
|
|
955
|
+
}
|
|
956
|
+
if (typeof value === "function") {
|
|
957
|
+
value(el);
|
|
958
|
+
return () => value(null);
|
|
959
|
+
}
|
|
960
|
+
if (typeof value === "object" && "current" in value) {
|
|
961
|
+
value.current = el;
|
|
962
|
+
return () => {
|
|
963
|
+
value.current = null;
|
|
964
|
+
};
|
|
965
|
+
}
|
|
966
|
+
return null;
|
|
967
|
+
}
|
|
968
|
+
|
|
969
|
+
// src/renderer/render-children.ts
|
|
970
|
+
function renderNodeToDOM(node, parent, anchor = null, namespace = null) {
|
|
971
|
+
if (node == null || typeof node === "boolean") {
|
|
972
|
+
const text2 = domOps.createTextNode("");
|
|
973
|
+
insertNode2(parent, text2, anchor);
|
|
974
|
+
return { type: "text", node: text2 };
|
|
975
|
+
}
|
|
976
|
+
if (typeof node === "string") {
|
|
977
|
+
const text2 = domOps.createTextNode(node);
|
|
978
|
+
insertNode2(parent, text2, anchor);
|
|
979
|
+
return { type: "text", node: text2 };
|
|
980
|
+
}
|
|
981
|
+
if (typeof node === "number") {
|
|
982
|
+
const text2 = domOps.createTextNode(String(node));
|
|
983
|
+
insertNode2(parent, text2, anchor);
|
|
984
|
+
return { type: "text", node: text2 };
|
|
985
|
+
}
|
|
986
|
+
if (node instanceof HtmlEscapedString) {
|
|
987
|
+
const text2 = domOps.createTextNode(node.value);
|
|
988
|
+
insertNode2(parent, text2, anchor);
|
|
989
|
+
return { type: "text", node: text2 };
|
|
990
|
+
}
|
|
991
|
+
if (isSignal(node) || isComputed(node)) {
|
|
992
|
+
const text2 = domOps.createTextNode(String(node.value));
|
|
993
|
+
insertNode2(parent, text2, anchor);
|
|
994
|
+
const owner = getCurrentInstance();
|
|
995
|
+
let initialized = false;
|
|
996
|
+
const dispose = effect(() => {
|
|
997
|
+
domOps.setTextContent(text2, String(node.value));
|
|
998
|
+
if (initialized) {
|
|
999
|
+
queueUpdatedHooks(owner);
|
|
1000
|
+
}
|
|
1001
|
+
initialized = true;
|
|
1002
|
+
});
|
|
1003
|
+
return { type: "reactive-text", node: text2, dispose };
|
|
1004
|
+
}
|
|
1005
|
+
if (Array.isArray(node)) {
|
|
1006
|
+
return renderArrayToDOM(node, parent, anchor, namespace);
|
|
1007
|
+
}
|
|
1008
|
+
if (node instanceof Promise) {
|
|
1009
|
+
const placeholder = domOps.createTextNode("");
|
|
1010
|
+
insertNode2(parent, placeholder, anchor);
|
|
1011
|
+
node.then((resolved) => {
|
|
1012
|
+
const mounted = renderNodeToDOM(resolved, parent, placeholder, namespace);
|
|
1013
|
+
domOps.remove(placeholder);
|
|
1014
|
+
});
|
|
1015
|
+
return { type: "text", node: placeholder };
|
|
1016
|
+
}
|
|
1017
|
+
if (typeof node === "object" && "tag" in node) {
|
|
1018
|
+
return renderElementToDOM(node, parent, anchor, namespace);
|
|
1019
|
+
}
|
|
1020
|
+
const text = domOps.createTextNode(String(node));
|
|
1021
|
+
insertNode2(parent, text, anchor);
|
|
1022
|
+
return { type: "text", node: text };
|
|
1023
|
+
}
|
|
1024
|
+
function renderArrayToDOM(nodes, parent, anchor, namespace) {
|
|
1025
|
+
const anchorComment = domOps.createComment("Sinwan-f");
|
|
1026
|
+
insertNode2(parent, anchorComment, anchor);
|
|
1027
|
+
const children = [];
|
|
1028
|
+
for (const child of nodes) {
|
|
1029
|
+
children.push(renderNodeToDOM(child, parent, anchor, namespace));
|
|
1030
|
+
}
|
|
1031
|
+
return { type: "fragment", children, anchor: anchorComment };
|
|
1032
|
+
}
|
|
1033
|
+
function renderChildrenToDOM(children, parent, namespace = null) {
|
|
1034
|
+
const mounted = [];
|
|
1035
|
+
for (const child of children) {
|
|
1036
|
+
mounted.push(renderNodeToDOM(child, parent, null, namespace));
|
|
1037
|
+
}
|
|
1038
|
+
return mounted;
|
|
1039
|
+
}
|
|
1040
|
+
function insertNode2(parent, child, anchor) {
|
|
1041
|
+
if (anchor) {
|
|
1042
|
+
domOps.insertBefore(parent, child, anchor);
|
|
1043
|
+
} else {
|
|
1044
|
+
domOps.appendChild(parent, child);
|
|
1045
|
+
}
|
|
1046
|
+
}
|
|
1047
|
+
|
|
1048
|
+
// src/renderer/mount.ts
|
|
1049
|
+
function mount(component, container, props) {
|
|
1050
|
+
container.innerHTML = "";
|
|
1051
|
+
const mergedProps = props ?? {};
|
|
1052
|
+
const instance = createComponentInstance(component, mergedProps, null);
|
|
1053
|
+
let result;
|
|
1054
|
+
let root;
|
|
1055
|
+
setCurrentInstance(instance);
|
|
1056
|
+
try {
|
|
1057
|
+
result = component(mergedProps);
|
|
1058
|
+
if (result instanceof Promise) {
|
|
1059
|
+
const placeholder = document.createTextNode("");
|
|
1060
|
+
container.appendChild(placeholder);
|
|
1061
|
+
root = { type: "text", node: placeholder };
|
|
1062
|
+
result.then((resolved) => {
|
|
1063
|
+
container.innerHTML = "";
|
|
1064
|
+
setCurrentInstance(instance);
|
|
1065
|
+
root = renderElementToDOM(resolved, container);
|
|
1066
|
+
setCurrentInstance(null);
|
|
1067
|
+
instance.element = root;
|
|
1068
|
+
fireMountedHooks(instance);
|
|
1069
|
+
});
|
|
1070
|
+
} else if (result && typeof result === "object" && "tag" in result) {
|
|
1071
|
+
root = renderElementToDOM(result, container);
|
|
1072
|
+
} else {
|
|
1073
|
+
root = renderNodeToDOM(result, container);
|
|
1074
|
+
}
|
|
1075
|
+
} catch (err) {
|
|
1076
|
+
setCurrentInstance(null);
|
|
1077
|
+
handleComponentError(instance, err);
|
|
1078
|
+
return {
|
|
1079
|
+
root: { type: "text", node: document.createTextNode("") },
|
|
1080
|
+
unmount() {}
|
|
1081
|
+
};
|
|
1082
|
+
}
|
|
1083
|
+
setCurrentInstance(null);
|
|
1084
|
+
instance.element = root;
|
|
1085
|
+
fireMountedHooks(instance);
|
|
1086
|
+
return {
|
|
1087
|
+
root,
|
|
1088
|
+
unmount() {
|
|
1089
|
+
fireUnmountedHooks(instance);
|
|
1090
|
+
unmountNode(root);
|
|
1091
|
+
container.innerHTML = "";
|
|
1092
|
+
}
|
|
1093
|
+
};
|
|
1094
|
+
}
|
|
1095
|
+
function render(node, container) {
|
|
1096
|
+
container.innerHTML = "";
|
|
1097
|
+
const root = renderNodeToDOM(node, container);
|
|
1098
|
+
return {
|
|
1099
|
+
root,
|
|
1100
|
+
unmount() {
|
|
1101
|
+
unmountNode(root);
|
|
1102
|
+
container.innerHTML = "";
|
|
1103
|
+
}
|
|
1104
|
+
};
|
|
1105
|
+
}
|
|
1106
|
+
export {
|
|
1107
|
+
unmountNode,
|
|
1108
|
+
toEventName,
|
|
1109
|
+
setDOMOps,
|
|
1110
|
+
resetDOMOps,
|
|
1111
|
+
renderNodeToDOM,
|
|
1112
|
+
renderElementToDOM,
|
|
1113
|
+
renderChildrenToDOM,
|
|
1114
|
+
render,
|
|
1115
|
+
mount,
|
|
1116
|
+
isEventProp,
|
|
1117
|
+
domOps,
|
|
1118
|
+
bindEvents,
|
|
1119
|
+
bindEvent,
|
|
1120
|
+
applyAttributes
|
|
1121
|
+
};
|
|
1122
|
+
|
|
1123
|
+
//# debugId=9C1A39184F093FF264756E2164756E21
|
|
1124
|
+
//# sourceMappingURL=index.development.js.map
|