 85bf1341f3
			
		
	
	85bf1341f3
	
	
	
		
			
			Frontend Enhancements: - Complete React TypeScript frontend with modern UI components - Distributed workflows management interface with real-time updates - Socket.IO integration for live agent status monitoring - Agent management dashboard with cluster visualization - Project management interface with metrics and task tracking - Responsive design with proper error handling and loading states Backend Infrastructure: - Distributed coordinator for multi-agent workflow orchestration - Cluster management API with comprehensive agent operations - Enhanced database models for agents and projects - Project service for filesystem-based project discovery - Performance monitoring and metrics collection - Comprehensive API documentation and error handling Documentation: - Complete distributed development guide (README_DISTRIBUTED.md) - Comprehensive development report with architecture insights - System configuration templates and deployment guides The platform now provides a complete web interface for managing the distributed AI cluster with real-time monitoring, workflow orchestration, and agent coordination capabilities. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
		
			
				
	
	
		
			172 lines
		
	
	
		
			4.3 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			172 lines
		
	
	
		
			4.3 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| import {
 | |
|   VOID, PRIMITIVE,
 | |
|   ARRAY, OBJECT,
 | |
|   DATE, REGEXP, MAP, SET,
 | |
|   ERROR, BIGINT
 | |
| } from './types.js';
 | |
| 
 | |
| const EMPTY = '';
 | |
| 
 | |
| const {toString} = {};
 | |
| const {keys} = Object;
 | |
| 
 | |
| const typeOf = value => {
 | |
|   const type = typeof value;
 | |
|   if (type !== 'object' || !value)
 | |
|     return [PRIMITIVE, type];
 | |
| 
 | |
|   const asString = toString.call(value).slice(8, -1);
 | |
|   switch (asString) {
 | |
|     case 'Array':
 | |
|       return [ARRAY, EMPTY];
 | |
|     case 'Object':
 | |
|       return [OBJECT, EMPTY];
 | |
|     case 'Date':
 | |
|       return [DATE, EMPTY];
 | |
|     case 'RegExp':
 | |
|       return [REGEXP, EMPTY];
 | |
|     case 'Map':
 | |
|       return [MAP, EMPTY];
 | |
|     case 'Set':
 | |
|       return [SET, EMPTY];
 | |
|     case 'DataView':
 | |
|       return [ARRAY, asString];
 | |
|   }
 | |
| 
 | |
|   if (asString.includes('Array'))
 | |
|     return [ARRAY, asString];
 | |
| 
 | |
|   if (asString.includes('Error'))
 | |
|     return [ERROR, asString];
 | |
| 
 | |
|   return [OBJECT, asString];
 | |
| };
 | |
| 
 | |
| const shouldSkip = ([TYPE, type]) => (
 | |
|   TYPE === PRIMITIVE &&
 | |
|   (type === 'function' || type === 'symbol')
 | |
| );
 | |
| 
 | |
| const serializer = (strict, json, $, _) => {
 | |
| 
 | |
|   const as = (out, value) => {
 | |
|     const index = _.push(out) - 1;
 | |
|     $.set(value, index);
 | |
|     return index;
 | |
|   };
 | |
| 
 | |
|   const pair = value => {
 | |
|     if ($.has(value))
 | |
|       return $.get(value);
 | |
| 
 | |
|     let [TYPE, type] = typeOf(value);
 | |
|     switch (TYPE) {
 | |
|       case PRIMITIVE: {
 | |
|         let entry = value;
 | |
|         switch (type) {
 | |
|           case 'bigint':
 | |
|             TYPE = BIGINT;
 | |
|             entry = value.toString();
 | |
|             break;
 | |
|           case 'function':
 | |
|           case 'symbol':
 | |
|             if (strict)
 | |
|               throw new TypeError('unable to serialize ' + type);
 | |
|             entry = null;
 | |
|             break;
 | |
|           case 'undefined':
 | |
|             return as([VOID], value);
 | |
|         }
 | |
|         return as([TYPE, entry], value);
 | |
|       }
 | |
|       case ARRAY: {
 | |
|         if (type) {
 | |
|           let spread = value;
 | |
|           if (type === 'DataView') {
 | |
|             spread = new Uint8Array(value.buffer);
 | |
|           }
 | |
|           else if (type === 'ArrayBuffer') {
 | |
|             spread = new Uint8Array(value);
 | |
|           }
 | |
|           return as([type, [...spread]], value);
 | |
|         }
 | |
| 
 | |
|         const arr = [];
 | |
|         const index = as([TYPE, arr], value);
 | |
|         for (const entry of value)
 | |
|           arr.push(pair(entry));
 | |
|         return index;
 | |
|       }
 | |
|       case OBJECT: {
 | |
|         if (type) {
 | |
|           switch (type) {
 | |
|             case 'BigInt':
 | |
|               return as([type, value.toString()], value);
 | |
|             case 'Boolean':
 | |
|             case 'Number':
 | |
|             case 'String':
 | |
|               return as([type, value.valueOf()], value);
 | |
|           }
 | |
|         }
 | |
| 
 | |
|         if (json && ('toJSON' in value))
 | |
|           return pair(value.toJSON());
 | |
| 
 | |
|         const entries = [];
 | |
|         const index = as([TYPE, entries], value);
 | |
|         for (const key of keys(value)) {
 | |
|           if (strict || !shouldSkip(typeOf(value[key])))
 | |
|             entries.push([pair(key), pair(value[key])]);
 | |
|         }
 | |
|         return index;
 | |
|       }
 | |
|       case DATE:
 | |
|         return as([TYPE, value.toISOString()], value);
 | |
|       case REGEXP: {
 | |
|         const {source, flags} = value;
 | |
|         return as([TYPE, {source, flags}], value);
 | |
|       }
 | |
|       case MAP: {
 | |
|         const entries = [];
 | |
|         const index = as([TYPE, entries], value);
 | |
|         for (const [key, entry] of value) {
 | |
|           if (strict || !(shouldSkip(typeOf(key)) || shouldSkip(typeOf(entry))))
 | |
|             entries.push([pair(key), pair(entry)]);
 | |
|         }
 | |
|         return index;
 | |
|       }
 | |
|       case SET: {
 | |
|         const entries = [];
 | |
|         const index = as([TYPE, entries], value);
 | |
|         for (const entry of value) {
 | |
|           if (strict || !shouldSkip(typeOf(entry)))
 | |
|             entries.push(pair(entry));
 | |
|         }
 | |
|         return index;
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     const {message} = value;
 | |
|     return as([TYPE, {name: type, message}], value);
 | |
|   };
 | |
| 
 | |
|   return pair;
 | |
| };
 | |
| 
 | |
| /**
 | |
|  * @typedef {Array<string,any>} Record a type representation
 | |
|  */
 | |
| 
 | |
| /**
 | |
|  * Returns an array of serialized Records.
 | |
|  * @param {any} value a serializable value.
 | |
|  * @param {{json?: boolean, lossy?: boolean}?} options an object with a `lossy` or `json` property that,
 | |
|  *  if `true`, will not throw errors on incompatible types, and behave more
 | |
|  *  like JSON stringify would behave. Symbol and Function will be discarded.
 | |
|  * @returns {Record[]}
 | |
|  */
 | |
|  export const serialize = (value, {json, lossy} = {}) => {
 | |
|   const _ = [];
 | |
|   return serializer(!(json || lossy), !!json, new Map, _)(value), _;
 | |
| };
 |