@sigx/terminal 0.1.4 → 0.1.5
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 +221 -115
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -250,6 +250,29 @@ function registerComponentPlugin(plugin) {
|
|
|
250
250
|
function getComponentPlugins() {
|
|
251
251
|
return plugins$1;
|
|
252
252
|
}
|
|
253
|
+
const contextExtensions = [];
|
|
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
|
+
*/
|
|
266
|
+
function registerContextExtension(extension) {
|
|
267
|
+
contextExtensions.push(extension);
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
* Apply all registered context extensions to a context object.
|
|
271
|
+
* Called internally by the renderer when creating component contexts.
|
|
272
|
+
*/
|
|
273
|
+
function applyContextExtensions(ctx) {
|
|
274
|
+
for (const extension of contextExtensions) extension(ctx);
|
|
275
|
+
}
|
|
253
276
|
|
|
254
277
|
//#endregion
|
|
255
278
|
//#region ../runtime-core/src/app.ts
|
|
@@ -825,6 +848,195 @@ function guid$1() {
|
|
|
825
848
|
});
|
|
826
849
|
}
|
|
827
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
|
+
function createPropsAccessor(reactiveProps) {
|
|
870
|
+
let defaults = {};
|
|
871
|
+
const proxy = new Proxy(function propsAccessor() {}, {
|
|
872
|
+
get(_, key) {
|
|
873
|
+
if (typeof key === "symbol") return void 0;
|
|
874
|
+
const value = reactiveProps[key];
|
|
875
|
+
return value != null ? value : defaults[key];
|
|
876
|
+
},
|
|
877
|
+
apply(_, __, args) {
|
|
878
|
+
if (args[0] && typeof args[0] === "object") defaults = {
|
|
879
|
+
...defaults,
|
|
880
|
+
...args[0]
|
|
881
|
+
};
|
|
882
|
+
return proxy;
|
|
883
|
+
},
|
|
884
|
+
has(_, key) {
|
|
885
|
+
if (typeof key === "symbol") return false;
|
|
886
|
+
return key in reactiveProps || key in defaults;
|
|
887
|
+
},
|
|
888
|
+
ownKeys() {
|
|
889
|
+
return [...new Set([...Object.keys(reactiveProps), ...Object.keys(defaults)])];
|
|
890
|
+
},
|
|
891
|
+
getOwnPropertyDescriptor(_, key) {
|
|
892
|
+
if (typeof key === "symbol") return void 0;
|
|
893
|
+
if (key in reactiveProps || key in defaults) return {
|
|
894
|
+
enumerable: true,
|
|
895
|
+
configurable: true,
|
|
896
|
+
writable: false
|
|
897
|
+
};
|
|
898
|
+
}
|
|
899
|
+
});
|
|
900
|
+
return proxy;
|
|
901
|
+
}
|
|
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
|
+
function createSlots(children, slotsFromProps) {
|
|
937
|
+
const versionSignal = signal({ v: 0 });
|
|
938
|
+
function extractNamedSlotsFromChildren(c) {
|
|
939
|
+
const defaultChildren = [];
|
|
940
|
+
const namedSlots = {};
|
|
941
|
+
if (c == null) return {
|
|
942
|
+
defaultChildren,
|
|
943
|
+
namedSlots
|
|
944
|
+
};
|
|
945
|
+
const items = Array.isArray(c) ? c : [c];
|
|
946
|
+
for (const child of items) if (child && typeof child === "object" && child.props && child.props.slot) {
|
|
947
|
+
const slotName = child.props.slot;
|
|
948
|
+
if (!namedSlots[slotName]) namedSlots[slotName] = [];
|
|
949
|
+
namedSlots[slotName].push(child);
|
|
950
|
+
} else defaultChildren.push(child);
|
|
951
|
+
return {
|
|
952
|
+
defaultChildren,
|
|
953
|
+
namedSlots
|
|
954
|
+
};
|
|
955
|
+
}
|
|
956
|
+
const slotsObj = {
|
|
957
|
+
_children: children,
|
|
958
|
+
_slotsFromProps: slotsFromProps || {},
|
|
959
|
+
_version: versionSignal,
|
|
960
|
+
_isPatching: false,
|
|
961
|
+
default: function() {
|
|
962
|
+
this._version.v;
|
|
963
|
+
const c = this._children;
|
|
964
|
+
const { defaultChildren } = extractNamedSlotsFromChildren(c);
|
|
965
|
+
return defaultChildren.filter((child) => child != null && child !== false && child !== true);
|
|
966
|
+
}
|
|
967
|
+
};
|
|
968
|
+
return new Proxy(slotsObj, { get(target, prop) {
|
|
969
|
+
if (prop in target) return target[prop];
|
|
970
|
+
if (typeof prop === "string") return function(scopedProps) {
|
|
971
|
+
target._version.v;
|
|
972
|
+
if (target._slotsFromProps && typeof target._slotsFromProps[prop] === "function") {
|
|
973
|
+
const result = target._slotsFromProps[prop](scopedProps);
|
|
974
|
+
if (result == null) return [];
|
|
975
|
+
return Array.isArray(result) ? result : [result];
|
|
976
|
+
}
|
|
977
|
+
const { namedSlots } = extractNamedSlotsFromChildren(target._children);
|
|
978
|
+
return namedSlots[prop] || [];
|
|
979
|
+
};
|
|
980
|
+
} });
|
|
981
|
+
}
|
|
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
|
+
function normalizeSubTree(result) {
|
|
1014
|
+
if (result == null || result === false || result === true) return {
|
|
1015
|
+
type: Text,
|
|
1016
|
+
props: {},
|
|
1017
|
+
key: null,
|
|
1018
|
+
children: [],
|
|
1019
|
+
dom: null,
|
|
1020
|
+
text: ""
|
|
1021
|
+
};
|
|
1022
|
+
if (Array.isArray(result)) return {
|
|
1023
|
+
type: Fragment,
|
|
1024
|
+
props: {},
|
|
1025
|
+
key: null,
|
|
1026
|
+
children: result,
|
|
1027
|
+
dom: null
|
|
1028
|
+
};
|
|
1029
|
+
if (typeof result === "string" || typeof result === "number") return {
|
|
1030
|
+
type: Text,
|
|
1031
|
+
props: {},
|
|
1032
|
+
key: null,
|
|
1033
|
+
children: [],
|
|
1034
|
+
dom: null,
|
|
1035
|
+
text: result
|
|
1036
|
+
};
|
|
1037
|
+
return result;
|
|
1038
|
+
}
|
|
1039
|
+
|
|
828
1040
|
//#endregion
|
|
829
1041
|
//#region ../runtime-core/src/models/index.ts
|
|
830
1042
|
const guid = guid$1;
|
|
@@ -1358,43 +1570,6 @@ function createRenderer(options) {
|
|
|
1358
1570
|
for (let i = beginIdx; i <= endIdx; i++) if (children[i] && isSameVNode(children[i], newChild)) return i;
|
|
1359
1571
|
return null;
|
|
1360
1572
|
}
|
|
1361
|
-
/**
|
|
1362
|
-
* Creates a props accessor that can be called with defaults or accessed directly.
|
|
1363
|
-
* After calling with defaults, direct property access uses those defaults.
|
|
1364
|
-
*/
|
|
1365
|
-
function createPropsAccessor(reactiveProps) {
|
|
1366
|
-
let defaults = {};
|
|
1367
|
-
const proxy = new Proxy(function propsAccessor() {}, {
|
|
1368
|
-
get(_, key) {
|
|
1369
|
-
if (typeof key === "symbol") return void 0;
|
|
1370
|
-
const value = reactiveProps[key];
|
|
1371
|
-
return value != null ? value : defaults[key];
|
|
1372
|
-
},
|
|
1373
|
-
apply(_, __, args) {
|
|
1374
|
-
if (args[0] && typeof args[0] === "object") defaults = {
|
|
1375
|
-
...defaults,
|
|
1376
|
-
...args[0]
|
|
1377
|
-
};
|
|
1378
|
-
return proxy;
|
|
1379
|
-
},
|
|
1380
|
-
has(_, key) {
|
|
1381
|
-
if (typeof key === "symbol") return false;
|
|
1382
|
-
return key in reactiveProps || key in defaults;
|
|
1383
|
-
},
|
|
1384
|
-
ownKeys() {
|
|
1385
|
-
return [...new Set([...Object.keys(reactiveProps), ...Object.keys(defaults)])];
|
|
1386
|
-
},
|
|
1387
|
-
getOwnPropertyDescriptor(_, key) {
|
|
1388
|
-
if (typeof key === "symbol") return void 0;
|
|
1389
|
-
if (key in reactiveProps || key in defaults) return {
|
|
1390
|
-
enumerable: true,
|
|
1391
|
-
configurable: true,
|
|
1392
|
-
writable: false
|
|
1393
|
-
};
|
|
1394
|
-
}
|
|
1395
|
-
});
|
|
1396
|
-
return proxy;
|
|
1397
|
-
}
|
|
1398
1573
|
function mountComponent(vnode, container, before, setup) {
|
|
1399
1574
|
const anchor = hostCreateComment("");
|
|
1400
1575
|
vnode.dom = anchor;
|
|
@@ -1435,6 +1610,7 @@ function createRenderer(options) {
|
|
|
1435
1610
|
renderFn: null,
|
|
1436
1611
|
update: () => {}
|
|
1437
1612
|
};
|
|
1613
|
+
applyContextExtensions(ctx);
|
|
1438
1614
|
ctx.__name = componentName;
|
|
1439
1615
|
if (currentAppContext) ctx._appContext = currentAppContext;
|
|
1440
1616
|
const componentInstance = {
|
|
@@ -1445,7 +1621,9 @@ function createRenderer(options) {
|
|
|
1445
1621
|
const prev = setCurrentInstance(ctx);
|
|
1446
1622
|
let renderFn;
|
|
1447
1623
|
try {
|
|
1448
|
-
|
|
1624
|
+
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 onMount.`);
|
|
1626
|
+
renderFn = setupResult;
|
|
1449
1627
|
notifyComponentCreated(currentAppContext, componentInstance);
|
|
1450
1628
|
} catch (err) {
|
|
1451
1629
|
if (!handleComponentError(currentAppContext, err, componentInstance, "setup")) throw err;
|
|
@@ -1490,84 +1668,12 @@ function createRenderer(options) {
|
|
|
1490
1668
|
cleanupHooks.forEach((hook) => hook(mountCtx));
|
|
1491
1669
|
};
|
|
1492
1670
|
}
|
|
1493
|
-
/**
|
|
1494
|
-
* Create slots object from children and slots prop.
|
|
1495
|
-
* Uses a version signal to trigger re-renders when children change.
|
|
1496
|
-
* Supports named slots via:
|
|
1497
|
-
* - `slots` prop object (e.g., slots={{ header: () => <div>...</div> }})
|
|
1498
|
-
* - `slot` prop on children (e.g., <div slot="header">...</div>)
|
|
1499
|
-
*/
|
|
1500
|
-
function createSlots(children, slotsFromProps) {
|
|
1501
|
-
const versionSignal = signal({ v: 0 });
|
|
1502
|
-
function extractNamedSlotsFromChildren(c) {
|
|
1503
|
-
const defaultChildren = [];
|
|
1504
|
-
const namedSlots = {};
|
|
1505
|
-
if (c == null) return {
|
|
1506
|
-
defaultChildren,
|
|
1507
|
-
namedSlots
|
|
1508
|
-
};
|
|
1509
|
-
const items = Array.isArray(c) ? c : [c];
|
|
1510
|
-
for (const child of items) if (child && typeof child === "object" && child.props && child.props.slot) {
|
|
1511
|
-
const slotName = child.props.slot;
|
|
1512
|
-
if (!namedSlots[slotName]) namedSlots[slotName] = [];
|
|
1513
|
-
namedSlots[slotName].push(child);
|
|
1514
|
-
} else defaultChildren.push(child);
|
|
1515
|
-
return {
|
|
1516
|
-
defaultChildren,
|
|
1517
|
-
namedSlots
|
|
1518
|
-
};
|
|
1519
|
-
}
|
|
1520
|
-
const slotsObj = {
|
|
1521
|
-
_children: children,
|
|
1522
|
-
_slotsFromProps: slotsFromProps || {},
|
|
1523
|
-
_version: versionSignal,
|
|
1524
|
-
_isPatching: false,
|
|
1525
|
-
default: function() {
|
|
1526
|
-
this._version.v;
|
|
1527
|
-
const c = this._children;
|
|
1528
|
-
const { defaultChildren } = extractNamedSlotsFromChildren(c);
|
|
1529
|
-
return defaultChildren.filter((child) => child != null && child !== false && child !== true);
|
|
1530
|
-
}
|
|
1531
|
-
};
|
|
1532
|
-
return new Proxy(slotsObj, { get(target, prop) {
|
|
1533
|
-
if (prop in target) return target[prop];
|
|
1534
|
-
if (typeof prop === "string") return function(scopedProps) {
|
|
1535
|
-
target._version.v;
|
|
1536
|
-
if (target._slotsFromProps && typeof target._slotsFromProps[prop] === "function") {
|
|
1537
|
-
const result = target._slotsFromProps[prop](scopedProps);
|
|
1538
|
-
if (result == null) return [];
|
|
1539
|
-
return Array.isArray(result) ? result : [result];
|
|
1540
|
-
}
|
|
1541
|
-
const { namedSlots } = extractNamedSlotsFromChildren(target._children);
|
|
1542
|
-
return namedSlots[prop] || [];
|
|
1543
|
-
};
|
|
1544
|
-
} });
|
|
1545
|
-
}
|
|
1546
|
-
/**
|
|
1547
|
-
* Normalize render result to a VNode (wrapping arrays in Fragment)
|
|
1548
|
-
* Note: Falsy values (null, undefined, false, true) from conditional rendering
|
|
1549
|
-
* are handled by mount() which guards against them, so no filtering needed here.
|
|
1550
|
-
*/
|
|
1551
|
-
function normalizeSubTree(result) {
|
|
1552
|
-
if (Array.isArray(result)) return {
|
|
1553
|
-
type: Fragment,
|
|
1554
|
-
props: {},
|
|
1555
|
-
key: null,
|
|
1556
|
-
children: result,
|
|
1557
|
-
dom: null
|
|
1558
|
-
};
|
|
1559
|
-
if (typeof result === "string" || typeof result === "number") return {
|
|
1560
|
-
type: Text,
|
|
1561
|
-
props: {},
|
|
1562
|
-
key: null,
|
|
1563
|
-
children: [],
|
|
1564
|
-
dom: null,
|
|
1565
|
-
text: result
|
|
1566
|
-
};
|
|
1567
|
-
return result;
|
|
1568
|
-
}
|
|
1569
1671
|
return {
|
|
1570
1672
|
render: render$1,
|
|
1673
|
+
patch,
|
|
1674
|
+
mount,
|
|
1675
|
+
unmount,
|
|
1676
|
+
mountComponent,
|
|
1571
1677
|
createApp: (rootComponent) => {
|
|
1572
1678
|
return { mount(selectorOrContainer) {
|
|
1573
1679
|
let container = null;
|
|
@@ -2440,5 +2546,5 @@ const terminalMount = (component, options, appContext) => {
|
|
|
2440
2546
|
setDefaultMount(terminalMount);
|
|
2441
2547
|
|
|
2442
2548
|
//#endregion
|
|
2443
|
-
export { AppContextKey, Button, Checkbox, Fragment, Input, InstanceLifetimes, ProgressBar, Select, SubscriptionHandler, Suspense, Text, Utils, batch, createApp, createPropsProxy, createRenderer, 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, notifyComponentCreated, notifyComponentMounted, notifyComponentUnmounted, notifyComponentUpdated, onCleanup, onKey, onMount, provide, registerComponentPlugin, registerFocusable, registerPendingPromise, render, renderNodeToLines, renderTerminal, setCurrentInstance, setDefaultMount, setPlatformSyncProcessor, signal, terminalMount, toSubscriber, unregisterFocusable, untrack, valueOf, watch };
|
|
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 };
|
|
2444
2550
|
//# sourceMappingURL=index.js.map
|