flexium 0.9.0 → 0.10.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +14 -0
- package/dist/{DrawText-CJikXQjL.d.cts → DrawText-ccZrs3Xs.d.cts} +1 -1
- package/dist/{DrawText-Bvzl40Vi.d.ts → DrawText-ngwNNh8O.d.ts} +1 -1
- package/dist/advanced.d.cts +3 -3
- package/dist/advanced.d.ts +3 -3
- package/dist/advanced.js +1 -1
- package/dist/advanced.js.map +1 -1
- package/dist/advanced.mjs +1 -1
- package/dist/advanced.mjs.map +1 -1
- package/dist/canvas.d.cts +5 -5
- package/dist/canvas.d.ts +5 -5
- package/dist/canvas.js +1 -1
- package/dist/canvas.mjs +1 -1
- package/dist/chunk-3BQXIHYI.mjs +3 -0
- package/dist/chunk-3BQXIHYI.mjs.map +1 -0
- package/dist/chunk-5236IK5I.js +2 -0
- package/dist/chunk-5236IK5I.js.map +1 -0
- package/dist/{chunk-PDOEMOWN.js → chunk-63AW5ZOC.js} +2 -2
- package/dist/{chunk-PDOEMOWN.js.map → chunk-63AW5ZOC.js.map} +1 -1
- package/dist/chunk-AJT35P3Z.js +3 -0
- package/dist/chunk-AJT35P3Z.js.map +1 -0
- package/dist/chunk-AYQMU7XC.js +3 -0
- package/dist/chunk-AYQMU7XC.js.map +1 -0
- package/dist/chunk-B7VP6HBY.mjs +2 -0
- package/dist/chunk-B7VP6HBY.mjs.map +1 -0
- package/dist/{chunk-R5CS7UZG.mjs → chunk-BYHIHYRR.mjs} +2 -2
- package/dist/{chunk-R5CS7UZG.mjs.map → chunk-BYHIHYRR.mjs.map} +1 -1
- package/dist/chunk-FOPCQGWG.mjs +3 -0
- package/dist/chunk-FOPCQGWG.mjs.map +1 -0
- package/dist/chunk-HLPVL6EK.mjs +2 -0
- package/dist/{chunk-JDTJFAXO.mjs.map → chunk-HLPVL6EK.mjs.map} +1 -1
- package/dist/{chunk-LXXN76HJ.mjs → chunk-KJPIJNFH.mjs} +2 -2
- package/dist/chunk-KJPIJNFH.mjs.map +1 -0
- package/dist/{chunk-GQKN4NPW.mjs → chunk-PVPY55Z7.mjs} +2 -2
- package/dist/{chunk-GQKN4NPW.mjs.map → chunk-PVPY55Z7.mjs.map} +1 -1
- package/dist/chunk-Q7WT5IIF.mjs +3 -0
- package/dist/chunk-Q7WT5IIF.mjs.map +1 -0
- package/dist/chunk-REM6WIZS.mjs +2 -0
- package/dist/chunk-REM6WIZS.mjs.map +1 -0
- package/dist/chunk-RSI6RYJ7.js +2 -0
- package/dist/chunk-RSI6RYJ7.js.map +1 -0
- package/dist/{chunk-RIVNKTUR.js → chunk-WOHSSPKD.js} +2 -2
- package/dist/chunk-WOHSSPKD.js.map +1 -0
- package/dist/{chunk-CBO2X74Q.js → chunk-WXEHDEIH.js} +2 -2
- package/dist/{chunk-CBO2X74Q.js.map → chunk-WXEHDEIH.js.map} +1 -1
- package/dist/chunk-XKPRCSXK.js +3 -0
- package/dist/chunk-XKPRCSXK.js.map +1 -0
- package/dist/{chunk-3P6DMEGB.js → chunk-YDZ37ZZ4.js} +2 -2
- package/dist/{chunk-3P6DMEGB.js.map → chunk-YDZ37ZZ4.js.map} +1 -1
- package/dist/{components-D4WeooPi.d.ts → components-B7KQ8C-i.d.ts} +2 -2
- package/dist/{components-DZy2r6m5.d.cts → components-CxnAnbpI.d.cts} +2 -2
- package/dist/core.d.cts +48 -136
- package/dist/core.d.ts +48 -136
- package/dist/core.js +1 -1
- package/dist/core.mjs +1 -1
- package/dist/dom.d.cts +2 -2
- package/dist/dom.d.ts +2 -2
- package/dist/dom.js +1 -1
- package/dist/dom.js.map +1 -1
- package/dist/dom.mjs +1 -1
- package/dist/dom.mjs.map +1 -1
- package/dist/{effect-BlnnM1t5.d.cts → effect-14CxUU8r.d.cts} +8 -4
- package/dist/{effect-BlnnM1t5.d.ts → effect-14CxUU8r.d.ts} +8 -4
- package/dist/effect-3LUCHSAZ.mjs +2 -0
- package/dist/effect-3LUCHSAZ.mjs.map +1 -0
- package/dist/effect-K45UU3N4.js +2 -0
- package/dist/effect-K45UU3N4.js.map +1 -0
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/index.mjs.map +1 -1
- package/dist/interactive.d.cts +15 -10
- package/dist/interactive.d.ts +15 -10
- package/dist/interactive.js +1 -1
- package/dist/interactive.js.map +1 -1
- package/dist/interactive.mjs +1 -1
- package/dist/interactive.mjs.map +1 -1
- package/dist/metafile-cjs.json +1 -1
- package/dist/metafile-esm.json +1 -1
- package/dist/{owner-Ce7KCWzi.d.cts → owner-QS9tPwPr.d.cts} +1 -8
- package/dist/{owner-Ce7KCWzi.d.ts → owner-QS9tPwPr.d.ts} +1 -8
- package/dist/{portal-C3ESJhlv.d.ts → portal-CVqrpmHd.d.ts} +2 -2
- package/dist/{portal-CAEbiMUZ.d.cts → portal-NLlE-fNZ.d.cts} +2 -2
- package/dist/primitives/layout.js +1 -1
- package/dist/primitives/layout.mjs +1 -1
- package/dist/primitives/motion.js +1 -1
- package/dist/primitives/motion.mjs +1 -1
- package/dist/primitives/ui.d.cts +3 -3
- package/dist/primitives/ui.d.ts +3 -3
- package/dist/primitives/ui.js +1 -1
- package/dist/primitives/ui.js.map +1 -1
- package/dist/primitives/ui.mjs +1 -1
- package/dist/primitives/ui.mjs.map +1 -1
- package/dist/primitives.d.cts +5 -5
- package/dist/primitives.d.ts +5 -5
- package/dist/primitives.js +1 -1
- package/dist/primitives.js.map +1 -1
- package/dist/primitives.mjs +1 -1
- package/dist/primitives.mjs.map +1 -1
- package/dist/router.d.cts +3 -3
- package/dist/router.d.ts +3 -3
- package/dist/router.js +1 -1
- package/dist/router.mjs +1 -1
- package/dist/server.js +1 -1
- package/dist/server.js.map +1 -1
- package/dist/server.mjs +1 -1
- package/dist/server.mjs.map +1 -1
- package/dist/signal-2QUI7H7B.js +2 -0
- package/dist/{signal-AXKUQJVA.js.map → signal-2QUI7H7B.js.map} +1 -1
- package/dist/signal-C6936A3J.d.cts +175 -0
- package/dist/signal-C6936A3J.d.ts +175 -0
- package/dist/signal-L3ZWGOVT.mjs +2 -0
- package/dist/{signal-HM2LG5YL.mjs.map → signal-L3ZWGOVT.mjs.map} +1 -1
- package/dist/test-exports.d.cts +7 -7
- package/dist/test-exports.d.ts +7 -7
- package/dist/test-exports.js +1 -1
- package/dist/test-exports.mjs +1 -1
- package/package.json +2 -1
- package/dist/chunk-6RV7ARJT.mjs +0 -3
- package/dist/chunk-6RV7ARJT.mjs.map +0 -1
- package/dist/chunk-GFL4VRAO.mjs +0 -3
- package/dist/chunk-GFL4VRAO.mjs.map +0 -1
- package/dist/chunk-JDTJFAXO.mjs +0 -2
- package/dist/chunk-LXXN76HJ.mjs.map +0 -1
- package/dist/chunk-MKE3KA43.js +0 -3
- package/dist/chunk-MKE3KA43.js.map +0 -1
- package/dist/chunk-RIVNKTUR.js.map +0 -1
- package/dist/chunk-TQLZ7UZX.js +0 -2
- package/dist/chunk-TQLZ7UZX.js.map +0 -1
- package/dist/chunk-WEYAKKNF.js +0 -3
- package/dist/chunk-WEYAKKNF.js.map +0 -1
- package/dist/chunk-WO6NQ3KR.mjs +0 -3
- package/dist/chunk-WO6NQ3KR.mjs.map +0 -1
- package/dist/chunk-Y4DUMNIW.mjs +0 -2
- package/dist/chunk-Y4DUMNIW.mjs.map +0 -1
- package/dist/chunk-ZG3LULLU.js +0 -3
- package/dist/chunk-ZG3LULLU.js.map +0 -1
- package/dist/signal-AXKUQJVA.js +0 -2
- package/dist/signal-Dxh9PsKr.d.cts +0 -69
- package/dist/signal-Dxh9PsKr.d.ts +0 -69
- package/dist/signal-HM2LG5YL.mjs +0 -2
- /package/dist/{scheduler-Z4QqUDjF.d.cts → sync-Z4QqUDjF.d.cts} +0 -0
- /package/dist/{scheduler-Z4QqUDjF.d.ts → sync-Z4QqUDjF.d.ts} +0 -0
package/dist/server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/server/index.ts"],"names":["VOID_ELEMENTS","renderToString","node","escapeHtml","isSignal","children","result","type","props","html","key","value","styleStr","k","v","str"],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../src/server/index.ts"],"names":["VOID_ELEMENTS","renderToString","node","escapeHtml","isSignal","children","result","type","props","html","key","value","styleStr","k","v","str"],"mappings":"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","file":"server.js","sourcesContent":["import { isSignal } from '../core/signal'\n\nconst VOID_ELEMENTS = new Set([\n 'area',\n 'base',\n 'br',\n 'col',\n 'embed',\n 'hr',\n 'img',\n 'input',\n 'link',\n 'meta',\n 'param',\n 'source',\n 'track',\n 'wbr',\n])\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function renderToString(node: any): string {\n if (node === null || node === undefined || node === false) {\n return ''\n }\n\n if (typeof node === 'string' || typeof node === 'number') {\n return escapeHtml(String(node))\n }\n\n if (Array.isArray(node)) {\n return node.map(renderToString).join('')\n }\n\n if (isSignal(node)) {\n return renderToString(node.value)\n }\n\n // Handle fragments (type === null or type === 'fragment')\n if (node.type === null || node.type === 'fragment') {\n const children = node.children || node.props?.children\n if (children) {\n return Array.isArray(children)\n ? children.map(renderToString).join('')\n : renderToString(children)\n }\n return ''\n }\n\n if (typeof node.type === 'function') {\n const result = node.type({ ...node.props, children: node.children })\n return renderToString(result)\n }\n\n if (typeof node.type === 'string') {\n const { type, props, children } = node\n let html = `<${type}`\n\n if (props) {\n for (const key in props) {\n const value = props[key]\n if (\n key === 'children' ||\n key.startsWith('on') ||\n value === null ||\n value === undefined ||\n value === false\n ) {\n continue\n }\n\n // Security: Validate attribute name to prevent injection\n // Only allow alphanumeric, hyphens, and colons\n if (!/^[a-zA-Z0-9-:]+$/.test(key)) {\n continue\n }\n\n if (key === 'className' || key === 'class') {\n html += ` class=\"${escapeHtml(value)}\"`\n } else if (key === 'style' && typeof value === 'object') {\n const styleStr = Object.entries(value)\n .map(\n ([k, v]) => `${k.replace(/([A-Z])/g, '-$1').toLowerCase()}:${v}`\n )\n .join(';')\n html += ` style=\"${escapeHtml(styleStr)}\"`\n } else {\n html += ` ${key}=\"${escapeHtml(String(value))}\"`\n }\n }\n }\n\n if (VOID_ELEMENTS.has(type)) {\n html += '/>'\n } else {\n html += '>'\n if (children) {\n html += Array.isArray(children)\n ? children.map(renderToString).join('')\n : renderToString(children)\n }\n html += `</${type}>`\n }\n\n return html\n }\n\n return ''\n}\n\nfunction escapeHtml(str: string): string {\n return str\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''')\n}\n"]}
|
package/dist/server.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {f}from'./chunk-B7VP6HBY.mjs';import'./chunk-Q7WT5IIF.mjs';var g=new Set(["area","base","br","col","embed","hr","img","input","link","meta","param","source","track","wbr"]);function s(r){if(r==null||r===false)return "";if(typeof r=="string"||typeof r=="number")return l(String(r));if(Array.isArray(r))return r.map(s).join("");if(f(r))return s(r.value);if(r.type===null||r.type==="fragment"){let t=r.children||r.props?.children;return t?Array.isArray(t)?t.map(s).join(""):s(t):""}if(typeof r.type=="function"){let t=r.type({...r.props,children:r.children});return s(t)}if(typeof r.type=="string"){let{type:t,props:c,children:a}=r,e=`<${t}`;if(c)for(let i in c){let n=c[i];if(!(i==="children"||i.startsWith("on")||n===null||n===void 0||n===false)&&/^[a-zA-Z0-9-:]+$/.test(i))if(i==="className"||i==="class")e+=` class="${l(n)}"`;else if(i==="style"&&typeof n=="object"){let f=Object.entries(n).map(([u,y])=>`${u.replace(/([A-Z])/g,"-$1").toLowerCase()}:${y}`).join(";");e+=` style="${l(f)}"`;}else e+=` ${i}="${l(String(n))}"`;}return g.has(t)?e+="/>":(e+=">",a&&(e+=Array.isArray(a)?a.map(s).join(""):s(a)),e+=`</${t}>`),e}return ""}function l(r){return r.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}export{s as renderToString};//# sourceMappingURL=server.mjs.map
|
|
2
2
|
//# sourceMappingURL=server.mjs.map
|
package/dist/server.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/server/index.ts"],"names":["VOID_ELEMENTS","renderToString","node","escapeHtml","isSignal","children","result","type","props","html","key","value","styleStr","k","v","str"],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../src/server/index.ts"],"names":["VOID_ELEMENTS","renderToString","node","escapeHtml","isSignal","children","result","type","props","html","key","value","styleStr","k","v","str"],"mappings":"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","file":"server.mjs","sourcesContent":["import { isSignal } from '../core/signal'\n\nconst VOID_ELEMENTS = new Set([\n 'area',\n 'base',\n 'br',\n 'col',\n 'embed',\n 'hr',\n 'img',\n 'input',\n 'link',\n 'meta',\n 'param',\n 'source',\n 'track',\n 'wbr',\n])\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function renderToString(node: any): string {\n if (node === null || node === undefined || node === false) {\n return ''\n }\n\n if (typeof node === 'string' || typeof node === 'number') {\n return escapeHtml(String(node))\n }\n\n if (Array.isArray(node)) {\n return node.map(renderToString).join('')\n }\n\n if (isSignal(node)) {\n return renderToString(node.value)\n }\n\n // Handle fragments (type === null or type === 'fragment')\n if (node.type === null || node.type === 'fragment') {\n const children = node.children || node.props?.children\n if (children) {\n return Array.isArray(children)\n ? children.map(renderToString).join('')\n : renderToString(children)\n }\n return ''\n }\n\n if (typeof node.type === 'function') {\n const result = node.type({ ...node.props, children: node.children })\n return renderToString(result)\n }\n\n if (typeof node.type === 'string') {\n const { type, props, children } = node\n let html = `<${type}`\n\n if (props) {\n for (const key in props) {\n const value = props[key]\n if (\n key === 'children' ||\n key.startsWith('on') ||\n value === null ||\n value === undefined ||\n value === false\n ) {\n continue\n }\n\n // Security: Validate attribute name to prevent injection\n // Only allow alphanumeric, hyphens, and colons\n if (!/^[a-zA-Z0-9-:]+$/.test(key)) {\n continue\n }\n\n if (key === 'className' || key === 'class') {\n html += ` class=\"${escapeHtml(value)}\"`\n } else if (key === 'style' && typeof value === 'object') {\n const styleStr = Object.entries(value)\n .map(\n ([k, v]) => `${k.replace(/([A-Z])/g, '-$1').toLowerCase()}:${v}`\n )\n .join(';')\n html += ` style=\"${escapeHtml(styleStr)}\"`\n } else {\n html += ` ${key}=\"${escapeHtml(String(value))}\"`\n }\n }\n }\n\n if (VOID_ELEMENTS.has(type)) {\n html += '/>'\n } else {\n html += '>'\n if (children) {\n html += Array.isArray(children)\n ? children.map(renderToString).join('')\n : renderToString(children)\n }\n html += `</${type}>`\n }\n\n return html\n }\n\n return ''\n}\n\nfunction escapeHtml(str: string): string {\n return str\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''')\n}\n"]}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
'use strict';var chunk5236IK5I_js=require('./chunk-5236IK5I.js');require('./chunk-AJT35P3Z.js');Object.defineProperty(exports,"ComputedNode",{enumerable:true,get:function(){return chunk5236IK5I_js.e}});Object.defineProperty(exports,"SignalNode",{enumerable:true,get:function(){return chunk5236IK5I_js.d}});Object.defineProperty(exports,"createResource",{enumerable:true,get:function(){return chunk5236IK5I_js.h}});Object.defineProperty(exports,"getDevToolsHooks",{enumerable:true,get:function(){return chunk5236IK5I_js.b}});Object.defineProperty(exports,"isSignal",{enumerable:true,get:function(){return chunk5236IK5I_js.f}});Object.defineProperty(exports,"onCleanup",{enumerable:true,get:function(){return chunk5236IK5I_js.g}});Object.defineProperty(exports,"setDevToolsHooks",{enumerable:true,get:function(){return chunk5236IK5I_js.c}});//# sourceMappingURL=signal-2QUI7H7B.js.map
|
|
2
|
+
//# sourceMappingURL=signal-2QUI7H7B.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":[],"names":[],"mappings":"","file":"signal-
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"signal-2QUI7H7B.js"}
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Graph.ts
|
|
3
|
+
*
|
|
4
|
+
* Core Graph Data Structures & Algorithms
|
|
5
|
+
* Implements the "Hardcore" Doubly Linked List for dependency tracking.
|
|
6
|
+
*
|
|
7
|
+
* This module is purely internal and has NO dependencies on other core modules
|
|
8
|
+
* to avoid circular references.
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* Flags for subscriber state (Optimization: Bitmasking)
|
|
12
|
+
*/
|
|
13
|
+
declare const enum SubscriberFlags {
|
|
14
|
+
Running = 1,
|
|
15
|
+
Notified = 2,
|
|
16
|
+
Dirty = 4,
|
|
17
|
+
Stale = 8,
|
|
18
|
+
Tracking = 16
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Node type identifiers for fast type checking (Performance: Avoid instanceof)
|
|
22
|
+
*/
|
|
23
|
+
declare const enum NodeType {
|
|
24
|
+
Signal = 1,
|
|
25
|
+
Computed = 2,
|
|
26
|
+
Effect = 3,
|
|
27
|
+
Resource = 4
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Link node connecting a Subscriber (Effect/Computed) to a Dependency (Signal/Computed).
|
|
31
|
+
*
|
|
32
|
+
* ASCII Visualization of the Doubly Linked Graph:
|
|
33
|
+
*
|
|
34
|
+
* [Signal A] <==> [Link 1] <==> [Effect B]
|
|
35
|
+
* ^
|
|
36
|
+
* | (Prev/Next Sub on Signal A)
|
|
37
|
+
* v
|
|
38
|
+
* [Link 2] <==> [Effect C]
|
|
39
|
+
*
|
|
40
|
+
* Each Link serves as a node in TWO lists simultaneously:
|
|
41
|
+
* 1. The Subscriber's list of dependencies (prevDep/nextDep)
|
|
42
|
+
* 2. The Dependency's list of subscribers (prevSub/nextSub)
|
|
43
|
+
*/
|
|
44
|
+
interface Link {
|
|
45
|
+
dep: IObservable | undefined;
|
|
46
|
+
sub: ISubscriber | undefined;
|
|
47
|
+
prevSub: Link | undefined;
|
|
48
|
+
nextSub: Link | undefined;
|
|
49
|
+
prevDep: Link | undefined;
|
|
50
|
+
nextDep: Link | undefined;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Base interface for subscriber nodes (Effect, Computed)
|
|
54
|
+
*/
|
|
55
|
+
interface ISubscriber {
|
|
56
|
+
execute(): void;
|
|
57
|
+
depsHead: Link | undefined;
|
|
58
|
+
flags: SubscriberFlags;
|
|
59
|
+
nodeType: NodeType;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Base interface for observable nodes (Signal, Computed)
|
|
63
|
+
*/
|
|
64
|
+
interface IObservable {
|
|
65
|
+
subsHead: Link | undefined;
|
|
66
|
+
version: number;
|
|
67
|
+
notify(): void;
|
|
68
|
+
nodeType: NodeType;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Signal System - Fine-grained reactivity without VDOM
|
|
73
|
+
*
|
|
74
|
+
* Architecture:
|
|
75
|
+
* - Signals are reactive primitives that notify subscribers on change
|
|
76
|
+
* - Computed signals automatically track dependencies and memoize results
|
|
77
|
+
* - Effects run side effects and auto-track dependencies
|
|
78
|
+
* - Batching prevents cascading updates for performance
|
|
79
|
+
*/
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Base interface for reactive signals
|
|
83
|
+
* @internal
|
|
84
|
+
*/
|
|
85
|
+
interface Signal<T> {
|
|
86
|
+
value: T;
|
|
87
|
+
(): T;
|
|
88
|
+
set(value: T): void;
|
|
89
|
+
peek(): T;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Computed signal interface (read-only)
|
|
93
|
+
* @internal
|
|
94
|
+
*/
|
|
95
|
+
interface Computed<T> {
|
|
96
|
+
readonly value: T;
|
|
97
|
+
(): T;
|
|
98
|
+
peek(): T;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Internal signal node for writable signals
|
|
102
|
+
*/
|
|
103
|
+
declare class SignalNode<T> implements IObservable {
|
|
104
|
+
private _value;
|
|
105
|
+
version: number;
|
|
106
|
+
nodeType: NodeType;
|
|
107
|
+
subsHead: Link | undefined;
|
|
108
|
+
constructor(_value: T);
|
|
109
|
+
/**
|
|
110
|
+
* Compatibility wrapper for legacy .value access
|
|
111
|
+
*/
|
|
112
|
+
get value(): T;
|
|
113
|
+
set value(newValue: T);
|
|
114
|
+
get(): T;
|
|
115
|
+
set(newValue: T): void;
|
|
116
|
+
peek(): T;
|
|
117
|
+
notify(): void;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Internal computed node for derived values
|
|
121
|
+
*/
|
|
122
|
+
declare class ComputedNode<T> implements ISubscriber, IObservable {
|
|
123
|
+
private computeFn;
|
|
124
|
+
version: number;
|
|
125
|
+
nodeType: NodeType;
|
|
126
|
+
flags: number;
|
|
127
|
+
subsHead: Link | undefined;
|
|
128
|
+
depsHead: Link | undefined;
|
|
129
|
+
private _value;
|
|
130
|
+
private lastCleanEpoch;
|
|
131
|
+
constructor(computeFn: () => T);
|
|
132
|
+
/**
|
|
133
|
+
* Compatibility wrapper for legacy .value access
|
|
134
|
+
*/
|
|
135
|
+
get value(): T;
|
|
136
|
+
execute(): void;
|
|
137
|
+
private _updateIfDirty;
|
|
138
|
+
private _needsRefetch;
|
|
139
|
+
get(): T;
|
|
140
|
+
peek(): T;
|
|
141
|
+
notify(): void;
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Check if a value is a signal
|
|
145
|
+
* @internal Use state() which handles all reactive patterns
|
|
146
|
+
*/
|
|
147
|
+
declare function isSignal(value: unknown): value is SignalNode<any> | ComputedNode<any>;
|
|
148
|
+
/**
|
|
149
|
+
* Registers a cleanup function that runs before the current effect re-runs or is disposed
|
|
150
|
+
*
|
|
151
|
+
* @param fn - Cleanup function
|
|
152
|
+
*/
|
|
153
|
+
declare function onCleanup(fn: () => void): void;
|
|
154
|
+
/**
|
|
155
|
+
* Resource interface for async data
|
|
156
|
+
*/
|
|
157
|
+
interface Resource<T> extends Signal<T | undefined> {
|
|
158
|
+
loading: boolean;
|
|
159
|
+
error: any;
|
|
160
|
+
state: 'unresolved' | 'pending' | 'ready' | 'refreshing' | 'errored';
|
|
161
|
+
latest: T | undefined;
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Creates a resource for handling async data
|
|
165
|
+
* @internal Use state(async () => ...) instead which returns [data, refetch, status, error]
|
|
166
|
+
*/
|
|
167
|
+
declare function createResource<T, S = any>(source: S | Signal<S> | (() => S), fetcher: (source: S, { value, refetching }: {
|
|
168
|
+
value: T | undefined;
|
|
169
|
+
refetching: any;
|
|
170
|
+
}) => Promise<T>): [Resource<T>, {
|
|
171
|
+
mutate: (v: T | undefined) => void;
|
|
172
|
+
refetch: () => void;
|
|
173
|
+
}];
|
|
174
|
+
|
|
175
|
+
export { ComputedNode as C, SignalNode as S, type Signal as a, type Computed as b, createResource as c, isSignal as i, onCleanup as o };
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Graph.ts
|
|
3
|
+
*
|
|
4
|
+
* Core Graph Data Structures & Algorithms
|
|
5
|
+
* Implements the "Hardcore" Doubly Linked List for dependency tracking.
|
|
6
|
+
*
|
|
7
|
+
* This module is purely internal and has NO dependencies on other core modules
|
|
8
|
+
* to avoid circular references.
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* Flags for subscriber state (Optimization: Bitmasking)
|
|
12
|
+
*/
|
|
13
|
+
declare const enum SubscriberFlags {
|
|
14
|
+
Running = 1,
|
|
15
|
+
Notified = 2,
|
|
16
|
+
Dirty = 4,
|
|
17
|
+
Stale = 8,
|
|
18
|
+
Tracking = 16
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Node type identifiers for fast type checking (Performance: Avoid instanceof)
|
|
22
|
+
*/
|
|
23
|
+
declare const enum NodeType {
|
|
24
|
+
Signal = 1,
|
|
25
|
+
Computed = 2,
|
|
26
|
+
Effect = 3,
|
|
27
|
+
Resource = 4
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Link node connecting a Subscriber (Effect/Computed) to a Dependency (Signal/Computed).
|
|
31
|
+
*
|
|
32
|
+
* ASCII Visualization of the Doubly Linked Graph:
|
|
33
|
+
*
|
|
34
|
+
* [Signal A] <==> [Link 1] <==> [Effect B]
|
|
35
|
+
* ^
|
|
36
|
+
* | (Prev/Next Sub on Signal A)
|
|
37
|
+
* v
|
|
38
|
+
* [Link 2] <==> [Effect C]
|
|
39
|
+
*
|
|
40
|
+
* Each Link serves as a node in TWO lists simultaneously:
|
|
41
|
+
* 1. The Subscriber's list of dependencies (prevDep/nextDep)
|
|
42
|
+
* 2. The Dependency's list of subscribers (prevSub/nextSub)
|
|
43
|
+
*/
|
|
44
|
+
interface Link {
|
|
45
|
+
dep: IObservable | undefined;
|
|
46
|
+
sub: ISubscriber | undefined;
|
|
47
|
+
prevSub: Link | undefined;
|
|
48
|
+
nextSub: Link | undefined;
|
|
49
|
+
prevDep: Link | undefined;
|
|
50
|
+
nextDep: Link | undefined;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Base interface for subscriber nodes (Effect, Computed)
|
|
54
|
+
*/
|
|
55
|
+
interface ISubscriber {
|
|
56
|
+
execute(): void;
|
|
57
|
+
depsHead: Link | undefined;
|
|
58
|
+
flags: SubscriberFlags;
|
|
59
|
+
nodeType: NodeType;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Base interface for observable nodes (Signal, Computed)
|
|
63
|
+
*/
|
|
64
|
+
interface IObservable {
|
|
65
|
+
subsHead: Link | undefined;
|
|
66
|
+
version: number;
|
|
67
|
+
notify(): void;
|
|
68
|
+
nodeType: NodeType;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Signal System - Fine-grained reactivity without VDOM
|
|
73
|
+
*
|
|
74
|
+
* Architecture:
|
|
75
|
+
* - Signals are reactive primitives that notify subscribers on change
|
|
76
|
+
* - Computed signals automatically track dependencies and memoize results
|
|
77
|
+
* - Effects run side effects and auto-track dependencies
|
|
78
|
+
* - Batching prevents cascading updates for performance
|
|
79
|
+
*/
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Base interface for reactive signals
|
|
83
|
+
* @internal
|
|
84
|
+
*/
|
|
85
|
+
interface Signal<T> {
|
|
86
|
+
value: T;
|
|
87
|
+
(): T;
|
|
88
|
+
set(value: T): void;
|
|
89
|
+
peek(): T;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Computed signal interface (read-only)
|
|
93
|
+
* @internal
|
|
94
|
+
*/
|
|
95
|
+
interface Computed<T> {
|
|
96
|
+
readonly value: T;
|
|
97
|
+
(): T;
|
|
98
|
+
peek(): T;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Internal signal node for writable signals
|
|
102
|
+
*/
|
|
103
|
+
declare class SignalNode<T> implements IObservable {
|
|
104
|
+
private _value;
|
|
105
|
+
version: number;
|
|
106
|
+
nodeType: NodeType;
|
|
107
|
+
subsHead: Link | undefined;
|
|
108
|
+
constructor(_value: T);
|
|
109
|
+
/**
|
|
110
|
+
* Compatibility wrapper for legacy .value access
|
|
111
|
+
*/
|
|
112
|
+
get value(): T;
|
|
113
|
+
set value(newValue: T);
|
|
114
|
+
get(): T;
|
|
115
|
+
set(newValue: T): void;
|
|
116
|
+
peek(): T;
|
|
117
|
+
notify(): void;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Internal computed node for derived values
|
|
121
|
+
*/
|
|
122
|
+
declare class ComputedNode<T> implements ISubscriber, IObservable {
|
|
123
|
+
private computeFn;
|
|
124
|
+
version: number;
|
|
125
|
+
nodeType: NodeType;
|
|
126
|
+
flags: number;
|
|
127
|
+
subsHead: Link | undefined;
|
|
128
|
+
depsHead: Link | undefined;
|
|
129
|
+
private _value;
|
|
130
|
+
private lastCleanEpoch;
|
|
131
|
+
constructor(computeFn: () => T);
|
|
132
|
+
/**
|
|
133
|
+
* Compatibility wrapper for legacy .value access
|
|
134
|
+
*/
|
|
135
|
+
get value(): T;
|
|
136
|
+
execute(): void;
|
|
137
|
+
private _updateIfDirty;
|
|
138
|
+
private _needsRefetch;
|
|
139
|
+
get(): T;
|
|
140
|
+
peek(): T;
|
|
141
|
+
notify(): void;
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Check if a value is a signal
|
|
145
|
+
* @internal Use state() which handles all reactive patterns
|
|
146
|
+
*/
|
|
147
|
+
declare function isSignal(value: unknown): value is SignalNode<any> | ComputedNode<any>;
|
|
148
|
+
/**
|
|
149
|
+
* Registers a cleanup function that runs before the current effect re-runs or is disposed
|
|
150
|
+
*
|
|
151
|
+
* @param fn - Cleanup function
|
|
152
|
+
*/
|
|
153
|
+
declare function onCleanup(fn: () => void): void;
|
|
154
|
+
/**
|
|
155
|
+
* Resource interface for async data
|
|
156
|
+
*/
|
|
157
|
+
interface Resource<T> extends Signal<T | undefined> {
|
|
158
|
+
loading: boolean;
|
|
159
|
+
error: any;
|
|
160
|
+
state: 'unresolved' | 'pending' | 'ready' | 'refreshing' | 'errored';
|
|
161
|
+
latest: T | undefined;
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Creates a resource for handling async data
|
|
165
|
+
* @internal Use state(async () => ...) instead which returns [data, refetch, status, error]
|
|
166
|
+
*/
|
|
167
|
+
declare function createResource<T, S = any>(source: S | Signal<S> | (() => S), fetcher: (source: S, { value, refetching }: {
|
|
168
|
+
value: T | undefined;
|
|
169
|
+
refetching: any;
|
|
170
|
+
}) => Promise<T>): [Resource<T>, {
|
|
171
|
+
mutate: (v: T | undefined) => void;
|
|
172
|
+
refetch: () => void;
|
|
173
|
+
}];
|
|
174
|
+
|
|
175
|
+
export { ComputedNode as C, SignalNode as S, type Signal as a, type Computed as b, createResource as c, isSignal as i, onCleanup as o };
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export{e as ComputedNode,d as SignalNode,h as createResource,b as getDevToolsHooks,f as isSignal,g as onCleanup,c as setDevToolsHooks}from'./chunk-B7VP6HBY.mjs';import'./chunk-Q7WT5IIF.mjs';//# sourceMappingURL=signal-L3ZWGOVT.mjs.map
|
|
2
|
+
//# sourceMappingURL=signal-L3ZWGOVT.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":[],"names":[],"mappings":"","file":"signal-
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"signal-L3ZWGOVT.mjs"}
|
package/dist/test-exports.d.cts
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
export { c as
|
|
2
|
-
export {
|
|
1
|
+
export { c as createResource, i as isSignal, o as onCleanup } from './signal-C6936A3J.cjs';
|
|
2
|
+
export { e as effect } from './effect-14CxUU8r.cjs';
|
|
3
|
+
export { r as root, u as untrack } from './owner-QS9tPwPr.cjs';
|
|
4
|
+
export { s as sync } from './sync-Z4QqUDjF.cjs';
|
|
3
5
|
export { state } from './core.cjs';
|
|
4
6
|
import { a as FNodeChild } from './renderer-DSLb-FGg.cjs';
|
|
5
|
-
export { h as Link, O as Outlet, g as Route, f as Router, e as createLocation, m as matchPath, r as router } from './components-
|
|
6
|
-
import { L as ListComponent } from './portal-
|
|
7
|
-
export { P as Portal, a as createReactiveRoot, d as domRenderer, f, r as render } from './portal-
|
|
7
|
+
export { h as Link, O as Outlet, g as Route, f as Router, e as createLocation, m as matchPath, r as router } from './components-CxnAnbpI.cjs';
|
|
8
|
+
import { L as ListComponent } from './portal-NLlE-fNZ.cjs';
|
|
9
|
+
export { P as Portal, a as createReactiveRoot, d as domRenderer, f, r as render } from './portal-NLlE-fNZ.cjs';
|
|
8
10
|
export { c as cleanupMotionState } from './Motion-BrOAJzgH.cjs';
|
|
9
|
-
export { e as effect } from './effect-BlnnM1t5.cjs';
|
|
10
|
-
export { o as onMount, r as root, u as untrack } from './owner-Ce7KCWzi.cjs';
|
|
11
11
|
|
|
12
12
|
/** Marker symbol for List components */
|
|
13
13
|
declare const LIST_MARKER: unique symbol;
|
package/dist/test-exports.d.ts
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
export { c as
|
|
2
|
-
export {
|
|
1
|
+
export { c as createResource, i as isSignal, o as onCleanup } from './signal-C6936A3J.js';
|
|
2
|
+
export { e as effect } from './effect-14CxUU8r.js';
|
|
3
|
+
export { r as root, u as untrack } from './owner-QS9tPwPr.js';
|
|
4
|
+
export { s as sync } from './sync-Z4QqUDjF.js';
|
|
3
5
|
export { state } from './core.js';
|
|
4
6
|
import { a as FNodeChild } from './renderer-DSLb-FGg.js';
|
|
5
|
-
export { h as Link, O as Outlet, g as Route, f as Router, e as createLocation, m as matchPath, r as router } from './components-
|
|
6
|
-
import { L as ListComponent } from './portal-
|
|
7
|
-
export { P as Portal, a as createReactiveRoot, d as domRenderer, f, r as render } from './portal-
|
|
7
|
+
export { h as Link, O as Outlet, g as Route, f as Router, e as createLocation, m as matchPath, r as router } from './components-B7KQ8C-i.js';
|
|
8
|
+
import { L as ListComponent } from './portal-CVqrpmHd.js';
|
|
9
|
+
export { P as Portal, a as createReactiveRoot, d as domRenderer, f, r as render } from './portal-CVqrpmHd.js';
|
|
8
10
|
export { c as cleanupMotionState } from './Motion-BrOAJzgH.js';
|
|
9
|
-
export { e as effect } from './effect-BlnnM1t5.js';
|
|
10
|
-
export { o as onMount, r as root, u as untrack } from './owner-Ce7KCWzi.js';
|
|
11
11
|
|
|
12
12
|
/** Marker symbol for List components */
|
|
13
13
|
declare const LIST_MARKER: unique symbol;
|
package/dist/test-exports.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
'use strict';var
|
|
1
|
+
'use strict';var chunkAYQMU7XC_js=require('./chunk-AYQMU7XC.js'),chunkXKPRCSXK_js=require('./chunk-XKPRCSXK.js'),chunkWXEHDEIH_js=require('./chunk-WXEHDEIH.js'),chunkRSI6RYJ7_js=require('./chunk-RSI6RYJ7.js'),chunk63AW5ZOC_js=require('./chunk-63AW5ZOC.js'),chunkQ7IWDVJ4_js=require('./chunk-Q7IWDVJ4.js');require('./chunk-WQFQO5LK.js');var chunk5236IK5I_js=require('./chunk-5236IK5I.js'),chunkAJT35P3Z_js=require('./chunk-AJT35P3Z.js');Object.defineProperty(exports,"Link",{enumerable:true,get:function(){return chunkAYQMU7XC_js.k}});Object.defineProperty(exports,"Outlet",{enumerable:true,get:function(){return chunkAYQMU7XC_js.j}});Object.defineProperty(exports,"Route",{enumerable:true,get:function(){return chunkAYQMU7XC_js.i}});Object.defineProperty(exports,"Router",{enumerable:true,get:function(){return chunkAYQMU7XC_js.h}});Object.defineProperty(exports,"createLocation",{enumerable:true,get:function(){return chunkAYQMU7XC_js.a}});Object.defineProperty(exports,"matchPath",{enumerable:true,get:function(){return chunkAYQMU7XC_js.d}});Object.defineProperty(exports,"router",{enumerable:true,get:function(){return chunkAYQMU7XC_js.g}});Object.defineProperty(exports,"LIST_MARKER",{enumerable:true,get:function(){return chunkXKPRCSXK_js.c}});Object.defineProperty(exports,"Portal",{enumerable:true,get:function(){return chunkXKPRCSXK_js.i}});Object.defineProperty(exports,"createReactiveRoot",{enumerable:true,get:function(){return chunkXKPRCSXK_js.f}});Object.defineProperty(exports,"domRenderer",{enumerable:true,get:function(){return chunkXKPRCSXK_js.b}});Object.defineProperty(exports,"isListComponent",{enumerable:true,get:function(){return chunkXKPRCSXK_js.d}});Object.defineProperty(exports,"render",{enumerable:true,get:function(){return chunkXKPRCSXK_js.g}});Object.defineProperty(exports,"context",{enumerable:true,get:function(){return chunkWXEHDEIH_js.b}});Object.defineProperty(exports,"createContext",{enumerable:true,get:function(){return chunkWXEHDEIH_js.a}});Object.defineProperty(exports,"state",{enumerable:true,get:function(){return chunkRSI6RYJ7_js.h}});Object.defineProperty(exports,"cleanupMotionState",{enumerable:true,get:function(){return chunk63AW5ZOC_js.a}});Object.defineProperty(exports,"f",{enumerable:true,get:function(){return chunkQ7IWDVJ4_js.a}});Object.defineProperty(exports,"createResource",{enumerable:true,get:function(){return chunk5236IK5I_js.h}});Object.defineProperty(exports,"isSignal",{enumerable:true,get:function(){return chunk5236IK5I_js.f}});Object.defineProperty(exports,"onCleanup",{enumerable:true,get:function(){return chunk5236IK5I_js.g}});Object.defineProperty(exports,"sync",{enumerable:true,get:function(){return chunk5236IK5I_js.a}});Object.defineProperty(exports,"effect",{enumerable:true,get:function(){return chunkAJT35P3Z_js.k}});Object.defineProperty(exports,"root",{enumerable:true,get:function(){return chunkAJT35P3Z_js.i}});Object.defineProperty(exports,"untrack",{enumerable:true,get:function(){return chunkAJT35P3Z_js.g}});//# sourceMappingURL=test-exports.js.map
|
|
2
2
|
//# sourceMappingURL=test-exports.js.map
|
package/dist/test-exports.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export{k as Link,j as Outlet,i as Route,h as Router,a as createLocation,d as matchPath,g as router}from'./chunk-
|
|
1
|
+
export{k as Link,j as Outlet,i as Route,h as Router,a as createLocation,d as matchPath,g as router}from'./chunk-3BQXIHYI.mjs';export{c as LIST_MARKER,i as Portal,f as createReactiveRoot,b as domRenderer,d as isListComponent,g as render}from'./chunk-FOPCQGWG.mjs';export{b as context,a as createContext}from'./chunk-HLPVL6EK.mjs';export{h as state}from'./chunk-REM6WIZS.mjs';export{a as cleanupMotionState}from'./chunk-PVPY55Z7.mjs';export{a as f}from'./chunk-WVEJT7HD.mjs';import'./chunk-KNF5ERPK.mjs';export{h as createResource,f as isSignal,g as onCleanup,a as sync}from'./chunk-B7VP6HBY.mjs';export{k as effect,i as root,g as untrack}from'./chunk-Q7WT5IIF.mjs';//# sourceMappingURL=test-exports.mjs.map
|
|
2
2
|
//# sourceMappingURL=test-exports.mjs.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "flexium",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.3",
|
|
4
4
|
"description": "A lightweight, signals-based UI framework with cross-platform renderers",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -155,6 +155,7 @@
|
|
|
155
155
|
"url": "https://github.com/Wick-Lim/flexium.js/issues"
|
|
156
156
|
},
|
|
157
157
|
"devDependencies": {
|
|
158
|
+
"@types/node": "^20.10.0",
|
|
158
159
|
"@typescript-eslint/eslint-plugin": "^6.0.0",
|
|
159
160
|
"@typescript-eslint/parser": "^6.0.0",
|
|
160
161
|
"@vitest/ui": "^1.0.0",
|
package/dist/chunk-6RV7ARJT.mjs
DELETED
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
import {a,b}from'./chunk-JDTJFAXO.mjs';import {c,a as a$1}from'./chunk-WVEJT7HD.mjs';import {k as k$1,l}from'./chunk-GFL4VRAO.mjs';function F(){let t=()=>({pathname:"/",search:"",hash:"",query:{}}),e=()=>typeof window>"u"?t():{pathname:window.location.pathname,search:window.location.search,hash:window.location.hash,query:$(window.location.search)},r=k$1(e()),n=c=>{if(!(typeof window>"u")){if(N(c)){console.error("[Flexium Router] Blocked navigation to unsafe path:",c);return}window.history.pushState({},"",c),r.value=e();}},a=()=>{try{r.value=e();}catch(c){console.error("[Flexium Router] Error handling popstate:",c);}};return typeof window<"u"&&window.addEventListener("popstate",a),[r,n,()=>{typeof window<"u"&&window.removeEventListener("popstate",a);}]}function N(t){let e=t.trim().toLowerCase();return ["javascript:","data:","vbscript:","file:"].some(n=>e.startsWith(n))}function j(t){return t.replace(/<[^>]*>/g,"").replace(/javascript:/gi,"").replace(/on\w+\s*=/gi,"")}var O=new Set(["__proto__","constructor","prototype"]);function $(t){let e=new URLSearchParams(t),r=Object.create(null);return e.forEach((n,a)=>{let i=j(a),c=j(n);i&&!O.has(i)&&(r[i]=c);}),r}function B(t,e){let r=[],n=e.replace(/:([^/]+)/g,(l,h)=>(r.push(h),"([^/]+)")),a=new RegExp(`^${n}$`),i=t.match(a);if(!i)return {matches:false,params:{}};let c={};return i.slice(1).forEach((l,h)=>{c[r[h]]=l;}),{matches:true,params:c}}function k(t){let e=[],r=Array.isArray(t)?t:[t];for(let n of r){if(!c(n))continue;let{path:a,index:i,component:c$1,beforeEnter:l}=n.props,h=n.children;if(!c$1&&!h){console.warn(`[Flexium Router] Route "${a||"(index)"}" has no component and no children. Skipping.`);continue}let R={path:a||"",index:!!i,component:c$1||(()=>null),children:h?k(h):[],beforeEnter:l};e.push(R);}return e}function D(t,e){for(let r of t){let n=S(r,e,"");if(n)return n}return null}function S(t,e,r){let n=r;t.path&&(n=r.replace(/\/$/,"")+"/"+t.path.replace(/^\//,""));let a=t.children.length===0,i=A(n,!a),c=e.match(i);if(c){let[l,...h]=c,R=M(n,h),o={route:t,params:R,pathname:l};if(a)return l===e?[o]:null;for(let f of t.children){let u=S(f,e,n);if(u)return [o,...u]}if(l===e){let f=t.children.find(u=>u.index);return f?[o,{route:f,params:{},pathname:l}]:[o]}}return null}function A(t,e){let r=t.replace(/:([^/]+)/g,()=>"([^/]+)");return r==="/"&&e?new RegExp("^"):new RegExp(`^${r}${e?"(?:/|$)":"$"}`)}function M(t,e){let r={},n=0;return t.replace(/:([^/]+)/g,(a,i)=>(r[i]=e[n++],"")),r}var v=a(null),y=a(0);function V(){let t=b(v);if(!t)throw new Error("router() must be called within a <Router> component");return t}function et(t){let[e,r]=F(),n=Array.isArray(t.children)?t.children:[t.children],a=[],i=[];for(let o of n)c(o)&&typeof o.type=="function"&&o.type===z?i.push(o):a.push(o);let c$1=k(i),l$1=l(()=>{let o=e();return D(c$1,o.pathname)||[]}),h=l(()=>{let o=l$1();return o.length>0?o[o.length-1].params:{}}),R=new Proxy({location:e,params:h,navigate:r,matches:l$1},{get(o,f){let u=o[f];if(f==="location"||f==="params"||f==="matches"){let p=u,_=()=>p.value;return new Proxy(_,{apply(){return p.value},get(b,s){if(s==="value")return p.value;if(s==="peek")return p.peek;if(s===Symbol.toPrimitive||s==="toString"||s==="valueOf")return ()=>p.value;let d=p[s];if(typeof d=="function")return d.bind(p);let g=p.value;if(g!==null&&typeof g=="object"){let C=g[s];return typeof C=="function"?C.bind(g):C}return d},has(b,s){if(s==="value"||s==="peek")return true;let d=p.value;return d!==null&&typeof d=="object"?s in d:s in p},ownKeys(b){let s=p.value;return s!==null&&typeof s=="object"?Reflect.ownKeys(s):[]},getOwnPropertyDescriptor(b,s){let d=p.value;if(d!==null&&typeof d=="object"){let g=Object.getOwnPropertyDescriptor(d,s);if(g)return {...g,configurable:true}}}})}return u}});return ()=>{let o=l$1(),f=null;if(o.length>0){let u=o[0];u.route.beforeEnter?u.route.beforeEnter(u.params)!==false&&(f=a$1(y.Provider,{value:1},[a$1("div",{key:u.route.path,style:{display:"contents"}},[a$1(u.route.component,{params:u.params})])])):f=a$1(y.Provider,{value:1},[a$1("div",{key:u.route.path,style:{display:"contents"}},[a$1(u.route.component,{params:u.params})])]);}return a$1(v.Provider,{value:R},[...a,a$1("main",{id:"main"},[f])])}}function z(t){return null}function nt(){let t=b(v),e=b(y);return t?()=>{let r=t.matches();if(e>=r.length)return null;let n=r[e];if(n.route.beforeEnter&&n.route.beforeEnter(n.params)===false)return null;let a=n.route.component;return a$1(y.Provider,{value:e+1},[a$1(a,{params:n.params})])}:null}function rt(t){let e=V(),r=n=>{n.preventDefault(),e.navigate(t.to);};return a$1("a",{href:t.to,class:t.class,onclick:r},t.children)}
|
|
2
|
-
export{F as a,N as b,j as c,B as d,k as e,D as f,V as g,et as h,z as i,nt as j,rt as k};//# sourceMappingURL=chunk-6RV7ARJT.mjs.map
|
|
3
|
-
//# sourceMappingURL=chunk-6RV7ARJT.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/router/core.ts","../src/router/utils.ts","../src/router/context.ts","../src/router/components.ts"],"names":["createLocation","getDefaultLoc","getLoc","parseQuery","loc","signal","navigate","path","isUnsafePath","handlePopState","error","normalizedPath","protocol","sanitizeQueryValue","value","DANGEROUS_KEYS","search","params","query","key","sanitizedKey","sanitizedValue","matchPath","pathname","routePath","paramNames","regexPath","_","paramName","regex","match","index","createRoutesFromChildren","children","routes","childArray","child","isFNode","component","beforeEnter","nestedChildren","route","matchRoutes","location","result","matchRouteBranch","parentPath","fullPath","isLeaf","matcher","compilePath","matchedPath","paramValues","paramsObj","extractParams","currentMatch","childMatches","indexRoute","c","prefix","values","i","RouterCtx","createContext","RouteDepthCtx","router","ctx","context","Router","props","nonRouteChildren","routeChildren","Route","matches","computed","m","routerContext","target","prop","_target","innerProp","signalProp","currentValue","objProp","desc","ms","matchedContent","rootMatch","f","_props","Outlet","depth","Component","Link","r","handleClick","e"],"mappings":"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","file":"chunk-6RV7ARJT.mjs","sourcesContent":["/**\n * Router Core Module\n *\n * Provides core routing functionality including location management,\n * path matching, and navigation.\n */\n\nimport { signal, Signal } from '../core/signal'\nimport { Location } from './types'\n\n/**\n * Creates a reactive location signal and navigate function.\n *\n * The location signal automatically updates when:\n * - navigate() is called\n * - Browser back/forward buttons are used (popstate event)\n *\n * @returns Tuple of [location signal, navigate function, cleanup function]\n *\n * @example\n * ```tsx\n * const [location, navigate, cleanup] = createLocation();\n * // Access current path\n * console.log(location().pathname);\n * // Navigate to new path\n * navigate('/users/123');\n * // Cleanup when done (removes popstate listener)\n * cleanup();\n * ```\n */\nexport function createLocation(): [Signal<Location>, (path: string) => void, () => void] {\n // SSR guard: return safe defaults on server\n const getDefaultLoc = (): Location => ({\n pathname: '/',\n search: '',\n hash: '',\n query: {},\n })\n\n const getLoc = (): Location => {\n if (typeof window === 'undefined') {\n return getDefaultLoc()\n }\n return {\n pathname: window.location.pathname,\n search: window.location.search,\n hash: window.location.hash,\n query: parseQuery(window.location.search),\n }\n }\n\n const loc = signal(getLoc())\n\n const navigate = (path: string) => {\n // SSR guard\n if (typeof window === 'undefined') return\n\n // Security: Validate path to prevent javascript: and other dangerous protocols\n if (isUnsafePath(path)) {\n console.error('[Flexium Router] Blocked navigation to unsafe path:', path)\n return\n }\n window.history.pushState({}, '', path)\n loc.value = getLoc()\n }\n\n // SSR guard for popstate listener\n const handlePopState = () => {\n try {\n loc.value = getLoc()\n } catch (error) {\n console.error('[Flexium Router] Error handling popstate:', error)\n }\n }\n\n if (typeof window !== 'undefined') {\n window.addEventListener('popstate', handlePopState)\n }\n\n // Cleanup function to remove listener\n const cleanup = () => {\n if (typeof window !== 'undefined') {\n window.removeEventListener('popstate', handlePopState)\n }\n }\n\n return [loc, navigate, cleanup]\n}\n\n/**\n * Check if a path contains unsafe protocols (XSS prevention)\n * @param path - Path to validate\n * @returns true if path is unsafe\n */\nexport function isUnsafePath(path: string): boolean {\n const normalizedPath = path.trim().toLowerCase()\n const unsafeProtocols = ['javascript:', 'data:', 'vbscript:', 'file:']\n return unsafeProtocols.some(protocol => normalizedPath.startsWith(protocol))\n}\n\n/**\n * Sanitize query parameter value to prevent XSS\n * @param value - Query parameter value\n * @returns Sanitized value\n */\nexport function sanitizeQueryValue(value: string): string {\n // Remove potential script tags and event handlers\n return value\n .replace(/<[^>]*>/g, '') // Remove HTML tags\n .replace(/javascript:/gi, '') // Remove javascript: protocol\n .replace(/on\\w+\\s*=/gi, '') // Remove event handlers like onclick=\n}\n\n/**\n * Parses URL search string into key-value object\n * @param search - URL search string (e.g., \"?foo=bar&baz=qux\")\n * @returns Object with query parameters\n */\n// Dangerous keys that could lead to prototype pollution\nconst DANGEROUS_KEYS = new Set(['__proto__', 'constructor', 'prototype'])\n\nfunction parseQuery(search: string): Record<string, string> {\n const params = new URLSearchParams(search)\n // Use Object.create(null) to prevent prototype pollution\n const query: Record<string, string> = Object.create(null)\n params.forEach((value, key) => {\n // Sanitize both key and value to prevent XSS\n const sanitizedKey = sanitizeQueryValue(key)\n const sanitizedValue = sanitizeQueryValue(value)\n // Block dangerous keys to prevent prototype pollution\n if (sanitizedKey && !DANGEROUS_KEYS.has(sanitizedKey)) {\n query[sanitizedKey] = sanitizedValue\n }\n })\n return query\n}\n\n/**\n * Matches a pathname against a route pattern.\n *\n * Supports dynamic segments with `:param` syntax.\n *\n * @param pathname - Current URL pathname (e.g., \"/users/123\")\n * @param routePath - Route pattern (e.g., \"/users/:id\")\n * @returns Object with `matches` boolean and extracted `params`\n *\n * @example\n * ```tsx\n * const result = matchPath('/users/123', '/users/:id');\n * // { matches: true, params: { id: '123' } }\n * ```\n */\nexport function matchPath(\n pathname: string,\n routePath: string\n): { matches: boolean; params: Record<string, string> } {\n const paramNames: string[] = []\n const regexPath = routePath.replace(/:([^/]+)/g, (_, paramName) => {\n paramNames.push(paramName)\n return '([^/]+)'\n })\n\n const regex = new RegExp(`^${regexPath}$`)\n const match = pathname.match(regex)\n\n if (!match) {\n return { matches: false, params: {} }\n }\n\n const params: Record<string, string> = {}\n match.slice(1).forEach((value, index) => {\n params[paramNames[index]] = value\n })\n\n return { matches: true, params }\n}\n","import { RouteDef, RouteMatch } from './types'\nimport type { FNodeChild } from '../core/renderer'\nimport { isFNode } from '../renderers/dom/f'\n\n/**\n * Flatten the children of <Router> or <Route> into a route configuration tree.\n * Note: This assumes `children` are FNodes representing <Route> components.\n */\nexport function createRoutesFromChildren(children: FNodeChild): RouteDef[] {\n const routes: RouteDef[] = []\n\n const childArray = Array.isArray(children) ? children : [children]\n\n for (const child of childArray) {\n if (!isFNode(child)) {\n continue\n }\n\n const { path, index, component, beforeEnter } = child.props as {\n path?: string\n index?: boolean\n component?: Function\n beforeEnter?: (\n params: Record<string, string>\n ) => boolean | Promise<boolean>\n }\n const nestedChildren = child.children\n\n // Skip routes without a component (unless they have children as layout routes)\n if (!component && !nestedChildren) {\n console.warn(\n `[Flexium Router] Route \"${path || '(index)'}\" has no component and no children. Skipping.`\n )\n continue\n }\n\n const route: RouteDef = {\n path: path || '',\n index: !!index,\n component: component || (() => null),\n children: nestedChildren ? createRoutesFromChildren(nestedChildren) : [],\n beforeEnter,\n }\n\n routes.push(route)\n }\n\n return routes\n}\n\n/**\n * Match a URL against a route tree.\n * Returns an array of matches (from root to leaf).\n */\nexport function matchRoutes(\n routes: RouteDef[],\n location: string\n): RouteMatch[] | null {\n for (const route of routes) {\n const result = matchRouteBranch(route, location, '')\n if (result) return result\n }\n return null\n}\n\nfunction matchRouteBranch(\n route: RouteDef,\n location: string,\n parentPath: string\n): RouteMatch[] | null {\n let fullPath = parentPath\n if (route.path) {\n fullPath =\n parentPath.replace(/\\/$/, '') + '/' + route.path.replace(/^\\//, '')\n }\n\n const isLeaf = route.children.length === 0\n const matcher = compilePath(fullPath, !isLeaf)\n const match = location.match(matcher)\n\n if (match) {\n const [matchedPath, ...paramValues] = match\n const paramsObj = extractParams(fullPath, paramValues)\n\n const currentMatch: RouteMatch = {\n route,\n params: paramsObj,\n pathname: matchedPath,\n }\n\n if (isLeaf) {\n // Exact match required for leaf\n if (matchedPath === location) return [currentMatch]\n return null\n }\n\n // Has children: try to match one of them\n // If no children match, and this route is an index route?\n // Or if this route matches partially, maybe an index child matches the rest?\n\n for (const child of route.children) {\n const childMatches = matchRouteBranch(child, location, fullPath)\n if (childMatches) {\n return [currentMatch, ...childMatches]\n }\n }\n\n // If no children matched, but we matched exactly this layout route?\n // E.g. /users matches /users layout, and maybe it renders index?\n if (matchedPath === location) {\n // Check for index route\n const indexRoute = route.children.find((c) => c.index)\n if (indexRoute) {\n return [\n currentMatch,\n { route: indexRoute, params: {}, pathname: matchedPath },\n ]\n }\n // Just the layout? Maybe.\n return [currentMatch]\n }\n }\n\n return null\n}\n\nfunction compilePath(path: string, prefix: boolean): RegExp {\n const regexPath = path.replace(/:([^/]+)/g, () => '([^/]+)')\n\n // If path is exactly \"/\", and we want prefix matching, it should match everything\n if (regexPath === '/' && prefix) {\n return new RegExp('^')\n }\n\n // If prefix matching allowed, ensure we match segment boundary\n return new RegExp(`^${regexPath}${prefix ? '(?:/|$)' : '$'}`)\n}\n\nfunction extractParams(path: string, values: string[]): Record<string, string> {\n const params: Record<string, string> = {}\n let i = 0\n // Re-parse to find param names... inefficient but works\n path.replace(/:([^/]+)/g, (_, paramName) => {\n params[paramName] = values[i++]\n return ''\n })\n return params\n}\n","import { createContext } from '../core/context'\nimport { RouterContext } from './types'\n\n// Global Router Context\nexport const RouterCtx = createContext<RouterContext | null>(null)\n\n// Current Route Depth Context (for Outlet)\n// Stores the index of the current match in the `matches` array\nexport const RouteDepthCtx = createContext<number>(0)\n","import { computed, type Signal, type Computed } from '../core/signal'\nimport { createLocation } from './core'\nimport { createRoutesFromChildren, matchRoutes } from './utils'\nimport { LinkProps, RouteProps, RouterContext } from './types'\nimport { f, isFNode } from '../renderers/dom/f'\nimport { RouterCtx, RouteDepthCtx } from './context'\nimport { context } from '../core/context'\nimport type { FNodeChild } from '../core/renderer'\n\n/**\n * Get the current router context.\n * Must be called within a <Router> component.\n *\n * @example\n * ```tsx\n * const r = router()\n * r.navigate('/dashboard')\n * ```\n */\nexport function router(): RouterContext {\n const ctx = context(RouterCtx)\n if (!ctx) {\n throw new Error('router() must be called within a <Router> component')\n }\n return ctx\n}\n\nexport function Router(props: { children: FNodeChild }) {\n const [location, navigate] = createLocation()\n\n // Separate Route children from non-Route children (like Nav, etc.)\n const childArray = Array.isArray(props.children) ? props.children : [props.children]\n const nonRouteChildren: FNodeChild[] = []\n const routeChildren: FNodeChild[] = []\n\n for (const child of childArray) {\n if (isFNode(child) && typeof child.type === 'function' && child.type === Route) {\n routeChildren.push(child)\n } else {\n nonRouteChildren.push(child)\n }\n }\n\n // Parse route configuration from Route children only\n const routes = createRoutesFromChildren(routeChildren)\n\n // Compute matches\n const matches = computed(() => {\n const loc = location()\n return matchRoutes(routes, loc.pathname) || []\n })\n\n const params = computed(() => {\n const m = matches()\n if (m.length > 0) {\n return m[m.length - 1].params\n }\n return {}\n })\n\n // Create routerContext as a stable object\n // The signals (location, params, matches) are already reactive\n // We create a proxy to ensure property access is properly tracked\n // When accessing location, params, or matches, automatically read the signal's value\n // to register subscriptions (similar to how state() proxy works)\n const routerContext: RouterContext = new Proxy({\n location,\n params,\n navigate,\n matches,\n }, {\n get(target, prop) {\n const value = target[prop as keyof RouterContext]\n \n // For signal/computed properties (location, params, matches),\n // return a proxy that automatically reads the signal's value when properties are accessed\n // This makes router() work like state() - property access triggers tracking\n if (prop === 'location' || prop === 'params' || prop === 'matches') {\n const signal = value as Signal<unknown> | Computed<unknown>\n \n // Create a callable target function (like state proxy does)\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const target = () => signal.value\n \n // Return a proxy that wraps the signal and automatically reads its value\n // when properties are accessed, ensuring subscriptions are registered\n // This follows the same pattern as state() proxy for consistency\n return new Proxy(target, {\n // Make the proxy callable - returns current value\n apply() {\n return signal.value\n },\n \n get(_target, innerProp) {\n // Accessing .value triggers subscription registration via signal's value getter\n if (innerProp === 'value') {\n return signal.value\n }\n \n // Allow direct access to peek() without tracking\n if (innerProp === 'peek') {\n return signal.peek\n }\n \n // Calling as function also triggers subscription\n if (innerProp === Symbol.toPrimitive || innerProp === 'toString' || innerProp === 'valueOf') {\n return () => signal.value\n }\n \n // For other signal properties (set, etc.), access them normally\n const signalProp = (signal as any)[innerProp]\n if (typeof signalProp === 'function') {\n return signalProp.bind(signal)\n }\n \n // If the signal's value is an object, access its properties\n // This enables r.location.pathname and r.params.id to work and register subscriptions\n // Note: accessing signal.value here tracks the signal in any enclosing effect\n const currentValue = signal.value\n if (currentValue !== null && typeof currentValue === 'object') {\n const obj = currentValue as Record<string | symbol, unknown>\n const objProp = obj[innerProp]\n // If it's a function (like array methods), bind it to the current value\n if (typeof objProp === 'function') {\n return objProp.bind(currentValue)\n }\n return objProp\n }\n \n return signalProp\n },\n \n // For property checks (like 'id' in params)\n has(_target, innerProp) {\n if (innerProp === 'value' || innerProp === 'peek') return true\n const currentValue = signal.value\n if (currentValue !== null && typeof currentValue === 'object') {\n return innerProp in (currentValue as object)\n }\n return innerProp in signal\n },\n \n // For Object.keys, for...in loops\n ownKeys(_target) {\n const currentValue = signal.value\n if (currentValue !== null && typeof currentValue === 'object') {\n return Reflect.ownKeys(currentValue as object)\n }\n return []\n },\n \n getOwnPropertyDescriptor(_target, innerProp) {\n const currentValue = signal.value\n if (currentValue !== null && typeof currentValue === 'object') {\n const desc = Object.getOwnPropertyDescriptor(currentValue as object, innerProp)\n if (desc) {\n return { ...desc, configurable: true }\n }\n }\n return undefined\n }\n })\n }\n \n // For navigate, return as-is\n return value\n }\n }) as RouterContext\n\n return () => {\n const ms = matches()\n\n // Matched route component (or null if no match)\n let matchedContent: FNodeChild = null\n if (ms.length > 0) {\n const rootMatch = ms[0]\n\n // Check beforeEnter guard\n if (rootMatch.route.beforeEnter) {\n const result = rootMatch.route.beforeEnter(rootMatch.params)\n if (result !== false) {\n matchedContent = f(RouteDepthCtx.Provider, { value: 1 }, [\n f('div', { key: rootMatch.route.path, style: { display: 'contents' } }, [\n f(rootMatch.route.component, { params: rootMatch.params }),\n ]),\n ])\n }\n } else {\n matchedContent = f(RouteDepthCtx.Provider, { value: 1 }, [\n f('div', { key: rootMatch.route.path, style: { display: 'contents' } }, [\n f(rootMatch.route.component, { params: rootMatch.params }),\n ]),\n ])\n }\n }\n\n // Render non-Route children (like Nav) and the matched route wrapped in main\n return f(RouterCtx.Provider, { value: routerContext }, [\n ...nonRouteChildren,\n f('main', { id: 'main' }, [matchedContent]),\n ])\n }\n}\n\n/**\n * Route configuration component.\n * Doesn't render anything directly; used by Router to build the route tree.\n */\nexport function Route(_props: RouteProps) {\n return null\n}\n\n/**\n * Renders the child route content.\n */\nexport function Outlet() {\n const router = context(RouterCtx)\n const depth = context(RouteDepthCtx) // Default 0\n\n // Safety check\n if (!router) return null\n\n return () => {\n const ms = router.matches()\n\n // Check if we have a match at this depth\n if (depth >= ms.length) return null\n\n const match = ms[depth]\n\n // Check beforeEnter guard\n if (match.route.beforeEnter) {\n const result = match.route.beforeEnter(match.params)\n if (result === false) return null\n }\n\n const Component = match.route.component\n\n // Render component and provide next depth\n return f(RouteDepthCtx.Provider, { value: depth + 1 }, [\n f(Component, { params: match.params }),\n ])\n }\n}\n\nexport function Link(props: LinkProps) {\n const r = router()\n\n const handleClick = (e: Event) => {\n e.preventDefault()\n r.navigate(props.to)\n }\n\n return f(\n 'a',\n {\n href: props.to,\n class: props.class,\n onclick: handleClick,\n },\n props.children\n )\n}\n"]}
|