add first attempt of adding set / map logic

This commit is contained in:
James Ha
2025-10-11 15:30:17 -07:00
committed by Bijin A B
parent 27da99b817
commit 15c2373fb0
3 changed files with 217 additions and 6 deletions

View File

@@ -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}

View File

@@ -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}

View File

@@ -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);
});