react-state-basis 0.6.1 → 0.6.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 +31 -29
- package/dist/{chunk-O2ZOR3L2.mjs → chunk-E3D6YEKB.mjs} +32 -24
- package/dist/chunk-E3D6YEKB.mjs.map +1 -0
- package/dist/index.js +83 -52
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +57 -30
- package/dist/index.mjs.map +1 -1
- package/dist/integrations/zustand.js +29 -23
- package/dist/integrations/zustand.js.map +1 -1
- package/dist/integrations/zustand.mjs +1 -1
- package/package.json +2 -1
- package/dist/chunk-O2ZOR3L2.mjs.map +0 -1
package/dist/index.mjs
CHANGED
|
@@ -2,18 +2,20 @@ import {
|
|
|
2
2
|
basis
|
|
3
3
|
} from "./chunk-I5ZFRXQP.mjs";
|
|
4
4
|
import {
|
|
5
|
+
INSTANCE_SEP,
|
|
5
6
|
WINDOW_SIZE,
|
|
6
7
|
beginEffectTracking,
|
|
7
8
|
configureBasis,
|
|
8
9
|
endEffectTracking,
|
|
9
10
|
getBasisMetrics,
|
|
10
11
|
history,
|
|
12
|
+
parseLabel,
|
|
11
13
|
printBasisHealthReport,
|
|
12
14
|
recordUpdate,
|
|
13
15
|
redundantLabels,
|
|
14
16
|
registerVariable,
|
|
15
17
|
unregisterVariable
|
|
16
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-E3D6YEKB.mjs";
|
|
17
19
|
|
|
18
20
|
// src/hooks.ts
|
|
19
21
|
import * as React from "react";
|
|
@@ -33,39 +35,52 @@ import {
|
|
|
33
35
|
} from "react";
|
|
34
36
|
var anonCount = 0;
|
|
35
37
|
var getFallbackLabel = (type) => `anon_${type}_${anonCount++}`;
|
|
38
|
+
var reactUseId = React.useId;
|
|
39
|
+
var legacyInstanceCounter = 0;
|
|
40
|
+
var useInstanceId = () => {
|
|
41
|
+
const [legacyId] = reactUseState(
|
|
42
|
+
() => typeof reactUseId === "function" ? "" : `legacy_${legacyInstanceCounter++}`
|
|
43
|
+
);
|
|
44
|
+
return typeof reactUseId === "function" ? reactUseId() : legacyId;
|
|
45
|
+
};
|
|
46
|
+
var withInstance = (label, instanceId) => `${label}${INSTANCE_SEP}${instanceId}`;
|
|
36
47
|
var React19 = React;
|
|
37
48
|
function useState(initialState, label) {
|
|
38
49
|
const [val, setVal] = reactUseState(initialState);
|
|
39
50
|
const effectiveLabel = reactUseRef(label || getFallbackLabel("state")).current;
|
|
51
|
+
const instanceId = useInstanceId();
|
|
52
|
+
const storageKey = withInstance(effectiveLabel, instanceId);
|
|
40
53
|
reactUseEffect(() => {
|
|
41
|
-
registerVariable(
|
|
54
|
+
registerVariable(storageKey, { role: "local" /* LOCAL */ });
|
|
42
55
|
return () => {
|
|
43
|
-
unregisterVariable(
|
|
56
|
+
unregisterVariable(storageKey);
|
|
44
57
|
};
|
|
45
|
-
}, [
|
|
58
|
+
}, [storageKey]);
|
|
46
59
|
const setter = reactUseCallback((value) => {
|
|
47
|
-
if (recordUpdate(
|
|
60
|
+
if (recordUpdate(storageKey)) {
|
|
48
61
|
setVal(value);
|
|
49
62
|
}
|
|
50
|
-
}, [
|
|
63
|
+
}, [storageKey]);
|
|
51
64
|
return [val, setter];
|
|
52
65
|
}
|
|
53
66
|
function useReducer(reducer, initialArg, init, label) {
|
|
54
67
|
const isLazy = typeof init === "function";
|
|
55
68
|
const providedLabel = label || (typeof init === "string" ? init : void 0);
|
|
56
69
|
const effectiveLabel = reactUseRef(providedLabel || getFallbackLabel("reducer")).current;
|
|
70
|
+
const instanceId = useInstanceId();
|
|
71
|
+
const storageKey = withInstance(effectiveLabel, instanceId);
|
|
57
72
|
const [state, dispatch] = isLazy ? reactUseReducer(reducer, initialArg, init) : reactUseReducer(reducer, initialArg);
|
|
58
73
|
reactUseEffect(() => {
|
|
59
|
-
registerVariable(
|
|
74
|
+
registerVariable(storageKey, { role: "local" /* LOCAL */ });
|
|
60
75
|
return () => {
|
|
61
|
-
unregisterVariable(
|
|
76
|
+
unregisterVariable(storageKey);
|
|
62
77
|
};
|
|
63
|
-
}, [
|
|
78
|
+
}, [storageKey]);
|
|
64
79
|
const basisDispatch = reactUseCallback((action) => {
|
|
65
|
-
if (recordUpdate(
|
|
80
|
+
if (recordUpdate(storageKey)) {
|
|
66
81
|
dispatch(action);
|
|
67
82
|
}
|
|
68
|
-
}, [
|
|
83
|
+
}, [storageKey, dispatch]);
|
|
69
84
|
return [state, basisDispatch];
|
|
70
85
|
}
|
|
71
86
|
function createContext(defaultValue, label) {
|
|
@@ -91,28 +106,34 @@ function useContext(context) {
|
|
|
91
106
|
}
|
|
92
107
|
function useMemo(factory, deps, label) {
|
|
93
108
|
const effectiveLabel = reactUseRef(label || getFallbackLabel("proj")).current;
|
|
109
|
+
const instanceId = useInstanceId();
|
|
110
|
+
const storageKey = withInstance(effectiveLabel, instanceId);
|
|
94
111
|
reactUseEffect(() => {
|
|
95
|
-
registerVariable(
|
|
112
|
+
registerVariable(storageKey, { role: "proj" /* PROJECTION */ });
|
|
96
113
|
return () => {
|
|
97
|
-
unregisterVariable(
|
|
114
|
+
unregisterVariable(storageKey);
|
|
98
115
|
};
|
|
99
|
-
}, [
|
|
116
|
+
}, [storageKey]);
|
|
100
117
|
return reactUseMemo(factory, deps || []);
|
|
101
118
|
}
|
|
102
119
|
function useCallback(callback, deps, label) {
|
|
103
120
|
const effectiveLabel = reactUseRef(label || getFallbackLabel("cb")).current;
|
|
121
|
+
const instanceId = useInstanceId();
|
|
122
|
+
const storageKey = withInstance(effectiveLabel, instanceId);
|
|
104
123
|
reactUseEffect(() => {
|
|
105
|
-
registerVariable(
|
|
124
|
+
registerVariable(storageKey, { role: "proj" /* PROJECTION */ });
|
|
106
125
|
return () => {
|
|
107
|
-
unregisterVariable(
|
|
126
|
+
unregisterVariable(storageKey);
|
|
108
127
|
};
|
|
109
|
-
}, [
|
|
128
|
+
}, [storageKey]);
|
|
110
129
|
return reactUseCallback(callback, deps);
|
|
111
130
|
}
|
|
112
131
|
function useEffect(effect, deps, label) {
|
|
113
132
|
const effectiveLabel = label || "anonymous_effect";
|
|
133
|
+
const instanceId = useInstanceId();
|
|
134
|
+
const storageKey = withInstance(effectiveLabel, instanceId);
|
|
114
135
|
reactUseEffect(() => {
|
|
115
|
-
beginEffectTracking(
|
|
136
|
+
beginEffectTracking(storageKey);
|
|
116
137
|
const destructor = effect();
|
|
117
138
|
endEffectTracking();
|
|
118
139
|
return typeof destructor === "function" ? destructor : void 0;
|
|
@@ -120,8 +141,10 @@ function useEffect(effect, deps, label) {
|
|
|
120
141
|
}
|
|
121
142
|
function useLayoutEffect(effect, deps, label) {
|
|
122
143
|
const effectiveLabel = label || "anonymous_layout_effect";
|
|
144
|
+
const instanceId = useInstanceId();
|
|
145
|
+
const storageKey = withInstance(effectiveLabel, instanceId);
|
|
123
146
|
reactUseLayoutEffect(() => {
|
|
124
|
-
beginEffectTracking(
|
|
147
|
+
beginEffectTracking(storageKey);
|
|
125
148
|
const destructor = effect();
|
|
126
149
|
endEffectTracking();
|
|
127
150
|
return typeof destructor === "function" ? destructor : void 0;
|
|
@@ -129,36 +152,40 @@ function useLayoutEffect(effect, deps, label) {
|
|
|
129
152
|
}
|
|
130
153
|
function useOptimistic(passthrough, reducer, label) {
|
|
131
154
|
const effectiveLabel = reactUseRef(label || getFallbackLabel("optimistic")).current;
|
|
155
|
+
const instanceId = useInstanceId();
|
|
156
|
+
const storageKey = withInstance(effectiveLabel, instanceId);
|
|
132
157
|
reactUseEffect(() => {
|
|
133
|
-
registerVariable(
|
|
158
|
+
registerVariable(storageKey, { role: "local" /* LOCAL */ });
|
|
134
159
|
return () => {
|
|
135
|
-
unregisterVariable(
|
|
160
|
+
unregisterVariable(storageKey);
|
|
136
161
|
};
|
|
137
|
-
}, [
|
|
162
|
+
}, [storageKey]);
|
|
138
163
|
const [state, reactAddOptimistic] = React19.useOptimistic(passthrough, reducer);
|
|
139
164
|
const addOptimistic = reactUseCallback((payload) => {
|
|
140
|
-
if (recordUpdate(
|
|
165
|
+
if (recordUpdate(storageKey)) {
|
|
141
166
|
reactAddOptimistic(payload);
|
|
142
167
|
}
|
|
143
|
-
}, [
|
|
168
|
+
}, [storageKey, reactAddOptimistic]);
|
|
144
169
|
return [state, addOptimistic];
|
|
145
170
|
}
|
|
146
171
|
function useActionState(action, initialState, permalink, label) {
|
|
147
172
|
const isLabelArg = typeof permalink === "string" && label === void 0;
|
|
148
173
|
const effectiveLabel = reactUseRef(isLabelArg ? permalink : label || getFallbackLabel("action_state")).current;
|
|
149
174
|
const actualPermalink = isLabelArg ? void 0 : permalink;
|
|
175
|
+
const instanceId = useInstanceId();
|
|
176
|
+
const storageKey = withInstance(effectiveLabel, instanceId);
|
|
150
177
|
const [state, reactDispatch, isPending] = React19.useActionState(action, initialState, actualPermalink);
|
|
151
178
|
reactUseEffect(() => {
|
|
152
|
-
registerVariable(
|
|
179
|
+
registerVariable(storageKey, { role: "local" /* LOCAL */ });
|
|
153
180
|
return () => {
|
|
154
|
-
unregisterVariable(
|
|
181
|
+
unregisterVariable(storageKey);
|
|
155
182
|
};
|
|
156
|
-
}, [
|
|
183
|
+
}, [storageKey]);
|
|
157
184
|
const basisDispatch = reactUseCallback((payload) => {
|
|
158
|
-
if (recordUpdate(
|
|
185
|
+
if (recordUpdate(storageKey)) {
|
|
159
186
|
reactDispatch(payload);
|
|
160
187
|
}
|
|
161
|
-
}, [
|
|
188
|
+
}, [storageKey, reactDispatch]);
|
|
162
189
|
return [state, basisDispatch, isPending];
|
|
163
190
|
}
|
|
164
191
|
var useRef = reactUseRef;
|
|
@@ -313,7 +340,7 @@ function renderMatrix(ctx, entries) {
|
|
|
313
340
|
};
|
|
314
341
|
for (let i = head; i < L; i++) addToPath(buffer[i], uiPos++);
|
|
315
342
|
for (let i = 0; i < head; i++) addToPath(buffer[i], uiPos++);
|
|
316
|
-
const stateName = label.
|
|
343
|
+
const stateName = parseLabel(label).name;
|
|
317
344
|
const textX = L * colW + pad + 10;
|
|
318
345
|
ctx.fillStyle = isContext ? HUD_THEME.header : isRedundant ? HUD_THEME.error : HUD_THEME.text;
|
|
319
346
|
const prefix = meta.role === "store" ? "\u03A3 " : isContext ? "\u03A9 " : isRedundant ? "! " : "";
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/hooks.ts","../src/context.tsx","../src/ui/BasisHUD.tsx","../src/ui/config.ts"],"sourcesContent":["// src/hooks.ts\n\nimport * as React from 'react';\nimport {\n useState as reactUseState,\n useEffect as reactUseEffect,\n useMemo as reactUseMemo,\n useReducer as reactUseReducer,\n useContext as reactUseContext,\n useSyncExternalStore as reactUseSyncExternalStore,\n createContext as reactCreateContext,\n useRef as reactUseRef,\n useLayoutEffect as reactUseLayoutEffect,\n useCallback as reactUseCallback,\n useTransition as reactUseTransition,\n useDeferredValue as reactUseDeferredValue,\n} from 'react';\n\nimport {\n registerVariable,\n unregisterVariable,\n recordUpdate,\n beginEffectTracking,\n endEffectTracking,\n history as engineHistory\n} from './engine';\nimport { SignalRole } from './core/types';\n\n// --- Internal Type Helpers ---\n\nlet anonCount = 0;\nconst getFallbackLabel = (type: string) => `anon_${type}_${anonCount++}`;\n\n/**\n * Standard React Reducer type inference helpers.\n */\ntype GetReducerState<R extends React.Reducer<any, any>> = R extends React.Reducer<infer S, any> ? S : never;\ntype GetReducerAction<R extends React.Reducer<any, any>> = R extends React.Reducer<any, infer A> ? A : never;\n\ninterface BasisContext<T> extends React.Context<T> {\n _basis_label?: string;\n}\n\n/**\n * React 19 Type Definitions for strictness.\n */\ninterface React19Extended {\n useOptimistic<S, P>(passthrough: S, reducer?: (state: S, payload: P) => S): [S, (payload: P) => void];\n useActionState<State, Payload>(\n action: (state: State, payload: Payload) => Promise<State> | State,\n initialState: State,\n permalink?: string\n ): [state: State, dispatch: (payload: Payload) => void, isPending: boolean];\n use<T>(usable: React.Usable<T>): T;\n}\n\nconst React19 = React as unknown as React19Extended;\n\n// --- useState ---\n\nexport function useState<S>(\n initialState: S | (() => S),\n label?: string\n): [S, React.Dispatch<React.SetStateAction<S>>] {\n const [val, setVal] = reactUseState(initialState);\n const effectiveLabel = reactUseRef(label || getFallbackLabel('state')).current;\n\n reactUseEffect(() => {\n registerVariable(effectiveLabel, { role: SignalRole.LOCAL });\n return () => { unregisterVariable(effectiveLabel); };\n }, [effectiveLabel]);\n\n const setter = reactUseCallback((value: React.SetStateAction<S>) => {\n if (recordUpdate(effectiveLabel)) {\n setVal(value);\n }\n }, [effectiveLabel]);\n\n return [val, setter];\n}\n\n// --- useReducer ---\n\n/**\n * PUBLIC OVERLOAD: Lazy initialization\n */\nexport function useReducer<R extends React.Reducer<any, any>, I>(\n reducer: R,\n initializerArg: I,\n initializer: (arg: I) => GetReducerState<R>,\n label?: string\n): [GetReducerState<R>, React.Dispatch<GetReducerAction<R>>];\n\n/**\n * PUBLIC OVERLOAD: Direct initialization\n */\nexport function useReducer<R extends React.Reducer<any, any>>(\n reducer: R,\n initialState: GetReducerState<R>,\n initializer?: undefined,\n label?: string\n): [GetReducerState<R>, React.Dispatch<GetReducerAction<R>>];\n\n/**\n * FINAL IMPLEMENTATION\n */\nexport function useReducer<R extends React.Reducer<any, any>, I>(\n reducer: R,\n initialArg: I | GetReducerState<R>,\n init?: ((arg: I) => GetReducerState<R>) | string,\n label?: string\n): [GetReducerState<R>, React.Dispatch<GetReducerAction<R>>] {\n const isLazy = typeof init === 'function';\n\n // v0.5.x Label Extraction: prioritize 4th arg, fallback to 3rd if string (Babel behavior)\n const providedLabel = label || (typeof init === 'string' ? init : undefined);\n const effectiveLabel = reactUseRef(providedLabel || getFallbackLabel('reducer')).current;\n\n const [state, dispatch] = isLazy\n ? reactUseReducer(reducer, initialArg as I, init as (arg: I) => GetReducerState<R>)\n : reactUseReducer(reducer, initialArg as GetReducerState<R>);\n\n reactUseEffect(() => {\n registerVariable(effectiveLabel, { role: SignalRole.LOCAL });\n return () => { unregisterVariable(effectiveLabel); };\n }, [effectiveLabel]);\n\n const basisDispatch = reactUseCallback((action: GetReducerAction<R>) => {\n if (recordUpdate(effectiveLabel)) {\n dispatch(action);\n }\n }, [effectiveLabel, dispatch]);\n\n return [state, basisDispatch];\n}\n\n// --- Context ---\n\nexport function createContext<T>(defaultValue: T, label?: string): React.Context<T> {\n const context = reactCreateContext(defaultValue) as BasisContext<T>;\n const effectiveLabel = label || getFallbackLabel('context');\n\n // Use non-enumerable property to store the Basis label\n Object.defineProperty(context, '_basis_label', {\n value: effectiveLabel,\n writable: false,\n enumerable: false\n });\n\n return context;\n}\n\nexport function useContext<T>(context: React.Context<T>): T {\n const val = reactUseContext(context);\n const label = (context as BasisContext<T>)._basis_label;\n\n reactUseLayoutEffect(() => {\n if (label) {\n registerVariable(label, { role: SignalRole.CONTEXT });\n recordUpdate(label);\n }\n }, [val, label]);\n\n return val;\n}\n\n// --- Projections ---\n\nexport function useMemo<T>(factory: () => T, deps: React.DependencyList | undefined, label?: string): T {\n const effectiveLabel = reactUseRef(label || getFallbackLabel('proj')).current;\n reactUseEffect(() => {\n registerVariable(effectiveLabel, { role: SignalRole.PROJECTION });\n return () => { unregisterVariable(effectiveLabel); };\n }, [effectiveLabel]);\n return reactUseMemo(factory, deps || []);\n}\n\nexport function useCallback<T extends (...args: unknown[]) => unknown>(callback: T, deps: React.DependencyList, label?: string): T {\n const effectiveLabel = reactUseRef(label || getFallbackLabel('cb')).current;\n reactUseEffect(() => {\n registerVariable(effectiveLabel, { role: SignalRole.PROJECTION });\n return () => { unregisterVariable(effectiveLabel); };\n }, [effectiveLabel]);\n return reactUseCallback(callback, deps);\n}\n\n// --- Effects ---\n\nexport function useEffect(effect: React.EffectCallback, deps?: React.DependencyList, label?: string): void {\n const effectiveLabel = label || 'anonymous_effect';\n reactUseEffect(() => {\n beginEffectTracking(effectiveLabel);\n const destructor = effect();\n endEffectTracking();\n return typeof destructor === 'function' ? destructor : undefined;\n }, deps);\n}\n\nexport function useLayoutEffect(effect: React.EffectCallback, deps?: React.DependencyList, label?: string): void {\n const effectiveLabel = label || 'anonymous_layout_effect';\n reactUseLayoutEffect(() => {\n beginEffectTracking(effectiveLabel);\n const destructor = effect();\n endEffectTracking();\n return typeof destructor === 'function' ? destructor : undefined;\n }, deps);\n}\n\n// --- React 19 ---\n\nexport function useOptimistic<S, P>(\n passthrough: S,\n reducer?: (state: S, payload: P) => S,\n label?: string\n): [S, (payload: P) => void] {\n const effectiveLabel = reactUseRef(label || getFallbackLabel('optimistic')).current;\n reactUseEffect(() => {\n registerVariable(effectiveLabel, { role: SignalRole.LOCAL });\n return () => { unregisterVariable(effectiveLabel); };\n }, [effectiveLabel]);\n\n const [state, reactAddOptimistic] = React19.useOptimistic(passthrough, reducer);\n\n const addOptimistic = reactUseCallback((payload: P) => {\n if (recordUpdate(effectiveLabel)) {\n reactAddOptimistic(payload);\n }\n }, [effectiveLabel, reactAddOptimistic]);\n\n return [state, addOptimistic];\n}\n\nexport function useActionState<State, Payload>(\n action: (state: State, payload: Payload) => Promise<State> | State,\n initialState: State,\n permalink?: string,\n label?: string\n): [state: State, dispatch: (payload: Payload) => void, isPending: boolean] {\n\n const isLabelArg = typeof permalink === 'string' && label === undefined;\n const effectiveLabel = reactUseRef(isLabelArg ? (permalink as string) : (label || getFallbackLabel('action_state'))).current;\n const actualPermalink = isLabelArg ? undefined : permalink;\n\n const [state, reactDispatch, isPending] = React19.useActionState(action, initialState, actualPermalink);\n\n reactUseEffect(() => {\n registerVariable(effectiveLabel, { role: SignalRole.LOCAL });\n return () => { unregisterVariable(effectiveLabel); };\n }, [effectiveLabel]);\n\n const basisDispatch = reactUseCallback((payload: Payload) => {\n if (recordUpdate(effectiveLabel)) {\n reactDispatch(payload);\n }\n }, [effectiveLabel, reactDispatch]);\n\n return [state, basisDispatch, isPending];\n}\n\n// --- Direct Exports ---\nexport const useRef = reactUseRef;\nexport const useId = React.useId;\nexport const useDebugValue = React.useDebugValue;\nexport const useImperativeHandle = React.useImperativeHandle;\nexport const useInsertionEffect = React.useInsertionEffect;\nexport const useSyncExternalStore = reactUseSyncExternalStore;\nexport const useTransition = reactUseTransition;\nexport const useDeferredValue = reactUseDeferredValue;\nexport const use = React19.use;\n\nexport const __test__ = {\n registerVariable,\n history: engineHistory,\n unregisterVariable,\n recordUpdate,\n beginEffectTracking,\n endEffectTracking\n};\n","// src/context.tsx\n\nimport React, { createContext, useContext, ReactNode, useLayoutEffect } from 'react';\nimport { configureBasis } from './engine';\nimport { BasisHUD } from './ui/BasisHUD';\n\nconst BasisContext = createContext({ debug: false });\nconst isWeb = typeof window !== 'undefined' && typeof window.document !== 'undefined';\n\ninterface BasisProviderProps {\n children: ReactNode;\n debug?: boolean;\n showHUD?: boolean;\n}\n\nexport const BasisProvider: React.FC<BasisProviderProps> = ({\n children,\n debug = true,\n showHUD = true\n}) => {\n useLayoutEffect(() => {\n configureBasis({ debug });\n if (isWeb) {\n (window as any)._basis_debug = debug;\n }\n }, [debug]);\n\n return (\n <BasisContext.Provider value={{ debug }}>\n {children}\n\n {(debug && showHUD && isWeb) && <BasisHUD />}\n </BasisContext.Provider>\n );\n};\n\nexport const useBasisConfig = () => useContext(BasisContext);","// src/ui/BasisHUD.tsx\n\nimport React, { useEffect, useRef, useState } from 'react';\nimport { history, redundantLabels } from '../engine';\nimport { HUD_DIMENSIONS as DIM, getHUDContainerStyle, HUD_THEME as THEME } from './config';\n\nexport const BasisHUD: React.FC = () => {\n const [isExpanded, setIsExpanded] = useState(false);\n const canvasRef = useRef<HTMLCanvasElement>(null);\n\n useEffect(() => {\n if (!isExpanded) return;\n\n let isMounted = true;\n let animationFrame: number | null = null;\n\n const draw = () => {\n if (!isMounted) {\n if (animationFrame !== null) {\n cancelAnimationFrame(animationFrame);\n }\n return;\n }\n\n const canvas = canvasRef.current;\n if (!canvas) return;\n const ctx = canvas.getContext('2d');\n if (!ctx) return;\n\n const entries = Array.from(history.entries()).sort((a, b) => {\n const roleOrder = (role: string) => {\n if (role === 'context') return 0;\n if (role === 'store') return 1;\n return 2;\n };\n return roleOrder(a[1].role) - roleOrder(b[1].role);\n });\n const dpr = window.devicePixelRatio || 1;\n const rawWidth = DIM.WINDOW_SIZE * DIM.COL_WIDTH + DIM.LABEL_WIDTH + DIM.PADDING * 2;\n const rawHeight = Math.max(entries.length * DIM.ROW_HEIGHT + DIM.PADDING * 2, 80);\n\n updateCanvasSize(canvas, rawWidth, rawHeight, dpr);\n ctx.save();\n ctx.scale(dpr, dpr);\n ctx.clearRect(0, 0, rawWidth, rawHeight);\n\n if (entries.length === 0) renderEmptyState(ctx);\n else renderMatrix(ctx, entries);\n\n ctx.restore();\n animationFrame = requestAnimationFrame(draw);\n };\n\n // Kick off the animation loop\n animationFrame = requestAnimationFrame(draw);\n\n return () => {\n isMounted = false;\n if (animationFrame !== null) {\n cancelAnimationFrame(animationFrame);\n }\n };\n }, [isExpanded]);\n\n return (\n <div style={getHUDContainerStyle(isExpanded)} onClick={() => setIsExpanded(!isExpanded)}>\n <HUDHeader isExpanded={isExpanded} />\n {isExpanded && (\n <div style={{ padding: '10px 14px 15px 14px' }}>\n <canvas ref={canvasRef} style={{ display: 'block' }} />\n </div>\n )}\n </div>\n );\n};\n\nfunction updateCanvasSize(canvas: HTMLCanvasElement, w: number, h: number, dpr: number) {\n const targetW = Math.floor(w * dpr);\n const targetH = Math.floor(h * dpr);\n if (canvas.width !== targetW || canvas.height !== targetH) {\n canvas.width = targetW;\n canvas.height = targetH;\n canvas.style.width = `${w}px`;\n canvas.style.height = `${h}px`;\n }\n}\n\nfunction renderEmptyState(ctx: CanvasRenderingContext2D) {\n ctx.fillStyle = THEME.textDim;\n ctx.font = '11px Inter, sans-serif';\n ctx.fillText('Waiting for state transitions...', DIM.PADDING, 30);\n}\n\nfunction renderMatrix(ctx: CanvasRenderingContext2D, entries: [string, any][]) {\n const L = DIM.WINDOW_SIZE;\n const colW = DIM.COL_WIDTH;\n const rowH = DIM.ROW_HEIGHT;\n const pad = DIM.PADDING;\n const cellW = colW - 1.5;\n const cellH = rowH - 4;\n\n const gridPath = new Path2D();\n const successPath = new Path2D();\n const contextPath = new Path2D();\n const errorPath = new Path2D();\n\n ctx.font = \"11px Inter, Menlo, monospace\";\n\n let rowIndex = 0;\n for (const [label, meta] of entries) {\n const y = rowIndex * rowH + pad;\n const isContext = meta.role === 'context' || meta.role === 'store';\n const isRedundant = !isContext && redundantLabels.has(label);\n\n const { buffer, head } = meta;\n let uiPos = 0;\n\n const addToPath = (val: number, xIdx: number) => {\n const x = xIdx * colW + pad;\n if (val === 1) {\n if (isContext) contextPath.rect(x, y, cellW, cellH);\n else if (isRedundant) errorPath.rect(x, y, cellW, cellH);\n else successPath.rect(x, y, cellW, cellH);\n } else {\n gridPath.rect(x, y, cellW, cellH);\n }\n };\n\n for (let i = head; i < L; i++) addToPath(buffer[i], uiPos++);\n for (let i = 0; i < head; i++) addToPath(buffer[i], uiPos++);\n\n const stateName = label.split(' -> ')[1] || label;\n const textX = (L * colW) + pad + 10;\n\n ctx.fillStyle = isContext ? THEME.header : (isRedundant ? THEME.error : THEME.text);\n const prefix = meta.role === 'store' ? \"Σ \" : isContext ? \"Ω \" : isRedundant ? \"! \" : \"\";\n ctx.fillText(prefix + stateName, textX, y + 9);\n\n rowIndex++;\n }\n\n ctx.fillStyle = THEME.grid; ctx.fill(gridPath);\n ctx.fillStyle = THEME.success; ctx.fill(successPath);\n ctx.fillStyle = THEME.header; ctx.fill(contextPath);\n ctx.fillStyle = THEME.error; ctx.fill(errorPath);\n}\n\nconst HUDHeader: React.FC<{ isExpanded: boolean }> = ({ isExpanded }) => (\n <div\n style={{\n padding: '10px 14px',\n backgroundColor: isExpanded ? THEME.header : 'transparent',\n color: isExpanded ? 'white' : THEME.header,\n fontWeight: 600,\n fontSize: '11px',\n letterSpacing: '0.05em',\n display: 'flex',\n justifyContent: 'space-between',\n alignItems: 'center',\n transition: 'background 0.3s',\n }}\n >\n <span>{isExpanded ? 'STATE BASIS MATRIX' : '📐 BASIS ACTIVE'}</span>\n {isExpanded && <span style={{ opacity: 0.8, fontSize: '9px' }}>v0.6.x</span>}\n </div>\n);","// src/ui/config.ts\n\nimport { WINDOW_SIZE } from '../core/constants';\n\nexport const HUD_DIMENSIONS = {\n WINDOW_SIZE,\n ROW_HEIGHT: 16,\n COL_WIDTH: 5,\n LABEL_WIDTH: 100,\n PADDING: 10,\n RADIUS: 1.5,\n};\n\nexport const HUD_THEME = {\n bg: 'rgba(15, 23, 42, 0.95)',\n border: '#334155',\n header: '#8b5cf6',\n text: '#f1f5f9',\n textDim: '#94a3b8',\n success: '#10b981',\n error: '#ef4444',\n grid: '#1e293b',\n};\n\nexport const getHUDContainerStyle = (isExpanded: boolean): React.CSSProperties => ({\n position: 'fixed',\n bottom: '20px',\n right: '20px',\n backgroundColor: HUD_THEME.bg,\n border: `1px solid ${HUD_THEME.border}`,\n borderRadius: '12px',\n backdropFilter: 'blur(8px)',\n boxShadow: '0 10px 25px -5px rgba(0, 0, 0, 0.3), 0 8px 10px -6px rgba(0, 0, 0, 0.3)',\n zIndex: 999999,\n overflow: 'hidden',\n width: isExpanded ? '380px' : '130px',\n transition: 'all 0.3s cubic-bezier(0.4, 0, 0.2, 1)',\n cursor: 'pointer',\n userSelect: 'none',\n WebkitUserSelect: 'none'\n});"],"mappings":"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","names":["useId","useDebugValue","useImperativeHandle","useInsertionEffect","createContext","useContext","useLayoutEffect","useEffect","useRef","useState","useState","useRef","useEffect","jsx","jsxs","createContext","useLayoutEffect","useContext"]}
|
|
1
|
+
{"version":3,"sources":["../src/hooks.ts","../src/context.tsx","../src/ui/BasisHUD.tsx","../src/ui/config.ts"],"sourcesContent":["// src/hooks.ts\n\nimport * as React from 'react';\nimport {\n useState as reactUseState,\n useEffect as reactUseEffect,\n useMemo as reactUseMemo,\n useReducer as reactUseReducer,\n useContext as reactUseContext,\n useSyncExternalStore as reactUseSyncExternalStore,\n createContext as reactCreateContext,\n useRef as reactUseRef,\n useLayoutEffect as reactUseLayoutEffect,\n useCallback as reactUseCallback,\n useTransition as reactUseTransition,\n useDeferredValue as reactUseDeferredValue,\n} from 'react';\n\nimport {\n registerVariable,\n unregisterVariable,\n recordUpdate,\n beginEffectTracking,\n endEffectTracking,\n history as engineHistory\n} from './engine';\nimport { SignalRole } from './core/types';\nimport { INSTANCE_SEP } from './core/constants';\n\n// --- Internal Type Helpers ---\n\nlet anonCount = 0;\nconst getFallbackLabel = (type: string) => `anon_${type}_${anonCount++}`;\n\nconst reactUseId = (React as unknown as { useId?: () => string }).useId;\nlet legacyInstanceCounter = 0;\n\nconst useInstanceId = (): string => {\n const [legacyId] = reactUseState(() =>\n typeof reactUseId === 'function' ? '' : `legacy_${legacyInstanceCounter++}`\n );\n return typeof reactUseId === 'function' ? reactUseId() : legacyId;\n};\n\nconst withInstance = (label: string, instanceId: string) =>\n `${label}${INSTANCE_SEP}${instanceId}`;\n\n/**\n * Standard React Reducer type inference helpers.\n */\ntype GetReducerState<R extends React.Reducer<any, any>> = R extends React.Reducer<infer S, any> ? S : never;\ntype GetReducerAction<R extends React.Reducer<any, any>> = R extends React.Reducer<any, infer A> ? A : never;\n\ninterface BasisContext<T> extends React.Context<T> {\n _basis_label?: string;\n}\n\n/**\n * React 19 Type Definitions for strictness.\n */\ninterface React19Extended {\n useOptimistic<S, P>(passthrough: S, reducer?: (state: S, payload: P) => S): [S, (payload: P) => void];\n useActionState<State, Payload>(\n action: (state: State, payload: Payload) => Promise<State> | State,\n initialState: State,\n permalink?: string\n ): [state: State, dispatch: (payload: Payload) => void, isPending: boolean];\n use<T>(usable: React.Usable<T>): T;\n}\n\nconst React19 = React as unknown as React19Extended;\n\n// --- useState ---\n\nexport function useState<S>(\n initialState: S | (() => S),\n label?: string\n): [S, React.Dispatch<React.SetStateAction<S>>] {\n const [val, setVal] = reactUseState(initialState);\n const effectiveLabel = reactUseRef(label || getFallbackLabel('state')).current;\n const instanceId = useInstanceId();\n const storageKey = withInstance(effectiveLabel, instanceId);\n\n reactUseEffect(() => {\n registerVariable(storageKey, { role: SignalRole.LOCAL });\n return () => { unregisterVariable(storageKey); };\n }, [storageKey]);\n\n const setter = reactUseCallback((value: React.SetStateAction<S>) => {\n if (recordUpdate(storageKey)) {\n setVal(value);\n }\n }, [storageKey]);\n\n return [val, setter];\n}\n\n// --- useReducer ---\n\n/**\n * PUBLIC OVERLOAD: Lazy initialization\n */\nexport function useReducer<R extends React.Reducer<any, any>, I>(\n reducer: R,\n initializerArg: I,\n initializer: (arg: I) => GetReducerState<R>,\n label?: string\n): [GetReducerState<R>, React.Dispatch<GetReducerAction<R>>];\n\n/**\n * PUBLIC OVERLOAD: Direct initialization\n */\nexport function useReducer<R extends React.Reducer<any, any>>(\n reducer: R,\n initialState: GetReducerState<R>,\n initializer?: undefined,\n label?: string\n): [GetReducerState<R>, React.Dispatch<GetReducerAction<R>>];\n\n/**\n * FINAL IMPLEMENTATION\n */\nexport function useReducer<R extends React.Reducer<any, any>, I>(\n reducer: R,\n initialArg: I | GetReducerState<R>,\n init?: ((arg: I) => GetReducerState<R>) | string,\n label?: string\n): [GetReducerState<R>, React.Dispatch<GetReducerAction<R>>] {\n const isLazy = typeof init === 'function';\n\n // v0.5.x Label Extraction: prioritize 4th arg, fallback to 3rd if string (Babel behavior)\n const providedLabel = label || (typeof init === 'string' ? init : undefined);\n const effectiveLabel = reactUseRef(providedLabel || getFallbackLabel('reducer')).current;\n const instanceId = useInstanceId();\n const storageKey = withInstance(effectiveLabel, instanceId);\n\n const [state, dispatch] = isLazy\n ? reactUseReducer(reducer, initialArg as I, init as (arg: I) => GetReducerState<R>)\n : reactUseReducer(reducer, initialArg as GetReducerState<R>);\n\n reactUseEffect(() => {\n registerVariable(storageKey, { role: SignalRole.LOCAL });\n return () => { unregisterVariable(storageKey); };\n }, [storageKey]);\n\n const basisDispatch = reactUseCallback((action: GetReducerAction<R>) => {\n if (recordUpdate(storageKey)) {\n dispatch(action);\n }\n }, [storageKey, dispatch]);\n\n return [state, basisDispatch];\n}\n\n// --- Context ---\n\nexport function createContext<T>(defaultValue: T, label?: string): React.Context<T> {\n const context = reactCreateContext(defaultValue) as BasisContext<T>;\n const effectiveLabel = label || getFallbackLabel('context');\n\n // Use non-enumerable property to store the Basis label\n Object.defineProperty(context, '_basis_label', {\n value: effectiveLabel,\n writable: false,\n enumerable: false\n });\n\n return context;\n}\n\nexport function useContext<T>(context: React.Context<T>): T {\n const val = reactUseContext(context);\n const label = (context as BasisContext<T>)._basis_label;\n\n reactUseLayoutEffect(() => {\n if (label) {\n registerVariable(label, { role: SignalRole.CONTEXT });\n recordUpdate(label);\n }\n }, [val, label]);\n\n return val;\n}\n\n// --- Projections ---\n\nexport function useMemo<T>(factory: () => T, deps: React.DependencyList | undefined, label?: string): T {\n const effectiveLabel = reactUseRef(label || getFallbackLabel('proj')).current;\n const instanceId = useInstanceId();\n const storageKey = withInstance(effectiveLabel, instanceId);\n reactUseEffect(() => {\n registerVariable(storageKey, { role: SignalRole.PROJECTION });\n return () => { unregisterVariable(storageKey); };\n }, [storageKey]);\n return reactUseMemo(factory, deps || []);\n}\n\nexport function useCallback<T extends (...args: unknown[]) => unknown>(callback: T, deps: React.DependencyList, label?: string): T {\n const effectiveLabel = reactUseRef(label || getFallbackLabel('cb')).current;\n const instanceId = useInstanceId();\n const storageKey = withInstance(effectiveLabel, instanceId);\n reactUseEffect(() => {\n registerVariable(storageKey, { role: SignalRole.PROJECTION });\n return () => { unregisterVariable(storageKey); };\n }, [storageKey]);\n return reactUseCallback(callback, deps);\n}\n\n// --- Effects ---\n\nexport function useEffect(effect: React.EffectCallback, deps?: React.DependencyList, label?: string): void {\n const effectiveLabel = label || 'anonymous_effect';\n const instanceId = useInstanceId();\n const storageKey = withInstance(effectiveLabel, instanceId);\n reactUseEffect(() => {\n beginEffectTracking(storageKey);\n const destructor = effect();\n endEffectTracking();\n return typeof destructor === 'function' ? destructor : undefined;\n }, deps);\n}\n\nexport function useLayoutEffect(effect: React.EffectCallback, deps?: React.DependencyList, label?: string): void {\n const effectiveLabel = label || 'anonymous_layout_effect';\n const instanceId = useInstanceId();\n const storageKey = withInstance(effectiveLabel, instanceId);\n reactUseLayoutEffect(() => {\n beginEffectTracking(storageKey);\n const destructor = effect();\n endEffectTracking();\n return typeof destructor === 'function' ? destructor : undefined;\n }, deps);\n}\n\n// --- React 19 ---\n\nexport function useOptimistic<S, P>(\n passthrough: S,\n reducer?: (state: S, payload: P) => S,\n label?: string\n): [S, (payload: P) => void] {\n const effectiveLabel = reactUseRef(label || getFallbackLabel('optimistic')).current;\n const instanceId = useInstanceId();\n const storageKey = withInstance(effectiveLabel, instanceId);\n reactUseEffect(() => {\n registerVariable(storageKey, { role: SignalRole.LOCAL });\n return () => { unregisterVariable(storageKey); };\n }, [storageKey]);\n\n const [state, reactAddOptimistic] = React19.useOptimistic(passthrough, reducer);\n\n const addOptimistic = reactUseCallback((payload: P) => {\n if (recordUpdate(storageKey)) {\n reactAddOptimistic(payload);\n }\n }, [storageKey, reactAddOptimistic]);\n\n return [state, addOptimistic];\n}\n\nexport function useActionState<State, Payload>(\n action: (state: State, payload: Payload) => Promise<State> | State,\n initialState: State,\n permalink?: string,\n label?: string\n): [state: State, dispatch: (payload: Payload) => void, isPending: boolean] {\n\n const isLabelArg = typeof permalink === 'string' && label === undefined;\n const effectiveLabel = reactUseRef(isLabelArg ? (permalink as string) : (label || getFallbackLabel('action_state'))).current;\n const actualPermalink = isLabelArg ? undefined : permalink;\n const instanceId = useInstanceId();\n const storageKey = withInstance(effectiveLabel, instanceId);\n\n const [state, reactDispatch, isPending] = React19.useActionState(action, initialState, actualPermalink);\n\n reactUseEffect(() => {\n registerVariable(storageKey, { role: SignalRole.LOCAL });\n return () => { unregisterVariable(storageKey); };\n }, [storageKey]);\n\n const basisDispatch = reactUseCallback((payload: Payload) => {\n if (recordUpdate(storageKey)) {\n reactDispatch(payload);\n }\n }, [storageKey, reactDispatch]);\n\n return [state, basisDispatch, isPending];\n}\n\n// --- Direct Exports ---\nexport const useRef = reactUseRef;\nexport const useId = React.useId;\nexport const useDebugValue = React.useDebugValue;\nexport const useImperativeHandle = React.useImperativeHandle;\nexport const useInsertionEffect = React.useInsertionEffect;\nexport const useSyncExternalStore = reactUseSyncExternalStore;\nexport const useTransition = reactUseTransition;\nexport const useDeferredValue = reactUseDeferredValue;\nexport const use = React19.use;\n\nexport const __test__ = {\n registerVariable,\n history: engineHistory,\n unregisterVariable,\n recordUpdate,\n beginEffectTracking,\n endEffectTracking\n};","// src/context.tsx\n\nimport React, { createContext, useContext, ReactNode, useLayoutEffect } from 'react';\nimport { configureBasis } from './engine';\nimport { BasisHUD } from './ui/BasisHUD';\n\nconst BasisContext = createContext({ debug: false });\nconst isWeb = typeof window !== 'undefined' && typeof window.document !== 'undefined';\n\ninterface BasisProviderProps {\n children: ReactNode;\n debug?: boolean;\n showHUD?: boolean;\n}\n\nexport const BasisProvider: React.FC<BasisProviderProps> = ({\n children,\n debug = true,\n showHUD = true\n}) => {\n useLayoutEffect(() => {\n configureBasis({ debug });\n if (isWeb) {\n (window as any)._basis_debug = debug;\n }\n }, [debug]);\n\n return (\n <BasisContext.Provider value={{ debug }}>\n {children}\n\n {(debug && showHUD && isWeb) && <BasisHUD />}\n </BasisContext.Provider>\n );\n};\n\nexport const useBasisConfig = () => useContext(BasisContext);","// src/ui/BasisHUD.tsx\n\nimport React, { useEffect, useRef, useState } from 'react';\nimport { history, redundantLabels } from '../engine';\nimport { HUD_DIMENSIONS as DIM, getHUDContainerStyle, HUD_THEME as THEME } from './config';\nimport { parseLabel } from '../core/label';\n\nexport const BasisHUD: React.FC = () => {\n const [isExpanded, setIsExpanded] = useState(false);\n const canvasRef = useRef<HTMLCanvasElement>(null);\n\n useEffect(() => {\n if (!isExpanded) return;\n\n let isMounted = true;\n let animationFrame: number | null = null;\n\n const draw = () => {\n if (!isMounted) {\n if (animationFrame !== null) {\n cancelAnimationFrame(animationFrame);\n }\n return;\n }\n\n const canvas = canvasRef.current;\n if (!canvas) return;\n const ctx = canvas.getContext('2d');\n if (!ctx) return;\n\n const entries = Array.from(history.entries()).sort((a, b) => {\n const roleOrder = (role: string) => {\n if (role === 'context') return 0;\n if (role === 'store') return 1;\n return 2;\n };\n return roleOrder(a[1].role) - roleOrder(b[1].role);\n });\n const dpr = window.devicePixelRatio || 1;\n const rawWidth = DIM.WINDOW_SIZE * DIM.COL_WIDTH + DIM.LABEL_WIDTH + DIM.PADDING * 2;\n const rawHeight = Math.max(entries.length * DIM.ROW_HEIGHT + DIM.PADDING * 2, 80);\n\n updateCanvasSize(canvas, rawWidth, rawHeight, dpr);\n ctx.save();\n ctx.scale(dpr, dpr);\n ctx.clearRect(0, 0, rawWidth, rawHeight);\n\n if (entries.length === 0) renderEmptyState(ctx);\n else renderMatrix(ctx, entries);\n\n ctx.restore();\n animationFrame = requestAnimationFrame(draw);\n };\n\n // Kick off the animation loop\n animationFrame = requestAnimationFrame(draw);\n\n return () => {\n isMounted = false;\n if (animationFrame !== null) {\n cancelAnimationFrame(animationFrame);\n }\n };\n }, [isExpanded]);\n\n return (\n <div style={getHUDContainerStyle(isExpanded)} onClick={() => setIsExpanded(!isExpanded)}>\n <HUDHeader isExpanded={isExpanded} />\n {isExpanded && (\n <div style={{ padding: '10px 14px 15px 14px' }}>\n <canvas ref={canvasRef} style={{ display: 'block' }} />\n </div>\n )}\n </div>\n );\n};\n\nfunction updateCanvasSize(canvas: HTMLCanvasElement, w: number, h: number, dpr: number) {\n const targetW = Math.floor(w * dpr);\n const targetH = Math.floor(h * dpr);\n if (canvas.width !== targetW || canvas.height !== targetH) {\n canvas.width = targetW;\n canvas.height = targetH;\n canvas.style.width = `${w}px`;\n canvas.style.height = `${h}px`;\n }\n}\n\nfunction renderEmptyState(ctx: CanvasRenderingContext2D) {\n ctx.fillStyle = THEME.textDim;\n ctx.font = '11px Inter, sans-serif';\n ctx.fillText('Waiting for state transitions...', DIM.PADDING, 30);\n}\n\nfunction renderMatrix(ctx: CanvasRenderingContext2D, entries: [string, any][]) {\n const L = DIM.WINDOW_SIZE;\n const colW = DIM.COL_WIDTH;\n const rowH = DIM.ROW_HEIGHT;\n const pad = DIM.PADDING;\n const cellW = colW - 1.5;\n const cellH = rowH - 4;\n\n const gridPath = new Path2D();\n const successPath = new Path2D();\n const contextPath = new Path2D();\n const errorPath = new Path2D();\n\n ctx.font = \"11px Inter, Menlo, monospace\";\n\n let rowIndex = 0;\n for (const [label, meta] of entries) {\n const y = rowIndex * rowH + pad;\n const isContext = meta.role === 'context' || meta.role === 'store';\n const isRedundant = !isContext && redundantLabels.has(label);\n\n const { buffer, head } = meta;\n let uiPos = 0;\n\n const addToPath = (val: number, xIdx: number) => {\n const x = xIdx * colW + pad;\n if (val === 1) {\n if (isContext) contextPath.rect(x, y, cellW, cellH);\n else if (isRedundant) errorPath.rect(x, y, cellW, cellH);\n else successPath.rect(x, y, cellW, cellH);\n } else {\n gridPath.rect(x, y, cellW, cellH);\n }\n };\n\n for (let i = head; i < L; i++) addToPath(buffer[i], uiPos++);\n for (let i = 0; i < head; i++) addToPath(buffer[i], uiPos++);\n\n const stateName = parseLabel(label).name;\n const textX = (L * colW) + pad + 10;\n\n ctx.fillStyle = isContext ? THEME.header : (isRedundant ? THEME.error : THEME.text);\n const prefix = meta.role === 'store' ? \"Σ \" : isContext ? \"Ω \" : isRedundant ? \"! \" : \"\";\n ctx.fillText(prefix + stateName, textX, y + 9);\n\n rowIndex++;\n }\n\n ctx.fillStyle = THEME.grid; ctx.fill(gridPath);\n ctx.fillStyle = THEME.success; ctx.fill(successPath);\n ctx.fillStyle = THEME.header; ctx.fill(contextPath);\n ctx.fillStyle = THEME.error; ctx.fill(errorPath);\n}\n\nconst HUDHeader: React.FC<{ isExpanded: boolean }> = ({ isExpanded }) => (\n <div\n style={{\n padding: '10px 14px',\n backgroundColor: isExpanded ? THEME.header : 'transparent',\n color: isExpanded ? 'white' : THEME.header,\n fontWeight: 600,\n fontSize: '11px',\n letterSpacing: '0.05em',\n display: 'flex',\n justifyContent: 'space-between',\n alignItems: 'center',\n transition: 'background 0.3s',\n }}\n >\n <span>{isExpanded ? 'STATE BASIS MATRIX' : '📐 BASIS ACTIVE'}</span>\n {isExpanded && <span style={{ opacity: 0.8, fontSize: '9px' }}>v0.6.x</span>}\n </div>\n);","// src/ui/config.ts\n\nimport { WINDOW_SIZE } from '../core/constants';\n\nexport const HUD_DIMENSIONS = {\n WINDOW_SIZE,\n ROW_HEIGHT: 16,\n COL_WIDTH: 5,\n LABEL_WIDTH: 100,\n PADDING: 10,\n RADIUS: 1.5,\n};\n\nexport const HUD_THEME = {\n bg: 'rgba(15, 23, 42, 0.95)',\n border: '#334155',\n header: '#8b5cf6',\n text: '#f1f5f9',\n textDim: '#94a3b8',\n success: '#10b981',\n error: '#ef4444',\n grid: '#1e293b',\n};\n\nexport const getHUDContainerStyle = (isExpanded: boolean): React.CSSProperties => ({\n position: 'fixed',\n bottom: '20px',\n right: '20px',\n backgroundColor: HUD_THEME.bg,\n border: `1px solid ${HUD_THEME.border}`,\n borderRadius: '12px',\n backdropFilter: 'blur(8px)',\n boxShadow: '0 10px 25px -5px rgba(0, 0, 0, 0.3), 0 8px 10px -6px rgba(0, 0, 0, 0.3)',\n zIndex: 999999,\n overflow: 'hidden',\n width: isExpanded ? '380px' : '130px',\n transition: 'all 0.3s cubic-bezier(0.4, 0, 0.2, 1)',\n cursor: 'pointer',\n userSelect: 'none',\n WebkitUserSelect: 'none'\n});"],"mappings":";;;;;;;;;;;;;;;;;;;;AAEA,YAAY,WAAW;AACvB;AAAA,EACE,YAAY;AAAA,EACZ,aAAa;AAAA,EACb,WAAW;AAAA,EACX,cAAc;AAAA,EACd,cAAc;AAAA,EACd,wBAAwB;AAAA,EACxB,iBAAiB;AAAA,EACjB,UAAU;AAAA,EACV,mBAAmB;AAAA,EACnB,eAAe;AAAA,EACf,iBAAiB;AAAA,EACjB,oBAAoB;AAAA,OACf;AAeP,IAAI,YAAY;AAChB,IAAM,mBAAmB,CAAC,SAAiB,QAAQ,IAAI,IAAI,WAAW;AAEtE,IAAM,aAA4D;AAClE,IAAI,wBAAwB;AAE5B,IAAM,gBAAgB,MAAc;AAClC,QAAM,CAAC,QAAQ,IAAI;AAAA,IAAc,MAC/B,OAAO,eAAe,aAAa,KAAK,UAAU,uBAAuB;AAAA,EAC3E;AACA,SAAO,OAAO,eAAe,aAAa,WAAW,IAAI;AAC3D;AAEA,IAAM,eAAe,CAAC,OAAe,eACnC,GAAG,KAAK,GAAG,YAAY,GAAG,UAAU;AAyBtC,IAAM,UAAU;AAIT,SAAS,SACd,cACA,OAC8C;AAC9C,QAAM,CAAC,KAAK,MAAM,IAAI,cAAc,YAAY;AAChD,QAAM,iBAAiB,YAAY,SAAS,iBAAiB,OAAO,CAAC,EAAE;AACvE,QAAM,aAAa,cAAc;AACjC,QAAM,aAAa,aAAa,gBAAgB,UAAU;AAE1D,iBAAe,MAAM;AACnB,qBAAiB,YAAY,EAAE,0BAAuB,CAAC;AACvD,WAAO,MAAM;AAAE,yBAAmB,UAAU;AAAA,IAAG;AAAA,EACjD,GAAG,CAAC,UAAU,CAAC;AAEf,QAAM,SAAS,iBAAiB,CAAC,UAAmC;AAClE,QAAI,aAAa,UAAU,GAAG;AAC5B,aAAO,KAAK;AAAA,IACd;AAAA,EACF,GAAG,CAAC,UAAU,CAAC;AAEf,SAAO,CAAC,KAAK,MAAM;AACrB;AA2BO,SAAS,WACd,SACA,YACA,MACA,OAC2D;AAC3D,QAAM,SAAS,OAAO,SAAS;AAG/B,QAAM,gBAAgB,UAAU,OAAO,SAAS,WAAW,OAAO;AAClE,QAAM,iBAAiB,YAAY,iBAAiB,iBAAiB,SAAS,CAAC,EAAE;AACjF,QAAM,aAAa,cAAc;AACjC,QAAM,aAAa,aAAa,gBAAgB,UAAU;AAE1D,QAAM,CAAC,OAAO,QAAQ,IAAI,SACtB,gBAAgB,SAAS,YAAiB,IAAsC,IAChF,gBAAgB,SAAS,UAAgC;AAE7D,iBAAe,MAAM;AACnB,qBAAiB,YAAY,EAAE,0BAAuB,CAAC;AACvD,WAAO,MAAM;AAAE,yBAAmB,UAAU;AAAA,IAAG;AAAA,EACjD,GAAG,CAAC,UAAU,CAAC;AAEf,QAAM,gBAAgB,iBAAiB,CAAC,WAAgC;AACtE,QAAI,aAAa,UAAU,GAAG;AAC5B,eAAS,MAAM;AAAA,IACjB;AAAA,EACF,GAAG,CAAC,YAAY,QAAQ,CAAC;AAEzB,SAAO,CAAC,OAAO,aAAa;AAC9B;AAIO,SAAS,cAAiB,cAAiB,OAAkC;AAClF,QAAM,UAAU,mBAAmB,YAAY;AAC/C,QAAM,iBAAiB,SAAS,iBAAiB,SAAS;AAG1D,SAAO,eAAe,SAAS,gBAAgB;AAAA,IAC7C,OAAO;AAAA,IACP,UAAU;AAAA,IACV,YAAY;AAAA,EACd,CAAC;AAED,SAAO;AACT;AAEO,SAAS,WAAc,SAA8B;AAC1D,QAAM,MAAM,gBAAgB,OAAO;AACnC,QAAM,QAAS,QAA4B;AAE3C,uBAAqB,MAAM;AACzB,QAAI,OAAO;AACT,uBAAiB,OAAO,EAAE,8BAAyB,CAAC;AACpD,mBAAa,KAAK;AAAA,IACpB;AAAA,EACF,GAAG,CAAC,KAAK,KAAK,CAAC;AAEf,SAAO;AACT;AAIO,SAAS,QAAW,SAAkB,MAAwC,OAAmB;AACtG,QAAM,iBAAiB,YAAY,SAAS,iBAAiB,MAAM,CAAC,EAAE;AACtE,QAAM,aAAa,cAAc;AACjC,QAAM,aAAa,aAAa,gBAAgB,UAAU;AAC1D,iBAAe,MAAM;AACnB,qBAAiB,YAAY,EAAE,8BAA4B,CAAC;AAC5D,WAAO,MAAM;AAAE,yBAAmB,UAAU;AAAA,IAAG;AAAA,EACjD,GAAG,CAAC,UAAU,CAAC;AACf,SAAO,aAAa,SAAS,QAAQ,CAAC,CAAC;AACzC;AAEO,SAAS,YAAuD,UAAa,MAA4B,OAAmB;AACjI,QAAM,iBAAiB,YAAY,SAAS,iBAAiB,IAAI,CAAC,EAAE;AACpE,QAAM,aAAa,cAAc;AACjC,QAAM,aAAa,aAAa,gBAAgB,UAAU;AAC1D,iBAAe,MAAM;AACnB,qBAAiB,YAAY,EAAE,8BAA4B,CAAC;AAC5D,WAAO,MAAM;AAAE,yBAAmB,UAAU;AAAA,IAAG;AAAA,EACjD,GAAG,CAAC,UAAU,CAAC;AACf,SAAO,iBAAiB,UAAU,IAAI;AACxC;AAIO,SAAS,UAAU,QAA8B,MAA6B,OAAsB;AACzG,QAAM,iBAAiB,SAAS;AAChC,QAAM,aAAa,cAAc;AACjC,QAAM,aAAa,aAAa,gBAAgB,UAAU;AAC1D,iBAAe,MAAM;AACnB,wBAAoB,UAAU;AAC9B,UAAM,aAAa,OAAO;AAC1B,sBAAkB;AAClB,WAAO,OAAO,eAAe,aAAa,aAAa;AAAA,EACzD,GAAG,IAAI;AACT;AAEO,SAAS,gBAAgB,QAA8B,MAA6B,OAAsB;AAC/G,QAAM,iBAAiB,SAAS;AAChC,QAAM,aAAa,cAAc;AACjC,QAAM,aAAa,aAAa,gBAAgB,UAAU;AAC1D,uBAAqB,MAAM;AACzB,wBAAoB,UAAU;AAC9B,UAAM,aAAa,OAAO;AAC1B,sBAAkB;AAClB,WAAO,OAAO,eAAe,aAAa,aAAa;AAAA,EACzD,GAAG,IAAI;AACT;AAIO,SAAS,cACd,aACA,SACA,OAC2B;AAC3B,QAAM,iBAAiB,YAAY,SAAS,iBAAiB,YAAY,CAAC,EAAE;AAC5E,QAAM,aAAa,cAAc;AACjC,QAAM,aAAa,aAAa,gBAAgB,UAAU;AAC1D,iBAAe,MAAM;AACnB,qBAAiB,YAAY,EAAE,0BAAuB,CAAC;AACvD,WAAO,MAAM;AAAE,yBAAmB,UAAU;AAAA,IAAG;AAAA,EACjD,GAAG,CAAC,UAAU,CAAC;AAEf,QAAM,CAAC,OAAO,kBAAkB,IAAI,QAAQ,cAAc,aAAa,OAAO;AAE9E,QAAM,gBAAgB,iBAAiB,CAAC,YAAe;AACrD,QAAI,aAAa,UAAU,GAAG;AAC5B,yBAAmB,OAAO;AAAA,IAC5B;AAAA,EACF,GAAG,CAAC,YAAY,kBAAkB,CAAC;AAEnC,SAAO,CAAC,OAAO,aAAa;AAC9B;AAEO,SAAS,eACd,QACA,cACA,WACA,OAC0E;AAE1E,QAAM,aAAa,OAAO,cAAc,YAAY,UAAU;AAC9D,QAAM,iBAAiB,YAAY,aAAc,YAAwB,SAAS,iBAAiB,cAAc,CAAE,EAAE;AACrH,QAAM,kBAAkB,aAAa,SAAY;AACjD,QAAM,aAAa,cAAc;AACjC,QAAM,aAAa,aAAa,gBAAgB,UAAU;AAE1D,QAAM,CAAC,OAAO,eAAe,SAAS,IAAI,QAAQ,eAAe,QAAQ,cAAc,eAAe;AAEtG,iBAAe,MAAM;AACnB,qBAAiB,YAAY,EAAE,0BAAuB,CAAC;AACvD,WAAO,MAAM;AAAE,yBAAmB,UAAU;AAAA,IAAG;AAAA,EACjD,GAAG,CAAC,UAAU,CAAC;AAEf,QAAM,gBAAgB,iBAAiB,CAAC,YAAqB;AAC3D,QAAI,aAAa,UAAU,GAAG;AAC5B,oBAAc,OAAO;AAAA,IACvB;AAAA,EACF,GAAG,CAAC,YAAY,aAAa,CAAC;AAE9B,SAAO,CAAC,OAAO,eAAe,SAAS;AACzC;AAGO,IAAM,SAAS;AACf,IAAMA,SAAc;AACpB,IAAMC,iBAAsB;AAC5B,IAAMC,uBAA4B;AAClC,IAAMC,sBAA2B;AACjC,IAAM,uBAAuB;AAC7B,IAAM,gBAAgB;AACtB,IAAM,mBAAmB;AACzB,IAAM,MAAM,QAAQ;;;ACxS3B,SAAgB,iBAAAC,gBAAe,cAAAC,aAAuB,mBAAAC,wBAAuB;;;ACA7E,SAAgB,aAAAC,YAAW,UAAAC,SAAQ,YAAAC,iBAAgB;;;ACE5C,IAAM,iBAAiB;AAAA,EAC5B;AAAA,EACA,YAAY;AAAA,EACZ,WAAW;AAAA,EACX,aAAa;AAAA,EACb,SAAS;AAAA,EACT,QAAQ;AACV;AAEO,IAAM,YAAY;AAAA,EACvB,IAAI;AAAA,EACJ,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,MAAM;AAAA,EACN,SAAS;AAAA,EACT,SAAS;AAAA,EACT,OAAO;AAAA,EACP,MAAM;AACR;AAEO,IAAM,uBAAuB,CAAC,gBAA8C;AAAA,EACjF,UAAU;AAAA,EACV,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,iBAAiB,UAAU;AAAA,EAC3B,QAAQ,aAAa,UAAU,MAAM;AAAA,EACrC,cAAc;AAAA,EACd,gBAAgB;AAAA,EAChB,WAAW;AAAA,EACX,QAAQ;AAAA,EACR,UAAU;AAAA,EACV,OAAO,aAAa,UAAU;AAAA,EAC9B,YAAY;AAAA,EACZ,QAAQ;AAAA,EACR,YAAY;AAAA,EACZ,kBAAkB;AACpB;;;AD0BI,SACE,KADF;AA3DG,IAAM,WAAqB,MAAM;AACtC,QAAM,CAAC,YAAY,aAAa,IAAIC,UAAS,KAAK;AAClD,QAAM,YAAYC,QAA0B,IAAI;AAEhD,EAAAC,WAAU,MAAM;AACd,QAAI,CAAC,WAAY;AAEjB,QAAI,YAAY;AAChB,QAAI,iBAAgC;AAEpC,UAAM,OAAO,MAAM;AACjB,UAAI,CAAC,WAAW;AACd,YAAI,mBAAmB,MAAM;AAC3B,+BAAqB,cAAc;AAAA,QACrC;AACA;AAAA,MACF;AAEA,YAAM,SAAS,UAAU;AACzB,UAAI,CAAC,OAAQ;AACb,YAAM,MAAM,OAAO,WAAW,IAAI;AAClC,UAAI,CAAC,IAAK;AAEV,YAAM,UAAU,MAAM,KAAK,QAAQ,QAAQ,CAAC,EAAE,KAAK,CAAC,GAAG,MAAM;AAC3D,cAAM,YAAY,CAAC,SAAiB;AAClC,cAAI,SAAS,UAAW,QAAO;AAC/B,cAAI,SAAS,QAAS,QAAO;AAC7B,iBAAO;AAAA,QACT;AACA,eAAO,UAAU,EAAE,CAAC,EAAE,IAAI,IAAI,UAAU,EAAE,CAAC,EAAE,IAAI;AAAA,MACnD,CAAC;AACD,YAAM,MAAM,OAAO,oBAAoB;AACvC,YAAM,WAAW,eAAI,cAAc,eAAI,YAAY,eAAI,cAAc,eAAI,UAAU;AACnF,YAAM,YAAY,KAAK,IAAI,QAAQ,SAAS,eAAI,aAAa,eAAI,UAAU,GAAG,EAAE;AAEhF,uBAAiB,QAAQ,UAAU,WAAW,GAAG;AACjD,UAAI,KAAK;AACT,UAAI,MAAM,KAAK,GAAG;AAClB,UAAI,UAAU,GAAG,GAAG,UAAU,SAAS;AAEvC,UAAI,QAAQ,WAAW,EAAG,kBAAiB,GAAG;AAAA,UACzC,cAAa,KAAK,OAAO;AAE9B,UAAI,QAAQ;AACZ,uBAAiB,sBAAsB,IAAI;AAAA,IAC7C;AAGA,qBAAiB,sBAAsB,IAAI;AAE3C,WAAO,MAAM;AACX,kBAAY;AACZ,UAAI,mBAAmB,MAAM;AAC3B,6BAAqB,cAAc;AAAA,MACrC;AAAA,IACF;AAAA,EACF,GAAG,CAAC,UAAU,CAAC;AAEf,SACE,qBAAC,SAAI,OAAO,qBAAqB,UAAU,GAAG,SAAS,MAAM,cAAc,CAAC,UAAU,GACpF;AAAA,wBAAC,aAAU,YAAwB;AAAA,IAClC,cACC,oBAAC,SAAI,OAAO,EAAE,SAAS,sBAAsB,GAC3C,8BAAC,YAAO,KAAK,WAAW,OAAO,EAAE,SAAS,QAAQ,GAAG,GACvD;AAAA,KAEJ;AAEJ;AAEA,SAAS,iBAAiB,QAA2B,GAAW,GAAW,KAAa;AACtF,QAAM,UAAU,KAAK,MAAM,IAAI,GAAG;AAClC,QAAM,UAAU,KAAK,MAAM,IAAI,GAAG;AAClC,MAAI,OAAO,UAAU,WAAW,OAAO,WAAW,SAAS;AACzD,WAAO,QAAQ;AACf,WAAO,SAAS;AAChB,WAAO,MAAM,QAAQ,GAAG,CAAC;AACzB,WAAO,MAAM,SAAS,GAAG,CAAC;AAAA,EAC5B;AACF;AAEA,SAAS,iBAAiB,KAA+B;AACvD,MAAI,YAAY,UAAM;AACtB,MAAI,OAAO;AACX,MAAI,SAAS,oCAAoC,eAAI,SAAS,EAAE;AAClE;AAEA,SAAS,aAAa,KAA+B,SAA0B;AAC7E,QAAM,IAAI,eAAI;AACd,QAAM,OAAO,eAAI;AACjB,QAAM,OAAO,eAAI;AACjB,QAAM,MAAM,eAAI;AAChB,QAAM,QAAQ,OAAO;AACrB,QAAM,QAAQ,OAAO;AAErB,QAAM,WAAW,IAAI,OAAO;AAC5B,QAAM,cAAc,IAAI,OAAO;AAC/B,QAAM,cAAc,IAAI,OAAO;AAC/B,QAAM,YAAY,IAAI,OAAO;AAE7B,MAAI,OAAO;AAEX,MAAI,WAAW;AACf,aAAW,CAAC,OAAO,IAAI,KAAK,SAAS;AACnC,UAAM,IAAI,WAAW,OAAO;AAC5B,UAAM,YAAY,KAAK,SAAS,aAAa,KAAK,SAAS;AAC3D,UAAM,cAAc,CAAC,aAAa,gBAAgB,IAAI,KAAK;AAE3D,UAAM,EAAE,QAAQ,KAAK,IAAI;AACzB,QAAI,QAAQ;AAEZ,UAAM,YAAY,CAAC,KAAa,SAAiB;AAC/C,YAAM,IAAI,OAAO,OAAO;AACxB,UAAI,QAAQ,GAAG;AACb,YAAI,UAAW,aAAY,KAAK,GAAG,GAAG,OAAO,KAAK;AAAA,iBACzC,YAAa,WAAU,KAAK,GAAG,GAAG,OAAO,KAAK;AAAA,YAClD,aAAY,KAAK,GAAG,GAAG,OAAO,KAAK;AAAA,MAC1C,OAAO;AACL,iBAAS,KAAK,GAAG,GAAG,OAAO,KAAK;AAAA,MAClC;AAAA,IACF;AAEA,aAAS,IAAI,MAAM,IAAI,GAAG,IAAK,WAAU,OAAO,CAAC,GAAG,OAAO;AAC3D,aAAS,IAAI,GAAG,IAAI,MAAM,IAAK,WAAU,OAAO,CAAC,GAAG,OAAO;AAE3D,UAAM,YAAY,WAAW,KAAK,EAAE;AACpC,UAAM,QAAS,IAAI,OAAQ,MAAM;AAEjC,QAAI,YAAY,YAAY,UAAM,SAAU,cAAc,UAAM,QAAQ,UAAM;AAC9E,UAAM,SAAS,KAAK,SAAS,UAAU,YAAO,YAAY,YAAO,cAAc,OAAO;AACtF,QAAI,SAAS,SAAS,WAAW,OAAO,IAAI,CAAC;AAE7C;AAAA,EACF;AAEA,MAAI,YAAY,UAAM;AAAM,MAAI,KAAK,QAAQ;AAC7C,MAAI,YAAY,UAAM;AAAS,MAAI,KAAK,WAAW;AACnD,MAAI,YAAY,UAAM;AAAQ,MAAI,KAAK,WAAW;AAClD,MAAI,YAAY,UAAM;AAAO,MAAI,KAAK,SAAS;AACjD;AAEA,IAAM,YAA+C,CAAC,EAAE,WAAW,MACjE;AAAA,EAAC;AAAA;AAAA,IACC,OAAO;AAAA,MACL,SAAS;AAAA,MACT,iBAAiB,aAAa,UAAM,SAAS;AAAA,MAC7C,OAAO,aAAa,UAAU,UAAM;AAAA,MACpC,YAAY;AAAA,MACZ,UAAU;AAAA,MACV,eAAe;AAAA,MACf,SAAS;AAAA,MACT,gBAAgB;AAAA,MAChB,YAAY;AAAA,MACZ,YAAY;AAAA,IACd;AAAA,IAEA;AAAA,0BAAC,UAAM,uBAAa,uBAAuB,0BAAkB;AAAA,MAC5D,cAAc,oBAAC,UAAK,OAAO,EAAE,SAAS,KAAK,UAAU,MAAM,GAAG,oBAAM;AAAA;AAAA;AACvE;;;ADzIE,SAGkC,OAAAC,MAHlC,QAAAC,aAAA;AAtBJ,IAAM,eAAeC,eAAc,EAAE,OAAO,MAAM,CAAC;AACnD,IAAM,QAAQ,OAAO,WAAW,eAAe,OAAO,OAAO,aAAa;AAQnE,IAAM,gBAA8C,CAAC;AAAA,EAC1D;AAAA,EACA,QAAQ;AAAA,EACR,UAAU;AACZ,MAAM;AACJ,EAAAC,iBAAgB,MAAM;AACpB,mBAAe,EAAE,MAAM,CAAC;AACxB,QAAI,OAAO;AACT,MAAC,OAAe,eAAe;AAAA,IACjC;AAAA,EACF,GAAG,CAAC,KAAK,CAAC;AAEV,SACE,gBAAAF,MAAC,aAAa,UAAb,EAAsB,OAAO,EAAE,MAAM,GACnC;AAAA;AAAA,IAEC,SAAS,WAAW,SAAU,gBAAAD,KAAC,YAAS;AAAA,KAC5C;AAEJ;AAEO,IAAM,iBAAiB,MAAMI,YAAW,YAAY;","names":["useId","useDebugValue","useImperativeHandle","useInsertionEffect","createContext","useContext","useLayoutEffect","useEffect","useRef","useState","useState","useRef","useEffect","jsx","jsxs","createContext","useLayoutEffect","useContext"]}
|
|
@@ -88,11 +88,26 @@ var calculateSpectralInfluence = (graph, maxIterations = 20, tolerance = 1e-3) =
|
|
|
88
88
|
return scores;
|
|
89
89
|
};
|
|
90
90
|
|
|
91
|
-
// src/core/
|
|
91
|
+
// src/core/constants.ts
|
|
92
|
+
var WINDOW_SIZE = 50;
|
|
93
|
+
var SIMILARITY_THRESHOLD = 0.88;
|
|
94
|
+
var LOOP_THRESHOLD = 150;
|
|
95
|
+
var VOLATILITY_THRESHOLD = 25;
|
|
96
|
+
var INSTANCE_SEP = "##";
|
|
97
|
+
|
|
98
|
+
// src/core/label.ts
|
|
99
|
+
var stripInstance = (label) => {
|
|
100
|
+
const idx = label.indexOf(INSTANCE_SEP);
|
|
101
|
+
return idx === -1 ? label : label.slice(0, idx);
|
|
102
|
+
};
|
|
92
103
|
var parseLabel = (label) => {
|
|
93
|
-
const
|
|
94
|
-
|
|
104
|
+
const base = stripInstance(label);
|
|
105
|
+
const parts = base.split(" -> ");
|
|
106
|
+
return { file: parts[0] || "Unknown", name: parts[1] || base };
|
|
95
107
|
};
|
|
108
|
+
var isSameField = (labelA, labelB) => stripInstance(labelA) === stripInstance(labelB);
|
|
109
|
+
|
|
110
|
+
// src/core/ranker.ts
|
|
96
111
|
var identifyTopIssues = (graph, history2, redundantLabels2, violationMap) => {
|
|
97
112
|
const results = [];
|
|
98
113
|
const influence = calculateSpectralInfluence(graph);
|
|
@@ -222,10 +237,6 @@ var STYLES = {
|
|
|
222
237
|
bold: "font-weight: bold;",
|
|
223
238
|
label: "background: #dfe6e9; color: #2d3436; padding: 0 4px; border-radius: 3px; font-family: monospace; font-weight: bold; border: 1px solid #b2bec3;"
|
|
224
239
|
};
|
|
225
|
-
var parseLabel2 = (label) => {
|
|
226
|
-
const parts = label.split(" -> ");
|
|
227
|
-
return { file: parts[0] || "Unknown", name: parts[1] || label };
|
|
228
|
-
};
|
|
229
240
|
var shouldLog = (key) => {
|
|
230
241
|
const now = Date.now();
|
|
231
242
|
const last = LAST_LOG_TIMES.get(key) || 0;
|
|
@@ -248,7 +259,7 @@ var getSuggestedFix = (issue, info) => {
|
|
|
248
259
|
return `Local state is 'shadowing' Global Context. This creates two sources of truth. Delete the local state and consume the %cContext%c value directly.`;
|
|
249
260
|
}
|
|
250
261
|
if (leaks.length > 0) {
|
|
251
|
-
const targetName =
|
|
262
|
+
const targetName = parseLabel(leaks[0].target).name;
|
|
252
263
|
if (issue.label.includes("effect")) {
|
|
253
264
|
return `This Effect triggers a synchronous re-render of ${targetName}. Calculate ${targetName} during the render phase (Derived State) or wrap in %cuseMemo%c if expensive.`;
|
|
254
265
|
}
|
|
@@ -278,7 +289,7 @@ var displayHealthReport = (history2, threshold, violationMap) => {
|
|
|
278
289
|
`font-weight: normal; color: ${THEME.muted}; font-style: italic;`
|
|
279
290
|
);
|
|
280
291
|
topIssues.forEach((issue, idx) => {
|
|
281
|
-
const info =
|
|
292
|
+
const info = parseLabel(issue.label);
|
|
282
293
|
const icon = issue.metric === "influence" ? "\u26A1" : "\u{1F4C8}";
|
|
283
294
|
const pColor = idx === 0 ? THEME.problem : idx === 1 ? THEME.solution : THEME.identity;
|
|
284
295
|
let displayName = info.name;
|
|
@@ -298,7 +309,7 @@ var displayHealthReport = (history2, threshold, violationMap) => {
|
|
|
298
309
|
const byFile = /* @__PURE__ */ new Map();
|
|
299
310
|
issue.violations.forEach((v) => {
|
|
300
311
|
if (issue.label.includes("Global Event") && v.type === "context_mirror") return;
|
|
301
|
-
const { file, name } =
|
|
312
|
+
const { file, name } = parseLabel(v.target);
|
|
302
313
|
if (!byFile.has(file)) byFile.set(file, []);
|
|
303
314
|
byFile.get(file).push(name);
|
|
304
315
|
});
|
|
@@ -373,7 +384,7 @@ var displayHealthReport = (history2, threshold, violationMap) => {
|
|
|
373
384
|
const clusterMetas = cluster.map((l) => ({
|
|
374
385
|
label: l,
|
|
375
386
|
meta: history2.get(l),
|
|
376
|
-
name:
|
|
387
|
+
name: parseLabel(l).name
|
|
377
388
|
}));
|
|
378
389
|
const hasCtx = clusterMetas.some(
|
|
379
390
|
(c) => c.meta.role === "context" /* CONTEXT */ || c.meta.role === "store" /* STORE */
|
|
@@ -414,8 +425,8 @@ var displayHealthReport = (history2, threshold, violationMap) => {
|
|
|
414
425
|
};
|
|
415
426
|
var displayRedundancyAlert = (labelA, metaA, labelB, metaB, sim) => {
|
|
416
427
|
if (!isWeb || !shouldLog(`redundant-${labelA}-${labelB}`)) return;
|
|
417
|
-
const infoA =
|
|
418
|
-
const infoB =
|
|
428
|
+
const infoA = parseLabel(labelA);
|
|
429
|
+
const infoB = parseLabel(labelB);
|
|
419
430
|
const isContextMirror = metaA.role === "local" /* LOCAL */ && metaB.role === "context" /* CONTEXT */ || metaB.role === "local" /* LOCAL */ && metaA.role === "context" /* CONTEXT */;
|
|
420
431
|
const isStoreMirror = metaA.role === "local" /* LOCAL */ && metaB.role === "store" /* STORE */ || metaB.role === "local" /* LOCAL */ && metaA.role === "store" /* STORE */;
|
|
421
432
|
const alertType = isContextMirror ? "CONTEXT MIRRORING" : isStoreMirror ? "STORE MIRRORING" : "DUPLICATE STATE";
|
|
@@ -460,8 +471,8 @@ var displayRedundancyAlert = (labelA, metaA, labelB, metaB, sim) => {
|
|
|
460
471
|
};
|
|
461
472
|
var displayCausalHint = (targetLabel, targetMeta, sourceLabel, sourceMeta) => {
|
|
462
473
|
if (!isWeb || !shouldLog(`causal-${sourceLabel}-${targetLabel}`)) return;
|
|
463
|
-
const target =
|
|
464
|
-
const source =
|
|
474
|
+
const target = parseLabel(targetLabel);
|
|
475
|
+
const source = parseLabel(sourceLabel);
|
|
465
476
|
const headerType = sourceMeta.role === "context" /* CONTEXT */ ? "CONTEXT SYNC LEAK" : sourceMeta.role === "store" /* STORE */ ? "STORE SYNC LEAK" : "DOUBLE RENDER";
|
|
466
477
|
const isEffect = sourceLabel.includes("effect") || sourceLabel.includes("useLayoutEffect");
|
|
467
478
|
console.groupCollapsed(`%c \u26A1 BASIS | ${headerType} `, STYLES.headerProblem);
|
|
@@ -492,21 +503,15 @@ var displayCausalHint = (targetLabel, targetMeta, sourceLabel, sourceMeta) => {
|
|
|
492
503
|
};
|
|
493
504
|
var displayViolentBreaker = (label, count, threshold) => {
|
|
494
505
|
if (!isWeb) return;
|
|
495
|
-
const
|
|
506
|
+
const { name } = parseLabel(label);
|
|
496
507
|
console.group(`%c \u{1F6D1} BASIS CRITICAL | CIRCUIT BREAKER `, STYLES.headerProblem);
|
|
497
508
|
console.error(`INFINITE LOOP DETECTED
|
|
498
|
-
Variable: ${
|
|
509
|
+
Variable: ${name}
|
|
499
510
|
Frequency: ${count} updates/sec`);
|
|
500
511
|
console.log(`%cACTION: Update BLOCKED to prevent browser freeze.`, `color: ${THEME.problem}; font-weight: bold;`);
|
|
501
512
|
console.groupEnd();
|
|
502
513
|
};
|
|
503
514
|
|
|
504
|
-
// src/core/constants.ts
|
|
505
|
-
var WINDOW_SIZE = 50;
|
|
506
|
-
var SIMILARITY_THRESHOLD = 0.88;
|
|
507
|
-
var LOOP_THRESHOLD = 150;
|
|
508
|
-
var VOLATILITY_THRESHOLD = 25;
|
|
509
|
-
|
|
510
515
|
// src/core/analysis.ts
|
|
511
516
|
var CAUSAL_MARGIN = 0.05;
|
|
512
517
|
var isEventDriven = (label, graph) => {
|
|
@@ -543,6 +548,7 @@ var calculateAllSimilarities = (entryA, entryB) => {
|
|
|
543
548
|
};
|
|
544
549
|
var shouldSkipComparison = (entryA, entryB, dirtyLabels2) => {
|
|
545
550
|
if (entryA.label === entryB.label) return true;
|
|
551
|
+
if (isSameField(entryA.label, entryB.label)) return true;
|
|
546
552
|
if (dirtyLabels2.has(entryB.label) && entryA.label > entryB.label) return true;
|
|
547
553
|
return false;
|
|
548
554
|
};
|