mirror of
https://github.com/usebruno/bruno.git
synced 2026-06-27 14:44:07 +00:00
add first attempt of adding set / map logic
This commit is contained in:
@@ -67,14 +67,55 @@ const LogTimestamp = ({ timestamp }) => {
|
||||
const LogMessage = ({ message, args }) => {
|
||||
const { displayedTheme } = useTheme();
|
||||
|
||||
// Helper function to transform Bruno special types back to readable format
|
||||
const transformBrunoTypes = obj => {
|
||||
if (typeof obj !== 'object' || obj === null) {
|
||||
return obj;
|
||||
}
|
||||
|
||||
// Handle Bruno special types
|
||||
if (obj.__brunoType) {
|
||||
switch (obj.__brunoType) {
|
||||
case 'Set':
|
||||
return {
|
||||
'[[Set]]': obj.__brunoValue,
|
||||
'size': obj.__brunoValue.length,
|
||||
};
|
||||
case 'Map':
|
||||
return {
|
||||
'[[Map]]': obj.__brunoValue,
|
||||
'size': obj.__brunoValue.length,
|
||||
};
|
||||
case 'Function':
|
||||
return `[Function: ${obj.__brunoValue.split('\n')[0].substring(0, 50)}...]`;
|
||||
case 'undefined':
|
||||
return 'undefined';
|
||||
default:
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
|
||||
// Recursively transform nested objects
|
||||
if (Array.isArray(obj)) {
|
||||
return obj.map(transformBrunoTypes);
|
||||
}
|
||||
|
||||
const transformed = {};
|
||||
for (const [key, value] of Object.entries(obj)) {
|
||||
transformed[key] = transformBrunoTypes(value);
|
||||
}
|
||||
return transformed;
|
||||
};
|
||||
|
||||
const formatMessage = (msg, originalArgs) => {
|
||||
if (originalArgs && originalArgs.length > 0) {
|
||||
return originalArgs.map((arg, index) => {
|
||||
if (typeof arg === 'object' && arg !== null) {
|
||||
const transformedArg = transformBrunoTypes(arg);
|
||||
return (
|
||||
<div key={index} className="log-object">
|
||||
<ReactJson
|
||||
src={arg}
|
||||
src={transformedArg}
|
||||
theme={displayedTheme === 'light' ? 'rjv-default' : 'monokai'}
|
||||
iconStyle="triangle"
|
||||
indentWidth={2}
|
||||
|
||||
@@ -163,6 +163,55 @@ const executeQuickJsVmAsync = async ({ script: externalScript, context: external
|
||||
v = await bru.sleep(timer);
|
||||
fn.apply();
|
||||
}
|
||||
|
||||
// Override console.log to handle Sets and Maps properly
|
||||
const originalConsoleLog = console.log;
|
||||
console.log = function(...args) {
|
||||
const processedArgs = args.map(arg => {
|
||||
if (arg instanceof Set) {
|
||||
return {
|
||||
__brunoType: 'Set',
|
||||
__brunoValue: Array.from(arg),
|
||||
size: arg.size
|
||||
};
|
||||
}
|
||||
if (arg instanceof Map) {
|
||||
return {
|
||||
__brunoType: 'Map',
|
||||
__brunoValue: Array.from(arg.entries()),
|
||||
size: arg.size
|
||||
};
|
||||
}
|
||||
return arg;
|
||||
});
|
||||
return originalConsoleLog.apply(this, processedArgs);
|
||||
};
|
||||
|
||||
// Also override other console methods
|
||||
['debug', 'info', 'warn', 'error'].forEach(method => {
|
||||
const originalMethod = console[method];
|
||||
console[method] = function(...args) {
|
||||
const processedArgs = args.map(arg => {
|
||||
if (arg instanceof Set) {
|
||||
return {
|
||||
__brunoType: 'Set',
|
||||
__brunoValue: Array.from(arg),
|
||||
size: arg.size
|
||||
};
|
||||
}
|
||||
if (arg instanceof Map) {
|
||||
return {
|
||||
__brunoType: 'Map',
|
||||
__brunoValue: Array.from(arg.entries()),
|
||||
size: arg.size
|
||||
};
|
||||
}
|
||||
return arg;
|
||||
});
|
||||
return originalMethod.apply(this, processedArgs);
|
||||
};
|
||||
});
|
||||
|
||||
await bru.sleep(0);
|
||||
try {
|
||||
${externalScript}
|
||||
|
||||
@@ -1,30 +1,151 @@
|
||||
const addConsoleShimToContext = (vm, console) => {
|
||||
if (!console) return;
|
||||
|
||||
// Helper function to convert QuickJS values to native values with Set/Map support
|
||||
const dumpWithSetMapSupport = arg => {
|
||||
try {
|
||||
// First try to dump normally
|
||||
const dumped = vm.dump(arg);
|
||||
|
||||
// Check if it's a Set by trying to access Set-specific properties
|
||||
if (vm.typeof(arg) === 'object' && arg !== vm.null && arg !== vm.undefined) {
|
||||
// Try to get the constructor name
|
||||
const constructorProp = vm.getProp(arg, 'constructor');
|
||||
if (constructorProp) {
|
||||
const constructorNameProp = vm.getProp(constructorProp, 'name');
|
||||
if (constructorNameProp) {
|
||||
const constructorName = vm.dump(constructorNameProp);
|
||||
constructorNameProp.dispose();
|
||||
|
||||
if (constructorName === 'Set') {
|
||||
// It's a Set, convert to our special format
|
||||
const sizeProp = vm.getProp(arg, 'size');
|
||||
const size = sizeProp ? vm.dump(sizeProp) : 0;
|
||||
sizeProp?.dispose();
|
||||
|
||||
// Get values by calling values() method
|
||||
const valuesFn = vm.getProp(arg, 'values');
|
||||
if (valuesFn) {
|
||||
const valuesIterator = vm.callFunction(valuesFn, arg);
|
||||
const values = [];
|
||||
|
||||
// Try to extract values (this is a simplified approach)
|
||||
try {
|
||||
// For now, we'll use a different approach - convert via Array.from
|
||||
const arrayFromFn = vm.getProp(vm.global, 'Array');
|
||||
if (arrayFromFn) {
|
||||
const fromFn = vm.getProp(arrayFromFn, 'from');
|
||||
if (fromFn) {
|
||||
const arrayResult = vm.callFunction(fromFn, arrayFromFn, arg);
|
||||
const arrayValues = vm.dump(arrayResult);
|
||||
arrayResult.dispose();
|
||||
fromFn.dispose();
|
||||
|
||||
constructorProp.dispose();
|
||||
valuesFn.dispose();
|
||||
valuesIterator?.dispose();
|
||||
arrayFromFn.dispose();
|
||||
|
||||
return {
|
||||
__brunoType: 'Set',
|
||||
__brunoValue: arrayValues,
|
||||
size: size,
|
||||
};
|
||||
}
|
||||
fromFn?.dispose();
|
||||
}
|
||||
arrayFromFn?.dispose();
|
||||
} catch (e) {
|
||||
// Fallback to empty array
|
||||
}
|
||||
|
||||
valuesFn.dispose();
|
||||
valuesIterator?.dispose();
|
||||
|
||||
return {
|
||||
__brunoType: 'Set',
|
||||
__brunoValue: values,
|
||||
size: size,
|
||||
};
|
||||
}
|
||||
} else if (constructorName === 'Map') {
|
||||
// It's a Map, convert to our special format
|
||||
const sizeProp = vm.getProp(arg, 'size');
|
||||
const size = sizeProp ? vm.dump(sizeProp) : 0;
|
||||
sizeProp?.dispose();
|
||||
|
||||
// Try to convert via Array.from
|
||||
try {
|
||||
const arrayFromFn = vm.getProp(vm.global, 'Array');
|
||||
if (arrayFromFn) {
|
||||
const fromFn = vm.getProp(arrayFromFn, 'from');
|
||||
if (fromFn) {
|
||||
const arrayResult = vm.callFunction(fromFn, arrayFromFn, arg);
|
||||
const arrayValues = vm.dump(arrayResult);
|
||||
arrayResult.dispose();
|
||||
fromFn.dispose();
|
||||
arrayFromFn.dispose();
|
||||
|
||||
constructorProp.dispose();
|
||||
|
||||
return {
|
||||
__brunoType: 'Map',
|
||||
__brunoValue: arrayValues,
|
||||
size: size,
|
||||
};
|
||||
}
|
||||
fromFn?.dispose();
|
||||
}
|
||||
arrayFromFn?.dispose();
|
||||
} catch (e) {
|
||||
// Fallback
|
||||
}
|
||||
|
||||
constructorProp.dispose();
|
||||
|
||||
return {
|
||||
__brunoType: 'Map',
|
||||
__brunoValue: [],
|
||||
size: size,
|
||||
};
|
||||
}
|
||||
}
|
||||
constructorNameProp?.dispose();
|
||||
}
|
||||
constructorProp?.dispose();
|
||||
}
|
||||
|
||||
return dumped;
|
||||
} catch (e) {
|
||||
// Fallback to normal dump
|
||||
return vm.dump(arg);
|
||||
}
|
||||
};
|
||||
|
||||
const consoleHandle = vm.newObject();
|
||||
|
||||
const logHandle = vm.newFunction('log', (...args) => {
|
||||
const nativeArgs = args.map(vm.dump);
|
||||
const nativeArgs = args.map(dumpWithSetMapSupport);
|
||||
console?.log?.(...nativeArgs);
|
||||
});
|
||||
|
||||
const debugHandle = vm.newFunction('debug', (...args) => {
|
||||
const nativeArgs = args.map(vm.dump);
|
||||
const nativeArgs = args.map(dumpWithSetMapSupport);
|
||||
console?.debug?.(...nativeArgs);
|
||||
});
|
||||
|
||||
const infoHandle = vm.newFunction('info', (...args) => {
|
||||
const nativeArgs = args.map(vm.dump);
|
||||
const nativeArgs = args.map(dumpWithSetMapSupport);
|
||||
console?.info?.(...nativeArgs);
|
||||
});
|
||||
|
||||
const warnHandle = vm.newFunction('warn', (...args) => {
|
||||
const nativeArgs = args.map(vm.dump);
|
||||
const nativeArgs = args.map(dumpWithSetMapSupport);
|
||||
console?.warn?.(...nativeArgs);
|
||||
});
|
||||
|
||||
const errorHandle = vm.newFunction('error', (...args) => {
|
||||
const nativeArgs = args.map(vm.dump);
|
||||
const nativeArgs = args.map(dumpWithSetMapSupport);
|
||||
console?.error?.(...nativeArgs);
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user