UNPKG

holosphere

Version:

Holonic Geospatial Communication Infrastructure

666 lines (597 loc) 27.3 kB
/** * @module holosphere * @version 1.1.17 * @description Holonic Geospatial Communication Infrastructure * @author Roberto Valenti * @license GPL-3.0-or-later */ import * as h3 from 'h3-js'; import OpenAI from 'openai'; import Gun from 'gun' import Ajv2019 from 'ajv/dist/2019.js' import * as Federation from './federation.js'; import * as SchemaOps from './schema.js'; import * as ContentOps from './content.js'; import * as NodeOps from './node.js'; import * as GlobalOps from './global.js'; import * as HologramOps from './hologram.js'; import * as ComputeOps from './compute.js'; import * as Utils from './utils.js'; // Define the version constant const HOLOSPHERE_VERSION = '1.1.17'; class HoloSphere { /** * Initializes a new instance of the HoloSphere class. * @param {string} appname - The name of the application. * @param {boolean} [strict=false] - Whether to enforce strict schema validation. * @param {string|null} [openaikey=null] - The OpenAI API key. * @param {object} [gunOptions={}] - Optional Gun constructor options (e.g., peers, localStorage, radisk). */ constructor(appname, strict = false, openaikey = null, gunOptions = {}) { console.log('HoloSphere v' + HOLOSPHERE_VERSION); this.appname = appname this.strict = strict; this.validator = new Ajv2019({ allErrors: true, strict: false, // Keep this false to avoid Ajv strict mode issues validateSchema: true // Always validate schemas }); // Define default Gun options const defaultGunOptions = { peers: ['https://gun.holons.io/gun','https://59.src.eco/gun'], axe: false // Add other potential defaults here if needed }; // Merge provided options with defaults const finalGunOptions = { ...defaultGunOptions, ...gunOptions }; console.log("Initializing Gun with options:", finalGunOptions); // Use provided Gun instance or create new one with final options this.gun = Gun(finalGunOptions); // Pass the merged options if (openaikey != null) { this.openai = new OpenAI({ apiKey: openaikey, }); } // Initialize subscriptions this.subscriptions = {}; // Initialize schema cache this.schemaCache = new Map(); } getGun() { return this.gun; } // ================================ SCHEMA FUNCTIONS ================================ /** * Sets the JSON schema for a specific lens. * @param {string} lens - The lens identifier. * @param {object} schema - The JSON schema to set. * @returns {Promise} - Resolves when the schema is set. */ async setSchema(lens, schema) { // Delegate to the external function return SchemaOps.setSchema(this, lens, schema); } /** * Retrieves the JSON schema for a specific lens. * @param {string} lens - The lens identifier. * @param {object} [options] - Additional options * @param {boolean} [options.useCache=true] - Whether to use the schema cache * @param {number} [options.maxCacheAge=3600000] - Maximum cache age in milliseconds (default: 1 hour) * @returns {Promise<object|null>} - The retrieved schema or null if not found. */ async getSchema(lens, options = {}) { // Delegate to the external function return SchemaOps.getSchema(this, lens, options); } /** * Clears the schema cache or a specific schema from the cache. * @param {string} [lens] - Optional lens to clear from cache. If not provided, clears entire cache. * @returns {boolean} - Returns true if successful */ clearSchemaCache(lens = null) { // Delegate to the external function return SchemaOps.clearSchemaCache(this, lens); } // ================================ CONTENT FUNCTIONS ================================ /** * Stores content in the specified holon and lens. * @param {string} holon - The holon identifier. * @param {string} lens - The lens under which to store the content. * @param {object} data - The data to store. * @param {string} [password] - Optional password for private holon. * @param {object} [options] - Additional options * @param {boolean} [options.autoPropagate=true] - Whether to automatically propagate to federated holons (default: true) * @param {object} [options.propagationOptions] - Options to pass to propagate * @param {boolean} [options.propagationOptions.useReferences=true] - Whether to use references instead of duplicating data * @returns {Promise<boolean>} - Returns true if successful, false if there was an error */ async put(holon, lens, data, password = null, options = {}) { // Delegate to the external function return ContentOps.put(this, holon, lens, data, password, options); } /** * Retrieves content from the specified holon and lens. * @param {string} holon - The holon identifier. * @param {string} lens - The lens from which to retrieve content. * @param {string} key - The specific key to retrieve. * @param {string} [password] - Optional password for private holon. * @param {object} [options] - Additional options * @param {boolean} [options.resolveReferences=true] - Whether to automatically resolve federation references * @returns {Promise<object|null>} - The retrieved content or null if not found. */ async get(holon, lens, key, password = null, options = {}) { // Delegate to the external function return ContentOps.get(this, holon, lens, key, password, options); } /** * Retrieves all content from the specified holon and lens. * @param {string} holon - The holon identifier. * @param {string} lens - The lens from which to retrieve content. * @param {string} [password] - Optional password for private holon. * @returns {Promise<Array<object>>} - The retrieved content. */ async getAll(holon, lens, password = null) { // Delegate to the external function return ContentOps.getAll(this, holon, lens, password); } /** * Parses data from GunDB, handling various data formats and references. * @param {*} data - The data to parse, could be a string, object, or GunDB reference. * @returns {Promise<object>} - The parsed data. */ async parse(rawData) { // Delegate to the external function return ContentOps.parse(this, rawData); } /** * Deletes a specific key from a given holon and lens. * @param {string} holon - The holon identifier. * @param {string} lens - The lens from which to delete the key. * @param {string} key - The specific key to delete. * @param {string} [password] - Optional password for private holon. * @returns {Promise<boolean>} - Returns true if successful */ async delete(holon, lens, key, password = null) { // Delegate to the external function (renamed to deleteFunc in module) return ContentOps.deleteFunc(this, holon, lens, key, password); } /** * Deletes all keys from a given holon and lens. * @param {string} holon - The holon identifier. * @param {string} lens - The lens from which to delete all keys. * @param {string} [password] - Optional password for private holon. * @returns {Promise<boolean>} - Returns true if successful */ async deleteAll(holon, lens, password = null) { // Delegate to the external function return ContentOps.deleteAll(this, holon, lens, password); } // ================================ NODE FUNCTIONS ================================ /** * Stores a specific gun node in a given holon and lens. * @param {string} holon - The holon identifier. * @param {string} lens - The lens under which to store the node. * @param {object} data - The node to store. */ async putNode(holon, lens, data) { // Delegate to the external function return NodeOps.putNode(this, holon, lens, data); } /** * Retrieves a specific gun node from the specified holon and lens. * @param {string} holon - The holon identifier. * @param {string} lens - The lens identifier. * @param {string} key - The specific key to retrieve. * @returns {Promise<any>} - The retrieved node or null if not found. */ async getNode(holon, lens, key) { // Delegate to the external function return NodeOps.getNode(this, holon, lens, key); } /** * Retrieves a Gun node reference using its soul path * @param {string} soul - The soul path of the node * @returns {Gun.ChainReference} - The Gun node reference */ getNodeRef(soul) { // Delegate to the external function return NodeOps.getNodeRef(this, soul); } /** * Retrieves a node directly using its soul path * @param {string} soul - The soul path of the node * @returns {Promise<any>} - The retrieved node or null if not found. */ async getNodeBySoul(soul) { // Delegate to the external function return NodeOps.getNodeBySoul(this, soul); } /** * Deletes a specific gun node from a given holon and lens. * @param {string} holon - The holon identifier. * @param {string} lens - The lens identifier. * @param {string} key - The key of the node to delete. * @returns {Promise<boolean>} - Returns true if successful */ async deleteNode(holon, lens, key) { // Delegate to the external function return NodeOps.deleteNode(this, holon, lens, key); } // ================================ GLOBAL FUNCTIONS ================================ /** * Stores data in a global (non-holon-specific) table. * @param {string} tableName - The table name to store data in. * @param {object} data - The data to store. If it has an 'id' field, it will be used as the key. * @param {string} [password] - Optional password for private holon. * @returns {Promise<void>} */ async putGlobal(tableName, data, password = null) { // Delegate to the external function return GlobalOps.putGlobal(this, tableName, data, password); } /** * Retrieves a specific key from a global table. * @param {string} tableName - The table name to retrieve from. * @param {string} key - The key to retrieve. * @param {string} [password] - Optional password for private holon. * @returns {Promise<object|null>} - The parsed data for the key or null if not found. */ async getGlobal(tableName, key, password = null) { // Delegate to the external function return GlobalOps.getGlobal(this, tableName, key, password); } /** * Retrieves all data from a global table. * @param {string} tableName - The table name to retrieve data from. * @param {string} [password] - Optional password for private holon. * @returns {Promise<Array<object>>} - The parsed data from the table as an array. */ async getAllGlobal(tableName, password = null) { // Delegate to the external function return GlobalOps.getAllGlobal(this, tableName, password); } /** * Deletes a specific key from a global table. * @param {string} tableName - The table name to delete from. * @param {string} key - The key to delete. * @param {string} [password] - Optional password for private holon. * @returns {Promise<boolean>} */ async deleteGlobal(tableName, key, password = null) { // Delegate to the external function return GlobalOps.deleteGlobal(this, tableName, key, password); } /** * Deletes an entire global table. * @param {string} tableName - The table name to delete. * @param {string} [password] - Optional password for private holon. * @returns {Promise<boolean>} */ async deleteAllGlobal(tableName, password = null) { // Delegate to the external function return GlobalOps.deleteAllGlobal(this, tableName, password); } // ================================ REFERENCE FUNCTIONS ================================ /** * Creates a soul hologram object for a data item * @param {string} holon - The holon where the original data is stored * @param {string} lens - The lens where the original data is stored * @param {object} data - The data to create a hologram for * @returns {object} - A hologram object with id and soul */ createHologram(holon, lens, data) { // Delegate to the external function return HologramOps.createHologram(this, holon, lens, data); } /** * Parses a soul path into its components * @param {string} soul - The soul path to parse * @returns {object|null} - The parsed components or null if invalid format */ parseSoulPath(soul) { // Delegate to the external function (doesn't need instance) return HologramOps.parseSoulPath(soul); } /** * Checks if an object is a hologram * @param {object} data - The data to check * @returns {boolean} - True if the object is a hologram */ isHologram(data) { // Delegate to the external function (doesn't need instance) return HologramOps.isHologram(data); } /** * Resolves a hologram to its actual data * @param {object} hologram - The hologram to resolve * @param {object} [options] - Optional parameters * @param {boolean} [options.followHolograms=true] - Whether to follow nested holograms * @param {Set<string>} [options.visited] - Internal use: Tracks visited souls to prevent loops * @returns {Promise<object|null>} - The resolved data, null if resolution failed due to target not found, or the original hologram for circular/invalid cases. */ async resolveHologram(hologram, options = {}) { // Delegate to the external function return HologramOps.resolveHologram(this, hologram, options); } // ================================ COMPUTE FUNCTIONS ================================ /** * Computes operations across multiple layers up the hierarchy * @param {string} holon - Starting holon identifier * @param {string} lens - The lens to compute * @param {object} options - Computation options * @param {number} [maxLevels=15] - Maximum levels to compute up * @param {string} [password] - Optional password for private holons */ async computeHierarchy(holon, lens, options, maxLevels = 15, password = null) { // Delegate to the external function return ComputeOps.computeHierarchy(this, holon, lens, options, maxLevels, password); } /** * Computes operations on content within a holon and lens for one layer up. * @param {string} holon - The holon identifier. * @param {string} lens - The lens to compute. * @param {object} options - Computation options * @param {string} options.operation - The operation to perform ('summarize', 'aggregate', 'concatenate') * @param {string[]} [options.fields] - Fields to perform operation on * @param {string} [options.targetField] - Field to store the result in * @param {string} [password] - Optional password for private holons * @throws {Error} If parameters are invalid or missing */ async compute(holon, lens, options, password = null) { // Delegate to the external function return ComputeOps.compute(this, holon, lens, options, password); } /** * Summarizes provided history text using OpenAI. * @param {string} history - The history text to summarize. * @returns {Promise<string>} - The summarized text. */ async summarize(history) { // Delegate to the external function return ComputeOps.summarize(this, history); } /** * Upcasts content to parent holonagons recursively using references. * @param {string} holon - The current holon identifier. * @param {string} lens - The lens under which to upcast. * @param {object} content - The content to upcast. * @param {number} [maxLevels=15] - Maximum levels to upcast. * @returns {Promise<object>} - The original content. */ async upcast(holon, lens, content, maxLevels = 15) { // Delegate to the external function return ComputeOps.upcast(this, holon, lens, content, maxLevels); } /** * Updates the parent holon with a new report. * @param {string} id - The child holon identifier. * @param {string} report - The report to update. * @returns {Promise<object>} - The updated parent information. */ async updateParent(id, report) { // Delegate to the external function return ComputeOps.updateParent(this, id, report); } /** * Propagates data to federated holons * @param {string} holon - The holon identifier * @param {string} lens - The lens identifier * @param {object} data - The data to propagate * @param {object} [options] - Propagation options * @returns {Promise<object>} - Result with success count and errors */ async propagate(holon, lens, data, options = {}) { return Federation.propagate(this, holon, lens, data, options); } /** * Converts latitude and longitude to a holon identifier. * @param {number} lat - The latitude. * @param {number} lng - The longitude. * @param {number} resolution - The resolution level. * @returns {Promise<string>} - The resulting holon identifier. */ async getHolon(lat, lng, resolution) { // Delegate to the external function return Utils.getHolon(lat, lng, resolution); } /** * Retrieves all containing holonagons at all scales for given coordinates. * @param {number} lat - The latitude. * @param {number} lng - The longitude. * @returns {Array<string>} - List of holon identifiers. */ getScalespace(lat, lng) { // Delegate to the external function return Utils.getScalespace(lat, lng); } /** * Retrieves all containing holonagons at all scales for a given holon. * @param {string} holon - The holon identifier. * @returns {Array<string>} - List of holon identifiers. */ getHolonScalespace(holon) { // Delegate to the external function return Utils.getHolonScalespace(holon); } /** * Subscribes to changes in a specific holon and lens. * @param {string} holon - The holon identifier. * @param {string} lens - The lens to subscribe to. * @param {function} callback - The callback to execute on changes. * @returns {Promise<object>} - Subscription object with unsubscribe method */ async subscribe(holon, lens, callback) { // Delegate to the external function return Utils.subscribe(this, holon, lens, callback); } /** * Notifies subscribers about data changes * @param {object} data - The data to notify about * @private */ notifySubscribers(data) { // Delegate to the external function return Utils.notifySubscribers(this, data); } // Add ID generation method generateId() { // Delegate to the external function return Utils.generateId(); } // ================================ FEDERATION FUNCTIONS ================================ /** * Creates a federation relationship between two holons * @param {string} holonId1 - The first holon ID * @param {string} holonId2 - The second holon ID * @param {string} [password1] - Optional password for the first holon * @param {string} [password2] - Optional password for the second holon * @param {boolean} [bidirectional=true] - Whether to set up bidirectional notifications automatically * @param {object} [lensConfig] - Optional lens-specific configuration * @param {string[]} [lensConfig.federate] - List of lenses to federate (default: all) * @param {string[]} [lensConfig.notify] - List of lenses to notify (default: all) * @returns {Promise<boolean>} - True if federation was created successfully */ async federate(holonId1, holonId2, password1 = null, password2 = null, bidirectional = true, lensConfig = {}) { return Federation.federate(this, holonId1, holonId2, password1, password2, bidirectional, lensConfig); } /** * Subscribes to federation notifications for a holon * @param {string} holonId - The holon ID to subscribe to * @param {string} password - Password for the holon * @param {function} callback - The callback to execute on notifications * @param {object} [options] - Subscription options * @param {string[]} [options.lenses] - Specific lenses to subscribe to (default: all) * @param {number} [options.throttle] - Throttle notifications in ms (default: 0) * @returns {Promise<object>} - Subscription object with unsubscribe() method */ async subscribeFederation(holonId, password, callback, options = {}) { return Federation.subscribeFederation(this, holonId, password, callback, options); } /** * Gets federation info for a holon * @param {string} holonId - The holon ID * @param {string} [password] - Optional password for the holon * @returns {Promise<object|null>} - Federation info or null if not found */ async getFederation(holonId, password = null) { return Federation.getFederation(this, holonId, password); } /** * Retrieves the lens-specific configuration for a federation link between two holons. * @param {string} holonId - The ID of the source holon. * @param {string} targetHolonId - The ID of the target holon in the federation link. * @param {string} [password] - Optional password for the source holon. * @returns {Promise<object|null>} - An object with 'federate' and 'notify' arrays, or null if not found. */ async getFederatedConfig(holonId, targetHolonId, password = null) { return Federation.getFederatedConfig(this, holonId, targetHolonId, password); } /** * Removes a federation relationship between holons * @param {string} holonId1 - The first holon ID * @param {string} holonId2 - The second holon ID * @param {string} password1 - Password for the first holon * @param {string} [password2] - Optional password for the second holon * @returns {Promise<boolean>} - True if federation was removed successfully */ async unfederate(holonId1, holonId2, password1, password2 = null) { return await Federation.unfederate(this, holonId1, holonId2, password1, password2); } /** * Removes a notification relationship between two spaces * This removes spaceId2 from the notify list of spaceId1 * * @param {string} holonId1 - The space to modify (remove from its notify list) * @param {string} holonId2 - The space to be removed from notifications * @param {string} [password1] - Optional password for the first space * @returns {Promise<boolean>} - True if notification was removed successfully */ async removeNotify(holonId1, holonId2, password1 = null) { console.log(`HoloSphere.removeNotify called: ${holonId1}, ${holonId2}`); try { const result = await Federation.removeNotify(this, holonId1, holonId2, password1); console.log(`HoloSphere.removeNotify completed successfully: ${result}`); return result; } catch (error) { console.error(`HoloSphere.removeNotify failed:`, error); throw error; } } /** * Get and aggregate data from federated holons * @param {string} holon The holon name * @param {string} lens The lens name * @param {Object} options Options for retrieval and aggregation * @returns {Promise<Array>} Combined array of local and federated data */ async getFederated(holon, lens, options = {}) { return Federation.getFederated(this, holon, lens, options); } /** * Tracks a federated message across different chats * @param {string} originalChatId - The ID of the original chat * @param {string} messageId - The ID of the original message * @param {string} federatedChatId - The ID of the federated chat * @param {string} federatedMessageId - The ID of the message in the federated chat * @param {string} type - The type of message (e.g., 'quest', 'announcement') * @returns {Promise<void>} */ async federateMessage(originalChatId, messageId, federatedChatId, federatedMessageId, type = 'generic') { return Federation.federateMessage(this, originalChatId, messageId, federatedChatId, federatedMessageId, type); } /** * Gets all federated messages for a given original message * @param {string} originalChatId - The ID of the original chat * @param {string} messageId - The ID of the original message * @returns {Promise<Object|null>} The tracking information for the message */ async getFederatedMessages(originalChatId, messageId) { return Federation.getFederatedMessages(this, originalChatId, messageId); } /** * Updates a federated message across all federated chats * @param {string} originalChatId - The ID of the original chat * @param {string} messageId - The ID of the original message * @param {Function} updateCallback - Function to update the message in each chat * @returns {Promise<void>} */ async updateFederatedMessages(originalChatId, messageId, updateCallback) { return Federation.updateFederatedMessages(this, originalChatId, messageId, updateCallback); } /** * Resets the federation settings for a holon * @param {string} holonId - The holon ID * @param {string} [password] - Optional password for the holon * @returns {Promise<boolean>} - True if federation was reset successfully */ async resetFederation(holonId, password = null) { return Federation.resetFederation(this, holonId, password); } // ================================ END FEDERATION FUNCTIONS ================================ /** * Closes the HoloSphere instance and cleans up resources. * @returns {Promise<void>} */ async close() { // Delegate to the external function return Utils.close(this); } /** * Creates a namespaced username for Gun authentication * @private * @param {string} holonId - The holon ID * @returns {string} - Namespaced username */ userName(holonId) { // Delegate to the external function return Utils.userName(this, holonId); } /** * Returns the current version of the HoloSphere library. * @returns {string} The library version. */ getVersion() { return HOLOSPHERE_VERSION; } } export default HoloSphere;