feat: disable Holon functionality via HOLON_ENABLED flag
- Added HOLON_ENABLED feature flag (set to false) to completely disable Holon functionality - HoloSphereService methods now return early with default values when disabled - Removed all console.log/error output when Holon is disabled - HolonShapeUtil shows "Feature Disabled" message when flag is false - HolonBrowser shows disabled message instead of attempting connections - Code preserved for future Nostr integration re-enablement 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
7f8d78036a
commit
bcbea3bf76
|
|
@ -1,5 +1,5 @@
|
||||||
import React, { useState, useEffect, useRef } from 'react'
|
import React, { useState, useEffect, useRef } from 'react'
|
||||||
import { holosphereService, HoloSphereService, HolonData, HolonLens } from '@/lib/HoloSphereService'
|
import { holosphereService, HoloSphereService, HolonData, HolonLens, HOLON_ENABLED } from '@/lib/HoloSphereService'
|
||||||
import * as h3 from 'h3-js'
|
import * as h3 from 'h3-js'
|
||||||
|
|
||||||
interface HolonBrowserProps {
|
interface HolonBrowserProps {
|
||||||
|
|
@ -32,6 +32,66 @@ export function HolonBrowser({ isOpen, onClose, onSelectHolon, shapeMode = false
|
||||||
const [isLoadingData, setIsLoadingData] = useState(false)
|
const [isLoadingData, setIsLoadingData] = useState(false)
|
||||||
const inputRef = useRef<HTMLInputElement>(null)
|
const inputRef = useRef<HTMLInputElement>(null)
|
||||||
|
|
||||||
|
// If Holon functionality is disabled, show a disabled message
|
||||||
|
if (!HOLON_ENABLED) {
|
||||||
|
if (!isOpen) return null
|
||||||
|
|
||||||
|
const disabledContent = (
|
||||||
|
<div style={{
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'column',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
padding: '40px',
|
||||||
|
height: '100%',
|
||||||
|
textAlign: 'center'
|
||||||
|
}}>
|
||||||
|
<div style={{ fontSize: '64px', marginBottom: '24px' }}>🌐</div>
|
||||||
|
<h2 style={{ fontSize: '20px', fontWeight: '600', color: '#374151', marginBottom: '12px' }}>
|
||||||
|
Holon Browser Disabled
|
||||||
|
</h2>
|
||||||
|
<p style={{ fontSize: '14px', color: '#6b7280', maxWidth: '400px' }}>
|
||||||
|
Holon functionality is currently disabled while awaiting Nostr integration.
|
||||||
|
This feature will be re-enabled in a future update.
|
||||||
|
</p>
|
||||||
|
{!shapeMode && (
|
||||||
|
<button
|
||||||
|
onClick={onClose}
|
||||||
|
style={{
|
||||||
|
marginTop: '24px',
|
||||||
|
padding: '8px 16px',
|
||||||
|
backgroundColor: '#6b7280',
|
||||||
|
color: 'white',
|
||||||
|
border: 'none',
|
||||||
|
borderRadius: '6px',
|
||||||
|
cursor: 'pointer'
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Close
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
|
||||||
|
if (shapeMode) {
|
||||||
|
return disabledContent
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-[9999]"
|
||||||
|
onClick={onClose}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="bg-white rounded-lg shadow-xl max-w-md w-full mx-4 overflow-hidden z-[10000]"
|
||||||
|
onClick={(e) => e.stopPropagation()}
|
||||||
|
>
|
||||||
|
{disabledContent}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (isOpen && inputRef.current) {
|
if (isOpen && inputRef.current) {
|
||||||
inputRef.current.focus()
|
inputRef.current.focus()
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,10 @@
|
||||||
* TODO: Integrate with Nostr protocol when Holons.io provides their Nostr-based API
|
* TODO: Integrate with Nostr protocol when Holons.io provides their Nostr-based API
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
// Feature flag to completely disable Holon functionality
|
||||||
|
// Set to true when ready to re-enable
|
||||||
|
export const HOLON_ENABLED = false
|
||||||
|
|
||||||
import * as h3 from 'h3-js'
|
import * as h3 from 'h3-js'
|
||||||
|
|
||||||
export interface HolonData {
|
export interface HolonData {
|
||||||
|
|
@ -45,7 +49,10 @@ export class HoloSphereService {
|
||||||
|
|
||||||
constructor(_appName: string = 'canvas-holons', _strict: boolean = false, _openaiKey?: string) {
|
constructor(_appName: string = 'canvas-holons', _strict: boolean = false, _openaiKey?: string) {
|
||||||
this.isInitialized = true
|
this.isInitialized = true
|
||||||
console.log('⚠️ HoloSphere service initialized (STUB MODE - awaiting Nostr integration)')
|
// Only log if Holon functionality is enabled
|
||||||
|
if (HOLON_ENABLED) {
|
||||||
|
console.log('⚠️ HoloSphere service initialized (STUB MODE - awaiting Nostr integration)')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async initialize(): Promise<boolean> {
|
async initialize(): Promise<boolean> {
|
||||||
|
|
@ -54,37 +61,40 @@ export class HoloSphereService {
|
||||||
|
|
||||||
// Get a holon for specific coordinates and resolution
|
// Get a holon for specific coordinates and resolution
|
||||||
async getHolon(lat: number, lng: number, resolution: number): Promise<string> {
|
async getHolon(lat: number, lng: number, resolution: number): Promise<string> {
|
||||||
|
if (!HOLON_ENABLED) return ''
|
||||||
try {
|
try {
|
||||||
return h3.latLngToCell(lat, lng, resolution)
|
return h3.latLngToCell(lat, lng, resolution)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('❌ Error getting holon:', error)
|
// Silently fail when disabled
|
||||||
return ''
|
return ''
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Store data in local cache (placeholder for Nostr)
|
// Store data in local cache (placeholder for Nostr)
|
||||||
async putData(holon: string, lens: string, data: any): Promise<boolean> {
|
async putData(holon: string, lens: string, data: any): Promise<boolean> {
|
||||||
|
if (!HOLON_ENABLED) return false
|
||||||
const key = `${holon}:${lens}`
|
const key = `${holon}:${lens}`
|
||||||
const existing = this.localCache.get(key) || {}
|
const existing = this.localCache.get(key) || {}
|
||||||
this.localCache.set(key, { ...existing, ...data })
|
this.localCache.set(key, { ...existing, ...data })
|
||||||
console.log(`📝 [STUB] Stored data locally: ${key}`)
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
// Retrieve data from local cache
|
// Retrieve data from local cache
|
||||||
async getData(holon: string, lens: string, _key?: string): Promise<any> {
|
async getData(holon: string, lens: string, _key?: string): Promise<any> {
|
||||||
|
if (!HOLON_ENABLED) return null
|
||||||
const cacheKey = `${holon}:${lens}`
|
const cacheKey = `${holon}:${lens}`
|
||||||
return this.localCache.get(cacheKey) || null
|
return this.localCache.get(cacheKey) || null
|
||||||
}
|
}
|
||||||
|
|
||||||
// Retrieve data with subscription (stub - just returns cached data)
|
// Retrieve data with subscription (stub - just returns cached data)
|
||||||
async getDataWithWait(holon: string, lens: string, _timeoutMs: number = 5000): Promise<any> {
|
async getDataWithWait(holon: string, lens: string, _timeoutMs: number = 5000): Promise<any> {
|
||||||
console.log(`🔍 [STUB] getDataWithWait: holon=${holon}, lens=${lens}`)
|
if (!HOLON_ENABLED) return null
|
||||||
return this.getData(holon, lens)
|
return this.getData(holon, lens)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete data from local cache
|
// Delete data from local cache
|
||||||
async deleteData(holon: string, lens: string, _key?: string): Promise<boolean> {
|
async deleteData(holon: string, lens: string, _key?: string): Promise<boolean> {
|
||||||
|
if (!HOLON_ENABLED) return false
|
||||||
const cacheKey = `${holon}:${lens}`
|
const cacheKey = `${holon}:${lens}`
|
||||||
this.localCache.delete(cacheKey)
|
this.localCache.delete(cacheKey)
|
||||||
return true
|
return true
|
||||||
|
|
@ -92,7 +102,7 @@ export class HoloSphereService {
|
||||||
|
|
||||||
// Schema methods (stub)
|
// Schema methods (stub)
|
||||||
async setSchema(_lens: string, _schema: any): Promise<boolean> {
|
async setSchema(_lens: string, _schema: any): Promise<boolean> {
|
||||||
console.log('⚠️ [STUB] setSchema not implemented')
|
if (!HOLON_ENABLED) return false
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -102,24 +112,25 @@ export class HoloSphereService {
|
||||||
|
|
||||||
// Subscribe to changes (stub - no-op)
|
// Subscribe to changes (stub - no-op)
|
||||||
subscribe(_holon: string, _lens: string, _callback: (data: any) => void): void {
|
subscribe(_holon: string, _lens: string, _callback: (data: any) => void): void {
|
||||||
console.log('⚠️ [STUB] subscribe not implemented - awaiting Nostr integration')
|
// No-op when disabled or in stub mode
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get holon hierarchy using h3-js
|
// Get holon hierarchy using h3-js
|
||||||
getHolonHierarchy(holon: string): { parent?: string; children: string[] } {
|
getHolonHierarchy(holon: string): { parent?: string; children: string[] } {
|
||||||
|
if (!HOLON_ENABLED) return { children: [] }
|
||||||
try {
|
try {
|
||||||
const resolution = h3.getResolution(holon)
|
const resolution = h3.getResolution(holon)
|
||||||
const parent = resolution > 0 ? h3.cellToParent(holon, resolution - 1) : undefined
|
const parent = resolution > 0 ? h3.cellToParent(holon, resolution - 1) : undefined
|
||||||
const children = h3.cellToChildren(holon, resolution + 1)
|
const children = h3.cellToChildren(holon, resolution + 1)
|
||||||
return { parent, children }
|
return { parent, children }
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('❌ Error getting holon hierarchy:', error)
|
|
||||||
return { children: [] }
|
return { children: [] }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get all scales for a holon
|
// Get all scales for a holon
|
||||||
getHolonScalespace(holon: string): string[] {
|
getHolonScalespace(holon: string): string[] {
|
||||||
|
if (!HOLON_ENABLED) return []
|
||||||
try {
|
try {
|
||||||
const resolution = h3.getResolution(holon)
|
const resolution = h3.getResolution(holon)
|
||||||
const scales: string[] = [holon]
|
const scales: string[] = [holon]
|
||||||
|
|
@ -133,19 +144,16 @@ export class HoloSphereService {
|
||||||
|
|
||||||
return scales
|
return scales
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('❌ Error getting holon scalespace:', error)
|
|
||||||
return []
|
return []
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Federation methods (stub)
|
// Federation methods (stub)
|
||||||
async federate(_spaceId1: string, _spaceId2: string, _password1?: string, _password2?: string, _bidirectional?: boolean): Promise<boolean> {
|
async federate(_spaceId1: string, _spaceId2: string, _password1?: string, _password2?: string, _bidirectional?: boolean): Promise<boolean> {
|
||||||
console.log('⚠️ [STUB] federate not implemented - awaiting Nostr integration')
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
async propagate(_holon: string, _lens: string, _data: any, _options?: { useReferences?: boolean; targetSpaces?: string[] }): Promise<boolean> {
|
async propagate(_holon: string, _lens: string, _data: any, _options?: { useReferences?: boolean; targetSpaces?: string[] }): Promise<boolean> {
|
||||||
console.log('⚠️ [STUB] propagate not implemented - awaiting Nostr integration')
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ import {
|
||||||
TLBaseShape,
|
TLBaseShape,
|
||||||
} from "tldraw"
|
} from "tldraw"
|
||||||
import React, { useState, useRef, useEffect, useCallback } from "react"
|
import React, { useState, useRef, useEffect, useCallback } from "react"
|
||||||
import { holosphereService, HoloSphereService, HolonConnection } from "@/lib/HoloSphereService"
|
import { holosphereService, HoloSphereService, HolonConnection, HOLON_ENABLED } from "@/lib/HoloSphereService"
|
||||||
import * as h3 from 'h3-js'
|
import * as h3 from 'h3-js'
|
||||||
import { StandardizedToolWrapper } from "../components/StandardizedToolWrapper"
|
import { StandardizedToolWrapper } from "../components/StandardizedToolWrapper"
|
||||||
import { usePinnedToView } from "../hooks/usePinnedToView"
|
import { usePinnedToView } from "../hooks/usePinnedToView"
|
||||||
|
|
@ -99,7 +99,45 @@ export class HolonShape extends BaseBoxShapeUtil<IHolon> {
|
||||||
data, connections, lastUpdated
|
data, connections, lastUpdated
|
||||||
} = shape.props
|
} = shape.props
|
||||||
|
|
||||||
console.log('🔧 Holon component rendering - isEditing:', isEditing, 'holonId:', holonId)
|
// If Holon functionality is disabled, show a disabled message
|
||||||
|
if (!HOLON_ENABLED) {
|
||||||
|
return (
|
||||||
|
<HTMLContainer style={{ width: w, height: h }}>
|
||||||
|
<div style={{
|
||||||
|
width: '100%',
|
||||||
|
height: '100%',
|
||||||
|
backgroundColor: '#f3f4f6',
|
||||||
|
border: '2px solid #d1d5db',
|
||||||
|
borderRadius: '8px',
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'column',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
padding: '20px',
|
||||||
|
boxSizing: 'border-box',
|
||||||
|
}}>
|
||||||
|
<div style={{ fontSize: '48px', marginBottom: '16px' }}>🌐</div>
|
||||||
|
<div style={{
|
||||||
|
fontSize: '16px',
|
||||||
|
fontWeight: '600',
|
||||||
|
color: '#374151',
|
||||||
|
marginBottom: '8px',
|
||||||
|
textAlign: 'center'
|
||||||
|
}}>
|
||||||
|
Holon Feature Disabled
|
||||||
|
</div>
|
||||||
|
<div style={{
|
||||||
|
fontSize: '12px',
|
||||||
|
color: '#6b7280',
|
||||||
|
textAlign: 'center',
|
||||||
|
maxWidth: '300px'
|
||||||
|
}}>
|
||||||
|
Holon functionality is currently disabled. It will be re-enabled when Nostr integration is available.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</HTMLContainer>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
const [isHovering, setIsHovering] = useState(false)
|
const [isHovering, setIsHovering] = useState(false)
|
||||||
const [isLoading, setIsLoading] = useState(false)
|
const [isLoading, setIsLoading] = useState(false)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue