@sigx/terminal 0.1.5 → 0.1.7
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/index.js +1053 -1149
- package/dist/index.js.map +1 -1
- package/package.json +9 -8
package/dist/index.js
CHANGED
|
@@ -1,7 +1,14 @@
|
|
|
1
|
-
|
|
1
|
+
var __commonJSMin = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
|
|
2
|
+
const ComputedSymbol = Symbol("computed");
|
|
2
3
|
let activeEffect = null;
|
|
3
|
-
|
|
4
|
-
|
|
4
|
+
var batchDepth = 0;
|
|
5
|
+
var pendingEffects = /* @__PURE__ */ new Set();
|
|
6
|
+
function setActiveEffect(effect) {
|
|
7
|
+
activeEffect = effect;
|
|
8
|
+
}
|
|
9
|
+
function getActiveEffect() {
|
|
10
|
+
return activeEffect;
|
|
11
|
+
}
|
|
5
12
|
function batch(fn) {
|
|
6
13
|
batchDepth++;
|
|
7
14
|
try {
|
|
@@ -11,10 +18,25 @@ function batch(fn) {
|
|
|
11
18
|
if (batchDepth === 0) {
|
|
12
19
|
const effects = Array.from(pendingEffects);
|
|
13
20
|
pendingEffects.clear();
|
|
14
|
-
for (const effect
|
|
21
|
+
for (const effect of effects) effect();
|
|
15
22
|
}
|
|
16
23
|
}
|
|
17
24
|
}
|
|
25
|
+
function cleanup(effect) {
|
|
26
|
+
if (!effect.deps) return;
|
|
27
|
+
for (const dep of effect.deps) dep.delete(effect);
|
|
28
|
+
effect.deps.length = 0;
|
|
29
|
+
}
|
|
30
|
+
function track(depSet) {
|
|
31
|
+
if (!activeEffect) return;
|
|
32
|
+
depSet.add(activeEffect);
|
|
33
|
+
activeEffect.deps.push(depSet);
|
|
34
|
+
}
|
|
35
|
+
function trigger(depSet) {
|
|
36
|
+
const effects = Array.from(depSet);
|
|
37
|
+
for (const effect of effects) if (batchDepth > 0) pendingEffects.add(effect);
|
|
38
|
+
else effect();
|
|
39
|
+
}
|
|
18
40
|
function runEffect(fn) {
|
|
19
41
|
const effectFn = function() {
|
|
20
42
|
cleanup(effectFn);
|
|
@@ -28,22 +50,226 @@ function runEffect(fn) {
|
|
|
28
50
|
runner.stop = () => cleanup(effectFn);
|
|
29
51
|
return runner;
|
|
30
52
|
}
|
|
31
|
-
function
|
|
32
|
-
|
|
33
|
-
for (const dep of effect$1.deps) dep.delete(effect$1);
|
|
34
|
-
effect$1.deps.length = 0;
|
|
53
|
+
function effect(fn) {
|
|
54
|
+
return runEffect(fn);
|
|
35
55
|
}
|
|
36
|
-
function
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
56
|
+
function untrack(fn) {
|
|
57
|
+
const prev = activeEffect;
|
|
58
|
+
activeEffect = null;
|
|
59
|
+
try {
|
|
60
|
+
return fn();
|
|
61
|
+
} finally {
|
|
62
|
+
activeEffect = prev;
|
|
63
|
+
}
|
|
40
64
|
}
|
|
41
|
-
function
|
|
42
|
-
const effects =
|
|
43
|
-
|
|
44
|
-
|
|
65
|
+
function effectScope(detached) {
|
|
66
|
+
const effects = [];
|
|
67
|
+
let active = true;
|
|
68
|
+
return {
|
|
69
|
+
run(fn) {
|
|
70
|
+
if (!active) return void 0;
|
|
71
|
+
return fn();
|
|
72
|
+
},
|
|
73
|
+
stop() {
|
|
74
|
+
active = false;
|
|
75
|
+
effects.forEach((e) => e());
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
const ITERATE_KEY = Symbol("iterate");
|
|
80
|
+
const reactiveToRaw = /* @__PURE__ */ new WeakMap();
|
|
81
|
+
const rawToReactive = /* @__PURE__ */ new WeakMap();
|
|
82
|
+
function toRaw(observed) {
|
|
83
|
+
const raw = reactiveToRaw.get(observed);
|
|
84
|
+
return raw ? toRaw(raw) : observed;
|
|
85
|
+
}
|
|
86
|
+
function isReactive(value) {
|
|
87
|
+
return reactiveToRaw.has(value);
|
|
88
|
+
}
|
|
89
|
+
function isCollection(value) {
|
|
90
|
+
if (!value || typeof value !== "object") return false;
|
|
91
|
+
const ctor = value.constructor;
|
|
92
|
+
return ctor === Set || ctor === Map || ctor === WeakSet || ctor === WeakMap;
|
|
93
|
+
}
|
|
94
|
+
function isIterableCollection(value) {
|
|
95
|
+
if (!value || typeof value !== "object") return false;
|
|
96
|
+
const ctor = value.constructor;
|
|
97
|
+
return ctor === Set || ctor === Map;
|
|
98
|
+
}
|
|
99
|
+
function shouldNotProxy(value) {
|
|
100
|
+
if (!value || typeof value !== "object") return false;
|
|
101
|
+
const proto = Object.prototype.toString.call(value);
|
|
102
|
+
return [
|
|
103
|
+
"[object Date]",
|
|
104
|
+
"[object RegExp]",
|
|
105
|
+
"[object Error]",
|
|
106
|
+
"[object Promise]",
|
|
107
|
+
"[object ArrayBuffer]",
|
|
108
|
+
"[object DataView]",
|
|
109
|
+
"[object Int8Array]",
|
|
110
|
+
"[object Uint8Array]",
|
|
111
|
+
"[object Uint8ClampedArray]",
|
|
112
|
+
"[object Int16Array]",
|
|
113
|
+
"[object Uint16Array]",
|
|
114
|
+
"[object Int32Array]",
|
|
115
|
+
"[object Uint32Array]",
|
|
116
|
+
"[object Float32Array]",
|
|
117
|
+
"[object Float64Array]",
|
|
118
|
+
"[object BigInt64Array]",
|
|
119
|
+
"[object BigUint64Array]"
|
|
120
|
+
].includes(proto);
|
|
121
|
+
}
|
|
122
|
+
function createCollectionInstrumentations(depsMap, getOrCreateDep) {
|
|
123
|
+
const instrumentations = {};
|
|
124
|
+
instrumentations.has = function(key) {
|
|
125
|
+
const target = toRaw(this);
|
|
126
|
+
const rawKey = toRaw(key);
|
|
127
|
+
track(getOrCreateDep(rawKey));
|
|
128
|
+
return target.has(rawKey);
|
|
129
|
+
};
|
|
130
|
+
instrumentations.get = function(key) {
|
|
131
|
+
const target = toRaw(this);
|
|
132
|
+
const rawKey = toRaw(key);
|
|
133
|
+
track(getOrCreateDep(rawKey));
|
|
134
|
+
const value = target.get(rawKey);
|
|
135
|
+
if (value && typeof value === "object") return rawToReactive.get(value) || value;
|
|
136
|
+
return value;
|
|
137
|
+
};
|
|
138
|
+
Object.defineProperty(instrumentations, "size", { get() {
|
|
139
|
+
const target = toRaw(this);
|
|
140
|
+
track(getOrCreateDep(ITERATE_KEY));
|
|
141
|
+
return target.size;
|
|
142
|
+
} });
|
|
143
|
+
instrumentations.forEach = function(callback, thisArg) {
|
|
144
|
+
const target = toRaw(this);
|
|
145
|
+
track(getOrCreateDep(ITERATE_KEY));
|
|
146
|
+
target.forEach((value, key) => {
|
|
147
|
+
const reactiveValue = value && typeof value === "object" ? rawToReactive.get(value) || value : value;
|
|
148
|
+
const reactiveKey = key && typeof key === "object" ? rawToReactive.get(key) || key : key;
|
|
149
|
+
callback.call(thisArg, reactiveValue, reactiveKey, this);
|
|
150
|
+
});
|
|
151
|
+
};
|
|
152
|
+
instrumentations.keys = function() {
|
|
153
|
+
const target = toRaw(this);
|
|
154
|
+
track(getOrCreateDep(ITERATE_KEY));
|
|
155
|
+
return createReactiveIterator(target.keys(), false);
|
|
156
|
+
};
|
|
157
|
+
instrumentations.values = function() {
|
|
158
|
+
const target = toRaw(this);
|
|
159
|
+
track(getOrCreateDep(ITERATE_KEY));
|
|
160
|
+
return createReactiveIterator(target.values(), true);
|
|
161
|
+
};
|
|
162
|
+
instrumentations.entries = function() {
|
|
163
|
+
const target = toRaw(this);
|
|
164
|
+
track(getOrCreateDep(ITERATE_KEY));
|
|
165
|
+
return createReactiveEntriesIterator(target.entries());
|
|
166
|
+
};
|
|
167
|
+
instrumentations[Symbol.iterator] = function() {
|
|
168
|
+
const target = toRaw(this);
|
|
169
|
+
track(getOrCreateDep(ITERATE_KEY));
|
|
170
|
+
if (target instanceof Set) return createReactiveIterator(target.values(), true);
|
|
171
|
+
else return createReactiveEntriesIterator(target.entries());
|
|
172
|
+
};
|
|
173
|
+
instrumentations.add = function(value) {
|
|
174
|
+
const target = toRaw(this);
|
|
175
|
+
const rawValue = toRaw(value);
|
|
176
|
+
const hadKey = target.has(rawValue);
|
|
177
|
+
target.add(rawValue);
|
|
178
|
+
if (!hadKey) {
|
|
179
|
+
const dep = depsMap.get(rawValue);
|
|
180
|
+
if (dep) trigger(dep);
|
|
181
|
+
const iterDep = depsMap.get(ITERATE_KEY);
|
|
182
|
+
if (iterDep) trigger(iterDep);
|
|
183
|
+
}
|
|
184
|
+
return this;
|
|
185
|
+
};
|
|
186
|
+
instrumentations.set = function(key, value) {
|
|
187
|
+
const target = toRaw(this);
|
|
188
|
+
const rawKey = toRaw(key);
|
|
189
|
+
const rawValue = toRaw(value);
|
|
190
|
+
const hadKey = target.has(rawKey);
|
|
191
|
+
const oldValue = target.get(rawKey);
|
|
192
|
+
target.set(rawKey, rawValue);
|
|
193
|
+
if (!hadKey) {
|
|
194
|
+
const iterDep = depsMap.get(ITERATE_KEY);
|
|
195
|
+
if (iterDep) trigger(iterDep);
|
|
196
|
+
}
|
|
197
|
+
if (!hadKey || !Object.is(oldValue, rawValue)) {
|
|
198
|
+
const dep = depsMap.get(rawKey);
|
|
199
|
+
if (dep) trigger(dep);
|
|
200
|
+
}
|
|
201
|
+
return this;
|
|
202
|
+
};
|
|
203
|
+
instrumentations.delete = function(key) {
|
|
204
|
+
const target = toRaw(this);
|
|
205
|
+
const rawKey = toRaw(key);
|
|
206
|
+
const hadKey = target.has(rawKey);
|
|
207
|
+
const result = target.delete(rawKey);
|
|
208
|
+
if (hadKey) {
|
|
209
|
+
const dep = depsMap.get(rawKey);
|
|
210
|
+
if (dep) trigger(dep);
|
|
211
|
+
const iterDep = depsMap.get(ITERATE_KEY);
|
|
212
|
+
if (iterDep) trigger(iterDep);
|
|
213
|
+
}
|
|
214
|
+
return result;
|
|
215
|
+
};
|
|
216
|
+
instrumentations.clear = function() {
|
|
217
|
+
const target = toRaw(this);
|
|
218
|
+
const hadItems = target.size > 0;
|
|
219
|
+
target.clear();
|
|
220
|
+
if (hadItems) for (const dep of depsMap.values()) trigger(dep);
|
|
221
|
+
};
|
|
222
|
+
return instrumentations;
|
|
223
|
+
}
|
|
224
|
+
function createReactiveIterator(innerIterator, wrapValues) {
|
|
225
|
+
return {
|
|
226
|
+
next() {
|
|
227
|
+
const { value, done } = innerIterator.next();
|
|
228
|
+
if (done) return {
|
|
229
|
+
value: void 0,
|
|
230
|
+
done: true
|
|
231
|
+
};
|
|
232
|
+
return {
|
|
233
|
+
value: wrapValues && value && typeof value === "object" ? rawToReactive.get(value) || value : value,
|
|
234
|
+
done: false
|
|
235
|
+
};
|
|
236
|
+
},
|
|
237
|
+
[Symbol.iterator]() {
|
|
238
|
+
return this;
|
|
239
|
+
}
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
function createReactiveEntriesIterator(innerIterator) {
|
|
243
|
+
return {
|
|
244
|
+
next() {
|
|
245
|
+
const { value, done } = innerIterator.next();
|
|
246
|
+
if (done) return {
|
|
247
|
+
value: void 0,
|
|
248
|
+
done: true
|
|
249
|
+
};
|
|
250
|
+
const [key, val] = value;
|
|
251
|
+
return {
|
|
252
|
+
value: [key && typeof key === "object" ? rawToReactive.get(key) || key : key, val && typeof val === "object" ? rawToReactive.get(val) || val : val],
|
|
253
|
+
done: false
|
|
254
|
+
};
|
|
255
|
+
},
|
|
256
|
+
[Symbol.iterator]() {
|
|
257
|
+
return this;
|
|
258
|
+
}
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
function isPrimitive(value) {
|
|
262
|
+
if (value === null || value === void 0) return true;
|
|
263
|
+
const type = typeof value;
|
|
264
|
+
return type === "string" || type === "number" || type === "boolean" || type === "symbol" || type === "bigint";
|
|
265
|
+
}
|
|
266
|
+
var accessObserver = null;
|
|
267
|
+
function getAccessObserver() {
|
|
268
|
+
return accessObserver;
|
|
269
|
+
}
|
|
270
|
+
function setAccessObserver(observer) {
|
|
271
|
+
accessObserver = observer;
|
|
45
272
|
}
|
|
46
|
-
let accessObserver = null;
|
|
47
273
|
function detectAccess(selector) {
|
|
48
274
|
let result = null;
|
|
49
275
|
const prev = accessObserver;
|
|
@@ -57,19 +283,43 @@ function detectAccess(selector) {
|
|
|
57
283
|
}
|
|
58
284
|
return result;
|
|
59
285
|
}
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
286
|
+
var arrayInstrumentations = {};
|
|
287
|
+
[
|
|
288
|
+
"push",
|
|
289
|
+
"pop",
|
|
290
|
+
"shift",
|
|
291
|
+
"unshift",
|
|
292
|
+
"splice",
|
|
293
|
+
"sort",
|
|
294
|
+
"reverse"
|
|
295
|
+
].forEach((method) => {
|
|
296
|
+
arrayInstrumentations[method] = function(...args) {
|
|
297
|
+
let res;
|
|
298
|
+
batch(() => {
|
|
299
|
+
res = Array.prototype[method].apply(this, args);
|
|
300
|
+
});
|
|
301
|
+
return res;
|
|
302
|
+
};
|
|
303
|
+
});
|
|
69
304
|
function signal(target) {
|
|
305
|
+
if (isPrimitive(target)) return signal({ value: target });
|
|
306
|
+
const objectTarget = target;
|
|
307
|
+
if (shouldNotProxy(objectTarget)) return objectTarget;
|
|
308
|
+
if (isReactive(objectTarget)) return objectTarget;
|
|
309
|
+
const existingProxy = rawToReactive.get(objectTarget);
|
|
310
|
+
if (existingProxy) return existingProxy;
|
|
70
311
|
const depsMap = /* @__PURE__ */ new Map();
|
|
71
312
|
const reactiveCache = /* @__PURE__ */ new WeakMap();
|
|
72
|
-
|
|
313
|
+
const getOrCreateDep = (key) => {
|
|
314
|
+
let dep = depsMap.get(key);
|
|
315
|
+
if (!dep) {
|
|
316
|
+
dep = /* @__PURE__ */ new Set();
|
|
317
|
+
depsMap.set(key, dep);
|
|
318
|
+
}
|
|
319
|
+
return dep;
|
|
320
|
+
};
|
|
321
|
+
const collectionInstrumentations = isCollection(objectTarget) ? createCollectionInstrumentations(depsMap, getOrCreateDep) : null;
|
|
322
|
+
const proxy = new Proxy(objectTarget, {
|
|
73
323
|
get(obj, prop, receiver) {
|
|
74
324
|
if (prop === "$set") return (newValue) => {
|
|
75
325
|
batch(() => {
|
|
@@ -85,16 +335,22 @@ function signal(target) {
|
|
|
85
335
|
}
|
|
86
336
|
});
|
|
87
337
|
};
|
|
338
|
+
if (collectionInstrumentations) {
|
|
339
|
+
if (prop === "size" && isIterableCollection(obj)) {
|
|
340
|
+
track(getOrCreateDep(ITERATE_KEY));
|
|
341
|
+
return obj.size;
|
|
342
|
+
}
|
|
343
|
+
if (prop in collectionInstrumentations) {
|
|
344
|
+
const instrumented = collectionInstrumentations[prop];
|
|
345
|
+
if (typeof instrumented === "function") return instrumented.bind(receiver);
|
|
346
|
+
return instrumented;
|
|
347
|
+
}
|
|
348
|
+
}
|
|
88
349
|
if (Array.isArray(obj) && typeof prop === "string" && arrayInstrumentations.hasOwnProperty(prop)) return arrayInstrumentations[prop];
|
|
89
350
|
const value = Reflect.get(obj, prop);
|
|
90
351
|
if (accessObserver) accessObserver(receiver, prop);
|
|
91
|
-
|
|
92
|
-
if (!
|
|
93
|
-
dep = /* @__PURE__ */ new Set();
|
|
94
|
-
depsMap.set(prop, dep);
|
|
95
|
-
}
|
|
96
|
-
track(dep);
|
|
97
|
-
if (value && typeof value === "object") {
|
|
352
|
+
if (!collectionInstrumentations) track(getOrCreateDep(prop));
|
|
353
|
+
if (value && typeof value === "object" && !shouldNotProxy(value)) {
|
|
98
354
|
let cached = reactiveCache.get(value);
|
|
99
355
|
if (!cached) {
|
|
100
356
|
cached = signal(value);
|
|
@@ -134,28 +390,26 @@ function signal(target) {
|
|
|
134
390
|
return result;
|
|
135
391
|
}
|
|
136
392
|
});
|
|
393
|
+
reactiveToRaw.set(proxy, objectTarget);
|
|
394
|
+
rawToReactive.set(objectTarget, proxy);
|
|
395
|
+
return proxy;
|
|
137
396
|
}
|
|
138
|
-
function
|
|
139
|
-
|
|
397
|
+
function traverse(value, depth = Infinity, seen = /* @__PURE__ */ new Set()) {
|
|
398
|
+
if (depth <= 0) return value;
|
|
399
|
+
if (value === null || typeof value !== "object") return value;
|
|
400
|
+
if (seen.has(value)) return value;
|
|
401
|
+
seen.add(value);
|
|
402
|
+
if (Array.isArray(value)) for (let i = 0; i < value.length; i++) traverse(value[i], depth - 1, seen);
|
|
403
|
+
else if (value instanceof Map) value.forEach((v, k) => {
|
|
404
|
+
traverse(k, depth - 1, seen);
|
|
405
|
+
traverse(v, depth - 1, seen);
|
|
406
|
+
});
|
|
407
|
+
else if (value instanceof Set) value.forEach((v) => {
|
|
408
|
+
traverse(v, depth - 1, seen);
|
|
409
|
+
});
|
|
410
|
+
else for (const key of Object.keys(value)) traverse(value[key], depth - 1, seen);
|
|
411
|
+
return value;
|
|
140
412
|
}
|
|
141
|
-
const arrayInstrumentations = {};
|
|
142
|
-
[
|
|
143
|
-
"push",
|
|
144
|
-
"pop",
|
|
145
|
-
"shift",
|
|
146
|
-
"unshift",
|
|
147
|
-
"splice",
|
|
148
|
-
"sort",
|
|
149
|
-
"reverse"
|
|
150
|
-
].forEach((method) => {
|
|
151
|
-
arrayInstrumentations[method] = function(...args) {
|
|
152
|
-
let res;
|
|
153
|
-
batch(() => {
|
|
154
|
-
res = Array.prototype[method].apply(this, args);
|
|
155
|
-
});
|
|
156
|
-
return res;
|
|
157
|
-
};
|
|
158
|
-
});
|
|
159
413
|
function watch(source, cb, options) {
|
|
160
414
|
let oldValue;
|
|
161
415
|
let isFirst = true;
|
|
@@ -163,8 +417,13 @@ function watch(source, cb, options) {
|
|
|
163
417
|
let paused = false;
|
|
164
418
|
let pendingValue;
|
|
165
419
|
let hasPending = false;
|
|
420
|
+
let stopped = false;
|
|
421
|
+
const deep = options?.deep;
|
|
422
|
+
const traverseDepth = deep === true ? Infinity : typeof deep === "number" ? deep : 0;
|
|
166
423
|
const runner = effect(() => {
|
|
167
|
-
|
|
424
|
+
if (stopped) return;
|
|
425
|
+
let newValue = typeof source === "function" ? source() : source;
|
|
426
|
+
if (traverseDepth > 0) traverse(newValue, traverseDepth);
|
|
168
427
|
if (paused) {
|
|
169
428
|
pendingValue = newValue;
|
|
170
429
|
hasPending = true;
|
|
@@ -174,15 +433,24 @@ function watch(source, cb, options) {
|
|
|
174
433
|
if (options?.immediate) {
|
|
175
434
|
if (cleanupFn) cleanupFn();
|
|
176
435
|
cb(newValue, oldValue, (fn) => cleanupFn = fn);
|
|
436
|
+
if (options?.once) {
|
|
437
|
+
stopped = true;
|
|
438
|
+
queueMicrotask(() => stop());
|
|
439
|
+
}
|
|
177
440
|
}
|
|
178
441
|
isFirst = false;
|
|
179
442
|
} else {
|
|
180
443
|
if (cleanupFn) cleanupFn();
|
|
181
444
|
cb(newValue, oldValue, (fn) => cleanupFn = fn);
|
|
445
|
+
if (options?.once) {
|
|
446
|
+
stopped = true;
|
|
447
|
+
queueMicrotask(() => stop());
|
|
448
|
+
}
|
|
182
449
|
}
|
|
183
450
|
oldValue = newValue;
|
|
184
451
|
});
|
|
185
452
|
const stop = () => {
|
|
453
|
+
stopped = true;
|
|
186
454
|
runner.stop();
|
|
187
455
|
if (cleanupFn) cleanupFn();
|
|
188
456
|
};
|
|
@@ -206,135 +474,281 @@ function watch(source, cb, options) {
|
|
|
206
474
|
resume
|
|
207
475
|
});
|
|
208
476
|
}
|
|
209
|
-
function
|
|
210
|
-
|
|
211
|
-
let
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
477
|
+
function computed(getterOrOptions) {
|
|
478
|
+
let getter;
|
|
479
|
+
let setter;
|
|
480
|
+
if (typeof getterOrOptions === "function") getter = getterOrOptions;
|
|
481
|
+
else {
|
|
482
|
+
getter = getterOrOptions.get;
|
|
483
|
+
setter = getterOrOptions.set;
|
|
484
|
+
}
|
|
485
|
+
const subscribers = /* @__PURE__ */ new Set();
|
|
486
|
+
let cachedValue;
|
|
487
|
+
let dirty = true;
|
|
488
|
+
const computedEffect = function() {
|
|
489
|
+
if (!dirty) {
|
|
490
|
+
dirty = true;
|
|
491
|
+
trigger(subscribers);
|
|
220
492
|
}
|
|
221
493
|
};
|
|
494
|
+
computedEffect.deps = [];
|
|
495
|
+
const computeValue = () => {
|
|
496
|
+
cleanup(computedEffect);
|
|
497
|
+
const prevEffect = getActiveEffect();
|
|
498
|
+
setActiveEffect(computedEffect);
|
|
499
|
+
try {
|
|
500
|
+
cachedValue = getter();
|
|
501
|
+
dirty = false;
|
|
502
|
+
return cachedValue;
|
|
503
|
+
} finally {
|
|
504
|
+
setActiveEffect(prevEffect);
|
|
505
|
+
}
|
|
506
|
+
};
|
|
507
|
+
const computedObj = {
|
|
508
|
+
[ComputedSymbol]: true,
|
|
509
|
+
get value() {
|
|
510
|
+
const observer = getAccessObserver();
|
|
511
|
+
if (observer) {
|
|
512
|
+
observer(computedObj, "value");
|
|
513
|
+
setAccessObserver(null);
|
|
514
|
+
}
|
|
515
|
+
track(subscribers);
|
|
516
|
+
const result = dirty ? computeValue() : cachedValue;
|
|
517
|
+
if (observer) setAccessObserver(observer);
|
|
518
|
+
return result;
|
|
519
|
+
}
|
|
520
|
+
};
|
|
521
|
+
if (setter) {
|
|
522
|
+
Object.defineProperty(computedObj, "value", {
|
|
523
|
+
get() {
|
|
524
|
+
const observer = getAccessObserver();
|
|
525
|
+
if (observer) {
|
|
526
|
+
observer(computedObj, "value");
|
|
527
|
+
setAccessObserver(null);
|
|
528
|
+
}
|
|
529
|
+
track(subscribers);
|
|
530
|
+
const result = dirty ? computeValue() : cachedValue;
|
|
531
|
+
if (observer) setAccessObserver(observer);
|
|
532
|
+
return result;
|
|
533
|
+
},
|
|
534
|
+
set(newValue) {
|
|
535
|
+
setter(newValue);
|
|
536
|
+
},
|
|
537
|
+
enumerable: true,
|
|
538
|
+
configurable: false
|
|
539
|
+
});
|
|
540
|
+
return computedObj;
|
|
541
|
+
}
|
|
542
|
+
return computedObj;
|
|
222
543
|
}
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
//#region ../runtime-core/src/platform.ts
|
|
226
|
-
let platformSyncProcessor$1 = null;
|
|
227
|
-
/**
|
|
228
|
-
* Set the platform-specific sync processor for intrinsic elements.
|
|
229
|
-
* Called by runtime-dom to handle checkbox/radio/select sync bindings.
|
|
230
|
-
*/
|
|
231
|
-
function setPlatformSyncProcessor(fn) {
|
|
232
|
-
platformSyncProcessor$1 = fn;
|
|
233
|
-
}
|
|
234
|
-
/**
|
|
235
|
-
* Get the current platform sync processor (for internal use).
|
|
236
|
-
*/
|
|
237
|
-
function getPlatformSyncProcessor() {
|
|
238
|
-
return platformSyncProcessor$1;
|
|
544
|
+
function isComputed(value) {
|
|
545
|
+
return value !== null && typeof value === "object" && ComputedSymbol in value;
|
|
239
546
|
}
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
547
|
+
var platformModelProcessor = null;
|
|
548
|
+
function setPlatformModelProcessor(fn) {
|
|
549
|
+
platformModelProcessor = fn;
|
|
550
|
+
}
|
|
551
|
+
function getPlatformModelProcessor() {
|
|
552
|
+
return platformModelProcessor;
|
|
553
|
+
}
|
|
554
|
+
var plugins = [];
|
|
244
555
|
function registerComponentPlugin(plugin) {
|
|
245
|
-
plugins
|
|
556
|
+
plugins.push(plugin);
|
|
246
557
|
}
|
|
247
|
-
/**
|
|
248
|
-
* Get all registered plugins (internal use)
|
|
249
|
-
*/
|
|
250
558
|
function getComponentPlugins() {
|
|
251
|
-
return plugins
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
/**
|
|
255
|
-
* Register a function that will be called to extend every component context.
|
|
256
|
-
* Extensions are called in order of registration.
|
|
257
|
-
*
|
|
258
|
-
* @example
|
|
259
|
-
* ```ts
|
|
260
|
-
* // In @sigx/server-renderer/client
|
|
261
|
-
* registerContextExtension((ctx) => {
|
|
262
|
-
* ctx.ssr = { load: () => {} };
|
|
263
|
-
* });
|
|
264
|
-
* ```
|
|
265
|
-
*/
|
|
559
|
+
return plugins;
|
|
560
|
+
}
|
|
561
|
+
var contextExtensions = [];
|
|
266
562
|
function registerContextExtension(extension) {
|
|
267
563
|
contextExtensions.push(extension);
|
|
268
564
|
}
|
|
269
|
-
/**
|
|
270
|
-
* Apply all registered context extensions to a context object.
|
|
271
|
-
* Called internally by the renderer when creating component contexts.
|
|
272
|
-
*/
|
|
273
565
|
function applyContextExtensions(ctx) {
|
|
274
566
|
for (const extension of contextExtensions) extension(ctx);
|
|
275
567
|
}
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
568
|
+
var require___vite_browser_external = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
569
|
+
module.exports = {};
|
|
570
|
+
}));
|
|
571
|
+
var asyncLocalStorage = null;
|
|
572
|
+
try {
|
|
573
|
+
if (typeof globalThis !== "undefined" && typeof globalThis.process !== "undefined") {
|
|
574
|
+
const nodeAsync = globalThis.process?.versions?.node ? require___vite_browser_external() : null;
|
|
575
|
+
if (nodeAsync?.AsyncLocalStorage) asyncLocalStorage = new nodeAsync.AsyncLocalStorage();
|
|
576
|
+
}
|
|
577
|
+
} catch {}
|
|
578
|
+
var _fallbackContext = {
|
|
579
|
+
currentComponentContext: null,
|
|
580
|
+
currentSuspenseBoundary: null
|
|
581
|
+
};
|
|
582
|
+
function getRequestContext() {
|
|
583
|
+
if (asyncLocalStorage) {
|
|
584
|
+
const store = asyncLocalStorage.getStore();
|
|
585
|
+
if (store) return store;
|
|
586
|
+
}
|
|
587
|
+
return _fallbackContext;
|
|
588
|
+
}
|
|
589
|
+
function getCurrentInstanceSafe() {
|
|
590
|
+
return getRequestContext().currentComponentContext;
|
|
591
|
+
}
|
|
592
|
+
function setCurrentInstanceSafe(ctx) {
|
|
593
|
+
const reqCtx = getRequestContext();
|
|
594
|
+
const prev = reqCtx.currentComponentContext;
|
|
595
|
+
reqCtx.currentComponentContext = ctx;
|
|
596
|
+
return prev;
|
|
597
|
+
}
|
|
598
|
+
function getCurrentSuspenseBoundarySafe() {
|
|
599
|
+
return getRequestContext().currentSuspenseBoundary;
|
|
600
|
+
}
|
|
601
|
+
function setCurrentSuspenseBoundarySafe(boundary) {
|
|
602
|
+
const reqCtx = getRequestContext();
|
|
603
|
+
const prev = reqCtx.currentSuspenseBoundary;
|
|
604
|
+
reqCtx.currentSuspenseBoundary = boundary;
|
|
605
|
+
return prev;
|
|
606
|
+
}
|
|
607
|
+
function runInRequestScope(fn) {
|
|
608
|
+
if (asyncLocalStorage) return asyncLocalStorage.run({
|
|
609
|
+
currentComponentContext: null,
|
|
610
|
+
currentSuspenseBoundary: null
|
|
611
|
+
}, fn);
|
|
612
|
+
return fn();
|
|
613
|
+
}
|
|
614
|
+
function hasRequestIsolation() {
|
|
615
|
+
return asyncLocalStorage !== null;
|
|
616
|
+
}
|
|
617
|
+
var currentComponentContext = null;
|
|
618
|
+
function getCurrentInstance() {
|
|
619
|
+
return getCurrentInstanceSafe() ?? currentComponentContext;
|
|
620
|
+
}
|
|
621
|
+
function setCurrentInstance(ctx) {
|
|
622
|
+
const prevSafe = setCurrentInstanceSafe(ctx);
|
|
623
|
+
const prevModule = currentComponentContext;
|
|
624
|
+
currentComponentContext = ctx;
|
|
625
|
+
return prevSafe ?? prevModule;
|
|
626
|
+
}
|
|
627
|
+
function onMounted(fn) {
|
|
628
|
+
if (currentComponentContext) currentComponentContext.onMounted(fn);
|
|
629
|
+
else console.warn("onMounted called outside of component setup");
|
|
630
|
+
}
|
|
631
|
+
function onUnmounted(fn) {
|
|
632
|
+
if (currentComponentContext) currentComponentContext.onUnmounted(fn);
|
|
633
|
+
else console.warn("onUnmounted called outside of component setup");
|
|
634
|
+
}
|
|
635
|
+
function onCreated(fn) {
|
|
636
|
+
if (currentComponentContext) currentComponentContext.onCreated(fn);
|
|
637
|
+
else console.warn("onCreated called outside of component setup");
|
|
638
|
+
}
|
|
639
|
+
function onUpdated(fn) {
|
|
640
|
+
if (currentComponentContext) currentComponentContext.onUpdated(fn);
|
|
641
|
+
else console.warn("onUpdated called outside of component setup");
|
|
642
|
+
}
|
|
643
|
+
var componentRegistry = /* @__PURE__ */ new Map();
|
|
644
|
+
function getComponentMeta(factory) {
|
|
645
|
+
return componentRegistry.get(factory);
|
|
646
|
+
}
|
|
647
|
+
function createPropsProxy(target, onAccess) {
|
|
648
|
+
return new Proxy(target, { get(obj, prop) {
|
|
649
|
+
if (typeof prop === "string" && onAccess) onAccess(prop);
|
|
650
|
+
return obj[prop];
|
|
651
|
+
} });
|
|
652
|
+
}
|
|
653
|
+
function component(setup, options) {
|
|
654
|
+
const factory = function(props) {
|
|
655
|
+
return {
|
|
656
|
+
type: factory,
|
|
657
|
+
props: props || {},
|
|
658
|
+
key: props?.key || null,
|
|
659
|
+
children: [],
|
|
660
|
+
dom: null
|
|
661
|
+
};
|
|
662
|
+
};
|
|
663
|
+
factory.__setup = setup;
|
|
664
|
+
factory.__name = options?.name;
|
|
665
|
+
factory.__props = null;
|
|
666
|
+
factory.__events = null;
|
|
667
|
+
factory.__ref = null;
|
|
668
|
+
factory.__slots = null;
|
|
669
|
+
componentRegistry.set(factory, {
|
|
670
|
+
name: options?.name,
|
|
671
|
+
setup
|
|
672
|
+
});
|
|
673
|
+
getComponentPlugins().forEach((p) => p.onDefine?.(options?.name, factory, setup));
|
|
674
|
+
return factory;
|
|
675
|
+
}
|
|
676
|
+
var globalInstances = /* @__PURE__ */ new Map();
|
|
677
|
+
var appContextToken = Symbol("sigx:appContext");
|
|
678
|
+
function lookupProvided(token) {
|
|
679
|
+
const ctx = getCurrentInstance();
|
|
680
|
+
if (!ctx) return;
|
|
681
|
+
let current = ctx;
|
|
682
|
+
while (current) {
|
|
683
|
+
if (current.provides && current.provides.has(token)) return current.provides.get(token);
|
|
684
|
+
current = current.parent;
|
|
685
|
+
}
|
|
686
|
+
}
|
|
687
|
+
function provideAtComponent(token, value) {
|
|
688
|
+
const ctx = getCurrentInstance();
|
|
689
|
+
if (!ctx) throw new Error("defineProvide must be called inside a component setup function");
|
|
690
|
+
if (!ctx.provides) ctx.provides = /* @__PURE__ */ new Map();
|
|
691
|
+
ctx.provides.set(token, value);
|
|
692
|
+
}
|
|
693
|
+
function defineInjectable(factory) {
|
|
694
|
+
const token = Symbol();
|
|
695
|
+
const useFn = (() => {
|
|
696
|
+
const provided = lookupProvided(token);
|
|
697
|
+
if (provided !== void 0) return provided;
|
|
698
|
+
if (!globalInstances.has(token)) globalInstances.set(token, factory());
|
|
699
|
+
return globalInstances.get(token);
|
|
700
|
+
});
|
|
701
|
+
useFn._factory = factory;
|
|
702
|
+
useFn._token = token;
|
|
703
|
+
return useFn;
|
|
704
|
+
}
|
|
705
|
+
function defineProvide(useFn, factory) {
|
|
706
|
+
const actualFactory = factory ?? useFn._factory;
|
|
707
|
+
const token = useFn._token;
|
|
708
|
+
if (!actualFactory || !token) throw new Error("defineProvide must be called with a function created by defineInjectable");
|
|
709
|
+
const instance = actualFactory();
|
|
710
|
+
provideAtComponent(token, instance);
|
|
711
|
+
return instance;
|
|
712
|
+
}
|
|
713
|
+
function useAppContext() {
|
|
714
|
+
return lookupProvided(appContextToken) ?? null;
|
|
715
|
+
}
|
|
716
|
+
function getAppContextToken() {
|
|
717
|
+
return appContextToken;
|
|
718
|
+
}
|
|
719
|
+
function provideAppContext(ctx, appContext) {
|
|
720
|
+
if (!ctx.provides) ctx.provides = /* @__PURE__ */ new Map();
|
|
721
|
+
ctx.provides.set(appContextToken, appContext);
|
|
722
|
+
if (appContext.provides) for (const [token, value] of appContext.provides) ctx.provides.set(token, value);
|
|
723
|
+
}
|
|
724
|
+
const __DIRECTIVE__ = Symbol.for("sigx.directive");
|
|
725
|
+
function defineDirective(definition) {
|
|
726
|
+
definition[__DIRECTIVE__] = true;
|
|
727
|
+
return definition;
|
|
728
|
+
}
|
|
729
|
+
function isDirective(value) {
|
|
730
|
+
return value != null && typeof value === "object" && value[__DIRECTIVE__] === true;
|
|
731
|
+
}
|
|
732
|
+
var isDev = typeof process !== "undefined" && process.env.NODE_ENV !== "production" || true;
|
|
733
|
+
var defaultMountFn = null;
|
|
296
734
|
function setDefaultMount(mountFn) {
|
|
297
735
|
defaultMountFn = mountFn;
|
|
298
736
|
}
|
|
299
|
-
/**
|
|
300
|
-
* Get the current default mount function.
|
|
301
|
-
* @internal
|
|
302
|
-
*/
|
|
303
737
|
function getDefaultMount() {
|
|
304
738
|
return defaultMountFn;
|
|
305
739
|
}
|
|
306
|
-
/**
|
|
307
|
-
* Create an application instance.
|
|
308
|
-
*
|
|
309
|
-
* @example
|
|
310
|
-
* ```tsx
|
|
311
|
-
* import { defineApp, defineInjectable } from '@sigx/runtime-core';
|
|
312
|
-
* import { render } from '@sigx/runtime-dom';
|
|
313
|
-
*
|
|
314
|
-
* // Define an injectable service
|
|
315
|
-
* const useApiConfig = defineInjectable(() => ({ baseUrl: 'https://api.example.com' }));
|
|
316
|
-
*
|
|
317
|
-
* const app = defineApp(<App />);
|
|
318
|
-
*
|
|
319
|
-
* app.use(myPlugin, { option: 'value' });
|
|
320
|
-
*
|
|
321
|
-
* // Provide using the injectable token (works with inject())
|
|
322
|
-
* app.provide(useApiConfig, { baseUrl: 'https://custom.api.com' });
|
|
323
|
-
*
|
|
324
|
-
* app.mount(document.getElementById('app')!, render);
|
|
325
|
-
* ```
|
|
326
|
-
*/
|
|
327
740
|
function defineApp(rootComponent) {
|
|
328
741
|
const installedPlugins = /* @__PURE__ */ new Set();
|
|
329
742
|
const context = {
|
|
330
743
|
app: null,
|
|
331
744
|
provides: /* @__PURE__ */ new Map(),
|
|
332
745
|
config: {},
|
|
333
|
-
hooks: []
|
|
746
|
+
hooks: [],
|
|
747
|
+
directives: /* @__PURE__ */ new Map()
|
|
334
748
|
};
|
|
335
749
|
let isMounted = false;
|
|
336
750
|
let container = null;
|
|
337
|
-
let unmountFn
|
|
751
|
+
let unmountFn = null;
|
|
338
752
|
const app = {
|
|
339
753
|
config: context.config,
|
|
340
754
|
use(plugin, options) {
|
|
@@ -348,16 +762,26 @@ function defineApp(rootComponent) {
|
|
|
348
762
|
else if (isDev) console.warn("Invalid plugin: must be a function or have an install() method.");
|
|
349
763
|
return app;
|
|
350
764
|
},
|
|
351
|
-
|
|
352
|
-
const
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
765
|
+
defineProvide(useFn, factory) {
|
|
766
|
+
const actualFactory = factory ?? useFn._factory;
|
|
767
|
+
const token = useFn._token;
|
|
768
|
+
if (!actualFactory || !token) throw new Error("defineProvide must be called with a function created by defineInjectable");
|
|
769
|
+
const instance = actualFactory();
|
|
770
|
+
context.provides.set(token, instance);
|
|
771
|
+
return instance;
|
|
356
772
|
},
|
|
357
773
|
hook(hooks) {
|
|
358
774
|
context.hooks.push(hooks);
|
|
359
775
|
return app;
|
|
360
776
|
},
|
|
777
|
+
directive(name, definition) {
|
|
778
|
+
if (definition !== void 0) {
|
|
779
|
+
if (isDev && !isDirective(definition)) console.warn(`[sigx] app.directive('${name}', ...) received a value that is not a valid directive definition. Use defineDirective() to create directive definitions.`);
|
|
780
|
+
context.directives.set(name, definition);
|
|
781
|
+
return app;
|
|
782
|
+
}
|
|
783
|
+
return context.directives.get(name);
|
|
784
|
+
},
|
|
361
785
|
mount(target, renderFn) {
|
|
362
786
|
if (isMounted) {
|
|
363
787
|
if (isDev) console.warn("App is already mounted. Call app.unmount() first.");
|
|
@@ -368,7 +792,7 @@ function defineApp(rootComponent) {
|
|
|
368
792
|
container = target;
|
|
369
793
|
isMounted = true;
|
|
370
794
|
const result = mountFn(rootComponent, target, context);
|
|
371
|
-
if (typeof result === "function") unmountFn
|
|
795
|
+
if (typeof result === "function") unmountFn = result;
|
|
372
796
|
return app;
|
|
373
797
|
},
|
|
374
798
|
unmount() {
|
|
@@ -376,7 +800,7 @@ function defineApp(rootComponent) {
|
|
|
376
800
|
if (isDev) console.warn("App is not mounted.");
|
|
377
801
|
return;
|
|
378
802
|
}
|
|
379
|
-
if (unmountFn
|
|
803
|
+
if (unmountFn) unmountFn();
|
|
380
804
|
context.provides.clear();
|
|
381
805
|
isMounted = false;
|
|
382
806
|
container = null;
|
|
@@ -389,15 +813,16 @@ function defineApp(rootComponent) {
|
|
|
389
813
|
},
|
|
390
814
|
get _container() {
|
|
391
815
|
return container;
|
|
816
|
+
},
|
|
817
|
+
get _rootComponent() {
|
|
818
|
+
return rootComponent;
|
|
392
819
|
}
|
|
393
820
|
};
|
|
394
821
|
context.app = app;
|
|
822
|
+
const appContextToken = getAppContextToken();
|
|
823
|
+
context.provides.set(appContextToken, context);
|
|
395
824
|
return app;
|
|
396
825
|
}
|
|
397
|
-
/**
|
|
398
|
-
* Notify all app hooks that a component was created.
|
|
399
|
-
* Called by the renderer after setup() returns.
|
|
400
|
-
*/
|
|
401
826
|
function notifyComponentCreated(context, instance) {
|
|
402
827
|
if (!context) return;
|
|
403
828
|
for (const hooks of context.hooks) try {
|
|
@@ -406,10 +831,6 @@ function notifyComponentCreated(context, instance) {
|
|
|
406
831
|
handleHookError(context, err, instance, "onComponentCreated");
|
|
407
832
|
}
|
|
408
833
|
}
|
|
409
|
-
/**
|
|
410
|
-
* Notify all app hooks that a component was mounted.
|
|
411
|
-
* Called by the renderer after mount hooks run.
|
|
412
|
-
*/
|
|
413
834
|
function notifyComponentMounted(context, instance) {
|
|
414
835
|
if (!context) return;
|
|
415
836
|
for (const hooks of context.hooks) try {
|
|
@@ -418,10 +839,6 @@ function notifyComponentMounted(context, instance) {
|
|
|
418
839
|
handleHookError(context, err, instance, "onComponentMounted");
|
|
419
840
|
}
|
|
420
841
|
}
|
|
421
|
-
/**
|
|
422
|
-
* Notify all app hooks that a component was unmounted.
|
|
423
|
-
* Called by the renderer before cleanup.
|
|
424
|
-
*/
|
|
425
842
|
function notifyComponentUnmounted(context, instance) {
|
|
426
843
|
if (!context) return;
|
|
427
844
|
for (const hooks of context.hooks) try {
|
|
@@ -430,10 +847,6 @@ function notifyComponentUnmounted(context, instance) {
|
|
|
430
847
|
handleHookError(context, err, instance, "onComponentUnmounted");
|
|
431
848
|
}
|
|
432
849
|
}
|
|
433
|
-
/**
|
|
434
|
-
* Notify all app hooks that a component updated.
|
|
435
|
-
* Called by the renderer after re-render.
|
|
436
|
-
*/
|
|
437
850
|
function notifyComponentUpdated(context, instance) {
|
|
438
851
|
if (!context) return;
|
|
439
852
|
for (const hooks of context.hooks) try {
|
|
@@ -442,10 +855,6 @@ function notifyComponentUpdated(context, instance) {
|
|
|
442
855
|
handleHookError(context, err, instance, "onComponentUpdated");
|
|
443
856
|
}
|
|
444
857
|
}
|
|
445
|
-
/**
|
|
446
|
-
* Handle an error in a component. Returns true if the error was handled.
|
|
447
|
-
* Called by the renderer when an error occurs in setup or render.
|
|
448
|
-
*/
|
|
449
858
|
function handleComponentError(context, err, instance, info) {
|
|
450
859
|
if (!context) return false;
|
|
451
860
|
for (const hooks of context.hooks) try {
|
|
@@ -460,105 +869,54 @@ function handleComponentError(context, err, instance, info) {
|
|
|
460
869
|
}
|
|
461
870
|
return false;
|
|
462
871
|
}
|
|
463
|
-
/**
|
|
464
|
-
* Handle errors that occur in hooks themselves
|
|
465
|
-
*/
|
|
466
872
|
function handleHookError(context, err, instance, hookName) {
|
|
467
873
|
console.error(`Error in ${hookName} hook:`, err);
|
|
468
874
|
if (context.config.errorHandler) try {
|
|
469
875
|
context.config.errorHandler(err, instance, `plugin hook: ${hookName}`);
|
|
470
876
|
} catch {}
|
|
471
877
|
}
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
//#region ../runtime-core/src/component.ts
|
|
475
|
-
let currentComponentContext = null;
|
|
476
|
-
function getCurrentInstance() {
|
|
477
|
-
return currentComponentContext;
|
|
878
|
+
function compound(main, sub) {
|
|
879
|
+
return Object.assign(main, sub);
|
|
478
880
|
}
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
return
|
|
881
|
+
var MODEL_SYMBOL = Symbol.for("sigx.model");
|
|
882
|
+
function createModel(tuple, updateHandler) {
|
|
883
|
+
const [obj, key] = tuple;
|
|
884
|
+
return {
|
|
885
|
+
get value() {
|
|
886
|
+
return obj[key];
|
|
887
|
+
},
|
|
888
|
+
set value(v) {
|
|
889
|
+
updateHandler(v);
|
|
890
|
+
},
|
|
891
|
+
get binding() {
|
|
892
|
+
return [
|
|
893
|
+
obj,
|
|
894
|
+
key,
|
|
895
|
+
updateHandler
|
|
896
|
+
];
|
|
897
|
+
},
|
|
898
|
+
[MODEL_SYMBOL]: true
|
|
899
|
+
};
|
|
483
900
|
}
|
|
484
|
-
function
|
|
485
|
-
|
|
486
|
-
|
|
901
|
+
function createModelFromBinding(binding) {
|
|
902
|
+
const [obj, key, handler] = binding;
|
|
903
|
+
return createModel([obj, key], handler);
|
|
487
904
|
}
|
|
488
|
-
function
|
|
489
|
-
|
|
490
|
-
else console.warn("onCleanup called outside of component setup");
|
|
905
|
+
function isModel(value) {
|
|
906
|
+
return value !== null && typeof value === "object" && MODEL_SYMBOL in value && value[MODEL_SYMBOL] === true;
|
|
491
907
|
}
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
* Get component metadata (for DevTools)
|
|
495
|
-
*/
|
|
496
|
-
function getComponentMeta(factory) {
|
|
497
|
-
return componentRegistry$1.get(factory);
|
|
908
|
+
function getModelSymbol() {
|
|
909
|
+
return MODEL_SYMBOL;
|
|
498
910
|
}
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
*/
|
|
502
|
-
function createPropsProxy(target, onAccess) {
|
|
503
|
-
return new Proxy(target, { get(obj, prop) {
|
|
504
|
-
if (typeof prop === "string" && onAccess) onAccess(prop);
|
|
505
|
-
return obj[prop];
|
|
506
|
-
} });
|
|
507
|
-
}
|
|
508
|
-
/**
|
|
509
|
-
* Define a component. Returns a JSX factory function.
|
|
510
|
-
*
|
|
511
|
-
* @param setup - Setup function that receives context and returns a render function
|
|
512
|
-
* @param options - Optional configuration (e.g., name for DevTools)
|
|
513
|
-
*
|
|
514
|
-
* @example
|
|
515
|
-
* ```tsx
|
|
516
|
-
* type CardProps = DefineProp<"title", string> & DefineSlot<"header">;
|
|
517
|
-
*
|
|
518
|
-
* export const Card = defineComponent<CardProps>((ctx) => {
|
|
519
|
-
* const { title } = ctx.props;
|
|
520
|
-
* const { slots } = ctx;
|
|
521
|
-
*
|
|
522
|
-
* return () => (
|
|
523
|
-
* <div class="card">
|
|
524
|
-
* {slots.header?.() ?? <h2>{title}</h2>}
|
|
525
|
-
* {slots.default()}
|
|
526
|
-
* </div>
|
|
527
|
-
* );
|
|
528
|
-
* });
|
|
529
|
-
* ```
|
|
530
|
-
*/
|
|
531
|
-
function defineComponent(setup, options) {
|
|
532
|
-
const factory = function(props) {
|
|
533
|
-
return {
|
|
534
|
-
type: factory,
|
|
535
|
-
props: props || {},
|
|
536
|
-
key: props?.key || null,
|
|
537
|
-
children: [],
|
|
538
|
-
dom: null
|
|
539
|
-
};
|
|
540
|
-
};
|
|
541
|
-
factory.__setup = setup;
|
|
542
|
-
factory.__name = options?.name;
|
|
543
|
-
factory.__props = null;
|
|
544
|
-
factory.__events = null;
|
|
545
|
-
factory.__ref = null;
|
|
546
|
-
factory.__slots = null;
|
|
547
|
-
componentRegistry$1.set(factory, {
|
|
548
|
-
name: options?.name,
|
|
549
|
-
setup
|
|
550
|
-
});
|
|
551
|
-
getComponentPlugins().forEach((p) => p.onDefine?.(options?.name, factory, setup));
|
|
552
|
-
return factory;
|
|
911
|
+
function isComponent(type) {
|
|
912
|
+
return typeof type === "function" && "__setup" in type;
|
|
553
913
|
}
|
|
554
|
-
|
|
555
|
-
//#endregion
|
|
556
|
-
//#region ../runtime-core/src/jsx-runtime.ts
|
|
557
914
|
const Fragment = Symbol.for("sigx.Fragment");
|
|
558
915
|
const Text = Symbol.for("sigx.Text");
|
|
559
|
-
function normalizeChildren
|
|
916
|
+
function normalizeChildren(children) {
|
|
560
917
|
if (children == null || children === false || children === true) return [];
|
|
561
|
-
if (
|
|
918
|
+
if (isComputed(children)) return normalizeChildren(children.value);
|
|
919
|
+
if (Array.isArray(children)) return children.flatMap((c) => normalizeChildren(c));
|
|
562
920
|
if (typeof children === "string" || typeof children === "number") return [{
|
|
563
921
|
type: Text,
|
|
564
922
|
props: {},
|
|
@@ -570,64 +928,92 @@ function normalizeChildren$1(children) {
|
|
|
570
928
|
if (children.type) return [children];
|
|
571
929
|
return [];
|
|
572
930
|
}
|
|
573
|
-
/**
|
|
574
|
-
* Check if a type is a sigx component (has __setup)
|
|
575
|
-
*/
|
|
576
|
-
function isComponent$2(type) {
|
|
577
|
-
return typeof type === "function" && "__setup" in type;
|
|
578
|
-
}
|
|
579
|
-
/**
|
|
580
|
-
* Create a JSX element - this is the core function called by TSX transpilation
|
|
581
|
-
*/
|
|
582
931
|
function jsx(type, props, key) {
|
|
583
932
|
const processedProps = { ...props || {} };
|
|
933
|
+
const models = {};
|
|
934
|
+
const isComponentType = isComponent(type);
|
|
584
935
|
if (props) {
|
|
585
|
-
for (const propKey in props) if (propKey === "
|
|
586
|
-
let
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
936
|
+
for (const propKey in props) if (propKey === "model") {
|
|
937
|
+
let modelBinding = props[propKey];
|
|
938
|
+
let tuple = null;
|
|
939
|
+
let updateHandler = null;
|
|
940
|
+
if (isModel(modelBinding)) {
|
|
941
|
+
const [obj, key, handler] = modelBinding.binding;
|
|
942
|
+
tuple = [obj, key];
|
|
943
|
+
updateHandler = handler;
|
|
944
|
+
} else if (typeof modelBinding === "function") {
|
|
945
|
+
const detected = detectAccess(modelBinding);
|
|
946
|
+
if (detected && typeof detected[1] === "string") tuple = detected;
|
|
947
|
+
} else if (Array.isArray(modelBinding) && modelBinding.length === 2 && typeof modelBinding[1] === "string") tuple = modelBinding;
|
|
948
|
+
if (tuple) {
|
|
949
|
+
const [stateObj, stateKey] = tuple;
|
|
593
950
|
let handled = false;
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
stateObj[key$1] = v;
|
|
951
|
+
if (!updateHandler) {
|
|
952
|
+
const existingHandler = processedProps["onUpdate:modelValue"];
|
|
953
|
+
updateHandler = (v) => {
|
|
954
|
+
const customHandler = stateObj[`onUpdate:${stateKey}`];
|
|
955
|
+
if (typeof customHandler === "function") customHandler(v);
|
|
956
|
+
else stateObj[stateKey] = v;
|
|
601
957
|
if (existingHandler) existingHandler(v);
|
|
602
958
|
};
|
|
603
959
|
}
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
960
|
+
const platformProcessor = getPlatformModelProcessor();
|
|
961
|
+
if (typeof type === "string" && platformProcessor) handled = platformProcessor(type, processedProps, tuple, props);
|
|
962
|
+
if (isComponentType) {
|
|
963
|
+
models.model = createModel(tuple, updateHandler);
|
|
964
|
+
processedProps["onUpdate:modelValue"] = updateHandler;
|
|
965
|
+
} else if (!handled) {
|
|
966
|
+
processedProps.modelValue = stateObj[stateKey];
|
|
967
|
+
processedProps["onUpdate:modelValue"] = updateHandler;
|
|
968
|
+
}
|
|
969
|
+
delete processedProps.model;
|
|
970
|
+
}
|
|
971
|
+
} else if (propKey.startsWith("model:")) {
|
|
972
|
+
let modelBinding = props[propKey];
|
|
973
|
+
const name = propKey.slice(6);
|
|
974
|
+
let tuple = null;
|
|
975
|
+
let updateHandler = null;
|
|
976
|
+
if (isModel(modelBinding)) {
|
|
977
|
+
const [obj, key, handler] = modelBinding.binding;
|
|
978
|
+
tuple = [obj, key];
|
|
979
|
+
updateHandler = handler;
|
|
980
|
+
} else if (typeof modelBinding === "function") {
|
|
981
|
+
const detected = detectAccess(modelBinding);
|
|
982
|
+
if (detected && typeof detected[1] === "string") tuple = detected;
|
|
983
|
+
} else if (Array.isArray(modelBinding) && modelBinding.length === 2 && typeof modelBinding[1] === "string") tuple = modelBinding;
|
|
984
|
+
if (tuple) {
|
|
985
|
+
const [stateObj, stateKey] = tuple;
|
|
986
|
+
const eventName = `onUpdate:${name}`;
|
|
987
|
+
if (!updateHandler) {
|
|
988
|
+
const existingHandler = processedProps[eventName];
|
|
989
|
+
updateHandler = (v) => {
|
|
990
|
+
const customHandler = stateObj[`onUpdate:${stateKey}`];
|
|
991
|
+
if (typeof customHandler === "function") customHandler(v);
|
|
992
|
+
else stateObj[stateKey] = v;
|
|
993
|
+
if (existingHandler) existingHandler(v);
|
|
994
|
+
};
|
|
995
|
+
}
|
|
996
|
+
if (isComponentType) {
|
|
997
|
+
models[name] = createModel(tuple, updateHandler);
|
|
998
|
+
processedProps[eventName] = updateHandler;
|
|
999
|
+
} else {
|
|
1000
|
+
processedProps[name] = stateObj[stateKey];
|
|
1001
|
+
processedProps[eventName] = updateHandler;
|
|
1002
|
+
}
|
|
618
1003
|
delete processedProps[propKey];
|
|
619
1004
|
}
|
|
620
1005
|
}
|
|
621
1006
|
}
|
|
622
|
-
if (
|
|
623
|
-
|
|
1007
|
+
if (Object.keys(models).length > 0) processedProps.$models = models;
|
|
1008
|
+
if (isComponent(type)) {
|
|
1009
|
+
const { children, ...rest } = processedProps;
|
|
624
1010
|
return {
|
|
625
1011
|
type,
|
|
626
1012
|
props: {
|
|
627
|
-
...rest
|
|
628
|
-
children
|
|
1013
|
+
...rest,
|
|
1014
|
+
children
|
|
629
1015
|
},
|
|
630
|
-
key: key || rest
|
|
1016
|
+
key: key || rest.key || null,
|
|
631
1017
|
children: [],
|
|
632
1018
|
dom: null
|
|
633
1019
|
};
|
|
@@ -638,33 +1024,17 @@ function jsx(type, props, key) {
|
|
|
638
1024
|
type,
|
|
639
1025
|
props: rest,
|
|
640
1026
|
key: key || rest.key || null,
|
|
641
|
-
children: normalizeChildren
|
|
1027
|
+
children: normalizeChildren(children),
|
|
642
1028
|
dom: null
|
|
643
1029
|
};
|
|
644
1030
|
}
|
|
645
|
-
/**
|
|
646
|
-
* JSX Factory for fragments
|
|
647
|
-
*/
|
|
648
1031
|
function jsxs(type, props, key) {
|
|
649
1032
|
return jsx(type, props, key);
|
|
650
1033
|
}
|
|
651
1034
|
const jsxDEV = jsx;
|
|
652
|
-
|
|
653
|
-
//#endregion
|
|
654
|
-
//#region ../runtime-core/src/lazy.tsx
|
|
655
|
-
/**
|
|
656
|
-
* Lazy loading utilities for sigx components.
|
|
657
|
-
*
|
|
658
|
-
* Provides runtime-only lazy loading with no build dependencies.
|
|
659
|
-
* Works with any bundler that supports dynamic import().
|
|
660
|
-
*/
|
|
661
|
-
let currentSuspenseBoundary$1 = null;
|
|
662
|
-
/**
|
|
663
|
-
* Register a promise with the current Suspense boundary
|
|
664
|
-
* @internal
|
|
665
|
-
*/
|
|
1035
|
+
var currentSuspenseBoundary = null;
|
|
666
1036
|
function registerPendingPromise(promise) {
|
|
667
|
-
const boundary = currentSuspenseBoundary
|
|
1037
|
+
const boundary = getCurrentSuspenseBoundarySafe() ?? currentSuspenseBoundary;
|
|
668
1038
|
if (boundary) {
|
|
669
1039
|
boundary.pending.add(promise);
|
|
670
1040
|
promise.finally(() => {
|
|
@@ -675,39 +1045,12 @@ function registerPendingPromise(promise) {
|
|
|
675
1045
|
}
|
|
676
1046
|
return false;
|
|
677
1047
|
}
|
|
678
|
-
/**
|
|
679
|
-
* Create a lazy-loaded component wrapper.
|
|
680
|
-
*
|
|
681
|
-
* The component will be loaded on first render. Use with `<Suspense>` to show
|
|
682
|
-
* a fallback while loading.
|
|
683
|
-
*
|
|
684
|
-
* @param loader - Function that returns a Promise resolving to the component
|
|
685
|
-
* @returns A component factory that loads the real component on demand
|
|
686
|
-
*
|
|
687
|
-
* @example
|
|
688
|
-
* ```tsx
|
|
689
|
-
* import { lazy, Suspense } from 'sigx';
|
|
690
|
-
*
|
|
691
|
-
* // Component will be in a separate chunk
|
|
692
|
-
* const HeavyChart = lazy(() => import('./components/HeavyChart'));
|
|
693
|
-
*
|
|
694
|
-
* // Usage
|
|
695
|
-
* <Suspense fallback={<Spinner />}>
|
|
696
|
-
* <HeavyChart data={chartData} />
|
|
697
|
-
* </Suspense>
|
|
698
|
-
*
|
|
699
|
-
* // Preload on hover
|
|
700
|
-
* <button onMouseEnter={() => HeavyChart.preload()}>
|
|
701
|
-
* Show Chart
|
|
702
|
-
* </button>
|
|
703
|
-
* ```
|
|
704
|
-
*/
|
|
705
1048
|
function lazy(loader) {
|
|
706
1049
|
let Component = null;
|
|
707
1050
|
let promise = null;
|
|
708
1051
|
let error = null;
|
|
709
1052
|
let state = "pending";
|
|
710
|
-
const LazyWrapper =
|
|
1053
|
+
const LazyWrapper = component((ctx) => {
|
|
711
1054
|
const loadState = ctx.signal({
|
|
712
1055
|
state,
|
|
713
1056
|
tick: 0
|
|
@@ -756,30 +1099,7 @@ function lazy(loader) {
|
|
|
756
1099
|
};
|
|
757
1100
|
return LazyWrapper;
|
|
758
1101
|
}
|
|
759
|
-
|
|
760
|
-
* Suspense boundary component for handling async loading states.
|
|
761
|
-
*
|
|
762
|
-
* Wraps lazy-loaded components and shows a fallback while they load.
|
|
763
|
-
*
|
|
764
|
-
* @example
|
|
765
|
-
* ```tsx
|
|
766
|
-
* import { lazy, Suspense } from 'sigx';
|
|
767
|
-
*
|
|
768
|
-
* const LazyDashboard = lazy(() => import('./Dashboard'));
|
|
769
|
-
*
|
|
770
|
-
* // Basic usage
|
|
771
|
-
* <Suspense fallback={<div>Loading...</div>}>
|
|
772
|
-
* <LazyDashboard />
|
|
773
|
-
* </Suspense>
|
|
774
|
-
*
|
|
775
|
-
* // With spinner component
|
|
776
|
-
* <Suspense fallback={<Spinner size="large" />}>
|
|
777
|
-
* <LazyDashboard />
|
|
778
|
-
* <LazyCharts />
|
|
779
|
-
* </Suspense>
|
|
780
|
-
* ```
|
|
781
|
-
*/
|
|
782
|
-
const Suspense = defineComponent((ctx) => {
|
|
1102
|
+
const Suspense = component((ctx) => {
|
|
783
1103
|
const { props, slots } = ctx;
|
|
784
1104
|
const state = ctx.signal({
|
|
785
1105
|
isReady: false,
|
|
@@ -792,14 +1112,15 @@ const Suspense = defineComponent((ctx) => {
|
|
|
792
1112
|
if (boundary.pending.size === 0) state.isReady = true;
|
|
793
1113
|
}
|
|
794
1114
|
};
|
|
795
|
-
ctx.
|
|
1115
|
+
ctx.onMounted(() => {
|
|
796
1116
|
if (boundary.pending.size === 0) state.isReady = true;
|
|
797
1117
|
});
|
|
798
1118
|
return () => {
|
|
799
1119
|
state.isReady;
|
|
800
1120
|
state.pendingCount;
|
|
801
|
-
const prevBoundary = currentSuspenseBoundary
|
|
802
|
-
currentSuspenseBoundary
|
|
1121
|
+
const prevBoundary = getCurrentSuspenseBoundarySafe() ?? currentSuspenseBoundary;
|
|
1122
|
+
currentSuspenseBoundary = boundary;
|
|
1123
|
+
setCurrentSuspenseBoundarySafe(boundary);
|
|
803
1124
|
try {
|
|
804
1125
|
const children = slots.default();
|
|
805
1126
|
if (boundary.pending.size > 0) {
|
|
@@ -823,19 +1144,42 @@ const Suspense = defineComponent((ctx) => {
|
|
|
823
1144
|
}
|
|
824
1145
|
throw err;
|
|
825
1146
|
} finally {
|
|
826
|
-
currentSuspenseBoundary
|
|
1147
|
+
currentSuspenseBoundary = prevBoundary;
|
|
1148
|
+
setCurrentSuspenseBoundarySafe(prevBoundary);
|
|
827
1149
|
}
|
|
828
1150
|
};
|
|
829
1151
|
}, { name: "Suspense" });
|
|
830
|
-
/**
|
|
831
|
-
* Check if a component is a lazy-loaded component
|
|
832
|
-
*/
|
|
833
1152
|
function isLazyComponent(component) {
|
|
834
1153
|
return component && component.__lazy === true;
|
|
835
1154
|
}
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
1155
|
+
const ErrorBoundary = component((ctx) => {
|
|
1156
|
+
const { fallback } = ctx.props;
|
|
1157
|
+
const { slots } = ctx;
|
|
1158
|
+
const state = ctx.signal({
|
|
1159
|
+
hasError: false,
|
|
1160
|
+
error: null
|
|
1161
|
+
});
|
|
1162
|
+
const retry = () => {
|
|
1163
|
+
state.hasError = false;
|
|
1164
|
+
state.error = null;
|
|
1165
|
+
};
|
|
1166
|
+
return () => {
|
|
1167
|
+
if (state.hasError && state.error) {
|
|
1168
|
+
if (typeof fallback === "function") return fallback(state.error, retry);
|
|
1169
|
+
return fallback ?? null;
|
|
1170
|
+
}
|
|
1171
|
+
try {
|
|
1172
|
+
return slots.default();
|
|
1173
|
+
} catch (e) {
|
|
1174
|
+
const error = e instanceof Error ? e : new Error(String(e));
|
|
1175
|
+
state.hasError = true;
|
|
1176
|
+
state.error = error;
|
|
1177
|
+
if (process.env.NODE_ENV !== "production") console.error("[ErrorBoundary] Caught error during render:", error);
|
|
1178
|
+
if (typeof fallback === "function") return fallback(error, retry);
|
|
1179
|
+
return fallback ?? null;
|
|
1180
|
+
}
|
|
1181
|
+
};
|
|
1182
|
+
}, { name: "ErrorBoundary" });
|
|
839
1183
|
var Utils = class {
|
|
840
1184
|
static isPromise(value) {
|
|
841
1185
|
return !!value && (typeof value === "object" || typeof value === "function") && typeof value.then === "function";
|
|
@@ -847,92 +1191,29 @@ function guid$1() {
|
|
|
847
1191
|
return (c == "x" ? r : r & 3 | 8).toString(16);
|
|
848
1192
|
});
|
|
849
1193
|
}
|
|
850
|
-
|
|
851
|
-
//#endregion
|
|
852
|
-
//#region ../runtime-core/src/utils/props-accessor.ts
|
|
853
|
-
/**
|
|
854
|
-
* Creates a props accessor that can be called with defaults or accessed directly.
|
|
855
|
-
* After calling with defaults, direct property access uses those defaults.
|
|
856
|
-
*
|
|
857
|
-
* @example
|
|
858
|
-
* ```ts
|
|
859
|
-
* // In component setup:
|
|
860
|
-
* const props = createPropsAccessor(reactiveProps);
|
|
861
|
-
*
|
|
862
|
-
* // Set defaults
|
|
863
|
-
* props({ count: 0, label: 'Default' });
|
|
864
|
-
*
|
|
865
|
-
* // Access props (falls back to defaults if not provided)
|
|
866
|
-
* const count = props.count;
|
|
867
|
-
* ```
|
|
868
|
-
*/
|
|
869
1194
|
function createPropsAccessor(reactiveProps) {
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
get(_, key) {
|
|
1195
|
+
return new Proxy(reactiveProps, {
|
|
1196
|
+
get(target, key) {
|
|
873
1197
|
if (typeof key === "symbol") return void 0;
|
|
874
|
-
|
|
875
|
-
return value != null ? value : defaults[key];
|
|
1198
|
+
return target[key];
|
|
876
1199
|
},
|
|
877
|
-
|
|
878
|
-
if (args[0] && typeof args[0] === "object") defaults = {
|
|
879
|
-
...defaults,
|
|
880
|
-
...args[0]
|
|
881
|
-
};
|
|
882
|
-
return proxy;
|
|
883
|
-
},
|
|
884
|
-
has(_, key) {
|
|
1200
|
+
has(target, key) {
|
|
885
1201
|
if (typeof key === "symbol") return false;
|
|
886
|
-
return key in
|
|
1202
|
+
return key in target;
|
|
887
1203
|
},
|
|
888
|
-
ownKeys() {
|
|
889
|
-
return
|
|
1204
|
+
ownKeys(target) {
|
|
1205
|
+
return Object.keys(target);
|
|
890
1206
|
},
|
|
891
|
-
getOwnPropertyDescriptor(
|
|
1207
|
+
getOwnPropertyDescriptor(target, key) {
|
|
892
1208
|
if (typeof key === "symbol") return void 0;
|
|
893
|
-
if (key in
|
|
1209
|
+
if (key in target) return {
|
|
894
1210
|
enumerable: true,
|
|
895
1211
|
configurable: true,
|
|
896
1212
|
writable: false
|
|
897
1213
|
};
|
|
898
1214
|
}
|
|
899
1215
|
});
|
|
900
|
-
return proxy;
|
|
901
1216
|
}
|
|
902
|
-
|
|
903
|
-
//#endregion
|
|
904
|
-
//#region ../runtime-core/src/utils/slots.ts
|
|
905
|
-
/**
|
|
906
|
-
* Slots system for component children.
|
|
907
|
-
* Supports default and named slots with reactivity.
|
|
908
|
-
*/
|
|
909
|
-
/**
|
|
910
|
-
* Create slots object from children and slots prop.
|
|
911
|
-
* Uses a version signal to trigger re-renders when children change.
|
|
912
|
-
*
|
|
913
|
-
* Supports named slots via:
|
|
914
|
-
* - `slots` prop object (e.g., `slots={{ header: () => <div>...</div> }}`)
|
|
915
|
-
* - `slot` prop on children (e.g., `<div slot="header">...</div>`)
|
|
916
|
-
*
|
|
917
|
-
* @example
|
|
918
|
-
* ```tsx
|
|
919
|
-
* // Parent component
|
|
920
|
-
* <Card slots={{ header: () => <h1>Title</h1> }}>
|
|
921
|
-
* <p>Default content</p>
|
|
922
|
-
* <span slot="footer">Footer text</span>
|
|
923
|
-
* </Card>
|
|
924
|
-
*
|
|
925
|
-
* // Card component setup
|
|
926
|
-
* const slots = createSlots(children, slotsFromProps);
|
|
927
|
-
* return () => (
|
|
928
|
-
* <div>
|
|
929
|
-
* {slots.header()}
|
|
930
|
-
* {slots.default()}
|
|
931
|
-
* {slots.footer()}
|
|
932
|
-
* </div>
|
|
933
|
-
* );
|
|
934
|
-
* ```
|
|
935
|
-
*/
|
|
936
1217
|
function createSlots(children, slotsFromProps) {
|
|
937
1218
|
const versionSignal = signal({ v: 0 });
|
|
938
1219
|
function extractNamedSlotsFromChildren(c) {
|
|
@@ -979,37 +1260,6 @@ function createSlots(children, slotsFromProps) {
|
|
|
979
1260
|
};
|
|
980
1261
|
} });
|
|
981
1262
|
}
|
|
982
|
-
|
|
983
|
-
//#endregion
|
|
984
|
-
//#region ../runtime-core/src/utils/normalize.ts
|
|
985
|
-
/**
|
|
986
|
-
* VNode normalization utilities.
|
|
987
|
-
* Converts render results into proper VNode structures.
|
|
988
|
-
*/
|
|
989
|
-
/**
|
|
990
|
-
* Normalize render result to a VNode (wrapping arrays in Fragment).
|
|
991
|
-
* Handles null, undefined, false, true by returning an empty Text node.
|
|
992
|
-
*
|
|
993
|
-
* This is used to normalize the return value of component render functions
|
|
994
|
-
* into a consistent VNode structure for the renderer to process.
|
|
995
|
-
*
|
|
996
|
-
* @example
|
|
997
|
-
* ```ts
|
|
998
|
-
* // Conditional rendering returns null/false
|
|
999
|
-
* normalizeSubTree(null) // → empty Text node
|
|
1000
|
-
* normalizeSubTree(false) // → empty Text node
|
|
1001
|
-
*
|
|
1002
|
-
* // Arrays become Fragments
|
|
1003
|
-
* normalizeSubTree([<A/>, <B/>]) // → Fragment with children
|
|
1004
|
-
*
|
|
1005
|
-
* // Primitives become Text nodes
|
|
1006
|
-
* normalizeSubTree("hello") // → Text node
|
|
1007
|
-
* normalizeSubTree(42) // → Text node
|
|
1008
|
-
*
|
|
1009
|
-
* // VNodes pass through
|
|
1010
|
-
* normalizeSubTree(<div/>) // → same VNode
|
|
1011
|
-
* ```
|
|
1012
|
-
*/
|
|
1013
1263
|
function normalizeSubTree(result) {
|
|
1014
1264
|
if (result == null || result === false || result === true) return {
|
|
1015
1265
|
type: Text,
|
|
@@ -1019,6 +1269,7 @@ function normalizeSubTree(result) {
|
|
|
1019
1269
|
dom: null,
|
|
1020
1270
|
text: ""
|
|
1021
1271
|
};
|
|
1272
|
+
if (isComputed(result)) return normalizeSubTree(result.value);
|
|
1022
1273
|
if (Array.isArray(result)) return {
|
|
1023
1274
|
type: Fragment,
|
|
1024
1275
|
props: {},
|
|
@@ -1036,22 +1287,16 @@ function normalizeSubTree(result) {
|
|
|
1036
1287
|
};
|
|
1037
1288
|
return result;
|
|
1038
1289
|
}
|
|
1039
|
-
|
|
1040
|
-
//#endregion
|
|
1041
|
-
//#region ../runtime-core/src/models/index.ts
|
|
1042
1290
|
const guid = guid$1;
|
|
1043
|
-
let InstanceLifetimes = /* @__PURE__ */ function(InstanceLifetimes
|
|
1044
|
-
InstanceLifetimes
|
|
1045
|
-
InstanceLifetimes
|
|
1046
|
-
InstanceLifetimes
|
|
1047
|
-
return InstanceLifetimes
|
|
1291
|
+
let InstanceLifetimes = /* @__PURE__ */ function(InstanceLifetimes) {
|
|
1292
|
+
InstanceLifetimes[InstanceLifetimes["Transient"] = 0] = "Transient";
|
|
1293
|
+
InstanceLifetimes[InstanceLifetimes["Scoped"] = 1] = "Scoped";
|
|
1294
|
+
InstanceLifetimes[InstanceLifetimes["Singleton"] = 2] = "Singleton";
|
|
1295
|
+
return InstanceLifetimes;
|
|
1048
1296
|
}({});
|
|
1049
1297
|
function valueOf(obj) {
|
|
1050
1298
|
return obj;
|
|
1051
1299
|
}
|
|
1052
|
-
|
|
1053
|
-
//#endregion
|
|
1054
|
-
//#region ../runtime-core/src/messaging/index.ts
|
|
1055
1300
|
function createTopic(options) {
|
|
1056
1301
|
let subscribers = [];
|
|
1057
1302
|
const publish = (data) => {
|
|
@@ -1064,7 +1309,7 @@ function createTopic(options) {
|
|
|
1064
1309
|
if (idx > -1) subscribers.splice(idx, 1);
|
|
1065
1310
|
};
|
|
1066
1311
|
try {
|
|
1067
|
-
|
|
1312
|
+
onUnmounted(unsubscribe);
|
|
1068
1313
|
} catch (e) {}
|
|
1069
1314
|
return { unsubscribe };
|
|
1070
1315
|
};
|
|
@@ -1080,72 +1325,10 @@ function createTopic(options) {
|
|
|
1080
1325
|
function toSubscriber(topic) {
|
|
1081
1326
|
return { subscribe: (handler) => topic.subscribe(handler) };
|
|
1082
1327
|
}
|
|
1083
|
-
|
|
1084
|
-
//#endregion
|
|
1085
|
-
//#region ../runtime-core/src/di/injectable.ts
|
|
1086
|
-
function inject(token) {
|
|
1087
|
-
const ctx = getCurrentInstance();
|
|
1088
|
-
if (!ctx) return void 0;
|
|
1089
|
-
let current = ctx;
|
|
1090
|
-
while (current) {
|
|
1091
|
-
if (current.provides && current.provides.has(token)) return current.provides.get(token);
|
|
1092
|
-
current = current.parent;
|
|
1093
|
-
}
|
|
1094
|
-
const appContext = getAppContext(ctx);
|
|
1095
|
-
if (appContext && appContext.provides.has(token)) return appContext.provides.get(token);
|
|
1096
|
-
}
|
|
1097
|
-
/**
|
|
1098
|
-
* Get the app context from the current component context
|
|
1099
|
-
*/
|
|
1100
|
-
function getAppContext(ctx) {
|
|
1101
|
-
let current = ctx;
|
|
1102
|
-
while (current) {
|
|
1103
|
-
if (current._appContext) return current._appContext;
|
|
1104
|
-
current = current.parent;
|
|
1105
|
-
}
|
|
1106
|
-
return null;
|
|
1107
|
-
}
|
|
1108
|
-
/**
|
|
1109
|
-
* Inject the App instance (useful for plugins)
|
|
1110
|
-
*/
|
|
1111
|
-
function injectApp() {
|
|
1112
|
-
return inject(AppContextKey);
|
|
1113
|
-
}
|
|
1114
|
-
function provide(token, value) {
|
|
1115
|
-
const ctx = getCurrentInstance();
|
|
1116
|
-
if (!ctx) {
|
|
1117
|
-
console.warn("provide called outside of component setup");
|
|
1118
|
-
return;
|
|
1119
|
-
}
|
|
1120
|
-
if (!ctx.provides) ctx.provides = /* @__PURE__ */ new Map();
|
|
1121
|
-
ctx.provides.set(token, value);
|
|
1122
|
-
}
|
|
1123
|
-
const globalInstances = /* @__PURE__ */ new Map();
|
|
1124
|
-
function defineInjectable(factory) {
|
|
1125
|
-
const token = factory;
|
|
1126
|
-
const useFn = () => {
|
|
1127
|
-
const injected = inject(token);
|
|
1128
|
-
if (injected) return injected;
|
|
1129
|
-
if (!globalInstances.has(token)) globalInstances.set(token, factory());
|
|
1130
|
-
return globalInstances.get(token);
|
|
1131
|
-
};
|
|
1132
|
-
useFn._factory = factory;
|
|
1133
|
-
useFn._token = token;
|
|
1134
|
-
return useFn;
|
|
1135
|
-
}
|
|
1136
|
-
function defineProvide(useFn) {
|
|
1137
|
-
const factory = useFn._factory;
|
|
1138
|
-
const token = useFn._token;
|
|
1139
|
-
if (!factory || !token) throw new Error("defineProvide must be called with a function created by defineInjectable");
|
|
1140
|
-
const instance = factory();
|
|
1141
|
-
provide(token, instance);
|
|
1142
|
-
return instance;
|
|
1143
|
-
}
|
|
1144
|
-
|
|
1145
|
-
//#endregion
|
|
1146
|
-
//#region ../runtime-core/src/di/factory.ts
|
|
1147
1328
|
var SubscriptionHandler = class {
|
|
1148
|
-
|
|
1329
|
+
constructor() {
|
|
1330
|
+
this.unsubs = [];
|
|
1331
|
+
}
|
|
1149
1332
|
add(unsub) {
|
|
1150
1333
|
this.unsubs.push(unsub);
|
|
1151
1334
|
}
|
|
@@ -1171,7 +1354,7 @@ function defineFactory(setup, lifetime, typeIdentifier) {
|
|
|
1171
1354
|
};
|
|
1172
1355
|
if (customDispose) customDispose(dispose);
|
|
1173
1356
|
else try {
|
|
1174
|
-
|
|
1357
|
+
onUnmounted(() => dispose());
|
|
1175
1358
|
} catch (e) {}
|
|
1176
1359
|
return {
|
|
1177
1360
|
...result,
|
|
@@ -1181,160 +1364,64 @@ function defineFactory(setup, lifetime, typeIdentifier) {
|
|
|
1181
1364
|
if (setup.length <= 1) return defineInjectable(() => factoryCreator());
|
|
1182
1365
|
return factoryCreator;
|
|
1183
1366
|
}
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
return result;
|
|
1208
|
-
}, lifetime);
|
|
1209
|
-
}
|
|
1210
|
-
function defineActions(actions, storeInstanceName, messages) {
|
|
1211
|
-
const events = {};
|
|
1212
|
-
const namespace = `${storeInstanceName}.actions.${guid()}`;
|
|
1213
|
-
const onDispatching = {};
|
|
1214
|
-
const onDispatched = {};
|
|
1215
|
-
const onFailure = {};
|
|
1216
|
-
const result = {
|
|
1217
|
-
onDispatching,
|
|
1218
|
-
onDispatched,
|
|
1219
|
-
onFailure
|
|
1220
|
-
};
|
|
1221
|
-
function getEvent(actionName, type) {
|
|
1222
|
-
const name = `${actionName}.${type}`;
|
|
1223
|
-
if (!events[name]) {
|
|
1224
|
-
events[name] = createTopic({
|
|
1225
|
-
namespace,
|
|
1226
|
-
name
|
|
1227
|
-
});
|
|
1228
|
-
messages.push(events[name]);
|
|
1229
|
-
}
|
|
1230
|
-
return events[name];
|
|
1231
|
-
}
|
|
1232
|
-
Object.keys(actions).forEach((actionName) => {
|
|
1233
|
-
onDispatching[actionName] = { subscribe: (fn) => {
|
|
1234
|
-
return getEvent(actionName, "onDispatching").subscribe(function() {
|
|
1235
|
-
fn.apply(this, arguments[0]);
|
|
1236
|
-
});
|
|
1237
|
-
} };
|
|
1238
|
-
onDispatched[actionName] = { subscribe: (fn) => {
|
|
1239
|
-
return getEvent(actionName, "onDispatched").subscribe(function() {
|
|
1240
|
-
const msg = arguments[0];
|
|
1241
|
-
const allArguments = [msg.result].concat(Array.from(msg.args));
|
|
1242
|
-
fn.apply(this, allArguments);
|
|
1243
|
-
});
|
|
1244
|
-
} };
|
|
1245
|
-
onFailure[actionName] = { subscribe: (fn) => {
|
|
1246
|
-
return getEvent(actionName, "onFailure").subscribe(function() {
|
|
1247
|
-
const msg = arguments[0];
|
|
1248
|
-
const allArguments = [msg.reason].concat(Array.from(msg.args));
|
|
1249
|
-
fn.apply(this, allArguments);
|
|
1250
|
-
});
|
|
1251
|
-
} };
|
|
1252
|
-
result[actionName] = function() {
|
|
1253
|
-
try {
|
|
1254
|
-
const currentArguments = arguments;
|
|
1255
|
-
getEvent(actionName, "onDispatching").publish(currentArguments);
|
|
1256
|
-
const returnedResult = actions[actionName].apply(this, currentArguments);
|
|
1257
|
-
if (Utils.isPromise(returnedResult)) returnedResult.then((result$1) => {
|
|
1258
|
-
getEvent(actionName, "onDispatched").publish({
|
|
1259
|
-
result: returnedResult,
|
|
1260
|
-
args: currentArguments
|
|
1261
|
-
});
|
|
1262
|
-
});
|
|
1263
|
-
else getEvent(actionName, "onDispatched").publish({
|
|
1264
|
-
result: returnedResult,
|
|
1265
|
-
args: currentArguments
|
|
1266
|
-
});
|
|
1267
|
-
return returnedResult;
|
|
1268
|
-
} catch (err) {
|
|
1269
|
-
console.error(err);
|
|
1270
|
-
getEvent(actionName, "onFailure").publish({
|
|
1271
|
-
reason: err,
|
|
1272
|
-
args: arguments
|
|
1273
|
-
});
|
|
1274
|
-
}
|
|
1275
|
-
};
|
|
1276
|
-
});
|
|
1277
|
-
return result;
|
|
1367
|
+
const CLIENT_DIRECTIVE_PREFIX = "client:";
|
|
1368
|
+
const CLIENT_DIRECTIVES = [
|
|
1369
|
+
"client:load",
|
|
1370
|
+
"client:idle",
|
|
1371
|
+
"client:visible",
|
|
1372
|
+
"client:media",
|
|
1373
|
+
"client:only"
|
|
1374
|
+
];
|
|
1375
|
+
function filterClientDirectives(props) {
|
|
1376
|
+
const filtered = {};
|
|
1377
|
+
for (const key in props) if (!key.startsWith("client:")) filtered[key] = props[key];
|
|
1378
|
+
return filtered;
|
|
1379
|
+
}
|
|
1380
|
+
function getHydrationDirective(props) {
|
|
1381
|
+
if (props["client:load"] !== void 0) return { strategy: "load" };
|
|
1382
|
+
if (props["client:idle"] !== void 0) return { strategy: "idle" };
|
|
1383
|
+
if (props["client:visible"] !== void 0) return { strategy: "visible" };
|
|
1384
|
+
if (props["client:only"] !== void 0) return { strategy: "only" };
|
|
1385
|
+
if (props["client:media"] !== void 0) return {
|
|
1386
|
+
strategy: "media",
|
|
1387
|
+
media: props["client:media"]
|
|
1388
|
+
};
|
|
1389
|
+
return null;
|
|
1278
1390
|
}
|
|
1279
|
-
function
|
|
1280
|
-
const
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
console.error(err);
|
|
1300
|
-
}
|
|
1301
|
-
};
|
|
1302
|
-
const eventKey = `onMutated${key.charAt(0).toUpperCase()}${key.slice(1)}`;
|
|
1303
|
-
if (!events[eventKey]) {
|
|
1304
|
-
const topic = createTopic({
|
|
1305
|
-
namespace: `${storeInstanceName}.events`,
|
|
1306
|
-
name: eventKey
|
|
1307
|
-
});
|
|
1308
|
-
events[eventKey] = topic;
|
|
1309
|
-
messages.push(topic);
|
|
1310
|
-
}
|
|
1311
|
-
}
|
|
1312
|
-
function triggerEvent(name, value$1) {
|
|
1313
|
-
const keyString = name;
|
|
1314
|
-
events[`onMutated${keyString.charAt(0).toUpperCase()}${keyString.slice(1)}`]?.publish(value$1);
|
|
1391
|
+
function hasClientDirective(props) {
|
|
1392
|
+
for (const key in props) if (key.startsWith("client:")) return true;
|
|
1393
|
+
return false;
|
|
1394
|
+
}
|
|
1395
|
+
function serializeProps(props) {
|
|
1396
|
+
const filtered = filterClientDirectives(props);
|
|
1397
|
+
const result = {};
|
|
1398
|
+
let hasProps = false;
|
|
1399
|
+
for (const key in filtered) {
|
|
1400
|
+
const value = filtered[key];
|
|
1401
|
+
if (key === "children" || key === "key" || key === "ref" || key === "slots") continue;
|
|
1402
|
+
if (typeof value === "function") continue;
|
|
1403
|
+
if (typeof value === "symbol") continue;
|
|
1404
|
+
if (value === void 0) continue;
|
|
1405
|
+
if (key.startsWith("on") && key.length > 2 && key[2] === key[2].toUpperCase()) continue;
|
|
1406
|
+
try {
|
|
1407
|
+
JSON.stringify(value);
|
|
1408
|
+
result[key] = value;
|
|
1409
|
+
hasProps = true;
|
|
1410
|
+
} catch {}
|
|
1315
1411
|
}
|
|
1316
|
-
|
|
1317
|
-
initProperty(key);
|
|
1318
|
-
});
|
|
1319
|
-
return {
|
|
1320
|
-
state,
|
|
1321
|
-
events,
|
|
1322
|
-
mutate
|
|
1323
|
-
};
|
|
1412
|
+
return hasProps ? result : void 0;
|
|
1324
1413
|
}
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
function isComponent(type) {
|
|
1332
|
-
return typeof type === "function" && "__setup" in type;
|
|
1414
|
+
function createEmit(reactiveProps) {
|
|
1415
|
+
return (event, ...args) => {
|
|
1416
|
+
const eventName = `on${event[0].toUpperCase() + event.slice(1)}`;
|
|
1417
|
+
const handler = ("value" in reactiveProps ? reactiveProps.value : reactiveProps)?.[eventName];
|
|
1418
|
+
if (handler && typeof handler === "function") handler(...args);
|
|
1419
|
+
};
|
|
1333
1420
|
}
|
|
1334
1421
|
function createRenderer(options) {
|
|
1335
|
-
const { insert: hostInsert, remove: hostRemove, patchProp: hostPatchProp, createElement: hostCreateElement, createText: hostCreateText, createComment: hostCreateComment, setText: hostSetText, setElementText: hostSetElementText, parentNode: hostParentNode, nextSibling: hostNextSibling, cloneNode: hostCloneNode, insertStaticContent: hostInsertStaticContent } = options;
|
|
1422
|
+
const { insert: hostInsert, remove: hostRemove, patchProp: hostPatchProp, createElement: hostCreateElement, createText: hostCreateText, createComment: hostCreateComment, setText: hostSetText, setElementText: hostSetElementText, parentNode: hostParentNode, nextSibling: hostNextSibling, cloneNode: hostCloneNode, insertStaticContent: hostInsertStaticContent, patchDirective: hostPatchDirective, onElementMounted: hostOnElementMounted, onElementUnmounted: hostOnElementUnmounted } = options;
|
|
1336
1423
|
let currentAppContext = null;
|
|
1337
|
-
function render
|
|
1424
|
+
function render(element, container, appContext) {
|
|
1338
1425
|
if (appContext) currentAppContext = appContext;
|
|
1339
1426
|
const oldVNode = container._vnode;
|
|
1340
1427
|
let vnode = null;
|
|
@@ -1363,7 +1450,72 @@ function createRenderer(options) {
|
|
|
1363
1450
|
container._vnode = null;
|
|
1364
1451
|
}
|
|
1365
1452
|
}
|
|
1366
|
-
|
|
1453
|
+
const svgTags = new Set([
|
|
1454
|
+
"svg",
|
|
1455
|
+
"animate",
|
|
1456
|
+
"animateMotion",
|
|
1457
|
+
"animateTransform",
|
|
1458
|
+
"circle",
|
|
1459
|
+
"clipPath",
|
|
1460
|
+
"defs",
|
|
1461
|
+
"desc",
|
|
1462
|
+
"ellipse",
|
|
1463
|
+
"feBlend",
|
|
1464
|
+
"feColorMatrix",
|
|
1465
|
+
"feComponentTransfer",
|
|
1466
|
+
"feComposite",
|
|
1467
|
+
"feConvolveMatrix",
|
|
1468
|
+
"feDiffuseLighting",
|
|
1469
|
+
"feDisplacementMap",
|
|
1470
|
+
"feDistantLight",
|
|
1471
|
+
"feDropShadow",
|
|
1472
|
+
"feFlood",
|
|
1473
|
+
"feFuncA",
|
|
1474
|
+
"feFuncB",
|
|
1475
|
+
"feFuncG",
|
|
1476
|
+
"feFuncR",
|
|
1477
|
+
"feGaussianBlur",
|
|
1478
|
+
"feImage",
|
|
1479
|
+
"feMerge",
|
|
1480
|
+
"feMergeNode",
|
|
1481
|
+
"feMorphology",
|
|
1482
|
+
"feOffset",
|
|
1483
|
+
"fePointLight",
|
|
1484
|
+
"feSpecularLighting",
|
|
1485
|
+
"feSpotLight",
|
|
1486
|
+
"feTile",
|
|
1487
|
+
"feTurbulence",
|
|
1488
|
+
"filter",
|
|
1489
|
+
"foreignObject",
|
|
1490
|
+
"g",
|
|
1491
|
+
"image",
|
|
1492
|
+
"line",
|
|
1493
|
+
"linearGradient",
|
|
1494
|
+
"marker",
|
|
1495
|
+
"mask",
|
|
1496
|
+
"metadata",
|
|
1497
|
+
"mpath",
|
|
1498
|
+
"path",
|
|
1499
|
+
"pattern",
|
|
1500
|
+
"polygon",
|
|
1501
|
+
"polyline",
|
|
1502
|
+
"radialGradient",
|
|
1503
|
+
"rect",
|
|
1504
|
+
"set",
|
|
1505
|
+
"stop",
|
|
1506
|
+
"switch",
|
|
1507
|
+
"symbol",
|
|
1508
|
+
"text",
|
|
1509
|
+
"textPath",
|
|
1510
|
+
"title",
|
|
1511
|
+
"tspan",
|
|
1512
|
+
"use",
|
|
1513
|
+
"view"
|
|
1514
|
+
]);
|
|
1515
|
+
function isSvgTag(tag) {
|
|
1516
|
+
return svgTags.has(tag);
|
|
1517
|
+
}
|
|
1518
|
+
function mount(vnode, container, before = null, parentIsSVG = false) {
|
|
1367
1519
|
if (vnode == null || vnode === false || vnode === true) return;
|
|
1368
1520
|
if (vnode.type === Text) {
|
|
1369
1521
|
const node = hostCreateText(String(vnode.text));
|
|
@@ -1376,28 +1528,34 @@ function createRenderer(options) {
|
|
|
1376
1528
|
const anchor = hostCreateComment("");
|
|
1377
1529
|
vnode.dom = anchor;
|
|
1378
1530
|
hostInsert(anchor, container, before);
|
|
1379
|
-
if (vnode.children) vnode.children.forEach((child) => mount(child, container, anchor));
|
|
1531
|
+
if (vnode.children) vnode.children.forEach((child) => mount(child, container, anchor, parentIsSVG));
|
|
1380
1532
|
return;
|
|
1381
1533
|
}
|
|
1382
1534
|
if (isComponent(vnode.type)) {
|
|
1383
1535
|
mountComponent(vnode, container, before, vnode.type.__setup);
|
|
1384
1536
|
return;
|
|
1385
1537
|
}
|
|
1386
|
-
const
|
|
1538
|
+
const tag = vnode.type;
|
|
1539
|
+
const isSVG = tag === "svg" || parentIsSVG && tag !== "foreignObject";
|
|
1540
|
+
const element = hostCreateElement(tag, isSVG);
|
|
1387
1541
|
vnode.dom = element;
|
|
1388
1542
|
element.__vnode = vnode;
|
|
1389
1543
|
if (vnode.props) {
|
|
1390
|
-
for (const key in vnode.props) if (key !== "children" && key !== "key" && key !== "ref")
|
|
1391
|
-
|
|
1544
|
+
for (const key in vnode.props) if (key !== "children" && key !== "key" && key !== "ref") if (key.charCodeAt(0) === 117 && key.startsWith("use:")) {
|
|
1545
|
+
if (hostPatchDirective) hostPatchDirective(element, key.slice(4), null, vnode.props[key], currentAppContext);
|
|
1546
|
+
} else hostPatchProp(element, key, null, vnode.props[key], isSVG);
|
|
1547
|
+
if (vnode.props.ref) untrack(() => {
|
|
1392
1548
|
if (typeof vnode.props.ref === "function") vnode.props.ref(element);
|
|
1393
1549
|
else if (typeof vnode.props.ref === "object") vnode.props.ref.current = element;
|
|
1394
|
-
}
|
|
1550
|
+
});
|
|
1395
1551
|
}
|
|
1552
|
+
const childIsSVG = isSVG && tag !== "foreignObject";
|
|
1396
1553
|
if (vnode.children) vnode.children.forEach((child) => {
|
|
1397
1554
|
child.parent = vnode;
|
|
1398
|
-
mount(child, element);
|
|
1555
|
+
mount(child, element, null, childIsSVG);
|
|
1399
1556
|
});
|
|
1400
1557
|
hostInsert(element, container, before);
|
|
1558
|
+
if (hostOnElementMounted) hostOnElementMounted(element);
|
|
1401
1559
|
}
|
|
1402
1560
|
function unmount(vnode, container) {
|
|
1403
1561
|
const internalVNode = vnode;
|
|
@@ -1407,10 +1565,10 @@ function createRenderer(options) {
|
|
|
1407
1565
|
const subTree = internalVNode._subTree;
|
|
1408
1566
|
if (subTree) unmount(subTree, container);
|
|
1409
1567
|
if (vnode.dom) hostRemove(vnode.dom);
|
|
1410
|
-
if (vnode.props?.ref) {
|
|
1568
|
+
if (vnode.props?.ref) untrack(() => {
|
|
1411
1569
|
if (typeof vnode.props.ref === "function") vnode.props.ref(null);
|
|
1412
1570
|
else if (typeof vnode.props.ref === "object") vnode.props.ref.current = null;
|
|
1413
|
-
}
|
|
1571
|
+
});
|
|
1414
1572
|
return;
|
|
1415
1573
|
}
|
|
1416
1574
|
if (vnode.type === Fragment) {
|
|
@@ -1418,10 +1576,11 @@ function createRenderer(options) {
|
|
|
1418
1576
|
if (vnode.dom) hostRemove(vnode.dom);
|
|
1419
1577
|
return;
|
|
1420
1578
|
}
|
|
1421
|
-
if (vnode.props?.ref) {
|
|
1579
|
+
if (vnode.props?.ref) untrack(() => {
|
|
1422
1580
|
if (typeof vnode.props.ref === "function") vnode.props.ref(null);
|
|
1423
1581
|
else if (vnode.props.ref && typeof vnode.props.ref === "object") vnode.props.ref.current = null;
|
|
1424
|
-
}
|
|
1582
|
+
});
|
|
1583
|
+
if (hostOnElementUnmounted && vnode.dom) hostOnElementUnmounted(vnode.dom);
|
|
1425
1584
|
if (vnode.children && vnode.children.length > 0) vnode.children.forEach((child) => unmount(child, vnode.dom));
|
|
1426
1585
|
if (vnode.dom) hostRemove(vnode.dom);
|
|
1427
1586
|
}
|
|
@@ -1429,7 +1588,7 @@ function createRenderer(options) {
|
|
|
1429
1588
|
if (oldVNode === newVNode) return;
|
|
1430
1589
|
if (!isSameVNode(oldVNode, newVNode)) {
|
|
1431
1590
|
const parent = hostParentNode(oldVNode.dom) || container;
|
|
1432
|
-
const nextSibling = hostNextSibling(oldVNode.dom);
|
|
1591
|
+
const nextSibling = oldVNode.dom ? hostNextSibling(oldVNode.dom) : null;
|
|
1433
1592
|
unmount(oldVNode, parent);
|
|
1434
1593
|
mount(newVNode, parent, nextSibling);
|
|
1435
1594
|
return;
|
|
@@ -1444,12 +1603,25 @@ function createRenderer(options) {
|
|
|
1444
1603
|
const props = oldInternal._componentProps;
|
|
1445
1604
|
newInternal._componentProps = props;
|
|
1446
1605
|
if (props) {
|
|
1447
|
-
const newProps
|
|
1606
|
+
const newProps = newVNode.props || {};
|
|
1607
|
+
const newModels = newVNode.props?.$models || {};
|
|
1448
1608
|
untrack(() => {
|
|
1449
|
-
for (const key in newProps
|
|
1450
|
-
if (props[key] !== newProps
|
|
1609
|
+
for (const key in newProps) if (key !== "children" && key !== "key" && key !== "ref" && key !== "$models") {
|
|
1610
|
+
if (props[key] !== newProps[key]) props[key] = newProps[key];
|
|
1611
|
+
}
|
|
1612
|
+
for (const modelKey in newModels) {
|
|
1613
|
+
const newModel = newModels[modelKey];
|
|
1614
|
+
const oldModel = props[modelKey];
|
|
1615
|
+
if (isModel(newModel)) {
|
|
1616
|
+
if (isModel(oldModel)) {
|
|
1617
|
+
const [newObj, newKey] = newModel.binding;
|
|
1618
|
+
const [oldObj, oldKey] = oldModel.binding;
|
|
1619
|
+
if (newObj === oldObj && newKey === oldKey) continue;
|
|
1620
|
+
}
|
|
1621
|
+
props[modelKey] = newModel;
|
|
1622
|
+
}
|
|
1451
1623
|
}
|
|
1452
|
-
for (const key in props) if (!(key in newProps
|
|
1624
|
+
for (const key in props) if (!(key in newProps) && !(key in newModels) && key !== "children" && key !== "key" && key !== "ref" && key !== "$models") delete props[key];
|
|
1453
1625
|
});
|
|
1454
1626
|
}
|
|
1455
1627
|
const slotsRef = oldInternal._slots;
|
|
@@ -1473,31 +1645,57 @@ function createRenderer(options) {
|
|
|
1473
1645
|
}
|
|
1474
1646
|
if (newVNode.type === Text) {
|
|
1475
1647
|
newVNode.dom = oldVNode.dom;
|
|
1648
|
+
if (!newVNode.dom) {
|
|
1649
|
+
const textNode = hostCreateText(String(newVNode.text));
|
|
1650
|
+
newVNode.dom = textNode;
|
|
1651
|
+
if (container) hostInsert(textNode, container, oldVNode.dom || null);
|
|
1652
|
+
return;
|
|
1653
|
+
}
|
|
1476
1654
|
if (oldVNode.text !== newVNode.text) hostSetText(newVNode.dom, String(newVNode.text));
|
|
1477
1655
|
return;
|
|
1478
1656
|
}
|
|
1479
1657
|
if (newVNode.type === Fragment) {
|
|
1480
|
-
patchChildren(oldVNode, newVNode, container);
|
|
1658
|
+
patchChildren(oldVNode, newVNode, container, false);
|
|
1481
1659
|
return;
|
|
1482
1660
|
}
|
|
1483
1661
|
const element = newVNode.dom = oldVNode.dom;
|
|
1662
|
+
if (!element) {
|
|
1663
|
+
mount(newVNode, container);
|
|
1664
|
+
return;
|
|
1665
|
+
}
|
|
1666
|
+
const tag = newVNode.type;
|
|
1667
|
+
const isSVG = tag === "svg" || isSvgTag(tag);
|
|
1484
1668
|
const oldProps = oldVNode.props || {};
|
|
1485
1669
|
const newProps = newVNode.props || {};
|
|
1486
|
-
for (const key in oldProps) if (!(key in newProps) && key !== "children" && key !== "key" && key !== "ref")
|
|
1670
|
+
for (const key in oldProps) if (!(key in newProps) && key !== "children" && key !== "key" && key !== "ref") if (key.charCodeAt(0) === 117 && key.startsWith("use:")) {
|
|
1671
|
+
if (hostPatchDirective) hostPatchDirective(element, key.slice(4), oldProps[key], null, currentAppContext);
|
|
1672
|
+
} else hostPatchProp(element, key, oldProps[key], null, isSVG);
|
|
1487
1673
|
for (const key in newProps) {
|
|
1488
1674
|
const oldValue = oldProps[key];
|
|
1489
1675
|
const newValue = newProps[key];
|
|
1490
|
-
if (key !== "children" && key !== "key" && key !== "ref" && oldValue !== newValue)
|
|
1676
|
+
if (key !== "children" && key !== "key" && key !== "ref" && oldValue !== newValue) if (key.charCodeAt(0) === 117 && key.startsWith("use:")) {
|
|
1677
|
+
if (hostPatchDirective) hostPatchDirective(element, key.slice(4), oldValue, newValue, currentAppContext);
|
|
1678
|
+
} else hostPatchProp(element, key, oldValue, newValue, isSVG);
|
|
1491
1679
|
}
|
|
1492
|
-
patchChildren(oldVNode, newVNode, element);
|
|
1680
|
+
patchChildren(oldVNode, newVNode, element, isSVG && tag !== "foreignObject");
|
|
1493
1681
|
}
|
|
1494
|
-
function patchChildren(oldVNode, newVNode, container) {
|
|
1682
|
+
function patchChildren(oldVNode, newVNode, container, parentIsSVG = false) {
|
|
1495
1683
|
const oldChildren = oldVNode.children;
|
|
1496
1684
|
const newChildren = newVNode.children;
|
|
1497
1685
|
newChildren.forEach((c) => c.parent = newVNode);
|
|
1498
|
-
reconcileChildrenArray(container, oldChildren, newChildren);
|
|
1686
|
+
reconcileChildrenArray(container, oldChildren, newChildren, parentIsSVG);
|
|
1687
|
+
}
|
|
1688
|
+
function checkDuplicateKeys(children) {
|
|
1689
|
+
if (process.env.NODE_ENV === "production") return;
|
|
1690
|
+
const seenKeys = /* @__PURE__ */ new Set();
|
|
1691
|
+
for (const child of children) if (child?.key != null) {
|
|
1692
|
+
const keyStr = String(child.key);
|
|
1693
|
+
if (seenKeys.has(keyStr)) console.warn(`[SignalX] Duplicate key "${child.key}" detected in list. Keys should be unique among siblings to ensure correct reconciliation. This may cause unexpected behavior when items are reordered, added, or removed.`);
|
|
1694
|
+
seenKeys.add(keyStr);
|
|
1695
|
+
}
|
|
1499
1696
|
}
|
|
1500
|
-
function reconcileChildrenArray(parent, oldChildren, newChildren) {
|
|
1697
|
+
function reconcileChildrenArray(parent, oldChildren, newChildren, parentIsSVG = false) {
|
|
1698
|
+
if (process.env.NODE_ENV !== "production") checkDuplicateKeys(newChildren);
|
|
1501
1699
|
let oldStartIdx = 0;
|
|
1502
1700
|
let oldEndIdx = oldChildren.length - 1;
|
|
1503
1701
|
let oldStartVNode = oldChildren[0];
|
|
@@ -1539,13 +1737,13 @@ function createRenderer(options) {
|
|
|
1539
1737
|
patch(vnodeToMove, newStartVNode, parent);
|
|
1540
1738
|
oldChildren[idxInOld] = void 0;
|
|
1541
1739
|
if (vnodeToMove.dom && oldStartVNode.dom) hostInsert(vnodeToMove.dom, parent, oldStartVNode.dom);
|
|
1542
|
-
} else mount(newStartVNode, parent, oldStartVNode.dom);
|
|
1740
|
+
} else mount(newStartVNode, parent, oldStartVNode.dom, parentIsSVG);
|
|
1543
1741
|
newStartVNode = newChildren[++newStartIdx];
|
|
1544
1742
|
}
|
|
1545
1743
|
if (oldStartIdx > oldEndIdx) {
|
|
1546
1744
|
if (newStartIdx <= newEndIdx) {
|
|
1547
1745
|
const anchor = newChildren[newEndIdx + 1] == null ? null : newChildren[newEndIdx + 1].dom;
|
|
1548
|
-
for (let i = newStartIdx; i <= newEndIdx; i++) mount(newChildren[i], parent, anchor);
|
|
1746
|
+
for (let i = newStartIdx; i <= newEndIdx; i++) mount(newChildren[i], parent, anchor, parentIsSVG);
|
|
1549
1747
|
}
|
|
1550
1748
|
} else if (newStartIdx > newEndIdx) {
|
|
1551
1749
|
for (let i = oldStartIdx; i <= oldEndIdx; i++) if (oldChildren[i]) unmount(oldChildren[i], parent);
|
|
@@ -1562,7 +1760,11 @@ function createRenderer(options) {
|
|
|
1562
1760
|
const map = /* @__PURE__ */ new Map();
|
|
1563
1761
|
for (let i = beginIdx; i <= endIdx; i++) {
|
|
1564
1762
|
const key = children[i]?.key;
|
|
1565
|
-
if (key != null)
|
|
1763
|
+
if (key != null) {
|
|
1764
|
+
const keyStr = String(key);
|
|
1765
|
+
if (process.env.NODE_ENV !== "production" && map.has(keyStr)) console.warn(`[SignalX] Duplicate key "${key}" detected in list. Keys should be unique among siblings to ensure correct reconciliation. This may cause unexpected behavior when items are reordered, added, or removed.`);
|
|
1766
|
+
map.set(keyStr, i);
|
|
1767
|
+
}
|
|
1566
1768
|
}
|
|
1567
1769
|
return map;
|
|
1568
1770
|
}
|
|
@@ -1577,14 +1779,21 @@ function createRenderer(options) {
|
|
|
1577
1779
|
hostInsert(anchor, container, before);
|
|
1578
1780
|
let exposed = null;
|
|
1579
1781
|
let exposeCalled = false;
|
|
1580
|
-
const { children, slots: slotsFromProps, ...propsData } = vnode.props || {};
|
|
1581
|
-
const
|
|
1782
|
+
const { children, slots: slotsFromProps, $models: modelsData, ...propsData } = vnode.props || {};
|
|
1783
|
+
const propsWithModels = { ...propsData };
|
|
1784
|
+
if (modelsData) for (const modelKey in modelsData) {
|
|
1785
|
+
const modelValue = modelsData[modelKey];
|
|
1786
|
+
if (isModel(modelValue)) propsWithModels[modelKey] = modelValue;
|
|
1787
|
+
}
|
|
1788
|
+
const reactiveProps = signal(propsWithModels);
|
|
1582
1789
|
const internalVNode = vnode;
|
|
1583
1790
|
internalVNode._componentProps = reactiveProps;
|
|
1584
1791
|
const slots = createSlots(children, slotsFromProps);
|
|
1585
1792
|
internalVNode._slots = slots;
|
|
1793
|
+
const createdHooks = [];
|
|
1586
1794
|
const mountHooks = [];
|
|
1587
|
-
const
|
|
1795
|
+
const updatedHooks = [];
|
|
1796
|
+
const unmountHooks = [];
|
|
1588
1797
|
const parentInstance = getCurrentInstance();
|
|
1589
1798
|
const componentName = vnode.type.__name;
|
|
1590
1799
|
const ctx = {
|
|
@@ -1592,16 +1801,19 @@ function createRenderer(options) {
|
|
|
1592
1801
|
signal,
|
|
1593
1802
|
props: createPropsAccessor(reactiveProps),
|
|
1594
1803
|
slots,
|
|
1595
|
-
emit: (
|
|
1596
|
-
const handler = reactiveProps[`on${event[0].toUpperCase() + event.slice(1)}`];
|
|
1597
|
-
if (handler && typeof handler === "function") handler(...args);
|
|
1598
|
-
},
|
|
1804
|
+
emit: createEmit(reactiveProps),
|
|
1599
1805
|
parent: parentInstance,
|
|
1600
|
-
|
|
1806
|
+
onMounted: (fn) => {
|
|
1601
1807
|
mountHooks.push(fn);
|
|
1602
1808
|
},
|
|
1603
|
-
|
|
1604
|
-
|
|
1809
|
+
onUnmounted: (fn) => {
|
|
1810
|
+
unmountHooks.push(fn);
|
|
1811
|
+
},
|
|
1812
|
+
onCreated: (fn) => {
|
|
1813
|
+
createdHooks.push(fn);
|
|
1814
|
+
},
|
|
1815
|
+
onUpdated: (fn) => {
|
|
1816
|
+
updatedHooks.push(fn);
|
|
1605
1817
|
},
|
|
1606
1818
|
expose: (exposedValue) => {
|
|
1607
1819
|
exposed = exposedValue;
|
|
@@ -1612,7 +1824,7 @@ function createRenderer(options) {
|
|
|
1612
1824
|
};
|
|
1613
1825
|
applyContextExtensions(ctx);
|
|
1614
1826
|
ctx.__name = componentName;
|
|
1615
|
-
if (currentAppContext) ctx
|
|
1827
|
+
if (!parentInstance && currentAppContext) provideAppContext(ctx, currentAppContext);
|
|
1616
1828
|
const componentInstance = {
|
|
1617
1829
|
name: componentName,
|
|
1618
1830
|
ctx,
|
|
@@ -1622,9 +1834,10 @@ function createRenderer(options) {
|
|
|
1622
1834
|
let renderFn;
|
|
1623
1835
|
try {
|
|
1624
1836
|
const setupResult = setup(ctx);
|
|
1625
|
-
if (setupResult && typeof setupResult.then === "function") throw new Error(`Async setup in component "${componentName}" is only supported during SSR. On the client, use pre-loaded data from hydration or fetch in
|
|
1837
|
+
if (setupResult && typeof setupResult.then === "function") throw new Error(`Async setup in component "${componentName}" is only supported during SSR. On the client, use pre-loaded data from hydration or fetch in onMounted.`);
|
|
1626
1838
|
renderFn = setupResult;
|
|
1627
1839
|
notifyComponentCreated(currentAppContext, componentInstance);
|
|
1840
|
+
createdHooks.forEach((hook) => hook());
|
|
1628
1841
|
} catch (err) {
|
|
1629
1842
|
if (!handleComponentError(currentAppContext, err, componentInstance, "setup")) throw err;
|
|
1630
1843
|
} finally {
|
|
@@ -1632,8 +1845,10 @@ function createRenderer(options) {
|
|
|
1632
1845
|
}
|
|
1633
1846
|
if (vnode.props?.ref) {
|
|
1634
1847
|
const refValue = exposeCalled ? exposed : null;
|
|
1635
|
-
|
|
1636
|
-
|
|
1848
|
+
untrack(() => {
|
|
1849
|
+
if (typeof vnode.props.ref === "function") vnode.props.ref(refValue);
|
|
1850
|
+
else if (vnode.props.ref && typeof vnode.props.ref === "object") vnode.props.ref.current = refValue;
|
|
1851
|
+
});
|
|
1637
1852
|
}
|
|
1638
1853
|
if (renderFn) {
|
|
1639
1854
|
ctx.renderFn = renderFn;
|
|
@@ -1647,6 +1862,7 @@ function createRenderer(options) {
|
|
|
1647
1862
|
if (prevSubTree) {
|
|
1648
1863
|
patch(prevSubTree, subTree, container);
|
|
1649
1864
|
notifyComponentUpdated(currentAppContext, componentInstance);
|
|
1865
|
+
updatedHooks.forEach((hook) => hook());
|
|
1650
1866
|
} else mount(subTree, container, anchor);
|
|
1651
1867
|
internalVNode._subTree = subTree;
|
|
1652
1868
|
} catch (err) {
|
|
@@ -1665,34 +1881,18 @@ function createRenderer(options) {
|
|
|
1665
1881
|
notifyComponentMounted(currentAppContext, componentInstance);
|
|
1666
1882
|
vnode.cleanup = () => {
|
|
1667
1883
|
notifyComponentUnmounted(currentAppContext, componentInstance);
|
|
1668
|
-
|
|
1884
|
+
unmountHooks.forEach((hook) => hook(mountCtx));
|
|
1669
1885
|
};
|
|
1670
1886
|
}
|
|
1671
1887
|
return {
|
|
1672
|
-
render
|
|
1888
|
+
render,
|
|
1673
1889
|
patch,
|
|
1674
1890
|
mount,
|
|
1675
1891
|
unmount,
|
|
1676
|
-
mountComponent
|
|
1677
|
-
createApp: (rootComponent) => {
|
|
1678
|
-
return { mount(selectorOrContainer) {
|
|
1679
|
-
let container = null;
|
|
1680
|
-
if (typeof selectorOrContainer === "string") {
|
|
1681
|
-
if (options.querySelector) container = options.querySelector(selectorOrContainer);
|
|
1682
|
-
} else container = selectorOrContainer;
|
|
1683
|
-
if (!container) {
|
|
1684
|
-
console.warn(`Container not found: ${selectorOrContainer}`);
|
|
1685
|
-
return;
|
|
1686
|
-
}
|
|
1687
|
-
render$1(rootComponent, container);
|
|
1688
|
-
} };
|
|
1689
|
-
}
|
|
1892
|
+
mountComponent
|
|
1690
1893
|
};
|
|
1691
1894
|
}
|
|
1692
|
-
|
|
1693
|
-
//#endregion
|
|
1694
|
-
//#region ../runtime-terminal/src/focus.ts
|
|
1695
|
-
const focusableIds = /* @__PURE__ */ new Set();
|
|
1895
|
+
var focusableIds = /* @__PURE__ */ new Set();
|
|
1696
1896
|
const focusState = signal({ activeId: null });
|
|
1697
1897
|
function registerFocusable(id) {
|
|
1698
1898
|
focusableIds.add(id);
|
|
@@ -1718,9 +1918,6 @@ function focusPrev() {
|
|
|
1718
1918
|
const ids = Array.from(focusableIds);
|
|
1719
1919
|
focusState.activeId = ids[((focusState.activeId ? ids.indexOf(focusState.activeId) : -1) - 1 + ids.length) % ids.length];
|
|
1720
1920
|
}
|
|
1721
|
-
|
|
1722
|
-
//#endregion
|
|
1723
|
-
//#region ../runtime-terminal/src/utils.ts
|
|
1724
1921
|
function getColorCode(color) {
|
|
1725
1922
|
switch (color) {
|
|
1726
1923
|
case "red": return "\x1B[31m";
|
|
@@ -1748,316 +1945,62 @@ function getBackgroundColorCode(color) {
|
|
|
1748
1945
|
function stripAnsi(str) {
|
|
1749
1946
|
return str.replace(/\x1B\[[0-9;]*[a-zA-Z]/g, "");
|
|
1750
1947
|
}
|
|
1751
|
-
|
|
1752
|
-
//#endregion
|
|
1753
|
-
//#region ../runtime-core/dist/index.js
|
|
1754
|
-
let platformSyncProcessor = null;
|
|
1755
|
-
/**
|
|
1756
|
-
* Get the current platform sync processor (for internal use).
|
|
1757
|
-
*/
|
|
1758
|
-
function getPlatformSyncProcessor$1() {
|
|
1759
|
-
return platformSyncProcessor;
|
|
1760
|
-
}
|
|
1761
|
-
const plugins = [];
|
|
1762
|
-
/**
|
|
1763
|
-
* Get all registered plugins (internal use)
|
|
1764
|
-
*/
|
|
1765
|
-
function getComponentPlugins$1() {
|
|
1766
|
-
return plugins;
|
|
1767
|
-
}
|
|
1768
|
-
const componentRegistry = /* @__PURE__ */ new Map();
|
|
1769
|
-
/**
|
|
1770
|
-
* Define a component. Returns a JSX factory function.
|
|
1771
|
-
*
|
|
1772
|
-
* @param setup - Setup function that receives context and returns a render function
|
|
1773
|
-
* @param options - Optional configuration (e.g., name for DevTools)
|
|
1774
|
-
*
|
|
1775
|
-
* @example
|
|
1776
|
-
* ```tsx
|
|
1777
|
-
* type CardProps = DefineProp<"title", string> & DefineSlot<"header">;
|
|
1778
|
-
*
|
|
1779
|
-
* export const Card = defineComponent<CardProps>((ctx) => {
|
|
1780
|
-
* const { title } = ctx.props;
|
|
1781
|
-
* const { slots } = ctx;
|
|
1782
|
-
*
|
|
1783
|
-
* return () => (
|
|
1784
|
-
* <div class="card">
|
|
1785
|
-
* {slots.header?.() ?? <h2>{title}</h2>}
|
|
1786
|
-
* {slots.default()}
|
|
1787
|
-
* </div>
|
|
1788
|
-
* );
|
|
1789
|
-
* });
|
|
1790
|
-
* ```
|
|
1791
|
-
*/
|
|
1792
|
-
function defineComponent$1(setup, options) {
|
|
1793
|
-
const factory = function(props) {
|
|
1794
|
-
return {
|
|
1795
|
-
type: factory,
|
|
1796
|
-
props: props || {},
|
|
1797
|
-
key: props?.key || null,
|
|
1798
|
-
children: [],
|
|
1799
|
-
dom: null
|
|
1800
|
-
};
|
|
1801
|
-
};
|
|
1802
|
-
factory.__setup = setup;
|
|
1803
|
-
factory.__name = options?.name;
|
|
1804
|
-
factory.__props = null;
|
|
1805
|
-
factory.__events = null;
|
|
1806
|
-
factory.__ref = null;
|
|
1807
|
-
factory.__slots = null;
|
|
1808
|
-
componentRegistry.set(factory, {
|
|
1809
|
-
name: options?.name,
|
|
1810
|
-
setup
|
|
1811
|
-
});
|
|
1812
|
-
getComponentPlugins$1().forEach((p) => p.onDefine?.(options?.name, factory, setup));
|
|
1813
|
-
return factory;
|
|
1814
|
-
}
|
|
1815
|
-
const Fragment$1 = Symbol.for("sigx.Fragment");
|
|
1816
|
-
const Text$1 = Symbol.for("sigx.Text");
|
|
1817
|
-
function normalizeChildren(children) {
|
|
1818
|
-
if (children == null || children === false || children === true) return [];
|
|
1819
|
-
if (Array.isArray(children)) return children.flatMap((c) => normalizeChildren(c));
|
|
1820
|
-
if (typeof children === "string" || typeof children === "number") return [{
|
|
1821
|
-
type: Text$1,
|
|
1822
|
-
props: {},
|
|
1823
|
-
key: null,
|
|
1824
|
-
children: [],
|
|
1825
|
-
dom: null,
|
|
1826
|
-
text: children
|
|
1827
|
-
}];
|
|
1828
|
-
if (children.type) return [children];
|
|
1829
|
-
return [];
|
|
1830
|
-
}
|
|
1831
|
-
/**
|
|
1832
|
-
* Check if a type is a sigx component (has __setup)
|
|
1833
|
-
*/
|
|
1834
|
-
function isComponent$1(type) {
|
|
1835
|
-
return typeof type === "function" && "__setup" in type;
|
|
1836
|
-
}
|
|
1837
|
-
/**
|
|
1838
|
-
* Create a JSX element - this is the core function called by TSX transpilation
|
|
1839
|
-
*/
|
|
1840
|
-
function jsx$1(type, props, key) {
|
|
1841
|
-
const processedProps = { ...props || {} };
|
|
1842
|
-
if (props) {
|
|
1843
|
-
for (const propKey in props) if (propKey === "sync") {
|
|
1844
|
-
let syncBinding = props[propKey];
|
|
1845
|
-
if (typeof syncBinding === "function") {
|
|
1846
|
-
const detected = detectAccess(syncBinding);
|
|
1847
|
-
if (detected) syncBinding = detected;
|
|
1848
|
-
}
|
|
1849
|
-
if (Array.isArray(syncBinding) && syncBinding.length === 2) {
|
|
1850
|
-
const [stateObj, key$1] = syncBinding;
|
|
1851
|
-
let handled = false;
|
|
1852
|
-
const platformProcessor = getPlatformSyncProcessor$1();
|
|
1853
|
-
if (typeof type === "string" && platformProcessor) handled = platformProcessor(type, processedProps, [stateObj, key$1], props);
|
|
1854
|
-
if (!handled) {
|
|
1855
|
-
processedProps.value = stateObj[key$1];
|
|
1856
|
-
const existingHandler = processedProps["onUpdate:value"];
|
|
1857
|
-
processedProps["onUpdate:value"] = (v) => {
|
|
1858
|
-
stateObj[key$1] = v;
|
|
1859
|
-
if (existingHandler) existingHandler(v);
|
|
1860
|
-
};
|
|
1861
|
-
}
|
|
1862
|
-
delete processedProps.sync;
|
|
1863
|
-
}
|
|
1864
|
-
} else if (propKey.startsWith("sync:")) {
|
|
1865
|
-
const syncBinding = props[propKey];
|
|
1866
|
-
if (Array.isArray(syncBinding) && syncBinding.length === 2) {
|
|
1867
|
-
const [stateObj, key$1] = syncBinding;
|
|
1868
|
-
const name = propKey.slice(5);
|
|
1869
|
-
processedProps[name] = stateObj[key$1];
|
|
1870
|
-
const eventName = `onUpdate:${name}`;
|
|
1871
|
-
const existingHandler = processedProps[eventName];
|
|
1872
|
-
processedProps[eventName] = (v) => {
|
|
1873
|
-
stateObj[key$1] = v;
|
|
1874
|
-
if (existingHandler) existingHandler(v);
|
|
1875
|
-
};
|
|
1876
|
-
delete processedProps[propKey];
|
|
1877
|
-
}
|
|
1878
|
-
}
|
|
1879
|
-
}
|
|
1880
|
-
if (isComponent$1(type)) {
|
|
1881
|
-
const { children: children$1, ...rest$1 } = processedProps;
|
|
1882
|
-
return {
|
|
1883
|
-
type,
|
|
1884
|
-
props: {
|
|
1885
|
-
...rest$1,
|
|
1886
|
-
children: children$1
|
|
1887
|
-
},
|
|
1888
|
-
key: key || rest$1.key || null,
|
|
1889
|
-
children: [],
|
|
1890
|
-
dom: null
|
|
1891
|
-
};
|
|
1892
|
-
}
|
|
1893
|
-
if (typeof type === "function" && type !== Fragment$1) return type(processedProps);
|
|
1894
|
-
const { children, ...rest } = processedProps;
|
|
1895
|
-
return {
|
|
1896
|
-
type,
|
|
1897
|
-
props: rest,
|
|
1898
|
-
key: key || rest.key || null,
|
|
1899
|
-
children: normalizeChildren(children),
|
|
1900
|
-
dom: null
|
|
1901
|
-
};
|
|
1902
|
-
}
|
|
1903
|
-
/**
|
|
1904
|
-
* JSX Factory for fragments
|
|
1905
|
-
*/
|
|
1906
|
-
function jsxs$1(type, props, key) {
|
|
1907
|
-
return jsx$1(type, props, key);
|
|
1908
|
-
}
|
|
1909
|
-
/**
|
|
1910
|
-
* Lazy loading utilities for sigx components.
|
|
1911
|
-
*
|
|
1912
|
-
* Provides runtime-only lazy loading with no build dependencies.
|
|
1913
|
-
* Works with any bundler that supports dynamic import().
|
|
1914
|
-
*/
|
|
1915
|
-
let currentSuspenseBoundary = null;
|
|
1916
|
-
/**
|
|
1917
|
-
* Register a promise with the current Suspense boundary
|
|
1918
|
-
* @internal
|
|
1919
|
-
*/
|
|
1920
|
-
function registerPendingPromise$1(promise) {
|
|
1921
|
-
const boundary = currentSuspenseBoundary;
|
|
1922
|
-
if (boundary) {
|
|
1923
|
-
boundary.pending.add(promise);
|
|
1924
|
-
promise.finally(() => {
|
|
1925
|
-
boundary.pending.delete(promise);
|
|
1926
|
-
if (boundary.pending.size === 0) boundary.onResolve();
|
|
1927
|
-
});
|
|
1928
|
-
return true;
|
|
1929
|
-
}
|
|
1930
|
-
return false;
|
|
1931
|
-
}
|
|
1932
|
-
/**
|
|
1933
|
-
* Suspense boundary component for handling async loading states.
|
|
1934
|
-
*
|
|
1935
|
-
* Wraps lazy-loaded components and shows a fallback while they load.
|
|
1936
|
-
*
|
|
1937
|
-
* @example
|
|
1938
|
-
* ```tsx
|
|
1939
|
-
* import { lazy, Suspense } from 'sigx';
|
|
1940
|
-
*
|
|
1941
|
-
* const LazyDashboard = lazy(() => import('./Dashboard'));
|
|
1942
|
-
*
|
|
1943
|
-
* // Basic usage
|
|
1944
|
-
* <Suspense fallback={<div>Loading...</div>}>
|
|
1945
|
-
* <LazyDashboard />
|
|
1946
|
-
* </Suspense>
|
|
1947
|
-
*
|
|
1948
|
-
* // With spinner component
|
|
1949
|
-
* <Suspense fallback={<Spinner size="large" />}>
|
|
1950
|
-
* <LazyDashboard />
|
|
1951
|
-
* <LazyCharts />
|
|
1952
|
-
* </Suspense>
|
|
1953
|
-
* ```
|
|
1954
|
-
*/
|
|
1955
|
-
const Suspense$1 = defineComponent$1((ctx) => {
|
|
1956
|
-
const { props, slots } = ctx;
|
|
1957
|
-
const state = ctx.signal({
|
|
1958
|
-
isReady: false,
|
|
1959
|
-
pendingCount: 0
|
|
1960
|
-
});
|
|
1961
|
-
const boundary = {
|
|
1962
|
-
pending: /* @__PURE__ */ new Set(),
|
|
1963
|
-
onResolve: () => {
|
|
1964
|
-
state.pendingCount = boundary.pending.size;
|
|
1965
|
-
if (boundary.pending.size === 0) state.isReady = true;
|
|
1966
|
-
}
|
|
1967
|
-
};
|
|
1968
|
-
ctx.onMount(() => {
|
|
1969
|
-
if (boundary.pending.size === 0) state.isReady = true;
|
|
1970
|
-
});
|
|
1971
|
-
return () => {
|
|
1972
|
-
state.isReady;
|
|
1973
|
-
state.pendingCount;
|
|
1974
|
-
const prevBoundary = currentSuspenseBoundary;
|
|
1975
|
-
currentSuspenseBoundary = boundary;
|
|
1976
|
-
try {
|
|
1977
|
-
const children = slots.default();
|
|
1978
|
-
if (boundary.pending.size > 0) {
|
|
1979
|
-
const fallback = props.fallback;
|
|
1980
|
-
if (typeof fallback === "function") return fallback();
|
|
1981
|
-
return fallback ?? null;
|
|
1982
|
-
}
|
|
1983
|
-
if (Array.isArray(children)) {
|
|
1984
|
-
const filtered = children.filter((c) => c != null && c !== false && c !== true);
|
|
1985
|
-
if (filtered.length === 0) return null;
|
|
1986
|
-
if (filtered.length === 1) return filtered[0];
|
|
1987
|
-
return filtered;
|
|
1988
|
-
}
|
|
1989
|
-
return children;
|
|
1990
|
-
} catch (err) {
|
|
1991
|
-
if (err instanceof Promise) {
|
|
1992
|
-
registerPendingPromise$1(err);
|
|
1993
|
-
const fallback = props.fallback;
|
|
1994
|
-
if (typeof fallback === "function") return fallback();
|
|
1995
|
-
return fallback ?? null;
|
|
1996
|
-
}
|
|
1997
|
-
throw err;
|
|
1998
|
-
} finally {
|
|
1999
|
-
currentSuspenseBoundary = prevBoundary;
|
|
2000
|
-
}
|
|
2001
|
-
};
|
|
2002
|
-
}, { name: "Suspense" });
|
|
2003
|
-
|
|
2004
|
-
//#endregion
|
|
2005
|
-
//#region ../runtime-terminal/src/components/Input.tsx
|
|
2006
|
-
/** @jsxImportSource @sigx/runtime-core */
|
|
2007
|
-
const Input = defineComponent(({ props, emit }) => {
|
|
1948
|
+
const Input = component(({ props, emit }) => {
|
|
2008
1949
|
const id = Math.random().toString(36).slice(2);
|
|
1950
|
+
let isReady = false;
|
|
2009
1951
|
const isFocused = () => focusState.activeId === id;
|
|
1952
|
+
const getValue = () => props.model?.value || "";
|
|
2010
1953
|
const handleKey = (key) => {
|
|
2011
1954
|
if (!isFocused()) return;
|
|
1955
|
+
if (!isReady) return;
|
|
2012
1956
|
if (key === "\r") {
|
|
2013
|
-
emit("submit",
|
|
1957
|
+
emit("submit", getValue());
|
|
2014
1958
|
return;
|
|
2015
1959
|
}
|
|
2016
1960
|
if (key === "\n") return;
|
|
2017
1961
|
if (key === "" || key === "\b") {
|
|
2018
|
-
const val =
|
|
1962
|
+
const val = getValue();
|
|
2019
1963
|
if (val.length > 0) {
|
|
2020
|
-
const newValue
|
|
2021
|
-
|
|
2022
|
-
emit("input", newValue
|
|
1964
|
+
const newValue = val.slice(0, -1);
|
|
1965
|
+
if (props.model) props.model.value = newValue;
|
|
1966
|
+
emit("input", newValue);
|
|
2023
1967
|
}
|
|
2024
1968
|
return;
|
|
2025
1969
|
}
|
|
2026
1970
|
if (key.length > 1) return;
|
|
2027
|
-
const newValue = (
|
|
2028
|
-
|
|
1971
|
+
const newValue = getValue() + key;
|
|
1972
|
+
if (props.model) props.model.value = newValue;
|
|
2029
1973
|
emit("input", newValue);
|
|
2030
1974
|
};
|
|
2031
1975
|
let keyCleanup = null;
|
|
2032
|
-
|
|
1976
|
+
onMounted(() => {
|
|
2033
1977
|
registerFocusable(id);
|
|
2034
1978
|
if (props.autofocus) focus(id);
|
|
2035
1979
|
keyCleanup = onKey(handleKey);
|
|
1980
|
+
setTimeout(() => {
|
|
1981
|
+
isReady = true;
|
|
1982
|
+
}, 50);
|
|
2036
1983
|
});
|
|
2037
|
-
|
|
1984
|
+
onUnmounted(() => {
|
|
2038
1985
|
if (keyCleanup) keyCleanup();
|
|
2039
1986
|
unregisterFocusable(id);
|
|
2040
1987
|
});
|
|
2041
1988
|
return () => {
|
|
2042
|
-
const val = (
|
|
1989
|
+
const val = getValue().replace(/[\r\n]+/g, " ");
|
|
2043
1990
|
const placeholder = (props.placeholder || "").replace(/[\r\n]+/g, " ");
|
|
2044
1991
|
const showCursor = isFocused();
|
|
2045
|
-
return /* @__PURE__ */ jsxs
|
|
1992
|
+
return /* @__PURE__ */ jsxs("box", {
|
|
2046
1993
|
border: "single",
|
|
2047
1994
|
borderColor: showCursor ? "green" : "white",
|
|
2048
1995
|
label: props.label,
|
|
2049
|
-
children: [/* @__PURE__ */ jsx
|
|
1996
|
+
children: [/* @__PURE__ */ jsx("text", { children: val || placeholder }), showCursor && /* @__PURE__ */ jsx("text", {
|
|
2050
1997
|
color: "cyan",
|
|
2051
1998
|
children: "_"
|
|
2052
1999
|
})]
|
|
2053
2000
|
});
|
|
2054
2001
|
};
|
|
2055
2002
|
}, { name: "Input" });
|
|
2056
|
-
|
|
2057
|
-
//#endregion
|
|
2058
|
-
//#region ../runtime-terminal/src/components/ProgressBar.tsx
|
|
2059
|
-
/** @jsxImportSource @sigx/runtime-core */
|
|
2060
|
-
const ProgressBar = defineComponent(({ props }) => {
|
|
2003
|
+
const ProgressBar = component(({ props }) => {
|
|
2061
2004
|
return () => {
|
|
2062
2005
|
const value = props.value || 0;
|
|
2063
2006
|
const max = props.max || 100;
|
|
@@ -2070,14 +2013,10 @@ const ProgressBar = defineComponent(({ props }) => {
|
|
|
2070
2013
|
const percentage = Math.min(Math.max(value / max, 0), 1);
|
|
2071
2014
|
const filledLen = Math.round(width * percentage);
|
|
2072
2015
|
const emptyLen = width - filledLen;
|
|
2073
|
-
return /* @__PURE__ */ jsx
|
|
2016
|
+
return /* @__PURE__ */ jsx("box", { children: /* @__PURE__ */ jsx("text", { children: colorCode + barChar.repeat(filledLen) + emptyChar.repeat(emptyLen) + reset + ` ${Math.round(percentage * 100)}%` }) });
|
|
2074
2017
|
};
|
|
2075
2018
|
}, { name: "ProgressBar" });
|
|
2076
|
-
|
|
2077
|
-
//#endregion
|
|
2078
|
-
//#region ../runtime-terminal/src/components/Button.tsx
|
|
2079
|
-
/** @jsxImportSource @sigx/runtime-core */
|
|
2080
|
-
const Button = defineComponent(({ props, emit }) => {
|
|
2019
|
+
const Button = component(({ props, emit }) => {
|
|
2081
2020
|
const id = Math.random().toString(36).slice(2);
|
|
2082
2021
|
const isFocused = () => focusState.activeId === id;
|
|
2083
2022
|
const pressed = signal({ value: false });
|
|
@@ -2095,11 +2034,11 @@ const Button = defineComponent(({ props, emit }) => {
|
|
|
2095
2034
|
};
|
|
2096
2035
|
let keyCleanup = null;
|
|
2097
2036
|
let pressTimer = null;
|
|
2098
|
-
|
|
2037
|
+
onMounted(() => {
|
|
2099
2038
|
registerFocusable(id);
|
|
2100
2039
|
keyCleanup = onKey(handleKey);
|
|
2101
2040
|
});
|
|
2102
|
-
|
|
2041
|
+
onUnmounted(() => {
|
|
2103
2042
|
if (keyCleanup) keyCleanup();
|
|
2104
2043
|
unregisterFocusable(id);
|
|
2105
2044
|
if (pressTimer) clearTimeout(pressTimer);
|
|
@@ -2108,42 +2047,38 @@ const Button = defineComponent(({ props, emit }) => {
|
|
|
2108
2047
|
const focused = isFocused();
|
|
2109
2048
|
const label = props.label || "Button";
|
|
2110
2049
|
const isPressed = pressed.value;
|
|
2111
|
-
return /* @__PURE__ */ jsx
|
|
2050
|
+
return /* @__PURE__ */ jsx("box", {
|
|
2112
2051
|
border: "single",
|
|
2113
2052
|
borderColor: isPressed ? "yellow" : focused ? "green" : "white",
|
|
2114
2053
|
backgroundColor: isPressed ? "red" : focused ? "blue" : void 0,
|
|
2115
2054
|
dropShadow: props.dropShadow,
|
|
2116
|
-
children: /* @__PURE__ */ jsx
|
|
2055
|
+
children: /* @__PURE__ */ jsx("text", {
|
|
2117
2056
|
color: focused ? "white" : void 0,
|
|
2118
2057
|
children: label
|
|
2119
2058
|
})
|
|
2120
2059
|
});
|
|
2121
2060
|
};
|
|
2122
2061
|
}, { name: "Button" });
|
|
2123
|
-
|
|
2124
|
-
//#endregion
|
|
2125
|
-
//#region ../runtime-terminal/src/components/Checkbox.tsx
|
|
2126
|
-
/** @jsxImportSource @sigx/runtime-core */
|
|
2127
|
-
const Checkbox = defineComponent(({ props, emit }) => {
|
|
2062
|
+
const Checkbox = component(({ props, emit }) => {
|
|
2128
2063
|
const id = Math.random().toString(36).slice(2);
|
|
2129
2064
|
const isFocused = () => focusState.activeId === id;
|
|
2130
|
-
const checked = () => !!props.value;
|
|
2065
|
+
const checked = () => !!props.model?.value;
|
|
2131
2066
|
const handleKey = (key) => {
|
|
2132
2067
|
if (!isFocused()) return;
|
|
2133
2068
|
if (props.disabled) return;
|
|
2134
2069
|
if (key === "\r" || key === " ") {
|
|
2135
2070
|
const next = !checked();
|
|
2136
|
-
|
|
2071
|
+
if (props.model) props.model.value = next;
|
|
2137
2072
|
emit("change", next);
|
|
2138
2073
|
}
|
|
2139
2074
|
};
|
|
2140
2075
|
let keyCleanup = null;
|
|
2141
|
-
|
|
2076
|
+
onMounted(() => {
|
|
2142
2077
|
registerFocusable(id);
|
|
2143
2078
|
if (props.autofocus) focus(id);
|
|
2144
2079
|
keyCleanup = onKey(handleKey);
|
|
2145
2080
|
});
|
|
2146
|
-
|
|
2081
|
+
onUnmounted(() => {
|
|
2147
2082
|
if (keyCleanup) keyCleanup();
|
|
2148
2083
|
unregisterFocusable(id);
|
|
2149
2084
|
});
|
|
@@ -2152,12 +2087,12 @@ const Checkbox = defineComponent(({ props, emit }) => {
|
|
|
2152
2087
|
const focused = isFocused();
|
|
2153
2088
|
const isChecked = checked();
|
|
2154
2089
|
const disabled = !!props.disabled;
|
|
2155
|
-
return /* @__PURE__ */ jsxs
|
|
2156
|
-
/* @__PURE__ */ jsx
|
|
2090
|
+
return /* @__PURE__ */ jsxs("box", { children: [
|
|
2091
|
+
/* @__PURE__ */ jsx("text", {
|
|
2157
2092
|
color: focused ? "cyan" : "white",
|
|
2158
2093
|
children: focused ? ">" : " "
|
|
2159
2094
|
}),
|
|
2160
|
-
/* @__PURE__ */ jsxs
|
|
2095
|
+
/* @__PURE__ */ jsxs("text", {
|
|
2161
2096
|
color: disabled ? "white" : isChecked ? "green" : focused ? "cyan" : "white",
|
|
2162
2097
|
children: [
|
|
2163
2098
|
"[",
|
|
@@ -2165,86 +2100,87 @@ const Checkbox = defineComponent(({ props, emit }) => {
|
|
|
2165
2100
|
"]"
|
|
2166
2101
|
]
|
|
2167
2102
|
}),
|
|
2168
|
-
label && /* @__PURE__ */ jsxs
|
|
2103
|
+
label && /* @__PURE__ */ jsxs("text", {
|
|
2169
2104
|
color: disabled ? "white" : focused ? "cyan" : void 0,
|
|
2170
2105
|
children: [" ", label]
|
|
2171
2106
|
})
|
|
2172
2107
|
] });
|
|
2173
2108
|
};
|
|
2174
2109
|
}, { name: "Checkbox" });
|
|
2175
|
-
|
|
2176
|
-
//#endregion
|
|
2177
|
-
//#region ../runtime-terminal/src/components/Select.tsx
|
|
2178
|
-
/** @jsxImportSource @sigx/runtime-core */
|
|
2179
|
-
const Select = defineComponent(({ props, emit }) => {
|
|
2110
|
+
const Select = component(({ props, emit }) => {
|
|
2180
2111
|
const id = Math.random().toString(36).slice(2);
|
|
2112
|
+
let isReady = false;
|
|
2181
2113
|
const isFocused = () => focusState.activeId === id;
|
|
2182
2114
|
const getCurrentIndex = () => {
|
|
2183
|
-
const idx = (props.options || []).findIndex((o) => o.value === props.value);
|
|
2115
|
+
const idx = (props.options || []).findIndex((o) => o.value === props.model?.value);
|
|
2184
2116
|
return idx >= 0 ? idx : 0;
|
|
2185
2117
|
};
|
|
2186
2118
|
const handleKey = (key) => {
|
|
2187
2119
|
if (!isFocused()) return;
|
|
2120
|
+
if (!isReady) return;
|
|
2188
2121
|
const options = props.options || [];
|
|
2189
2122
|
if (options.length === 0) return;
|
|
2190
2123
|
const currentIndex = getCurrentIndex();
|
|
2191
2124
|
if (key === "\x1B[A" || key === "k") {
|
|
2192
2125
|
const newValue = options[currentIndex > 0 ? currentIndex - 1 : options.length - 1].value;
|
|
2193
|
-
|
|
2126
|
+
if (props.model) props.model.value = newValue;
|
|
2194
2127
|
emit("change", newValue);
|
|
2195
2128
|
return;
|
|
2196
2129
|
}
|
|
2197
2130
|
if (key === "\x1B[B" || key === "j") {
|
|
2198
2131
|
const newValue = options[currentIndex < options.length - 1 ? currentIndex + 1 : 0].value;
|
|
2199
|
-
|
|
2132
|
+
if (props.model) props.model.value = newValue;
|
|
2200
2133
|
emit("change", newValue);
|
|
2201
2134
|
return;
|
|
2202
2135
|
}
|
|
2203
2136
|
if (key === "\r") {
|
|
2204
|
-
emit("submit", props.value || options[0]?.value || "");
|
|
2137
|
+
emit("submit", props.model?.value || options[0]?.value || "");
|
|
2205
2138
|
return;
|
|
2206
2139
|
}
|
|
2207
2140
|
};
|
|
2208
2141
|
let keyCleanup = null;
|
|
2209
|
-
|
|
2142
|
+
onMounted(() => {
|
|
2210
2143
|
registerFocusable(id);
|
|
2211
2144
|
if (props.autofocus) focus(id);
|
|
2212
2145
|
keyCleanup = onKey(handleKey);
|
|
2146
|
+
setTimeout(() => {
|
|
2147
|
+
isReady = true;
|
|
2148
|
+
}, 50);
|
|
2213
2149
|
});
|
|
2214
|
-
|
|
2150
|
+
onUnmounted(() => {
|
|
2215
2151
|
if (keyCleanup) keyCleanup();
|
|
2216
2152
|
unregisterFocusable(id);
|
|
2217
2153
|
});
|
|
2218
2154
|
return () => {
|
|
2219
2155
|
const options = props.options || [];
|
|
2220
2156
|
const focused = isFocused();
|
|
2221
|
-
const currentValue = props.value || options[0]?.value || "";
|
|
2157
|
+
const currentValue = props.model?.value || options[0]?.value || "";
|
|
2222
2158
|
const label = props.label;
|
|
2223
|
-
|
|
2159
|
+
const selectedOption = options.find((o) => o.value === currentValue);
|
|
2160
|
+
const optionElements = options.map((option) => {
|
|
2161
|
+
const isSelected = option.value === currentValue;
|
|
2162
|
+
return /* @__PURE__ */ jsx("box", { children: /* @__PURE__ */ jsxs("text", {
|
|
2163
|
+
color: isSelected ? "cyan" : "white",
|
|
2164
|
+
children: [
|
|
2165
|
+
isSelected ? "❯" : " ",
|
|
2166
|
+
" ",
|
|
2167
|
+
option.label
|
|
2168
|
+
]
|
|
2169
|
+
}) });
|
|
2170
|
+
});
|
|
2171
|
+
const descriptionElement = props.showDescription && selectedOption?.description ? /* @__PURE__ */ jsx("box", { children: /* @__PURE__ */ jsxs("text", {
|
|
2172
|
+
color: "#666666",
|
|
2173
|
+
children: [" ↳ ", selectedOption.description]
|
|
2174
|
+
}) }) : null;
|
|
2175
|
+
return /* @__PURE__ */ jsxs("box", { children: [/* @__PURE__ */ jsx("box", {
|
|
2224
2176
|
border: "single",
|
|
2225
2177
|
borderColor: focused ? "green" : "white",
|
|
2226
2178
|
label,
|
|
2227
|
-
children:
|
|
2228
|
-
|
|
2229
|
-
return /* @__PURE__ */ jsxs$1("box", { children: [/* @__PURE__ */ jsxs$1("text", {
|
|
2230
|
-
color: isSelected ? "cyan" : "white",
|
|
2231
|
-
children: [
|
|
2232
|
-
isSelected ? "❯" : " ",
|
|
2233
|
-
" ",
|
|
2234
|
-
option.label
|
|
2235
|
-
]
|
|
2236
|
-
}), option.description && isSelected && /* @__PURE__ */ jsxs$1(Fragment$1, { children: [/* @__PURE__ */ jsx$1("br", {}), /* @__PURE__ */ jsxs$1("text", {
|
|
2237
|
-
color: "white",
|
|
2238
|
-
children: [" ", option.description]
|
|
2239
|
-
})] })] });
|
|
2240
|
-
})
|
|
2241
|
-
});
|
|
2179
|
+
children: optionElements
|
|
2180
|
+
}), descriptionElement] });
|
|
2242
2181
|
};
|
|
2243
2182
|
}, { name: "Select" });
|
|
2244
|
-
|
|
2245
|
-
//#endregion
|
|
2246
|
-
//#region ../runtime-terminal/src/index.ts
|
|
2247
|
-
const renderer = createRenderer({
|
|
2183
|
+
const { render } = createRenderer({
|
|
2248
2184
|
patchProp: (el, key, prev, next) => {
|
|
2249
2185
|
el.props[key] = next;
|
|
2250
2186
|
scheduleRender();
|
|
@@ -2315,9 +2251,8 @@ const renderer = createRenderer({
|
|
|
2315
2251
|
};
|
|
2316
2252
|
}
|
|
2317
2253
|
});
|
|
2318
|
-
|
|
2319
|
-
|
|
2320
|
-
let isRendering = false;
|
|
2254
|
+
var rootNode = null;
|
|
2255
|
+
var isRendering = false;
|
|
2321
2256
|
function scheduleRender() {
|
|
2322
2257
|
if (isRendering) return;
|
|
2323
2258
|
isRendering = true;
|
|
@@ -2333,10 +2268,6 @@ function flushRender() {
|
|
|
2333
2268
|
process.stdout.write(lines.join("\x1B[K\n") + "\x1B[K");
|
|
2334
2269
|
process.stdout.write("\x1B[J");
|
|
2335
2270
|
}
|
|
2336
|
-
/**
|
|
2337
|
-
* Check if a node has a box element as an immediate child.
|
|
2338
|
-
* This is used to determine if a component wrapper should be treated as a block element.
|
|
2339
|
-
*/
|
|
2340
2271
|
function hasBoxChild(node) {
|
|
2341
2272
|
for (const child of node.children) if (child.tag === "box") return true;
|
|
2342
2273
|
return false;
|
|
@@ -2425,7 +2356,7 @@ function getBorderChars(style) {
|
|
|
2425
2356
|
v: "│"
|
|
2426
2357
|
};
|
|
2427
2358
|
}
|
|
2428
|
-
|
|
2359
|
+
var keyHandlers = /* @__PURE__ */ new Set();
|
|
2429
2360
|
function onKey(handler) {
|
|
2430
2361
|
keyHandlers.add(handler);
|
|
2431
2362
|
return () => keyHandlers.delete(handler);
|
|
@@ -2472,16 +2403,7 @@ function renderTerminal(app, options = {}) {
|
|
|
2472
2403
|
}
|
|
2473
2404
|
} };
|
|
2474
2405
|
}
|
|
2475
|
-
|
|
2476
|
-
/**
|
|
2477
|
-
* Helper function to mount the terminal for CLI apps.
|
|
2478
|
-
* Returns a mount target that can be passed to defineApp().mount().
|
|
2479
|
-
*
|
|
2480
|
-
* @example
|
|
2481
|
-
* ```tsx
|
|
2482
|
-
* defineApp(MyApp).mount(mountTerminal());
|
|
2483
|
-
* ```
|
|
2484
|
-
*/
|
|
2406
|
+
var unmountFn = null;
|
|
2485
2407
|
function mountTerminal(options = { clearConsole: true }) {
|
|
2486
2408
|
return {
|
|
2487
2409
|
mount: terminalMount,
|
|
@@ -2491,9 +2413,6 @@ function mountTerminal(options = { clearConsole: true }) {
|
|
|
2491
2413
|
}
|
|
2492
2414
|
};
|
|
2493
2415
|
}
|
|
2494
|
-
/**
|
|
2495
|
-
* Exit the terminal app cleanly, restoring terminal state.
|
|
2496
|
-
*/
|
|
2497
2416
|
function exitTerminal() {
|
|
2498
2417
|
if (unmountFn) {
|
|
2499
2418
|
unmountFn();
|
|
@@ -2502,20 +2421,6 @@ function exitTerminal() {
|
|
|
2502
2421
|
process.stdout.write("\x1B[?25h");
|
|
2503
2422
|
process.stdout.write("\x1B[2J\x1B[H");
|
|
2504
2423
|
}
|
|
2505
|
-
/**
|
|
2506
|
-
* Mount function for Terminal environments.
|
|
2507
|
-
* Use this with defineApp().mount() to render to the terminal.
|
|
2508
|
-
*
|
|
2509
|
-
* @example
|
|
2510
|
-
* ```tsx
|
|
2511
|
-
* import { defineApp } from '@sigx/runtime-core';
|
|
2512
|
-
* import { terminalMount } from '@sigx/runtime-terminal';
|
|
2513
|
-
*
|
|
2514
|
-
* const app = defineApp(<Counter />);
|
|
2515
|
-
* app.use(loggingPlugin)
|
|
2516
|
-
* .mount({ clearConsole: true }, terminalMount);
|
|
2517
|
-
* ```
|
|
2518
|
-
*/
|
|
2519
2424
|
const terminalMount = (component, options, appContext) => {
|
|
2520
2425
|
rootNode = {
|
|
2521
2426
|
type: "root",
|
|
@@ -2544,7 +2449,6 @@ const terminalMount = (component, options, appContext) => {
|
|
|
2544
2449
|
};
|
|
2545
2450
|
};
|
|
2546
2451
|
setDefaultMount(terminalMount);
|
|
2452
|
+
export { Button, CLIENT_DIRECTIVES, CLIENT_DIRECTIVE_PREFIX, Checkbox, ComputedSymbol, ErrorBoundary, Fragment, Input, InstanceLifetimes, ProgressBar, Select, SubscriptionHandler, Suspense, Text, Utils, __DIRECTIVE__, applyContextExtensions, batch, cleanup, component, compound, computed, createEmit, createModel, createModelFromBinding, createPropsAccessor, createPropsProxy, createRenderer, createSlots, createTopic, defineApp, defineDirective, defineFactory, defineInjectable, defineProvide, detectAccess, effect, effectScope, exitTerminal, filterClientDirectives, focus, focusNext, focusPrev, focusState, getAppContextToken, getComponentMeta, getComponentPlugins, getCurrentInstance, getDefaultMount, getHydrationDirective, getModelSymbol, getPlatformModelProcessor, guid, handleComponentError, hasClientDirective, hasRequestIsolation, isComponent, isComputed, isDirective, isLazyComponent, isModel, isReactive, jsx, jsxDEV, jsxs, lazy, mountTerminal, normalizeSubTree, notifyComponentCreated, notifyComponentMounted, notifyComponentUnmounted, notifyComponentUpdated, onCreated, onKey, onMounted, onUnmounted, onUpdated, provideAppContext, registerComponentPlugin, registerContextExtension, registerFocusable, registerPendingPromise, render, renderNodeToLines, renderTerminal, runInRequestScope, serializeProps, setCurrentInstance, setDefaultMount, setPlatformModelProcessor, signal, terminalMount, toRaw, toSubscriber, track, trigger, unregisterFocusable, untrack, useAppContext, valueOf, watch };
|
|
2547
2453
|
|
|
2548
|
-
//#endregion
|
|
2549
|
-
export { AppContextKey, Button, Checkbox, Fragment, Input, InstanceLifetimes, ProgressBar, Select, SubscriptionHandler, Suspense, Text, Utils, applyContextExtensions, batch, createApp, createPropsAccessor, createPropsProxy, createRenderer, createSlots, createTopic, defineApp, defineComponent, defineFactory, defineInjectable, defineProvide, defineStore, detectAccess, effect, effectScope, exitTerminal, focus, focusNext, focusPrev, focusState, getComponentMeta, getComponentPlugins, getCurrentInstance, getDefaultMount, getPlatformSyncProcessor, guid, handleComponentError, inject, injectApp, isLazyComponent, jsx, jsxDEV, jsxs, lazy, mountTerminal, normalizeSubTree, notifyComponentCreated, notifyComponentMounted, notifyComponentUnmounted, notifyComponentUpdated, onCleanup, onKey, onMount, provide, registerComponentPlugin, registerContextExtension, registerFocusable, registerPendingPromise, render, renderNodeToLines, renderTerminal, setCurrentInstance, setDefaultMount, setPlatformSyncProcessor, signal, terminalMount, toSubscriber, unregisterFocusable, untrack, valueOf, watch };
|
|
2550
2454
|
//# sourceMappingURL=index.js.map
|