@sigx/terminal 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +3 -0
- package/dist/index.js +1929 -0
- package/dist/index.js.map +1 -0
- package/package.json +58 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,1929 @@
|
|
|
1
|
+
//#region ../reactivity/src/index.ts
|
|
2
|
+
let activeEffect = null;
|
|
3
|
+
let batchDepth = 0;
|
|
4
|
+
const pendingEffects = /* @__PURE__ */ new Set();
|
|
5
|
+
function batch(fn) {
|
|
6
|
+
batchDepth++;
|
|
7
|
+
try {
|
|
8
|
+
fn();
|
|
9
|
+
} finally {
|
|
10
|
+
batchDepth--;
|
|
11
|
+
if (batchDepth === 0) {
|
|
12
|
+
const effects = Array.from(pendingEffects);
|
|
13
|
+
pendingEffects.clear();
|
|
14
|
+
for (const effect$1 of effects) effect$1();
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
function runEffect(fn) {
|
|
19
|
+
const effect$1 = function() {
|
|
20
|
+
cleanup(effect$1);
|
|
21
|
+
activeEffect = effect$1;
|
|
22
|
+
fn();
|
|
23
|
+
activeEffect = null;
|
|
24
|
+
};
|
|
25
|
+
effect$1.deps = [];
|
|
26
|
+
effect$1();
|
|
27
|
+
return () => cleanup(effect$1);
|
|
28
|
+
}
|
|
29
|
+
function cleanup(effect$1) {
|
|
30
|
+
if (!effect$1.deps) return;
|
|
31
|
+
for (const dep of effect$1.deps) dep.delete(effect$1);
|
|
32
|
+
effect$1.deps.length = 0;
|
|
33
|
+
}
|
|
34
|
+
function track(depSet) {
|
|
35
|
+
if (!activeEffect) return;
|
|
36
|
+
depSet.add(activeEffect);
|
|
37
|
+
activeEffect.deps.push(depSet);
|
|
38
|
+
}
|
|
39
|
+
function trigger(depSet) {
|
|
40
|
+
const effects = Array.from(depSet);
|
|
41
|
+
for (const effect$1 of effects) if (batchDepth > 0) pendingEffects.add(effect$1);
|
|
42
|
+
else effect$1();
|
|
43
|
+
}
|
|
44
|
+
let accessObserver = null;
|
|
45
|
+
function detectAccess(selector) {
|
|
46
|
+
let result = null;
|
|
47
|
+
const prev = accessObserver;
|
|
48
|
+
accessObserver = (target, key) => {
|
|
49
|
+
result = [target, key];
|
|
50
|
+
};
|
|
51
|
+
try {
|
|
52
|
+
selector();
|
|
53
|
+
} finally {
|
|
54
|
+
accessObserver = prev;
|
|
55
|
+
}
|
|
56
|
+
return result;
|
|
57
|
+
}
|
|
58
|
+
function untrack(fn) {
|
|
59
|
+
const prev = activeEffect;
|
|
60
|
+
activeEffect = null;
|
|
61
|
+
try {
|
|
62
|
+
return fn();
|
|
63
|
+
} finally {
|
|
64
|
+
activeEffect = prev;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
function signal(target) {
|
|
68
|
+
const depsMap = /* @__PURE__ */ new Map();
|
|
69
|
+
const reactiveCache = /* @__PURE__ */ new WeakMap();
|
|
70
|
+
return new Proxy(target, {
|
|
71
|
+
get(obj, prop, receiver) {
|
|
72
|
+
if (prop === "$set") return (newValue) => {
|
|
73
|
+
batch(() => {
|
|
74
|
+
if (Array.isArray(obj) && Array.isArray(newValue)) {
|
|
75
|
+
const len = newValue.length;
|
|
76
|
+
for (let i = 0; i < len; i++) Reflect.set(receiver, String(i), newValue[i]);
|
|
77
|
+
Reflect.set(receiver, "length", len);
|
|
78
|
+
} else {
|
|
79
|
+
const newKeys = Object.keys(newValue);
|
|
80
|
+
const oldKeys = Object.keys(obj);
|
|
81
|
+
for (const key of newKeys) Reflect.set(receiver, key, newValue[key]);
|
|
82
|
+
for (const key of oldKeys) if (!(key in newValue)) Reflect.deleteProperty(receiver, key);
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
};
|
|
86
|
+
if (Array.isArray(obj) && typeof prop === "string" && arrayInstrumentations.hasOwnProperty(prop)) return arrayInstrumentations[prop];
|
|
87
|
+
const value = Reflect.get(obj, prop);
|
|
88
|
+
if (accessObserver) accessObserver(receiver, prop);
|
|
89
|
+
let dep = depsMap.get(prop);
|
|
90
|
+
if (!dep) {
|
|
91
|
+
dep = /* @__PURE__ */ new Set();
|
|
92
|
+
depsMap.set(prop, dep);
|
|
93
|
+
}
|
|
94
|
+
track(dep);
|
|
95
|
+
if (value && typeof value === "object") {
|
|
96
|
+
let cached = reactiveCache.get(value);
|
|
97
|
+
if (!cached) {
|
|
98
|
+
cached = signal(value);
|
|
99
|
+
reactiveCache.set(value, cached);
|
|
100
|
+
}
|
|
101
|
+
return cached;
|
|
102
|
+
}
|
|
103
|
+
return value;
|
|
104
|
+
},
|
|
105
|
+
set(obj, prop, newValue) {
|
|
106
|
+
const oldLength = Array.isArray(obj) ? obj.length : 0;
|
|
107
|
+
const oldValue = Reflect.get(obj, prop);
|
|
108
|
+
const result = Reflect.set(obj, prop, newValue);
|
|
109
|
+
if (!Object.is(oldValue, newValue)) {
|
|
110
|
+
const dep = depsMap.get(prop);
|
|
111
|
+
if (dep) trigger(dep);
|
|
112
|
+
if (Array.isArray(obj)) {
|
|
113
|
+
if (prop !== "length" && obj.length !== oldLength) {
|
|
114
|
+
const lengthDep = depsMap.get("length");
|
|
115
|
+
if (lengthDep) trigger(lengthDep);
|
|
116
|
+
}
|
|
117
|
+
if (prop === "length" && typeof newValue === "number" && newValue < oldLength) for (let i = newValue; i < oldLength; i++) {
|
|
118
|
+
const idxDep = depsMap.get(String(i));
|
|
119
|
+
if (idxDep) trigger(idxDep);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
return result;
|
|
124
|
+
},
|
|
125
|
+
deleteProperty(obj, prop) {
|
|
126
|
+
const hasKey = Object.prototype.hasOwnProperty.call(obj, prop);
|
|
127
|
+
const result = Reflect.deleteProperty(obj, prop);
|
|
128
|
+
if (result && hasKey) {
|
|
129
|
+
const dep = depsMap.get(prop);
|
|
130
|
+
if (dep) trigger(dep);
|
|
131
|
+
}
|
|
132
|
+
return result;
|
|
133
|
+
}
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
function effect(fn) {
|
|
137
|
+
return runEffect(fn);
|
|
138
|
+
}
|
|
139
|
+
const arrayInstrumentations = {};
|
|
140
|
+
[
|
|
141
|
+
"push",
|
|
142
|
+
"pop",
|
|
143
|
+
"shift",
|
|
144
|
+
"unshift",
|
|
145
|
+
"splice",
|
|
146
|
+
"sort",
|
|
147
|
+
"reverse"
|
|
148
|
+
].forEach((method) => {
|
|
149
|
+
arrayInstrumentations[method] = function(...args) {
|
|
150
|
+
let res;
|
|
151
|
+
batch(() => {
|
|
152
|
+
res = Array.prototype[method].apply(this, args);
|
|
153
|
+
});
|
|
154
|
+
return res;
|
|
155
|
+
};
|
|
156
|
+
});
|
|
157
|
+
function watch(source, cb, options) {
|
|
158
|
+
let oldValue;
|
|
159
|
+
let isFirst = true;
|
|
160
|
+
let cleanupFn = null;
|
|
161
|
+
const runner = effect(() => {
|
|
162
|
+
const newValue = typeof source === "function" ? source() : source;
|
|
163
|
+
if (isFirst) {
|
|
164
|
+
if (options?.immediate) {
|
|
165
|
+
if (cleanupFn) cleanupFn();
|
|
166
|
+
cb(newValue, oldValue, (fn) => cleanupFn = fn);
|
|
167
|
+
}
|
|
168
|
+
isFirst = false;
|
|
169
|
+
} else {
|
|
170
|
+
if (cleanupFn) cleanupFn();
|
|
171
|
+
cb(newValue, oldValue, (fn) => cleanupFn = fn);
|
|
172
|
+
}
|
|
173
|
+
oldValue = newValue;
|
|
174
|
+
});
|
|
175
|
+
const stop = () => {
|
|
176
|
+
runner();
|
|
177
|
+
if (cleanupFn) cleanupFn();
|
|
178
|
+
};
|
|
179
|
+
const handle = stop;
|
|
180
|
+
handle.stop = stop;
|
|
181
|
+
handle.pause = () => {};
|
|
182
|
+
handle.resume = () => {};
|
|
183
|
+
return handle;
|
|
184
|
+
}
|
|
185
|
+
function effectScope(detached) {
|
|
186
|
+
const effects = [];
|
|
187
|
+
let active = true;
|
|
188
|
+
return {
|
|
189
|
+
run(fn) {
|
|
190
|
+
if (!active) return void 0;
|
|
191
|
+
return fn();
|
|
192
|
+
},
|
|
193
|
+
stop() {
|
|
194
|
+
active = false;
|
|
195
|
+
effects.forEach((e) => e());
|
|
196
|
+
}
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
//#endregion
|
|
201
|
+
//#region ../runtime-core/src/platform.ts
|
|
202
|
+
let platformSyncProcessor$1 = null;
|
|
203
|
+
/**
|
|
204
|
+
* Set the platform-specific sync processor for intrinsic elements.
|
|
205
|
+
* Called by runtime-dom to handle checkbox/radio/select sync bindings.
|
|
206
|
+
*/
|
|
207
|
+
function setPlatformSyncProcessor(fn) {
|
|
208
|
+
platformSyncProcessor$1 = fn;
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* Get the current platform sync processor (for internal use).
|
|
212
|
+
*/
|
|
213
|
+
function getPlatformSyncProcessor() {
|
|
214
|
+
return platformSyncProcessor$1;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
//#endregion
|
|
218
|
+
//#region ../runtime-core/src/plugins.ts
|
|
219
|
+
const plugins = [];
|
|
220
|
+
function registerComponentPlugin(plugin) {
|
|
221
|
+
plugins.push(plugin);
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Get all registered plugins (internal use)
|
|
225
|
+
*/
|
|
226
|
+
function getComponentPlugins() {
|
|
227
|
+
return plugins;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
//#endregion
|
|
231
|
+
//#region ../runtime-core/src/app.ts
|
|
232
|
+
const isDev = typeof process !== "undefined" && true || true;
|
|
233
|
+
/**
|
|
234
|
+
* Unique symbol for app context injection
|
|
235
|
+
*/
|
|
236
|
+
const AppContextKey = Symbol("sigx:app");
|
|
237
|
+
let defaultMountFn = null;
|
|
238
|
+
/**
|
|
239
|
+
* Set the default mount function for the platform.
|
|
240
|
+
* Called by platform packages (runtime-dom, runtime-terminal) on import.
|
|
241
|
+
*
|
|
242
|
+
* @example
|
|
243
|
+
* ```typescript
|
|
244
|
+
* // In @sigx/runtime-dom
|
|
245
|
+
* import { setDefaultMount } from '@sigx/runtime-core';
|
|
246
|
+
* setDefaultMount(domMount);
|
|
247
|
+
* ```
|
|
248
|
+
*/
|
|
249
|
+
function setDefaultMount(mountFn) {
|
|
250
|
+
defaultMountFn = mountFn;
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* Get the current default mount function.
|
|
254
|
+
* @internal
|
|
255
|
+
*/
|
|
256
|
+
function getDefaultMount() {
|
|
257
|
+
return defaultMountFn;
|
|
258
|
+
}
|
|
259
|
+
/**
|
|
260
|
+
* Create an application instance.
|
|
261
|
+
*
|
|
262
|
+
* @example
|
|
263
|
+
* ```tsx
|
|
264
|
+
* import { defineApp, defineInjectable } from '@sigx/runtime-core';
|
|
265
|
+
* import { render } from '@sigx/runtime-dom';
|
|
266
|
+
*
|
|
267
|
+
* // Define an injectable service
|
|
268
|
+
* const useApiConfig = defineInjectable(() => ({ baseUrl: 'https://api.example.com' }));
|
|
269
|
+
*
|
|
270
|
+
* const app = defineApp(<App />);
|
|
271
|
+
*
|
|
272
|
+
* app.use(myPlugin, { option: 'value' });
|
|
273
|
+
*
|
|
274
|
+
* // Provide using the injectable token (works with inject())
|
|
275
|
+
* app.provide(useApiConfig, { baseUrl: 'https://custom.api.com' });
|
|
276
|
+
*
|
|
277
|
+
* app.mount(document.getElementById('app')!, render);
|
|
278
|
+
* ```
|
|
279
|
+
*/
|
|
280
|
+
function defineApp(rootComponent) {
|
|
281
|
+
const installedPlugins = /* @__PURE__ */ new Set();
|
|
282
|
+
const context = {
|
|
283
|
+
app: null,
|
|
284
|
+
provides: /* @__PURE__ */ new Map(),
|
|
285
|
+
config: {},
|
|
286
|
+
hooks: []
|
|
287
|
+
};
|
|
288
|
+
let isMounted = false;
|
|
289
|
+
let container = null;
|
|
290
|
+
let unmountFn = null;
|
|
291
|
+
const app = {
|
|
292
|
+
config: context.config,
|
|
293
|
+
use(plugin, options) {
|
|
294
|
+
if (installedPlugins.has(plugin)) {
|
|
295
|
+
if (isDev) console.warn(`Plugin ${plugin.name || "anonymous"} is already installed.`);
|
|
296
|
+
return app;
|
|
297
|
+
}
|
|
298
|
+
installedPlugins.add(plugin);
|
|
299
|
+
if (typeof plugin === "function") plugin(app, options);
|
|
300
|
+
else if (plugin && typeof plugin.install === "function") plugin.install(app, options);
|
|
301
|
+
else if (isDev) console.warn("Invalid plugin: must be a function or have an install() method.");
|
|
302
|
+
return app;
|
|
303
|
+
},
|
|
304
|
+
provide(token, value) {
|
|
305
|
+
const actualToken = token?._token ?? token;
|
|
306
|
+
if (isDev && context.provides.has(actualToken)) console.warn(`App-level provide: token is being overwritten.`);
|
|
307
|
+
context.provides.set(actualToken, value);
|
|
308
|
+
return app;
|
|
309
|
+
},
|
|
310
|
+
hook(hooks) {
|
|
311
|
+
context.hooks.push(hooks);
|
|
312
|
+
return app;
|
|
313
|
+
},
|
|
314
|
+
mount(target, renderFn) {
|
|
315
|
+
if (isMounted) {
|
|
316
|
+
if (isDev) console.warn("App is already mounted. Call app.unmount() first.");
|
|
317
|
+
return app;
|
|
318
|
+
}
|
|
319
|
+
const mountFn = renderFn ?? defaultMountFn;
|
|
320
|
+
if (!mountFn) throw new Error("No mount function provided and no default mount function set. Either pass a mount function to app.mount(), or import a platform package (e.g., @sigx/runtime-dom or @sigx/runtime-terminal) that sets the default.");
|
|
321
|
+
container = target;
|
|
322
|
+
isMounted = true;
|
|
323
|
+
const result = mountFn(rootComponent, target, context);
|
|
324
|
+
if (typeof result === "function") unmountFn = result;
|
|
325
|
+
return app;
|
|
326
|
+
},
|
|
327
|
+
unmount() {
|
|
328
|
+
if (!isMounted) {
|
|
329
|
+
if (isDev) console.warn("App is not mounted.");
|
|
330
|
+
return;
|
|
331
|
+
}
|
|
332
|
+
if (unmountFn) unmountFn();
|
|
333
|
+
context.provides.clear();
|
|
334
|
+
isMounted = false;
|
|
335
|
+
container = null;
|
|
336
|
+
},
|
|
337
|
+
get _context() {
|
|
338
|
+
return context;
|
|
339
|
+
},
|
|
340
|
+
get _isMounted() {
|
|
341
|
+
return isMounted;
|
|
342
|
+
},
|
|
343
|
+
get _container() {
|
|
344
|
+
return container;
|
|
345
|
+
}
|
|
346
|
+
};
|
|
347
|
+
context.app = app;
|
|
348
|
+
return app;
|
|
349
|
+
}
|
|
350
|
+
/**
|
|
351
|
+
* Notify all app hooks that a component was created.
|
|
352
|
+
* Called by the renderer after setup() returns.
|
|
353
|
+
*/
|
|
354
|
+
function notifyComponentCreated(context, instance) {
|
|
355
|
+
if (!context) return;
|
|
356
|
+
for (const hooks of context.hooks) try {
|
|
357
|
+
hooks.onComponentCreated?.(instance);
|
|
358
|
+
} catch (err) {
|
|
359
|
+
handleHookError(context, err, instance, "onComponentCreated");
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
/**
|
|
363
|
+
* Notify all app hooks that a component was mounted.
|
|
364
|
+
* Called by the renderer after mount hooks run.
|
|
365
|
+
*/
|
|
366
|
+
function notifyComponentMounted(context, instance) {
|
|
367
|
+
if (!context) return;
|
|
368
|
+
for (const hooks of context.hooks) try {
|
|
369
|
+
hooks.onComponentMounted?.(instance);
|
|
370
|
+
} catch (err) {
|
|
371
|
+
handleHookError(context, err, instance, "onComponentMounted");
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
/**
|
|
375
|
+
* Notify all app hooks that a component was unmounted.
|
|
376
|
+
* Called by the renderer before cleanup.
|
|
377
|
+
*/
|
|
378
|
+
function notifyComponentUnmounted(context, instance) {
|
|
379
|
+
if (!context) return;
|
|
380
|
+
for (const hooks of context.hooks) try {
|
|
381
|
+
hooks.onComponentUnmounted?.(instance);
|
|
382
|
+
} catch (err) {
|
|
383
|
+
handleHookError(context, err, instance, "onComponentUnmounted");
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
/**
|
|
387
|
+
* Notify all app hooks that a component updated.
|
|
388
|
+
* Called by the renderer after re-render.
|
|
389
|
+
*/
|
|
390
|
+
function notifyComponentUpdated(context, instance) {
|
|
391
|
+
if (!context) return;
|
|
392
|
+
for (const hooks of context.hooks) try {
|
|
393
|
+
hooks.onComponentUpdated?.(instance);
|
|
394
|
+
} catch (err) {
|
|
395
|
+
handleHookError(context, err, instance, "onComponentUpdated");
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
/**
|
|
399
|
+
* Handle an error in a component. Returns true if the error was handled.
|
|
400
|
+
* Called by the renderer when an error occurs in setup or render.
|
|
401
|
+
*/
|
|
402
|
+
function handleComponentError(context, err, instance, info) {
|
|
403
|
+
if (!context) return false;
|
|
404
|
+
for (const hooks of context.hooks) try {
|
|
405
|
+
if (hooks.onComponentError?.(err, instance, info) === true) return true;
|
|
406
|
+
} catch (hookErr) {
|
|
407
|
+
console.error("Error in onComponentError hook:", hookErr);
|
|
408
|
+
}
|
|
409
|
+
if (context.config.errorHandler) try {
|
|
410
|
+
if (context.config.errorHandler(err, instance, info) === true) return true;
|
|
411
|
+
} catch (handlerErr) {
|
|
412
|
+
console.error("Error in app.config.errorHandler:", handlerErr);
|
|
413
|
+
}
|
|
414
|
+
return false;
|
|
415
|
+
}
|
|
416
|
+
/**
|
|
417
|
+
* Handle errors that occur in hooks themselves
|
|
418
|
+
*/
|
|
419
|
+
function handleHookError(context, err, instance, hookName) {
|
|
420
|
+
console.error(`Error in ${hookName} hook:`, err);
|
|
421
|
+
if (context.config.errorHandler) try {
|
|
422
|
+
context.config.errorHandler(err, instance, `plugin hook: ${hookName}`);
|
|
423
|
+
} catch {}
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
//#endregion
|
|
427
|
+
//#region ../runtime-core/src/component.ts
|
|
428
|
+
let currentComponentContext = null;
|
|
429
|
+
function getCurrentInstance() {
|
|
430
|
+
return currentComponentContext;
|
|
431
|
+
}
|
|
432
|
+
function setCurrentInstance(ctx) {
|
|
433
|
+
const prev = currentComponentContext;
|
|
434
|
+
currentComponentContext = ctx;
|
|
435
|
+
return prev;
|
|
436
|
+
}
|
|
437
|
+
function onMount(fn) {
|
|
438
|
+
if (currentComponentContext) currentComponentContext.onMount(fn);
|
|
439
|
+
else console.warn("onMount called outside of component setup");
|
|
440
|
+
}
|
|
441
|
+
function onCleanup(fn) {
|
|
442
|
+
if (currentComponentContext) currentComponentContext.onCleanup(fn);
|
|
443
|
+
else console.warn("onCleanup called outside of component setup");
|
|
444
|
+
}
|
|
445
|
+
const componentRegistry = /* @__PURE__ */ new Map();
|
|
446
|
+
/**
|
|
447
|
+
* Get component metadata (for DevTools)
|
|
448
|
+
*/
|
|
449
|
+
function getComponentMeta(factory) {
|
|
450
|
+
return componentRegistry.get(factory);
|
|
451
|
+
}
|
|
452
|
+
/**
|
|
453
|
+
* Helper to create a proxy that tracks property access
|
|
454
|
+
*/
|
|
455
|
+
function createPropsProxy(target, onAccess) {
|
|
456
|
+
return new Proxy(target, { get(obj, prop) {
|
|
457
|
+
if (typeof prop === "string" && onAccess) onAccess(prop);
|
|
458
|
+
return obj[prop];
|
|
459
|
+
} });
|
|
460
|
+
}
|
|
461
|
+
/**
|
|
462
|
+
* Define a component. Returns a JSX factory function.
|
|
463
|
+
*
|
|
464
|
+
* @param setup - Setup function that receives context and returns a render function
|
|
465
|
+
* @param options - Optional configuration (e.g., name for DevTools)
|
|
466
|
+
*
|
|
467
|
+
* @example
|
|
468
|
+
* ```tsx
|
|
469
|
+
* type CardProps = DefineProp<"title", string> & DefineSlot<"header">;
|
|
470
|
+
*
|
|
471
|
+
* export const Card = defineComponent<CardProps>((ctx) => {
|
|
472
|
+
* const { title } = ctx.props;
|
|
473
|
+
* const { slots } = ctx;
|
|
474
|
+
*
|
|
475
|
+
* return () => (
|
|
476
|
+
* <div class="card">
|
|
477
|
+
* {slots.header?.() ?? <h2>{title}</h2>}
|
|
478
|
+
* {slots.default()}
|
|
479
|
+
* </div>
|
|
480
|
+
* );
|
|
481
|
+
* });
|
|
482
|
+
* ```
|
|
483
|
+
*/
|
|
484
|
+
function defineComponent(setup, options) {
|
|
485
|
+
const factory = function(props) {
|
|
486
|
+
return {
|
|
487
|
+
type: factory,
|
|
488
|
+
props: props || {},
|
|
489
|
+
key: props?.key || null,
|
|
490
|
+
children: [],
|
|
491
|
+
dom: null
|
|
492
|
+
};
|
|
493
|
+
};
|
|
494
|
+
factory.__setup = setup;
|
|
495
|
+
factory.__name = options?.name;
|
|
496
|
+
factory.__props = null;
|
|
497
|
+
factory.__events = null;
|
|
498
|
+
factory.__ref = null;
|
|
499
|
+
factory.__slots = null;
|
|
500
|
+
componentRegistry.set(factory, {
|
|
501
|
+
name: options?.name,
|
|
502
|
+
setup
|
|
503
|
+
});
|
|
504
|
+
getComponentPlugins().forEach((p) => p.onDefine?.(options?.name, factory, setup));
|
|
505
|
+
return factory;
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
//#endregion
|
|
509
|
+
//#region ../runtime-core/src/jsx-runtime.ts
|
|
510
|
+
const Fragment = Symbol.for("sigx.Fragment");
|
|
511
|
+
const Text = Symbol.for("sigx.Text");
|
|
512
|
+
function normalizeChildren$1(children) {
|
|
513
|
+
if (children == null || children === false || children === true) return [];
|
|
514
|
+
if (Array.isArray(children)) return children.flatMap((c) => normalizeChildren$1(c));
|
|
515
|
+
if (typeof children === "string" || typeof children === "number") return [{
|
|
516
|
+
type: Text,
|
|
517
|
+
props: {},
|
|
518
|
+
key: null,
|
|
519
|
+
children: [],
|
|
520
|
+
dom: null,
|
|
521
|
+
text: children
|
|
522
|
+
}];
|
|
523
|
+
if (children.type) return [children];
|
|
524
|
+
return [];
|
|
525
|
+
}
|
|
526
|
+
/**
|
|
527
|
+
* Check if a type is a sigx component (has __setup)
|
|
528
|
+
*/
|
|
529
|
+
function isComponent$2(type) {
|
|
530
|
+
return typeof type === "function" && "__setup" in type;
|
|
531
|
+
}
|
|
532
|
+
/**
|
|
533
|
+
* Create a JSX element - this is the core function called by TSX transpilation
|
|
534
|
+
*/
|
|
535
|
+
function jsx(type, props, key) {
|
|
536
|
+
const processedProps = { ...props || {} };
|
|
537
|
+
if (props) {
|
|
538
|
+
for (const propKey in props) if (propKey === "sync") {
|
|
539
|
+
let syncBinding = props[propKey];
|
|
540
|
+
if (typeof syncBinding === "function") {
|
|
541
|
+
const detected = detectAccess(syncBinding);
|
|
542
|
+
if (detected) syncBinding = detected;
|
|
543
|
+
}
|
|
544
|
+
if (Array.isArray(syncBinding) && syncBinding.length === 2) {
|
|
545
|
+
const [stateObj, key$1] = syncBinding;
|
|
546
|
+
let handled = false;
|
|
547
|
+
const platformProcessor = getPlatformSyncProcessor();
|
|
548
|
+
if (typeof type === "string" && platformProcessor) handled = platformProcessor(type, processedProps, [stateObj, key$1], props);
|
|
549
|
+
if (!handled) {
|
|
550
|
+
processedProps.value = stateObj[key$1];
|
|
551
|
+
const existingHandler = processedProps["onUpdate:value"];
|
|
552
|
+
processedProps["onUpdate:value"] = (v) => {
|
|
553
|
+
stateObj[key$1] = v;
|
|
554
|
+
if (existingHandler) existingHandler(v);
|
|
555
|
+
};
|
|
556
|
+
}
|
|
557
|
+
delete processedProps.sync;
|
|
558
|
+
}
|
|
559
|
+
} else if (propKey.startsWith("sync:")) {
|
|
560
|
+
const syncBinding = props[propKey];
|
|
561
|
+
if (Array.isArray(syncBinding) && syncBinding.length === 2) {
|
|
562
|
+
const [stateObj, key$1] = syncBinding;
|
|
563
|
+
const name = propKey.slice(5);
|
|
564
|
+
processedProps[name] = stateObj[key$1];
|
|
565
|
+
const eventName = `onUpdate:${name}`;
|
|
566
|
+
const existingHandler = processedProps[eventName];
|
|
567
|
+
processedProps[eventName] = (v) => {
|
|
568
|
+
stateObj[key$1] = v;
|
|
569
|
+
if (existingHandler) existingHandler(v);
|
|
570
|
+
};
|
|
571
|
+
delete processedProps[propKey];
|
|
572
|
+
}
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
if (isComponent$2(type)) {
|
|
576
|
+
const { children: children$1, ...rest$1 } = processedProps;
|
|
577
|
+
return {
|
|
578
|
+
type,
|
|
579
|
+
props: {
|
|
580
|
+
...rest$1,
|
|
581
|
+
children: children$1
|
|
582
|
+
},
|
|
583
|
+
key: key || rest$1.key || null,
|
|
584
|
+
children: [],
|
|
585
|
+
dom: null
|
|
586
|
+
};
|
|
587
|
+
}
|
|
588
|
+
if (typeof type === "function" && type !== Fragment) return type(processedProps);
|
|
589
|
+
const { children, ...rest } = processedProps;
|
|
590
|
+
return {
|
|
591
|
+
type,
|
|
592
|
+
props: rest,
|
|
593
|
+
key: key || rest.key || null,
|
|
594
|
+
children: normalizeChildren$1(children),
|
|
595
|
+
dom: null
|
|
596
|
+
};
|
|
597
|
+
}
|
|
598
|
+
/**
|
|
599
|
+
* JSX Factory for fragments
|
|
600
|
+
*/
|
|
601
|
+
function jsxs(type, props, key) {
|
|
602
|
+
return jsx(type, props, key);
|
|
603
|
+
}
|
|
604
|
+
const jsxDEV = jsx;
|
|
605
|
+
|
|
606
|
+
//#endregion
|
|
607
|
+
//#region ../runtime-core/src/utils/index.ts
|
|
608
|
+
var Utils = class {
|
|
609
|
+
static isPromise(value) {
|
|
610
|
+
return !!value && (typeof value === "object" || typeof value === "function") && typeof value.then === "function";
|
|
611
|
+
}
|
|
612
|
+
};
|
|
613
|
+
function guid$1() {
|
|
614
|
+
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function(c) {
|
|
615
|
+
var r = Math.random() * 16 | 0;
|
|
616
|
+
return (c == "x" ? r : r & 3 | 8).toString(16);
|
|
617
|
+
});
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
//#endregion
|
|
621
|
+
//#region ../runtime-core/src/models/index.ts
|
|
622
|
+
const guid = guid$1;
|
|
623
|
+
let InstanceLifetimes = /* @__PURE__ */ function(InstanceLifetimes$1) {
|
|
624
|
+
InstanceLifetimes$1[InstanceLifetimes$1["Transient"] = 0] = "Transient";
|
|
625
|
+
InstanceLifetimes$1[InstanceLifetimes$1["Scoped"] = 1] = "Scoped";
|
|
626
|
+
InstanceLifetimes$1[InstanceLifetimes$1["Singleton"] = 2] = "Singleton";
|
|
627
|
+
return InstanceLifetimes$1;
|
|
628
|
+
}({});
|
|
629
|
+
function valueOf(obj) {
|
|
630
|
+
return obj;
|
|
631
|
+
}
|
|
632
|
+
|
|
633
|
+
//#endregion
|
|
634
|
+
//#region ../runtime-core/src/messaging/index.ts
|
|
635
|
+
function createTopic(options) {
|
|
636
|
+
let subscribers = [];
|
|
637
|
+
const publish = (data) => {
|
|
638
|
+
subscribers.forEach((s) => s(data));
|
|
639
|
+
};
|
|
640
|
+
const subscribe = (handler) => {
|
|
641
|
+
subscribers.push(handler);
|
|
642
|
+
const unsubscribe = () => {
|
|
643
|
+
const idx = subscribers.indexOf(handler);
|
|
644
|
+
if (idx > -1) subscribers.splice(idx, 1);
|
|
645
|
+
};
|
|
646
|
+
try {
|
|
647
|
+
onCleanup(unsubscribe);
|
|
648
|
+
} catch (e) {}
|
|
649
|
+
return { unsubscribe };
|
|
650
|
+
};
|
|
651
|
+
const destroy = () => {
|
|
652
|
+
subscribers = [];
|
|
653
|
+
};
|
|
654
|
+
return {
|
|
655
|
+
publish,
|
|
656
|
+
subscribe,
|
|
657
|
+
destroy
|
|
658
|
+
};
|
|
659
|
+
}
|
|
660
|
+
function toSubscriber(topic) {
|
|
661
|
+
return { subscribe: (handler) => topic.subscribe(handler) };
|
|
662
|
+
}
|
|
663
|
+
|
|
664
|
+
//#endregion
|
|
665
|
+
//#region ../runtime-core/src/di/injectable.ts
|
|
666
|
+
function inject(token) {
|
|
667
|
+
const ctx = getCurrentInstance();
|
|
668
|
+
if (!ctx) return void 0;
|
|
669
|
+
let current = ctx;
|
|
670
|
+
while (current) {
|
|
671
|
+
if (current.provides && current.provides.has(token)) return current.provides.get(token);
|
|
672
|
+
current = current.parent;
|
|
673
|
+
}
|
|
674
|
+
const appContext = getAppContext(ctx);
|
|
675
|
+
if (appContext && appContext.provides.has(token)) return appContext.provides.get(token);
|
|
676
|
+
}
|
|
677
|
+
/**
|
|
678
|
+
* Get the app context from the current component context
|
|
679
|
+
*/
|
|
680
|
+
function getAppContext(ctx) {
|
|
681
|
+
let current = ctx;
|
|
682
|
+
while (current) {
|
|
683
|
+
if (current._appContext) return current._appContext;
|
|
684
|
+
current = current.parent;
|
|
685
|
+
}
|
|
686
|
+
return null;
|
|
687
|
+
}
|
|
688
|
+
/**
|
|
689
|
+
* Inject the App instance (useful for plugins)
|
|
690
|
+
*/
|
|
691
|
+
function injectApp() {
|
|
692
|
+
return inject(AppContextKey);
|
|
693
|
+
}
|
|
694
|
+
function provide(token, value) {
|
|
695
|
+
const ctx = getCurrentInstance();
|
|
696
|
+
if (!ctx) {
|
|
697
|
+
console.warn("provide called outside of component setup");
|
|
698
|
+
return;
|
|
699
|
+
}
|
|
700
|
+
if (!ctx.provides) ctx.provides = /* @__PURE__ */ new Map();
|
|
701
|
+
ctx.provides.set(token, value);
|
|
702
|
+
}
|
|
703
|
+
const globalInstances = /* @__PURE__ */ new Map();
|
|
704
|
+
function defineInjectable(factory) {
|
|
705
|
+
const token = factory;
|
|
706
|
+
const useFn = () => {
|
|
707
|
+
const injected = inject(token);
|
|
708
|
+
if (injected) return injected;
|
|
709
|
+
if (!globalInstances.has(token)) globalInstances.set(token, factory());
|
|
710
|
+
return globalInstances.get(token);
|
|
711
|
+
};
|
|
712
|
+
useFn._factory = factory;
|
|
713
|
+
useFn._token = token;
|
|
714
|
+
return useFn;
|
|
715
|
+
}
|
|
716
|
+
function defineProvide(useFn) {
|
|
717
|
+
const factory = useFn._factory;
|
|
718
|
+
const token = useFn._token;
|
|
719
|
+
if (!factory || !token) throw new Error("defineProvide must be called with a function created by defineInjectable");
|
|
720
|
+
const instance = factory();
|
|
721
|
+
provide(token, instance);
|
|
722
|
+
return instance;
|
|
723
|
+
}
|
|
724
|
+
|
|
725
|
+
//#endregion
|
|
726
|
+
//#region ../runtime-core/src/di/factory.ts
|
|
727
|
+
var SubscriptionHandler = class {
|
|
728
|
+
unsubs = [];
|
|
729
|
+
add(unsub) {
|
|
730
|
+
this.unsubs.push(unsub);
|
|
731
|
+
}
|
|
732
|
+
unsubscribe() {
|
|
733
|
+
this.unsubs.forEach((u) => u());
|
|
734
|
+
this.unsubs = [];
|
|
735
|
+
}
|
|
736
|
+
};
|
|
737
|
+
function defineFactory(setup, lifetime, typeIdentifier) {
|
|
738
|
+
const factoryCreator = (...args) => {
|
|
739
|
+
const subscriptions = new SubscriptionHandler();
|
|
740
|
+
const deactivations = /* @__PURE__ */ new Set();
|
|
741
|
+
let customDispose = null;
|
|
742
|
+
const result = setup({
|
|
743
|
+
onDeactivated: (fn) => deactivations.add(fn),
|
|
744
|
+
subscriptions,
|
|
745
|
+
overrideDispose: (fn) => customDispose = fn
|
|
746
|
+
}, ...args);
|
|
747
|
+
const dispose = () => {
|
|
748
|
+
deactivations.forEach((d) => d());
|
|
749
|
+
subscriptions.unsubscribe();
|
|
750
|
+
result.dispose?.();
|
|
751
|
+
};
|
|
752
|
+
if (customDispose) customDispose(dispose);
|
|
753
|
+
else try {
|
|
754
|
+
onCleanup(() => dispose());
|
|
755
|
+
} catch (e) {}
|
|
756
|
+
return {
|
|
757
|
+
...result,
|
|
758
|
+
dispose
|
|
759
|
+
};
|
|
760
|
+
};
|
|
761
|
+
if (setup.length <= 1) return defineInjectable(() => factoryCreator());
|
|
762
|
+
return factoryCreator;
|
|
763
|
+
}
|
|
764
|
+
|
|
765
|
+
//#endregion
|
|
766
|
+
//#region ../runtime-core/src/stores/store.ts
|
|
767
|
+
function defineStore(name, setup, lifetime = InstanceLifetimes.Scoped) {
|
|
768
|
+
return defineFactory((ctxFactory, ...args) => {
|
|
769
|
+
const scope = effectScope(true);
|
|
770
|
+
let messages = [];
|
|
771
|
+
const id = `${name}_${guid()}`;
|
|
772
|
+
const result = setup({
|
|
773
|
+
...ctxFactory,
|
|
774
|
+
defineState: (state) => {
|
|
775
|
+
return defineState(state, id, scope, messages);
|
|
776
|
+
},
|
|
777
|
+
defineActions: (actions) => {
|
|
778
|
+
return defineActions(actions, id, messages);
|
|
779
|
+
}
|
|
780
|
+
}, ...args);
|
|
781
|
+
ctxFactory.onDeactivated(() => {
|
|
782
|
+
scope.stop();
|
|
783
|
+
messages?.forEach((m) => m.destroy());
|
|
784
|
+
messages = null;
|
|
785
|
+
});
|
|
786
|
+
if (!result.name) result.name = id;
|
|
787
|
+
return result;
|
|
788
|
+
}, lifetime);
|
|
789
|
+
}
|
|
790
|
+
function defineActions(actions, storeInstanceName, messages) {
|
|
791
|
+
const events = {};
|
|
792
|
+
const namespace = `${storeInstanceName}.actions.${guid()}`;
|
|
793
|
+
const onDispatching = {};
|
|
794
|
+
const onDispatched = {};
|
|
795
|
+
const onFailure = {};
|
|
796
|
+
const result = {
|
|
797
|
+
onDispatching,
|
|
798
|
+
onDispatched,
|
|
799
|
+
onFailure
|
|
800
|
+
};
|
|
801
|
+
function getEvent(actionName, type) {
|
|
802
|
+
const name = `${actionName}.${type}`;
|
|
803
|
+
if (!events[name]) {
|
|
804
|
+
events[name] = createTopic({
|
|
805
|
+
namespace,
|
|
806
|
+
name
|
|
807
|
+
});
|
|
808
|
+
messages.push(events[name]);
|
|
809
|
+
}
|
|
810
|
+
return events[name];
|
|
811
|
+
}
|
|
812
|
+
Object.keys(actions).forEach((actionName) => {
|
|
813
|
+
onDispatching[actionName] = { subscribe: (fn) => {
|
|
814
|
+
return getEvent(actionName, "onDispatching").subscribe(function() {
|
|
815
|
+
fn.apply(this, arguments[0]);
|
|
816
|
+
});
|
|
817
|
+
} };
|
|
818
|
+
onDispatched[actionName] = { subscribe: (fn) => {
|
|
819
|
+
return getEvent(actionName, "onDispatched").subscribe(function() {
|
|
820
|
+
const msg = arguments[0];
|
|
821
|
+
const allArguments = [msg.result].concat(Array.from(msg.args));
|
|
822
|
+
fn.apply(this, allArguments);
|
|
823
|
+
});
|
|
824
|
+
} };
|
|
825
|
+
onFailure[actionName] = { subscribe: (fn) => {
|
|
826
|
+
return getEvent(actionName, "onFailure").subscribe(function() {
|
|
827
|
+
const msg = arguments[0];
|
|
828
|
+
const allArguments = [msg.reason].concat(Array.from(msg.args));
|
|
829
|
+
fn.apply(this, allArguments);
|
|
830
|
+
});
|
|
831
|
+
} };
|
|
832
|
+
result[actionName] = function() {
|
|
833
|
+
try {
|
|
834
|
+
const currentArguments = arguments;
|
|
835
|
+
getEvent(actionName, "onDispatching").publish(currentArguments);
|
|
836
|
+
const returnedResult = actions[actionName].apply(this, currentArguments);
|
|
837
|
+
if (Utils.isPromise(returnedResult)) returnedResult.then((result$1) => {
|
|
838
|
+
getEvent(actionName, "onDispatched").publish({
|
|
839
|
+
result: returnedResult,
|
|
840
|
+
args: currentArguments
|
|
841
|
+
});
|
|
842
|
+
});
|
|
843
|
+
else getEvent(actionName, "onDispatched").publish({
|
|
844
|
+
result: returnedResult,
|
|
845
|
+
args: currentArguments
|
|
846
|
+
});
|
|
847
|
+
return returnedResult;
|
|
848
|
+
} catch (err) {
|
|
849
|
+
console.error(err);
|
|
850
|
+
getEvent(actionName, "onFailure").publish({
|
|
851
|
+
reason: err,
|
|
852
|
+
args: arguments
|
|
853
|
+
});
|
|
854
|
+
}
|
|
855
|
+
};
|
|
856
|
+
});
|
|
857
|
+
return result;
|
|
858
|
+
}
|
|
859
|
+
function defineState(value, storeInstanceName, scope, messages) {
|
|
860
|
+
const state = signal(value);
|
|
861
|
+
const events = {};
|
|
862
|
+
const mutate = {};
|
|
863
|
+
function initProperty(key) {
|
|
864
|
+
scope.run(() => {
|
|
865
|
+
watch(() => state[key], (newValue) => {
|
|
866
|
+
triggerEvent(key, newValue);
|
|
867
|
+
}, {
|
|
868
|
+
deep: true,
|
|
869
|
+
immediate: true
|
|
870
|
+
});
|
|
871
|
+
});
|
|
872
|
+
mutate[key] = (val) => {
|
|
873
|
+
try {
|
|
874
|
+
let newValue;
|
|
875
|
+
if (typeof val === "function") newValue = val(state[key]);
|
|
876
|
+
else newValue = val;
|
|
877
|
+
state[key] = newValue;
|
|
878
|
+
} catch (err) {
|
|
879
|
+
console.error(err);
|
|
880
|
+
}
|
|
881
|
+
};
|
|
882
|
+
const eventKey = `onMutated${key.charAt(0).toUpperCase()}${key.slice(1)}`;
|
|
883
|
+
if (!events[eventKey]) {
|
|
884
|
+
const topic = createTopic({
|
|
885
|
+
namespace: `${storeInstanceName}.events`,
|
|
886
|
+
name: eventKey
|
|
887
|
+
});
|
|
888
|
+
events[eventKey] = topic;
|
|
889
|
+
messages.push(topic);
|
|
890
|
+
}
|
|
891
|
+
}
|
|
892
|
+
function triggerEvent(name, value$1) {
|
|
893
|
+
const keyString = name;
|
|
894
|
+
events[`onMutated${keyString.charAt(0).toUpperCase()}${keyString.slice(1)}`]?.publish(value$1);
|
|
895
|
+
}
|
|
896
|
+
if (value) Object.keys(value).forEach((key) => {
|
|
897
|
+
initProperty(key);
|
|
898
|
+
});
|
|
899
|
+
return {
|
|
900
|
+
state,
|
|
901
|
+
events,
|
|
902
|
+
mutate
|
|
903
|
+
};
|
|
904
|
+
}
|
|
905
|
+
|
|
906
|
+
//#endregion
|
|
907
|
+
//#region ../runtime-core/src/renderer.ts
|
|
908
|
+
/**
|
|
909
|
+
* Check if a vnode type is a component (has __setup)
|
|
910
|
+
*/
|
|
911
|
+
function isComponent(type) {
|
|
912
|
+
return typeof type === "function" && "__setup" in type;
|
|
913
|
+
}
|
|
914
|
+
function createRenderer(options) {
|
|
915
|
+
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;
|
|
916
|
+
let isPatching = false;
|
|
917
|
+
let currentAppContext = null;
|
|
918
|
+
function render$1(element, container, appContext) {
|
|
919
|
+
if (appContext) currentAppContext = appContext;
|
|
920
|
+
const oldVNode = container._vnode;
|
|
921
|
+
let vnode = null;
|
|
922
|
+
if (element != null && element !== false && element !== true) if (typeof element === "string" || typeof element === "number") vnode = {
|
|
923
|
+
type: Text,
|
|
924
|
+
props: {},
|
|
925
|
+
key: null,
|
|
926
|
+
children: [],
|
|
927
|
+
dom: null,
|
|
928
|
+
text: element
|
|
929
|
+
};
|
|
930
|
+
else vnode = element;
|
|
931
|
+
if (vnode) {
|
|
932
|
+
if (oldVNode) patch(oldVNode, vnode, container);
|
|
933
|
+
else mount(vnode, container);
|
|
934
|
+
container._vnode = vnode;
|
|
935
|
+
} else if (oldVNode) {
|
|
936
|
+
unmount(oldVNode, container);
|
|
937
|
+
container._vnode = null;
|
|
938
|
+
}
|
|
939
|
+
}
|
|
940
|
+
function mount(vnode, container, before = null) {
|
|
941
|
+
if (vnode.type === Text) {
|
|
942
|
+
const node = hostCreateText(String(vnode.text));
|
|
943
|
+
vnode.dom = node;
|
|
944
|
+
node.__vnode = vnode;
|
|
945
|
+
hostInsert(node, container, before);
|
|
946
|
+
return;
|
|
947
|
+
}
|
|
948
|
+
if (vnode.type === Fragment) {
|
|
949
|
+
const anchor = hostCreateComment("");
|
|
950
|
+
vnode.dom = anchor;
|
|
951
|
+
hostInsert(anchor, container, before);
|
|
952
|
+
vnode.children.forEach((child) => mount(child, container, anchor));
|
|
953
|
+
return;
|
|
954
|
+
}
|
|
955
|
+
if (isComponent(vnode.type)) {
|
|
956
|
+
mountComponent(vnode, container, before, vnode.type.__setup);
|
|
957
|
+
return;
|
|
958
|
+
}
|
|
959
|
+
const element = hostCreateElement(vnode.type);
|
|
960
|
+
vnode.dom = element;
|
|
961
|
+
element.__vnode = vnode;
|
|
962
|
+
if (vnode.props) {
|
|
963
|
+
for (const key in vnode.props) if (key !== "children" && key !== "key" && key !== "ref") hostPatchProp(element, key, null, vnode.props[key]);
|
|
964
|
+
}
|
|
965
|
+
if (vnode.props.ref) {
|
|
966
|
+
if (typeof vnode.props.ref === "function") vnode.props.ref(element);
|
|
967
|
+
else if (vnode.props.ref && typeof vnode.props.ref === "object") vnode.props.ref.current = element;
|
|
968
|
+
}
|
|
969
|
+
vnode.children.forEach((child) => {
|
|
970
|
+
child.parent = vnode;
|
|
971
|
+
mount(child, element);
|
|
972
|
+
});
|
|
973
|
+
hostInsert(element, container, before);
|
|
974
|
+
}
|
|
975
|
+
function unmount(vnode, container) {
|
|
976
|
+
if (vnode._effect) vnode._effect();
|
|
977
|
+
if (vnode.cleanup) vnode.cleanup();
|
|
978
|
+
if (isComponent(vnode.type)) {
|
|
979
|
+
const subTree = vnode._subTree;
|
|
980
|
+
if (subTree) unmount(subTree, container);
|
|
981
|
+
if (vnode.dom) hostRemove(vnode.dom);
|
|
982
|
+
if (vnode.props?.ref) {
|
|
983
|
+
if (typeof vnode.props.ref === "function") vnode.props.ref(null);
|
|
984
|
+
else if (typeof vnode.props.ref === "object") vnode.props.ref.current = null;
|
|
985
|
+
}
|
|
986
|
+
return;
|
|
987
|
+
}
|
|
988
|
+
if (vnode.type === Fragment) {
|
|
989
|
+
vnode.children.forEach((child) => unmount(child, container));
|
|
990
|
+
if (vnode.dom) hostRemove(vnode.dom);
|
|
991
|
+
return;
|
|
992
|
+
}
|
|
993
|
+
if (vnode.props?.ref) {
|
|
994
|
+
if (typeof vnode.props.ref === "function") vnode.props.ref(null);
|
|
995
|
+
else if (vnode.props.ref && typeof vnode.props.ref === "object") vnode.props.ref.current = null;
|
|
996
|
+
}
|
|
997
|
+
if (vnode.children && vnode.children.length > 0) vnode.children.forEach((child) => unmount(child, vnode.dom));
|
|
998
|
+
if (vnode.dom) hostRemove(vnode.dom);
|
|
999
|
+
}
|
|
1000
|
+
function patch(oldVNode, newVNode, container) {
|
|
1001
|
+
if (oldVNode === newVNode) return;
|
|
1002
|
+
if (!isSameVNode(oldVNode, newVNode)) {
|
|
1003
|
+
const parent = hostParentNode(oldVNode.dom) || container;
|
|
1004
|
+
const nextSibling = hostNextSibling(oldVNode.dom);
|
|
1005
|
+
unmount(oldVNode, parent);
|
|
1006
|
+
mount(newVNode, parent, nextSibling);
|
|
1007
|
+
return;
|
|
1008
|
+
}
|
|
1009
|
+
if (oldVNode._effect) {
|
|
1010
|
+
newVNode.dom = oldVNode.dom;
|
|
1011
|
+
newVNode._effect = oldVNode._effect;
|
|
1012
|
+
newVNode._subTree = oldVNode._subTree;
|
|
1013
|
+
newVNode._slots = oldVNode._slots;
|
|
1014
|
+
const props = oldVNode._componentProps;
|
|
1015
|
+
newVNode._componentProps = props;
|
|
1016
|
+
if (props) {
|
|
1017
|
+
const newProps$1 = newVNode.props || {};
|
|
1018
|
+
untrack(() => {
|
|
1019
|
+
for (const key in newProps$1) if (key !== "children" && key !== "key" && key !== "ref") {
|
|
1020
|
+
if (props[key] !== newProps$1[key]) props[key] = newProps$1[key];
|
|
1021
|
+
}
|
|
1022
|
+
for (const key in props) if (!(key in newProps$1) && key !== "children" && key !== "key" && key !== "ref") delete props[key];
|
|
1023
|
+
});
|
|
1024
|
+
}
|
|
1025
|
+
const slotsRef = oldVNode._slots;
|
|
1026
|
+
const newChildren = newVNode.props?.children;
|
|
1027
|
+
const newSlotsFromProps = newVNode.props?.slots;
|
|
1028
|
+
if (slotsRef) {
|
|
1029
|
+
if (newChildren !== void 0) slotsRef._children = newChildren;
|
|
1030
|
+
if (newSlotsFromProps !== void 0) slotsRef._slotsFromProps = newSlotsFromProps;
|
|
1031
|
+
if (!isPatching) {
|
|
1032
|
+
isPatching = true;
|
|
1033
|
+
try {
|
|
1034
|
+
untrack(() => {
|
|
1035
|
+
slotsRef._version.v++;
|
|
1036
|
+
});
|
|
1037
|
+
} finally {
|
|
1038
|
+
isPatching = false;
|
|
1039
|
+
}
|
|
1040
|
+
}
|
|
1041
|
+
}
|
|
1042
|
+
return;
|
|
1043
|
+
}
|
|
1044
|
+
if (newVNode.type === Text) {
|
|
1045
|
+
newVNode.dom = oldVNode.dom;
|
|
1046
|
+
if (oldVNode.text !== newVNode.text) hostSetText(newVNode.dom, String(newVNode.text));
|
|
1047
|
+
return;
|
|
1048
|
+
}
|
|
1049
|
+
if (newVNode.type === Fragment) {
|
|
1050
|
+
patchChildren(oldVNode, newVNode, container);
|
|
1051
|
+
return;
|
|
1052
|
+
}
|
|
1053
|
+
const element = newVNode.dom = oldVNode.dom;
|
|
1054
|
+
const oldProps = oldVNode.props || {};
|
|
1055
|
+
const newProps = newVNode.props || {};
|
|
1056
|
+
for (const key in oldProps) if (!(key in newProps) && key !== "children" && key !== "key" && key !== "ref") hostPatchProp(element, key, oldProps[key], null);
|
|
1057
|
+
for (const key in newProps) {
|
|
1058
|
+
const oldValue = oldProps[key];
|
|
1059
|
+
const newValue = newProps[key];
|
|
1060
|
+
if (key !== "children" && key !== "key" && key !== "ref" && oldValue !== newValue) hostPatchProp(element, key, oldValue, newValue);
|
|
1061
|
+
}
|
|
1062
|
+
patchChildren(oldVNode, newVNode, element);
|
|
1063
|
+
}
|
|
1064
|
+
function patchChildren(oldVNode, newVNode, container) {
|
|
1065
|
+
const oldChildren = oldVNode.children;
|
|
1066
|
+
const newChildren = newVNode.children;
|
|
1067
|
+
newChildren.forEach((c) => c.parent = newVNode);
|
|
1068
|
+
reconcileChildrenArray(container, oldChildren, newChildren);
|
|
1069
|
+
}
|
|
1070
|
+
function reconcileChildrenArray(parent, oldChildren, newChildren) {
|
|
1071
|
+
let oldStartIdx = 0;
|
|
1072
|
+
let oldEndIdx = oldChildren.length - 1;
|
|
1073
|
+
let oldStartVNode = oldChildren[0];
|
|
1074
|
+
let oldEndVNode = oldChildren[oldEndIdx];
|
|
1075
|
+
let newStartIdx = 0;
|
|
1076
|
+
let newEndIdx = newChildren.length - 1;
|
|
1077
|
+
let newStartVNode = newChildren[0];
|
|
1078
|
+
let newEndVNode = newChildren[newEndIdx];
|
|
1079
|
+
let oldKeyToIdx;
|
|
1080
|
+
while (oldStartIdx <= oldEndIdx && newStartIdx <= newEndIdx) if (oldStartVNode == null) oldStartVNode = oldChildren[++oldStartIdx];
|
|
1081
|
+
else if (oldEndVNode == null) oldEndVNode = oldChildren[--oldEndIdx];
|
|
1082
|
+
else if (isSameVNode(oldStartVNode, newStartVNode)) {
|
|
1083
|
+
patch(oldStartVNode, newStartVNode, parent);
|
|
1084
|
+
oldStartVNode = oldChildren[++oldStartIdx];
|
|
1085
|
+
newStartVNode = newChildren[++newStartIdx];
|
|
1086
|
+
} else if (isSameVNode(oldEndVNode, newEndVNode)) {
|
|
1087
|
+
patch(oldEndVNode, newEndVNode, parent);
|
|
1088
|
+
oldEndVNode = oldChildren[--oldEndIdx];
|
|
1089
|
+
newEndVNode = newChildren[--newEndIdx];
|
|
1090
|
+
} else if (isSameVNode(oldStartVNode, newEndVNode)) {
|
|
1091
|
+
patch(oldStartVNode, newEndVNode, parent);
|
|
1092
|
+
const nodeToMove = oldStartVNode.dom;
|
|
1093
|
+
const anchor = hostNextSibling(oldEndVNode.dom);
|
|
1094
|
+
if (nodeToMove) hostInsert(nodeToMove, parent, anchor);
|
|
1095
|
+
oldStartVNode = oldChildren[++oldStartIdx];
|
|
1096
|
+
newEndVNode = newChildren[--newEndIdx];
|
|
1097
|
+
} else if (isSameVNode(oldEndVNode, newStartVNode)) {
|
|
1098
|
+
patch(oldEndVNode, newStartVNode, parent);
|
|
1099
|
+
const nodeToMove = oldEndVNode.dom;
|
|
1100
|
+
const anchor = oldStartVNode.dom;
|
|
1101
|
+
if (nodeToMove) hostInsert(nodeToMove, parent, anchor);
|
|
1102
|
+
oldEndVNode = oldChildren[--oldEndIdx];
|
|
1103
|
+
newStartVNode = newChildren[++newStartIdx];
|
|
1104
|
+
} else {
|
|
1105
|
+
if (!oldKeyToIdx) oldKeyToIdx = createKeyToKeyIndexMap(oldChildren, oldStartIdx, oldEndIdx);
|
|
1106
|
+
const idxInOld = newStartVNode.key != null ? oldKeyToIdx.get(String(newStartVNode.key)) : findIndexInOld(oldChildren, newStartVNode, oldStartIdx, oldEndIdx);
|
|
1107
|
+
if (idxInOld != null) {
|
|
1108
|
+
const vnodeToMove = oldChildren[idxInOld];
|
|
1109
|
+
patch(vnodeToMove, newStartVNode, parent);
|
|
1110
|
+
oldChildren[idxInOld] = void 0;
|
|
1111
|
+
if (vnodeToMove.dom && oldStartVNode.dom) hostInsert(vnodeToMove.dom, parent, oldStartVNode.dom);
|
|
1112
|
+
} else mount(newStartVNode, parent, oldStartVNode.dom);
|
|
1113
|
+
newStartVNode = newChildren[++newStartIdx];
|
|
1114
|
+
}
|
|
1115
|
+
if (oldStartIdx > oldEndIdx) {
|
|
1116
|
+
if (newStartIdx <= newEndIdx) {
|
|
1117
|
+
const anchor = newChildren[newEndIdx + 1] == null ? null : newChildren[newEndIdx + 1].dom;
|
|
1118
|
+
for (let i = newStartIdx; i <= newEndIdx; i++) mount(newChildren[i], parent, anchor);
|
|
1119
|
+
}
|
|
1120
|
+
} else if (newStartIdx > newEndIdx) {
|
|
1121
|
+
for (let i = oldStartIdx; i <= oldEndIdx; i++) if (oldChildren[i]) unmount(oldChildren[i], parent);
|
|
1122
|
+
}
|
|
1123
|
+
}
|
|
1124
|
+
function isSameVNode(n1, n2) {
|
|
1125
|
+
const k1 = n1.key == null ? null : n1.key;
|
|
1126
|
+
const k2 = n2.key == null ? null : n2.key;
|
|
1127
|
+
if (n1.type !== n2.type) return false;
|
|
1128
|
+
if (k1 === k2) return true;
|
|
1129
|
+
return String(k1) === String(k2);
|
|
1130
|
+
}
|
|
1131
|
+
function createKeyToKeyIndexMap(children, beginIdx, endIdx) {
|
|
1132
|
+
const map = /* @__PURE__ */ new Map();
|
|
1133
|
+
for (let i = beginIdx; i <= endIdx; i++) {
|
|
1134
|
+
const key = children[i]?.key;
|
|
1135
|
+
if (key != null) map.set(String(key), i);
|
|
1136
|
+
}
|
|
1137
|
+
return map;
|
|
1138
|
+
}
|
|
1139
|
+
function findIndexInOld(children, newChild, beginIdx, endIdx) {
|
|
1140
|
+
for (let i = beginIdx; i <= endIdx; i++) if (children[i] && isSameVNode(children[i], newChild)) return i;
|
|
1141
|
+
return null;
|
|
1142
|
+
}
|
|
1143
|
+
function mountComponent(vnode, container, before, setup) {
|
|
1144
|
+
const anchor = hostCreateComment("");
|
|
1145
|
+
vnode.dom = anchor;
|
|
1146
|
+
anchor.__vnode = vnode;
|
|
1147
|
+
hostInsert(anchor, container, before);
|
|
1148
|
+
let exposed = null;
|
|
1149
|
+
let exposeCalled = false;
|
|
1150
|
+
const { children, slots: slotsFromProps, ...propsData } = vnode.props || {};
|
|
1151
|
+
const reactiveProps = signal(propsData);
|
|
1152
|
+
vnode._componentProps = reactiveProps;
|
|
1153
|
+
const slots = createSlots(children, slotsFromProps);
|
|
1154
|
+
vnode._slots = slots;
|
|
1155
|
+
const mountHooks = [];
|
|
1156
|
+
const cleanupHooks = [];
|
|
1157
|
+
const parentInstance = getCurrentInstance();
|
|
1158
|
+
const componentName = vnode.type.__name;
|
|
1159
|
+
const ctx = {
|
|
1160
|
+
el: container,
|
|
1161
|
+
signal,
|
|
1162
|
+
props: reactiveProps,
|
|
1163
|
+
slots,
|
|
1164
|
+
emit: (event, ...args) => {
|
|
1165
|
+
const handler = reactiveProps[`on${event[0].toUpperCase() + event.slice(1)}`];
|
|
1166
|
+
if (handler && typeof handler === "function") handler(...args);
|
|
1167
|
+
},
|
|
1168
|
+
parent: parentInstance,
|
|
1169
|
+
onMount: (fn) => {
|
|
1170
|
+
mountHooks.push(fn);
|
|
1171
|
+
},
|
|
1172
|
+
onCleanup: (fn) => {
|
|
1173
|
+
cleanupHooks.push(fn);
|
|
1174
|
+
},
|
|
1175
|
+
expose: (exposedValue) => {
|
|
1176
|
+
exposed = exposedValue;
|
|
1177
|
+
exposeCalled = true;
|
|
1178
|
+
}
|
|
1179
|
+
};
|
|
1180
|
+
ctx.__name = componentName;
|
|
1181
|
+
if (currentAppContext) ctx._appContext = currentAppContext;
|
|
1182
|
+
const componentInstance = {
|
|
1183
|
+
name: componentName,
|
|
1184
|
+
ctx,
|
|
1185
|
+
vnode
|
|
1186
|
+
};
|
|
1187
|
+
const prev = setCurrentInstance(ctx);
|
|
1188
|
+
let renderFn;
|
|
1189
|
+
try {
|
|
1190
|
+
renderFn = setup(ctx);
|
|
1191
|
+
notifyComponentCreated(currentAppContext, componentInstance);
|
|
1192
|
+
} catch (err) {
|
|
1193
|
+
if (!handleComponentError(currentAppContext, err, componentInstance, "setup")) throw err;
|
|
1194
|
+
} finally {
|
|
1195
|
+
setCurrentInstance(prev);
|
|
1196
|
+
}
|
|
1197
|
+
if (vnode.props.ref) {
|
|
1198
|
+
const refValue = exposeCalled ? exposed : null;
|
|
1199
|
+
if (typeof vnode.props.ref === "function") vnode.props.ref(refValue);
|
|
1200
|
+
else if (vnode.props.ref && typeof vnode.props.ref === "object") vnode.props.ref.current = refValue;
|
|
1201
|
+
}
|
|
1202
|
+
if (renderFn) vnode._effect = effect(() => {
|
|
1203
|
+
const prevInstance = setCurrentInstance(ctx);
|
|
1204
|
+
try {
|
|
1205
|
+
const subTreeResult = renderFn();
|
|
1206
|
+
if (subTreeResult == null) return;
|
|
1207
|
+
const subTree = normalizeSubTree(subTreeResult);
|
|
1208
|
+
const prevSubTree = vnode._subTree;
|
|
1209
|
+
if (prevSubTree) {
|
|
1210
|
+
patch(prevSubTree, subTree, container);
|
|
1211
|
+
notifyComponentUpdated(currentAppContext, componentInstance);
|
|
1212
|
+
} else mount(subTree, container, anchor);
|
|
1213
|
+
vnode._subTree = subTree;
|
|
1214
|
+
} catch (err) {
|
|
1215
|
+
if (!handleComponentError(currentAppContext, err, componentInstance, "render")) throw err;
|
|
1216
|
+
} finally {
|
|
1217
|
+
setCurrentInstance(prevInstance);
|
|
1218
|
+
}
|
|
1219
|
+
});
|
|
1220
|
+
const mountCtx = { el: container };
|
|
1221
|
+
mountHooks.forEach((hook) => hook(mountCtx));
|
|
1222
|
+
notifyComponentMounted(currentAppContext, componentInstance);
|
|
1223
|
+
vnode.cleanup = () => {
|
|
1224
|
+
notifyComponentUnmounted(currentAppContext, componentInstance);
|
|
1225
|
+
cleanupHooks.forEach((hook) => hook(mountCtx));
|
|
1226
|
+
};
|
|
1227
|
+
}
|
|
1228
|
+
/**
|
|
1229
|
+
* Create slots object from children and slots prop.
|
|
1230
|
+
* Uses a version signal to trigger re-renders when children change.
|
|
1231
|
+
* Supports named slots via:
|
|
1232
|
+
* - `slots` prop object (e.g., slots={{ header: () => <div>...</div> }})
|
|
1233
|
+
* - `slot` prop on children (e.g., <div slot="header">...</div>)
|
|
1234
|
+
*/
|
|
1235
|
+
function createSlots(children, slotsFromProps) {
|
|
1236
|
+
const versionSignal = signal({ v: 0 });
|
|
1237
|
+
function extractNamedSlotsFromChildren(c) {
|
|
1238
|
+
const defaultChildren = [];
|
|
1239
|
+
const namedSlots = {};
|
|
1240
|
+
if (c == null) return {
|
|
1241
|
+
defaultChildren,
|
|
1242
|
+
namedSlots
|
|
1243
|
+
};
|
|
1244
|
+
const items = Array.isArray(c) ? c : [c];
|
|
1245
|
+
for (const child of items) if (child && typeof child === "object" && child.props && child.props.slot) {
|
|
1246
|
+
const slotName = child.props.slot;
|
|
1247
|
+
if (!namedSlots[slotName]) namedSlots[slotName] = [];
|
|
1248
|
+
namedSlots[slotName].push(child);
|
|
1249
|
+
} else defaultChildren.push(child);
|
|
1250
|
+
return {
|
|
1251
|
+
defaultChildren,
|
|
1252
|
+
namedSlots
|
|
1253
|
+
};
|
|
1254
|
+
}
|
|
1255
|
+
const slotsObj = {
|
|
1256
|
+
_children: children,
|
|
1257
|
+
_slotsFromProps: slotsFromProps || {},
|
|
1258
|
+
_version: versionSignal,
|
|
1259
|
+
default: function() {
|
|
1260
|
+
this._version.v;
|
|
1261
|
+
const c = this._children;
|
|
1262
|
+
const { defaultChildren } = extractNamedSlotsFromChildren(c);
|
|
1263
|
+
return defaultChildren;
|
|
1264
|
+
}
|
|
1265
|
+
};
|
|
1266
|
+
return new Proxy(slotsObj, { get(target, prop) {
|
|
1267
|
+
if (prop in target) return target[prop];
|
|
1268
|
+
if (typeof prop === "string") return function(scopedProps) {
|
|
1269
|
+
target._version.v;
|
|
1270
|
+
if (target._slotsFromProps && typeof target._slotsFromProps[prop] === "function") {
|
|
1271
|
+
const result = target._slotsFromProps[prop](scopedProps);
|
|
1272
|
+
if (result == null) return [];
|
|
1273
|
+
return Array.isArray(result) ? result : [result];
|
|
1274
|
+
}
|
|
1275
|
+
const { namedSlots } = extractNamedSlotsFromChildren(target._children);
|
|
1276
|
+
return namedSlots[prop] || [];
|
|
1277
|
+
};
|
|
1278
|
+
} });
|
|
1279
|
+
}
|
|
1280
|
+
/**
|
|
1281
|
+
* Normalize render result to a VNode (wrapping arrays in Fragment)
|
|
1282
|
+
*/
|
|
1283
|
+
function normalizeSubTree(result) {
|
|
1284
|
+
if (Array.isArray(result)) return {
|
|
1285
|
+
type: Fragment,
|
|
1286
|
+
props: {},
|
|
1287
|
+
key: null,
|
|
1288
|
+
children: result,
|
|
1289
|
+
dom: null
|
|
1290
|
+
};
|
|
1291
|
+
if (typeof result === "string" || typeof result === "number") return {
|
|
1292
|
+
type: Text,
|
|
1293
|
+
props: {},
|
|
1294
|
+
key: null,
|
|
1295
|
+
children: [],
|
|
1296
|
+
dom: null,
|
|
1297
|
+
text: result
|
|
1298
|
+
};
|
|
1299
|
+
return result;
|
|
1300
|
+
}
|
|
1301
|
+
return {
|
|
1302
|
+
render: render$1,
|
|
1303
|
+
createApp: (rootComponent) => {
|
|
1304
|
+
return { mount(selectorOrContainer) {
|
|
1305
|
+
let container = null;
|
|
1306
|
+
if (typeof selectorOrContainer === "string") {
|
|
1307
|
+
if (options.querySelector) container = options.querySelector(selectorOrContainer);
|
|
1308
|
+
} else container = selectorOrContainer;
|
|
1309
|
+
if (!container) {
|
|
1310
|
+
console.warn(`Container not found: ${selectorOrContainer}`);
|
|
1311
|
+
return;
|
|
1312
|
+
}
|
|
1313
|
+
render$1(rootComponent, container);
|
|
1314
|
+
} };
|
|
1315
|
+
}
|
|
1316
|
+
};
|
|
1317
|
+
}
|
|
1318
|
+
|
|
1319
|
+
//#endregion
|
|
1320
|
+
//#region ../runtime-terminal/src/focus.ts
|
|
1321
|
+
const focusableIds = /* @__PURE__ */ new Set();
|
|
1322
|
+
const focusState = signal({ activeId: null });
|
|
1323
|
+
function registerFocusable(id) {
|
|
1324
|
+
focusableIds.add(id);
|
|
1325
|
+
if (focusState.activeId === null) focusState.activeId = id;
|
|
1326
|
+
}
|
|
1327
|
+
function unregisterFocusable(id) {
|
|
1328
|
+
focusableIds.delete(id);
|
|
1329
|
+
if (focusState.activeId === id) {
|
|
1330
|
+
focusState.activeId = null;
|
|
1331
|
+
if (focusableIds.size > 0) focusState.activeId = focusableIds.values().next().value || null;
|
|
1332
|
+
}
|
|
1333
|
+
}
|
|
1334
|
+
function focus(id) {
|
|
1335
|
+
if (focusableIds.has(id)) focusState.activeId = id;
|
|
1336
|
+
}
|
|
1337
|
+
function focusNext() {
|
|
1338
|
+
if (focusableIds.size === 0) return;
|
|
1339
|
+
const ids = Array.from(focusableIds);
|
|
1340
|
+
focusState.activeId = ids[((focusState.activeId ? ids.indexOf(focusState.activeId) : -1) + 1) % ids.length];
|
|
1341
|
+
}
|
|
1342
|
+
function focusPrev() {
|
|
1343
|
+
if (focusableIds.size === 0) return;
|
|
1344
|
+
const ids = Array.from(focusableIds);
|
|
1345
|
+
focusState.activeId = ids[((focusState.activeId ? ids.indexOf(focusState.activeId) : -1) - 1 + ids.length) % ids.length];
|
|
1346
|
+
}
|
|
1347
|
+
|
|
1348
|
+
//#endregion
|
|
1349
|
+
//#region ../runtime-terminal/src/utils.ts
|
|
1350
|
+
function getColorCode(color) {
|
|
1351
|
+
switch (color) {
|
|
1352
|
+
case "red": return "\x1B[31m";
|
|
1353
|
+
case "green": return "\x1B[32m";
|
|
1354
|
+
case "blue": return "\x1B[34m";
|
|
1355
|
+
case "yellow": return "\x1B[33m";
|
|
1356
|
+
case "cyan": return "\x1B[36m";
|
|
1357
|
+
case "white": return "\x1B[37m";
|
|
1358
|
+
case "black": return "\x1B[30m";
|
|
1359
|
+
default: return "";
|
|
1360
|
+
}
|
|
1361
|
+
}
|
|
1362
|
+
function getBackgroundColorCode(color) {
|
|
1363
|
+
switch (color) {
|
|
1364
|
+
case "red": return "\x1B[41m";
|
|
1365
|
+
case "green": return "\x1B[42m";
|
|
1366
|
+
case "blue": return "\x1B[44m";
|
|
1367
|
+
case "yellow": return "\x1B[43m";
|
|
1368
|
+
case "cyan": return "\x1B[46m";
|
|
1369
|
+
case "white": return "\x1B[47m";
|
|
1370
|
+
case "black": return "\x1B[40m";
|
|
1371
|
+
default: return "";
|
|
1372
|
+
}
|
|
1373
|
+
}
|
|
1374
|
+
function stripAnsi(str) {
|
|
1375
|
+
return str.replace(/\x1B\[[0-9;]*[a-zA-Z]/g, "");
|
|
1376
|
+
}
|
|
1377
|
+
|
|
1378
|
+
//#endregion
|
|
1379
|
+
//#region ../runtime-core/dist/index.js
|
|
1380
|
+
let platformSyncProcessor = null;
|
|
1381
|
+
/**
|
|
1382
|
+
* Get the current platform sync processor (for internal use).
|
|
1383
|
+
*/
|
|
1384
|
+
function getPlatformSyncProcessor$1() {
|
|
1385
|
+
return platformSyncProcessor;
|
|
1386
|
+
}
|
|
1387
|
+
const Fragment$1 = Symbol.for("sigx.Fragment");
|
|
1388
|
+
const Text$1 = Symbol.for("sigx.Text");
|
|
1389
|
+
function normalizeChildren(children) {
|
|
1390
|
+
if (children == null || children === false || children === true) return [];
|
|
1391
|
+
if (Array.isArray(children)) return children.flatMap((c) => normalizeChildren(c));
|
|
1392
|
+
if (typeof children === "string" || typeof children === "number") return [{
|
|
1393
|
+
type: Text$1,
|
|
1394
|
+
props: {},
|
|
1395
|
+
key: null,
|
|
1396
|
+
children: [],
|
|
1397
|
+
dom: null,
|
|
1398
|
+
text: children
|
|
1399
|
+
}];
|
|
1400
|
+
if (children.type) return [children];
|
|
1401
|
+
return [];
|
|
1402
|
+
}
|
|
1403
|
+
/**
|
|
1404
|
+
* Check if a type is a sigx component (has __setup)
|
|
1405
|
+
*/
|
|
1406
|
+
function isComponent$1(type) {
|
|
1407
|
+
return typeof type === "function" && "__setup" in type;
|
|
1408
|
+
}
|
|
1409
|
+
/**
|
|
1410
|
+
* Create a JSX element - this is the core function called by TSX transpilation
|
|
1411
|
+
*/
|
|
1412
|
+
function jsx$1(type, props, key) {
|
|
1413
|
+
const processedProps = { ...props || {} };
|
|
1414
|
+
if (props) {
|
|
1415
|
+
for (const propKey in props) if (propKey === "sync") {
|
|
1416
|
+
let syncBinding = props[propKey];
|
|
1417
|
+
if (typeof syncBinding === "function") {
|
|
1418
|
+
const detected = detectAccess(syncBinding);
|
|
1419
|
+
if (detected) syncBinding = detected;
|
|
1420
|
+
}
|
|
1421
|
+
if (Array.isArray(syncBinding) && syncBinding.length === 2) {
|
|
1422
|
+
const [stateObj, key$1] = syncBinding;
|
|
1423
|
+
let handled = false;
|
|
1424
|
+
const platformProcessor = getPlatformSyncProcessor$1();
|
|
1425
|
+
if (typeof type === "string" && platformProcessor) handled = platformProcessor(type, processedProps, [stateObj, key$1], props);
|
|
1426
|
+
if (!handled) {
|
|
1427
|
+
processedProps.value = stateObj[key$1];
|
|
1428
|
+
const existingHandler = processedProps["onUpdate:value"];
|
|
1429
|
+
processedProps["onUpdate:value"] = (v) => {
|
|
1430
|
+
stateObj[key$1] = v;
|
|
1431
|
+
if (existingHandler) existingHandler(v);
|
|
1432
|
+
};
|
|
1433
|
+
}
|
|
1434
|
+
delete processedProps.sync;
|
|
1435
|
+
}
|
|
1436
|
+
} else if (propKey.startsWith("sync:")) {
|
|
1437
|
+
const syncBinding = props[propKey];
|
|
1438
|
+
if (Array.isArray(syncBinding) && syncBinding.length === 2) {
|
|
1439
|
+
const [stateObj, key$1] = syncBinding;
|
|
1440
|
+
const name = propKey.slice(5);
|
|
1441
|
+
processedProps[name] = stateObj[key$1];
|
|
1442
|
+
const eventName = `onUpdate:${name}`;
|
|
1443
|
+
const existingHandler = processedProps[eventName];
|
|
1444
|
+
processedProps[eventName] = (v) => {
|
|
1445
|
+
stateObj[key$1] = v;
|
|
1446
|
+
if (existingHandler) existingHandler(v);
|
|
1447
|
+
};
|
|
1448
|
+
delete processedProps[propKey];
|
|
1449
|
+
}
|
|
1450
|
+
}
|
|
1451
|
+
}
|
|
1452
|
+
if (isComponent$1(type)) {
|
|
1453
|
+
const { children: children$1, ...rest$1 } = processedProps;
|
|
1454
|
+
return {
|
|
1455
|
+
type,
|
|
1456
|
+
props: {
|
|
1457
|
+
...rest$1,
|
|
1458
|
+
children: children$1
|
|
1459
|
+
},
|
|
1460
|
+
key: key || rest$1.key || null,
|
|
1461
|
+
children: [],
|
|
1462
|
+
dom: null
|
|
1463
|
+
};
|
|
1464
|
+
}
|
|
1465
|
+
if (typeof type === "function" && type !== Fragment$1) return type(processedProps);
|
|
1466
|
+
const { children, ...rest } = processedProps;
|
|
1467
|
+
return {
|
|
1468
|
+
type,
|
|
1469
|
+
props: rest,
|
|
1470
|
+
key: key || rest.key || null,
|
|
1471
|
+
children: normalizeChildren(children),
|
|
1472
|
+
dom: null
|
|
1473
|
+
};
|
|
1474
|
+
}
|
|
1475
|
+
/**
|
|
1476
|
+
* JSX Factory for fragments
|
|
1477
|
+
*/
|
|
1478
|
+
function jsxs$1(type, props, key) {
|
|
1479
|
+
return jsx$1(type, props, key);
|
|
1480
|
+
}
|
|
1481
|
+
|
|
1482
|
+
//#endregion
|
|
1483
|
+
//#region ../runtime-terminal/src/components/Input.tsx
|
|
1484
|
+
/** @jsxImportSource @sigx/runtime-core */
|
|
1485
|
+
const Input = defineComponent(({ props, emit }) => {
|
|
1486
|
+
const id = Math.random().toString(36).slice(2);
|
|
1487
|
+
const isFocused = () => focusState.activeId === id;
|
|
1488
|
+
const handleKey = (key) => {
|
|
1489
|
+
if (!isFocused()) return;
|
|
1490
|
+
if (key === "\r") {
|
|
1491
|
+
emit("submit", props.value || "");
|
|
1492
|
+
return;
|
|
1493
|
+
}
|
|
1494
|
+
if (key === "\n") return;
|
|
1495
|
+
if (key === "" || key === "\b") {
|
|
1496
|
+
const val = props.value || "";
|
|
1497
|
+
if (val.length > 0) {
|
|
1498
|
+
const newValue$1 = val.slice(0, -1);
|
|
1499
|
+
emit("update:value", newValue$1);
|
|
1500
|
+
emit("input", newValue$1);
|
|
1501
|
+
}
|
|
1502
|
+
return;
|
|
1503
|
+
}
|
|
1504
|
+
if (key.length > 1) return;
|
|
1505
|
+
const newValue = (props.value || "") + key;
|
|
1506
|
+
emit("update:value", newValue);
|
|
1507
|
+
emit("input", newValue);
|
|
1508
|
+
};
|
|
1509
|
+
let keyCleanup = null;
|
|
1510
|
+
onMount(() => {
|
|
1511
|
+
registerFocusable(id);
|
|
1512
|
+
if (props.autofocus) focus(id);
|
|
1513
|
+
keyCleanup = onKey(handleKey);
|
|
1514
|
+
});
|
|
1515
|
+
onCleanup(() => {
|
|
1516
|
+
if (keyCleanup) keyCleanup();
|
|
1517
|
+
unregisterFocusable(id);
|
|
1518
|
+
});
|
|
1519
|
+
return () => {
|
|
1520
|
+
const val = (props.value || "").replace(/[\r\n]+/g, " ");
|
|
1521
|
+
const placeholder = (props.placeholder || "").replace(/[\r\n]+/g, " ");
|
|
1522
|
+
const showCursor = isFocused();
|
|
1523
|
+
return /* @__PURE__ */ jsxs$1("box", {
|
|
1524
|
+
border: "single",
|
|
1525
|
+
borderColor: showCursor ? "green" : "white",
|
|
1526
|
+
label: props.label,
|
|
1527
|
+
children: [/* @__PURE__ */ jsx$1("text", { children: val || placeholder }), showCursor && /* @__PURE__ */ jsx$1("text", {
|
|
1528
|
+
color: "cyan",
|
|
1529
|
+
children: "_"
|
|
1530
|
+
})]
|
|
1531
|
+
});
|
|
1532
|
+
};
|
|
1533
|
+
}, { name: "Input" });
|
|
1534
|
+
|
|
1535
|
+
//#endregion
|
|
1536
|
+
//#region ../runtime-terminal/src/components/ProgressBar.tsx
|
|
1537
|
+
/** @jsxImportSource @sigx/runtime-core */
|
|
1538
|
+
const ProgressBar = defineComponent(({ props }) => {
|
|
1539
|
+
return () => {
|
|
1540
|
+
const value = props.value || 0;
|
|
1541
|
+
const max = props.max || 100;
|
|
1542
|
+
const width = props.width || 20;
|
|
1543
|
+
const barChar = props.char || "█";
|
|
1544
|
+
const emptyChar = props.emptyChar || "░";
|
|
1545
|
+
const color = props.color;
|
|
1546
|
+
const colorCode = color ? getColorCode(color) : "";
|
|
1547
|
+
const reset = color ? "\x1B[0m" : "";
|
|
1548
|
+
const percentage = Math.min(Math.max(value / max, 0), 1);
|
|
1549
|
+
const filledLen = Math.round(width * percentage);
|
|
1550
|
+
const emptyLen = width - filledLen;
|
|
1551
|
+
return /* @__PURE__ */ jsx$1("box", { children: /* @__PURE__ */ jsx$1("text", { children: colorCode + barChar.repeat(filledLen) + emptyChar.repeat(emptyLen) + reset + ` ${Math.round(percentage * 100)}%` }) });
|
|
1552
|
+
};
|
|
1553
|
+
}, { name: "ProgressBar" });
|
|
1554
|
+
|
|
1555
|
+
//#endregion
|
|
1556
|
+
//#region ../runtime-terminal/src/components/Button.tsx
|
|
1557
|
+
/** @jsxImportSource @sigx/runtime-core */
|
|
1558
|
+
const Button = defineComponent(({ props, emit }) => {
|
|
1559
|
+
const id = Math.random().toString(36).slice(2);
|
|
1560
|
+
const isFocused = () => focusState.activeId === id;
|
|
1561
|
+
const pressed = signal({ value: false });
|
|
1562
|
+
const handleKey = (key) => {
|
|
1563
|
+
if (!isFocused()) return;
|
|
1564
|
+
if (key === "\r" || key === " ") {
|
|
1565
|
+
pressed.value = true;
|
|
1566
|
+
if (pressTimer) clearTimeout(pressTimer);
|
|
1567
|
+
pressTimer = setTimeout(() => {
|
|
1568
|
+
pressed.value = false;
|
|
1569
|
+
pressTimer = null;
|
|
1570
|
+
}, 120);
|
|
1571
|
+
emit("click");
|
|
1572
|
+
}
|
|
1573
|
+
};
|
|
1574
|
+
let keyCleanup = null;
|
|
1575
|
+
let pressTimer = null;
|
|
1576
|
+
onMount(() => {
|
|
1577
|
+
registerFocusable(id);
|
|
1578
|
+
keyCleanup = onKey(handleKey);
|
|
1579
|
+
});
|
|
1580
|
+
onCleanup(() => {
|
|
1581
|
+
if (keyCleanup) keyCleanup();
|
|
1582
|
+
unregisterFocusable(id);
|
|
1583
|
+
if (pressTimer) clearTimeout(pressTimer);
|
|
1584
|
+
});
|
|
1585
|
+
return () => {
|
|
1586
|
+
const focused = isFocused();
|
|
1587
|
+
const label = props.label || "Button";
|
|
1588
|
+
const isPressed = pressed.value;
|
|
1589
|
+
return /* @__PURE__ */ jsx$1("box", {
|
|
1590
|
+
border: "single",
|
|
1591
|
+
borderColor: isPressed ? "yellow" : focused ? "green" : "white",
|
|
1592
|
+
backgroundColor: isPressed ? "red" : focused ? "blue" : void 0,
|
|
1593
|
+
dropShadow: props.dropShadow,
|
|
1594
|
+
children: /* @__PURE__ */ jsx$1("text", {
|
|
1595
|
+
color: focused ? "white" : void 0,
|
|
1596
|
+
children: label
|
|
1597
|
+
})
|
|
1598
|
+
});
|
|
1599
|
+
};
|
|
1600
|
+
}, { name: "Button" });
|
|
1601
|
+
|
|
1602
|
+
//#endregion
|
|
1603
|
+
//#region ../runtime-terminal/src/components/Checkbox.tsx
|
|
1604
|
+
/** @jsxImportSource @sigx/runtime-core */
|
|
1605
|
+
const Checkbox = defineComponent(({ props, emit }) => {
|
|
1606
|
+
const id = Math.random().toString(36).slice(2);
|
|
1607
|
+
const isFocused = () => focusState.activeId === id;
|
|
1608
|
+
const checked = () => !!props.value;
|
|
1609
|
+
const handleKey = (key) => {
|
|
1610
|
+
if (!isFocused()) return;
|
|
1611
|
+
if (props.disabled) return;
|
|
1612
|
+
if (key === "\r" || key === " ") {
|
|
1613
|
+
const next = !checked();
|
|
1614
|
+
emit("update:value", next);
|
|
1615
|
+
emit("change", next);
|
|
1616
|
+
}
|
|
1617
|
+
};
|
|
1618
|
+
let keyCleanup = null;
|
|
1619
|
+
onMount(() => {
|
|
1620
|
+
registerFocusable(id);
|
|
1621
|
+
if (props.autofocus) focus(id);
|
|
1622
|
+
keyCleanup = onKey(handleKey);
|
|
1623
|
+
});
|
|
1624
|
+
onCleanup(() => {
|
|
1625
|
+
if (keyCleanup) keyCleanup();
|
|
1626
|
+
unregisterFocusable(id);
|
|
1627
|
+
});
|
|
1628
|
+
return () => {
|
|
1629
|
+
const label = props.label || "";
|
|
1630
|
+
const focused = isFocused();
|
|
1631
|
+
const isChecked = checked();
|
|
1632
|
+
const disabled = !!props.disabled;
|
|
1633
|
+
return /* @__PURE__ */ jsxs$1("box", { children: [
|
|
1634
|
+
/* @__PURE__ */ jsx$1("text", {
|
|
1635
|
+
color: focused ? "cyan" : "white",
|
|
1636
|
+
children: focused ? ">" : " "
|
|
1637
|
+
}),
|
|
1638
|
+
/* @__PURE__ */ jsxs$1("text", {
|
|
1639
|
+
color: disabled ? "white" : isChecked ? "green" : focused ? "cyan" : "white",
|
|
1640
|
+
children: [
|
|
1641
|
+
"[",
|
|
1642
|
+
isChecked ? "x" : " ",
|
|
1643
|
+
"]"
|
|
1644
|
+
]
|
|
1645
|
+
}),
|
|
1646
|
+
label && /* @__PURE__ */ jsxs$1("text", {
|
|
1647
|
+
color: disabled ? "white" : focused ? "cyan" : void 0,
|
|
1648
|
+
children: [" ", label]
|
|
1649
|
+
})
|
|
1650
|
+
] });
|
|
1651
|
+
};
|
|
1652
|
+
}, { name: "Checkbox" });
|
|
1653
|
+
|
|
1654
|
+
//#endregion
|
|
1655
|
+
//#region ../runtime-terminal/src/index.ts
|
|
1656
|
+
const renderer = createRenderer({
|
|
1657
|
+
patchProp: (el, key, prev, next) => {
|
|
1658
|
+
el.props[key] = next;
|
|
1659
|
+
scheduleRender();
|
|
1660
|
+
},
|
|
1661
|
+
insert: (child, parent, anchor) => {
|
|
1662
|
+
child.parentNode = parent;
|
|
1663
|
+
const index = anchor ? parent.children.indexOf(anchor) : -1;
|
|
1664
|
+
if (index > -1) parent.children.splice(index, 0, child);
|
|
1665
|
+
else parent.children.push(child);
|
|
1666
|
+
scheduleRender();
|
|
1667
|
+
},
|
|
1668
|
+
remove: (child) => {
|
|
1669
|
+
if (child.parentNode) {
|
|
1670
|
+
const index = child.parentNode.children.indexOf(child);
|
|
1671
|
+
if (index > -1) child.parentNode.children.splice(index, 1);
|
|
1672
|
+
child.parentNode = null;
|
|
1673
|
+
}
|
|
1674
|
+
scheduleRender();
|
|
1675
|
+
},
|
|
1676
|
+
createElement: (tag) => {
|
|
1677
|
+
return {
|
|
1678
|
+
type: "element",
|
|
1679
|
+
tag,
|
|
1680
|
+
props: {},
|
|
1681
|
+
children: []
|
|
1682
|
+
};
|
|
1683
|
+
},
|
|
1684
|
+
createText: (text) => {
|
|
1685
|
+
return {
|
|
1686
|
+
type: "text",
|
|
1687
|
+
text,
|
|
1688
|
+
props: {},
|
|
1689
|
+
children: []
|
|
1690
|
+
};
|
|
1691
|
+
},
|
|
1692
|
+
createComment: (text) => {
|
|
1693
|
+
return {
|
|
1694
|
+
type: "comment",
|
|
1695
|
+
text,
|
|
1696
|
+
props: {},
|
|
1697
|
+
children: []
|
|
1698
|
+
};
|
|
1699
|
+
},
|
|
1700
|
+
setText: (node, text) => {
|
|
1701
|
+
node.text = text;
|
|
1702
|
+
scheduleRender();
|
|
1703
|
+
},
|
|
1704
|
+
setElementText: (node, text) => {
|
|
1705
|
+
node.children = [{
|
|
1706
|
+
type: "text",
|
|
1707
|
+
text,
|
|
1708
|
+
props: {},
|
|
1709
|
+
children: [],
|
|
1710
|
+
parentNode: node
|
|
1711
|
+
}];
|
|
1712
|
+
scheduleRender();
|
|
1713
|
+
},
|
|
1714
|
+
parentNode: (node) => node.parentNode || null,
|
|
1715
|
+
nextSibling: (node) => {
|
|
1716
|
+
if (!node.parentNode) return null;
|
|
1717
|
+
const idx = node.parentNode.children.indexOf(node);
|
|
1718
|
+
return node.parentNode.children[idx + 1] || null;
|
|
1719
|
+
},
|
|
1720
|
+
cloneNode: (node) => {
|
|
1721
|
+
return {
|
|
1722
|
+
...node,
|
|
1723
|
+
children: []
|
|
1724
|
+
};
|
|
1725
|
+
}
|
|
1726
|
+
});
|
|
1727
|
+
const { render, createApp } = renderer;
|
|
1728
|
+
let rootNode = null;
|
|
1729
|
+
let isRendering = false;
|
|
1730
|
+
function scheduleRender() {
|
|
1731
|
+
if (isRendering) return;
|
|
1732
|
+
isRendering = true;
|
|
1733
|
+
setTimeout(() => {
|
|
1734
|
+
flushRender();
|
|
1735
|
+
isRendering = false;
|
|
1736
|
+
}, 10);
|
|
1737
|
+
}
|
|
1738
|
+
function flushRender() {
|
|
1739
|
+
if (!rootNode) return;
|
|
1740
|
+
process.stdout.write("\x1B[H");
|
|
1741
|
+
const lines = renderNodeToLines(rootNode);
|
|
1742
|
+
process.stdout.write(lines.join("\x1B[K\n") + "\x1B[K");
|
|
1743
|
+
process.stdout.write("\x1B[J");
|
|
1744
|
+
}
|
|
1745
|
+
/**
|
|
1746
|
+
* Check if a node has a box element as an immediate child.
|
|
1747
|
+
* This is used to determine if a component wrapper should be treated as a block element.
|
|
1748
|
+
*/
|
|
1749
|
+
function hasBoxChild(node) {
|
|
1750
|
+
for (const child of node.children) if (child.tag === "box") return true;
|
|
1751
|
+
return false;
|
|
1752
|
+
}
|
|
1753
|
+
function renderNodeToLines(node) {
|
|
1754
|
+
if (node.type === "text") return [node.text || ""];
|
|
1755
|
+
if (node.type === "comment") return [];
|
|
1756
|
+
let lines = [""];
|
|
1757
|
+
const color = node.props.color;
|
|
1758
|
+
const reset = color ? "\x1B[0m" : "";
|
|
1759
|
+
const colorCode = getColorCode(color);
|
|
1760
|
+
for (const child of node.children) if (child.type === "text") lines[lines.length - 1] += colorCode + (child.text || "") + reset;
|
|
1761
|
+
else if (child.tag === "br") lines.push("");
|
|
1762
|
+
else {
|
|
1763
|
+
const childLines = renderNodeToLines(child);
|
|
1764
|
+
if (child.tag === "box" || hasBoxChild(child)) if (lines.length === 1 && lines[0] === "") lines = childLines;
|
|
1765
|
+
else lines.push(...childLines);
|
|
1766
|
+
else if (childLines.length > 0) if (childLines.length > 1) if (lines.length === 1 && lines[0] === "") lines = childLines;
|
|
1767
|
+
else lines.push(...childLines);
|
|
1768
|
+
else {
|
|
1769
|
+
lines[lines.length - 1] += childLines[0];
|
|
1770
|
+
for (let i = 1; i < childLines.length; i++) lines.push(childLines[i]);
|
|
1771
|
+
}
|
|
1772
|
+
}
|
|
1773
|
+
if (node.tag === "box" && node.props.border) return drawBox(lines, node.props.border, node.props.borderColor, node.props.backgroundColor, node.props.dropShadow, node.props.label);
|
|
1774
|
+
return lines;
|
|
1775
|
+
}
|
|
1776
|
+
function drawBox(contentLines, style, color, backgroundColor, dropShadow, label) {
|
|
1777
|
+
const borderChars = getBorderChars(style);
|
|
1778
|
+
const colorCode = color ? getColorCode(color) : "";
|
|
1779
|
+
const bgCode = backgroundColor ? getBackgroundColorCode(backgroundColor) : "";
|
|
1780
|
+
const reset = color || backgroundColor ? "\x1B[0m" : "";
|
|
1781
|
+
const width = contentLines.reduce((max, line) => Math.max(max, stripAnsi(line).length), 0);
|
|
1782
|
+
const labelText = label || "";
|
|
1783
|
+
const labelLength = stripAnsi(labelText).length;
|
|
1784
|
+
const boxInnerWidth = Math.max(width, labelLength + 2);
|
|
1785
|
+
let topInner = "";
|
|
1786
|
+
if (labelText) {
|
|
1787
|
+
const spaceForLabel = boxInnerWidth - labelLength - 2;
|
|
1788
|
+
const leftH = Math.floor(spaceForLabel / 2);
|
|
1789
|
+
const rightH = spaceForLabel - leftH;
|
|
1790
|
+
topInner = borderChars.h.repeat(leftH) + " " + labelText + " " + borderChars.h.repeat(rightH);
|
|
1791
|
+
} else topInner = borderChars.h.repeat(boxInnerWidth);
|
|
1792
|
+
const top = bgCode + colorCode + borderChars.tl + topInner + borderChars.tr + reset;
|
|
1793
|
+
const bottom = bgCode + colorCode + borderChars.bl + borderChars.h.repeat(boxInnerWidth) + borderChars.br + reset;
|
|
1794
|
+
const result = [];
|
|
1795
|
+
result.push(top);
|
|
1796
|
+
for (const line of contentLines) {
|
|
1797
|
+
const visibleLength = stripAnsi(line).length;
|
|
1798
|
+
const padding = " ".repeat(boxInnerWidth - visibleLength);
|
|
1799
|
+
const lineWithBg = bgCode + line.replace(/\x1b\[0m/g, `\x1b[0m${bgCode}`);
|
|
1800
|
+
result.push(bgCode + colorCode + borderChars.v + reset + lineWithBg + bgCode + padding + colorCode + borderChars.v + reset);
|
|
1801
|
+
}
|
|
1802
|
+
result.push(bottom);
|
|
1803
|
+
if (dropShadow) {
|
|
1804
|
+
const shadowBlock = "\x1B[90m▒\x1B[0m";
|
|
1805
|
+
for (let i = 1; i < result.length; i++) result[i] += shadowBlock;
|
|
1806
|
+
const bottomShadow = " " + shadowBlock.repeat(width + 2);
|
|
1807
|
+
result.push(bottomShadow);
|
|
1808
|
+
}
|
|
1809
|
+
return result;
|
|
1810
|
+
}
|
|
1811
|
+
function getBorderChars(style) {
|
|
1812
|
+
if (style === "double") return {
|
|
1813
|
+
tl: "╔",
|
|
1814
|
+
tr: "╗",
|
|
1815
|
+
bl: "╚",
|
|
1816
|
+
br: "╝",
|
|
1817
|
+
h: "═",
|
|
1818
|
+
v: "║"
|
|
1819
|
+
};
|
|
1820
|
+
if (style === "rounded") return {
|
|
1821
|
+
tl: "╭",
|
|
1822
|
+
tr: "╮",
|
|
1823
|
+
bl: "╰",
|
|
1824
|
+
br: "╯",
|
|
1825
|
+
h: "─",
|
|
1826
|
+
v: "│"
|
|
1827
|
+
};
|
|
1828
|
+
return {
|
|
1829
|
+
tl: "┌",
|
|
1830
|
+
tr: "┐",
|
|
1831
|
+
bl: "└",
|
|
1832
|
+
br: "┘",
|
|
1833
|
+
h: "─",
|
|
1834
|
+
v: "│"
|
|
1835
|
+
};
|
|
1836
|
+
}
|
|
1837
|
+
const keyHandlers = /* @__PURE__ */ new Set();
|
|
1838
|
+
function onKey(handler) {
|
|
1839
|
+
keyHandlers.add(handler);
|
|
1840
|
+
return () => keyHandlers.delete(handler);
|
|
1841
|
+
}
|
|
1842
|
+
function handleInput(key) {
|
|
1843
|
+
if (key === "") {
|
|
1844
|
+
process.stdout.write("\x1B[?25h");
|
|
1845
|
+
process.exit();
|
|
1846
|
+
}
|
|
1847
|
+
if (key === " ") {
|
|
1848
|
+
focusNext();
|
|
1849
|
+
return;
|
|
1850
|
+
}
|
|
1851
|
+
if (key === "\x1B[Z") {
|
|
1852
|
+
focusPrev();
|
|
1853
|
+
return;
|
|
1854
|
+
}
|
|
1855
|
+
for (const handler of keyHandlers) handler(key);
|
|
1856
|
+
}
|
|
1857
|
+
function renderTerminal(app, options = {}) {
|
|
1858
|
+
rootNode = {
|
|
1859
|
+
type: "root",
|
|
1860
|
+
props: {},
|
|
1861
|
+
children: []
|
|
1862
|
+
};
|
|
1863
|
+
const container = rootNode;
|
|
1864
|
+
if (process.stdin.isTTY) {
|
|
1865
|
+
process.stdin.setRawMode(true);
|
|
1866
|
+
process.stdin.resume();
|
|
1867
|
+
process.stdin.setEncoding("utf8");
|
|
1868
|
+
process.stdin.on("data", handleInput);
|
|
1869
|
+
}
|
|
1870
|
+
if (options.clearConsole) process.stdout.write("\x1B[2J\x1B[3J\x1B[H");
|
|
1871
|
+
process.stdout.write("\x1B[?25l");
|
|
1872
|
+
render(app, container);
|
|
1873
|
+
flushRender();
|
|
1874
|
+
return { unmount: () => {
|
|
1875
|
+
render(null, container);
|
|
1876
|
+
process.stdout.write("\x1B[?25h");
|
|
1877
|
+
if (process.stdin.isTTY) {
|
|
1878
|
+
process.stdin.setRawMode(false);
|
|
1879
|
+
process.stdin.pause();
|
|
1880
|
+
process.stdin.off("data", handleInput);
|
|
1881
|
+
}
|
|
1882
|
+
} };
|
|
1883
|
+
}
|
|
1884
|
+
/**
|
|
1885
|
+
* Mount function for Terminal environments.
|
|
1886
|
+
* Use this with defineApp().mount() to render to the terminal.
|
|
1887
|
+
*
|
|
1888
|
+
* @example
|
|
1889
|
+
* ```tsx
|
|
1890
|
+
* import { defineApp } from '@sigx/runtime-core';
|
|
1891
|
+
* import { terminalMount } from '@sigx/runtime-terminal';
|
|
1892
|
+
*
|
|
1893
|
+
* const app = defineApp(<Counter />);
|
|
1894
|
+
* app.use(loggingPlugin)
|
|
1895
|
+
* .mount({ clearConsole: true }, terminalMount);
|
|
1896
|
+
* ```
|
|
1897
|
+
*/
|
|
1898
|
+
const terminalMount = (component, options, appContext) => {
|
|
1899
|
+
rootNode = {
|
|
1900
|
+
type: "root",
|
|
1901
|
+
props: {},
|
|
1902
|
+
children: []
|
|
1903
|
+
};
|
|
1904
|
+
const container = rootNode;
|
|
1905
|
+
if (process.stdin.isTTY) {
|
|
1906
|
+
process.stdin.setRawMode(true);
|
|
1907
|
+
process.stdin.resume();
|
|
1908
|
+
process.stdin.setEncoding("utf8");
|
|
1909
|
+
process.stdin.on("data", handleInput);
|
|
1910
|
+
}
|
|
1911
|
+
if (options?.clearConsole) process.stdout.write("\x1B[2J\x1B[3J\x1B[H");
|
|
1912
|
+
process.stdout.write("\x1B[?25l");
|
|
1913
|
+
render(component, container, appContext);
|
|
1914
|
+
flushRender();
|
|
1915
|
+
return () => {
|
|
1916
|
+
render(null, container);
|
|
1917
|
+
process.stdout.write("\x1B[?25h");
|
|
1918
|
+
if (process.stdin.isTTY) {
|
|
1919
|
+
process.stdin.setRawMode(false);
|
|
1920
|
+
process.stdin.pause();
|
|
1921
|
+
process.stdin.off("data", handleInput);
|
|
1922
|
+
}
|
|
1923
|
+
};
|
|
1924
|
+
};
|
|
1925
|
+
setDefaultMount(terminalMount);
|
|
1926
|
+
|
|
1927
|
+
//#endregion
|
|
1928
|
+
export { AppContextKey, Button, Checkbox, Fragment, Input, InstanceLifetimes, ProgressBar, SubscriptionHandler, Text, Utils, batch, createApp, createPropsProxy, createRenderer, createTopic, defineApp, defineComponent, defineFactory, defineInjectable, defineProvide, defineStore, detectAccess, effect, effectScope, focus, focusNext, focusPrev, focusState, getComponentMeta, getComponentPlugins, getCurrentInstance, getDefaultMount, getPlatformSyncProcessor, guid, handleComponentError, inject, injectApp, jsx, jsxDEV, jsxs, notifyComponentCreated, notifyComponentMounted, notifyComponentUnmounted, notifyComponentUpdated, onCleanup, onKey, onMount, provide, registerComponentPlugin, registerFocusable, render, renderNodeToLines, renderTerminal, setCurrentInstance, setDefaultMount, setPlatformSyncProcessor, signal, terminalMount, toSubscriber, unregisterFocusable, untrack, valueOf, watch };
|
|
1929
|
+
//# sourceMappingURL=index.js.map
|