holosphere 2.0.0-alpha0 → 2.0.0-alpha10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +473 -0
- package/FEATURES.md +431 -0
- package/LICENSE +29 -42
- package/LICENSE-AGPL.md +180 -0
- package/README.md +97 -16
- package/dist/2019-D2OG2idw.js +6680 -0
- package/dist/2019-D2OG2idw.js.map +1 -0
- package/dist/2019-EION3wKo.cjs +8 -0
- package/dist/2019-EION3wKo.cjs.map +1 -0
- package/dist/_commonjsHelpers-C37NGDzP.cjs +2 -0
- package/dist/_commonjsHelpers-C37NGDzP.cjs.map +1 -0
- package/dist/_commonjsHelpers-CUmg6egw.js +7 -0
- package/dist/_commonjsHelpers-CUmg6egw.js.map +1 -0
- package/dist/browser-BSniCNqO.js +3058 -0
- package/dist/browser-BSniCNqO.js.map +1 -0
- package/dist/browser-Cq59Ij19.cjs +2 -0
- package/dist/browser-Cq59Ij19.cjs.map +1 -0
- package/dist/cdn/holosphere.min.js +55 -0
- package/dist/cdn/holosphere.min.js.map +1 -0
- package/dist/cjs/holosphere.cjs +2 -0
- package/dist/cjs/holosphere.cjs.map +1 -0
- package/dist/esm/holosphere.js +53 -0
- package/dist/esm/holosphere.js.map +1 -0
- package/dist/index-DDGt_V9o.cjs +12 -0
- package/dist/index-DDGt_V9o.cjs.map +1 -0
- package/dist/index-DJXftyvB.js +39841 -0
- package/dist/index-DJXftyvB.js.map +1 -0
- package/dist/index-DMbdcMtK.cjs +18 -0
- package/dist/index-DMbdcMtK.cjs.map +1 -0
- package/dist/index-DeZ1xz_s.js +15104 -0
- package/dist/index-DeZ1xz_s.js.map +1 -0
- package/dist/indexeddb-storage-BFt6hMeF.js +176 -0
- package/dist/indexeddb-storage-BFt6hMeF.js.map +1 -0
- package/dist/indexeddb-storage-BK5tv4Sh.cjs +2 -0
- package/dist/indexeddb-storage-BK5tv4Sh.cjs.map +1 -0
- package/dist/memory-storage-C9HuoL2E.js +91 -0
- package/dist/memory-storage-C9HuoL2E.js.map +1 -0
- package/dist/memory-storage-Dao7jfYG.cjs +2 -0
- package/dist/memory-storage-Dao7jfYG.cjs.map +1 -0
- package/dist/secp256k1-BbKzbLtD.cjs +12 -0
- package/dist/secp256k1-BbKzbLtD.cjs.map +1 -0
- package/dist/secp256k1-CreY7Pcl.js +1890 -0
- package/dist/secp256k1-CreY7Pcl.js.map +1 -0
- package/docs/CONTRACTS.md +797 -0
- package/docs/FOSDEM_PROPOSAL.md +388 -0
- package/docs/LOCALFIRST.md +266 -0
- package/docs/api/ai_aggregation.js.html +333 -0
- package/docs/api/ai_breakdown.js.html +524 -0
- package/docs/api/ai_classifier.js.html +231 -0
- package/docs/api/ai_council.js.html +246 -0
- package/docs/api/ai_embeddings.js.html +304 -0
- package/docs/api/ai_federation-ai.js.html +338 -0
- package/docs/api/ai_h3-ai.js.html +970 -0
- package/docs/api/ai_index.js.html +124 -0
- package/docs/api/ai_json-ops.js.html +241 -0
- package/docs/api/ai_llm-service.js.html +239 -0
- package/docs/api/ai_nl-query.js.html +236 -0
- package/docs/api/ai_relationships.js.html +367 -0
- package/docs/api/ai_schema-extractor.js.html +235 -0
- package/docs/api/ai_spatial.js.html +307 -0
- package/docs/api/ai_tts.js.html +214 -0
- package/docs/api/content_social-protocols.js.html +180 -0
- package/docs/api/core_holosphere.js.html +757 -0
- package/docs/api/crypto_nostr-utils.js.html +306 -0
- package/docs/api/crypto_secp256k1.js.html +267 -0
- package/docs/api/data/search.json +1 -0
- package/docs/api/federation_discovery.js.html +337 -0
- package/docs/api/federation_handshake.js.html +478 -0
- package/docs/api/federation_hologram.js.html +1053 -0
- package/docs/api/federation_registry.js.html +389 -0
- package/docs/api/fonts/Inconsolata-Regular.ttf +0 -0
- package/docs/api/fonts/OpenSans-Regular.ttf +0 -0
- package/docs/api/fonts/WorkSans-Bold.ttf +0 -0
- package/docs/api/global.html +3 -0
- package/docs/api/hierarchical_upcast.js.html +128 -0
- package/docs/api/index.html +265 -0
- package/docs/api/index.js.html +1868 -0
- package/docs/api/lib_ai-methods.js.html +660 -0
- package/docs/api/lib_contract-methods.js.html +445 -0
- package/docs/api/lib_errors.js.html +56 -0
- package/docs/api/lib_federation-methods.js.html +348 -0
- package/docs/api/lib_index.js.html +33 -0
- package/docs/api/module-ai.html +5 -0
- package/docs/api/module-ai_aggregation-SmartAggregation.html +6 -0
- package/docs/api/module-ai_aggregation.SmartAggregation.html +3 -0
- package/docs/api/module-ai_aggregation.html +3 -0
- package/docs/api/module-ai_breakdown-TaskBreakdown.html +5 -0
- package/docs/api/module-ai_breakdown.TaskBreakdown.html +3 -0
- package/docs/api/module-ai_breakdown.html +3 -0
- package/docs/api/module-ai_classifier-Classifier.html +6 -0
- package/docs/api/module-ai_classifier.Classifier.html +3 -0
- package/docs/api/module-ai_classifier.html +3 -0
- package/docs/api/module-ai_council-Council.html +6 -0
- package/docs/api/module-ai_council.Council.html +3 -0
- package/docs/api/module-ai_council.html +3 -0
- package/docs/api/module-ai_embeddings-Embeddings.html +5 -0
- package/docs/api/module-ai_embeddings.Embeddings.html +3 -0
- package/docs/api/module-ai_embeddings.html +3 -0
- package/docs/api/module-ai_federation-ai-FederationAdvisor.html +6 -0
- package/docs/api/module-ai_federation-ai.FederationAdvisor.html +3 -0
- package/docs/api/module-ai_federation-ai.html +3 -0
- package/docs/api/module-ai_h3-ai-H3AI.html +6 -0
- package/docs/api/module-ai_h3-ai.H3AI.html +3 -0
- package/docs/api/module-ai_h3-ai.html +3 -0
- package/docs/api/module-ai_json-ops-JSONOps.html +5 -0
- package/docs/api/module-ai_json-ops.JSONOps.html +3 -0
- package/docs/api/module-ai_json-ops.html +3 -0
- package/docs/api/module-ai_llm-service-LLMService.html +5 -0
- package/docs/api/module-ai_llm-service.LLMService.html +3 -0
- package/docs/api/module-ai_llm-service.html +3 -0
- package/docs/api/module-ai_nl-query-NLQuery.html +5 -0
- package/docs/api/module-ai_nl-query.NLQuery.html +3 -0
- package/docs/api/module-ai_nl-query.html +3 -0
- package/docs/api/module-ai_relationships-RelationshipDiscovery.html +6 -0
- package/docs/api/module-ai_relationships.RelationshipDiscovery.html +3 -0
- package/docs/api/module-ai_relationships.html +3 -0
- package/docs/api/module-ai_schema-extractor-SchemaExtractor.html +5 -0
- package/docs/api/module-ai_schema-extractor.SchemaExtractor.html +3 -0
- package/docs/api/module-ai_schema-extractor.html +3 -0
- package/docs/api/module-ai_spatial-SpatialAnalysis.html +6 -0
- package/docs/api/module-ai_spatial.SpatialAnalysis.html +3 -0
- package/docs/api/module-ai_spatial.html +3 -0
- package/docs/api/module-ai_tts-TTS.html +5 -0
- package/docs/api/module-ai_tts.TTS.html +3 -0
- package/docs/api/module-ai_tts.html +3 -0
- package/docs/api/module-content_social-protocols.html +3 -0
- package/docs/api/module-core_holosphere-HoloSphere.html +6 -0
- package/docs/api/module-core_holosphere.HoloSphere.html +3 -0
- package/docs/api/module-core_holosphere.html +3 -0
- package/docs/api/module-crypto_nostr-utils.html +3 -0
- package/docs/api/module-crypto_secp256k1.html +3 -0
- package/docs/api/module-federation_hologram.html +3 -0
- package/docs/api/module-hierarchical_upcast.html +3 -0
- package/docs/api/module-holosphere-HoloSphereBase.html +3 -0
- package/docs/api/module-holosphere.html +3 -0
- package/docs/api/module-lib_ai-methods.html +3 -0
- package/docs/api/module-lib_contract-methods.html +3 -0
- package/docs/api/module-lib_errors-AuthorizationError.html +3 -0
- package/docs/api/module-lib_errors-ValidationError.html +3 -0
- package/docs/api/module-lib_errors.AuthorizationError.html +3 -0
- package/docs/api/module-lib_errors.ValidationError.html +3 -0
- package/docs/api/module-lib_errors.html +3 -0
- package/docs/api/module-lib_federation-methods.html +3 -0
- package/docs/api/module-lib_index.html +3 -0
- package/docs/api/module-schema_validator-ValidationError.html +3 -0
- package/docs/api/module-schema_validator.ValidationError.html +3 -0
- package/docs/api/module-schema_validator.html +3 -0
- package/docs/api/module-spatial_h3-operations.html +4 -0
- package/docs/api/module-storage_backend-factory.BackendFactory.html +3 -0
- package/docs/api/module-storage_backend-factory.html +3 -0
- package/docs/api/module-storage_backend-interface-StorageBackend.html +3 -0
- package/docs/api/module-storage_backend-interface.StorageBackend.html +3 -0
- package/docs/api/module-storage_backend-interface.html +3 -0
- package/docs/api/module-storage_backends_activitypub-backend-ActivityPubBackend.html +7 -0
- package/docs/api/module-storage_backends_activitypub-backend.ActivityPubBackend.html +3 -0
- package/docs/api/module-storage_backends_activitypub-backend.html +3 -0
- package/docs/api/module-storage_backends_activitypub_server-ActivityPubServer.html +8 -0
- package/docs/api/module-storage_backends_activitypub_server.ActivityPubServer.html +3 -0
- package/docs/api/module-storage_backends_activitypub_server.html +3 -0
- package/docs/api/module-storage_backends_gundb-backend-GunDBBackend.html +7 -0
- package/docs/api/module-storage_backends_gundb-backend.GunDBBackend.html +3 -0
- package/docs/api/module-storage_backends_gundb-backend.html +3 -0
- package/docs/api/module-storage_backends_nostr-backend-NostrBackend.html +8 -0
- package/docs/api/module-storage_backends_nostr-backend.NostrBackend.html +3 -0
- package/docs/api/module-storage_backends_nostr-backend.html +3 -0
- package/docs/api/module-storage_filesystem-storage-FileSystemStorage.html +5 -0
- package/docs/api/module-storage_filesystem-storage-browser-FileSystemStorage.html +3 -0
- package/docs/api/module-storage_filesystem-storage-browser.FileSystemStorage.html +3 -0
- package/docs/api/module-storage_filesystem-storage-browser.html +3 -0
- package/docs/api/module-storage_filesystem-storage.FileSystemStorage.html +3 -0
- package/docs/api/module-storage_filesystem-storage.html +3 -0
- package/docs/api/module-storage_global-tables.html +3 -0
- package/docs/api/module-storage_gun-async.html +3 -0
- package/docs/api/module-storage_gun-auth-GunAuth.html +5 -0
- package/docs/api/module-storage_gun-auth.GunAuth.html +3 -0
- package/docs/api/module-storage_gun-auth.html +3 -0
- package/docs/api/module-storage_gun-federation.html +3 -0
- package/docs/api/module-storage_gun-references-GunReferenceHandler.html +5 -0
- package/docs/api/module-storage_gun-references.GunReferenceHandler.html +3 -0
- package/docs/api/module-storage_gun-references.html +3 -0
- package/docs/api/module-storage_gun-schema-GunSchemaValidator.html +5 -0
- package/docs/api/module-storage_gun-schema.GunSchemaValidator.html +3 -0
- package/docs/api/module-storage_gun-schema.html +3 -0
- package/docs/api/module-storage_gun-wrapper.html +11 -0
- package/docs/api/module-storage_indexeddb-storage-IndexedDBStorage.html +5 -0
- package/docs/api/module-storage_indexeddb-storage.IndexedDBStorage.html +3 -0
- package/docs/api/module-storage_indexeddb-storage.html +3 -0
- package/docs/api/module-storage_key-storage-simple.html +3 -0
- package/docs/api/module-storage_key-storage.html +4 -0
- package/docs/api/module-storage_memory-storage-MemoryStorage.html +5 -0
- package/docs/api/module-storage_memory-storage.MemoryStorage.html +3 -0
- package/docs/api/module-storage_memory-storage.html +3 -0
- package/docs/api/module-storage_migration-MigrationTool.html +6 -0
- package/docs/api/module-storage_migration.MigrationTool.html +3 -0
- package/docs/api/module-storage_migration.html +3 -0
- package/docs/api/module-storage_nostr-async.html +18 -0
- package/docs/api/module-storage_nostr-client-LRUCache.html +3 -0
- package/docs/api/module-storage_nostr-client-NostrClient.html +7 -0
- package/docs/api/module-storage_nostr-client.NostrClient.html +15 -0
- package/docs/api/module-storage_nostr-client.html +6 -0
- package/docs/api/module-storage_nostr-wrapper.html +3 -0
- package/docs/api/module-storage_outbox-queue-OutboxQueue.html +4 -0
- package/docs/api/module-storage_outbox-queue.OutboxQueue.html +3 -0
- package/docs/api/module-storage_outbox-queue.html +3 -0
- package/docs/api/module-storage_persistent-storage-PersistentStorage.html +3 -0
- package/docs/api/module-storage_persistent-storage.html +4 -0
- package/docs/api/module-storage_sync-service-SyncService.html +5 -0
- package/docs/api/module-storage_sync-service.SyncService.html +3 -0
- package/docs/api/module-storage_sync-service.html +3 -0
- package/docs/api/module-storage_unified-storage.html +3 -0
- package/docs/api/module-subscriptions_manager.SubscriptionRegistry.html +3 -0
- package/docs/api/module-subscriptions_manager.html +3 -0
- package/docs/api/schema_validator.js.html +113 -0
- package/docs/api/scripts/core.js +726 -0
- package/docs/api/scripts/core.min.js +23 -0
- package/docs/api/scripts/resize.js +90 -0
- package/docs/api/scripts/search.js +265 -0
- package/docs/api/scripts/search.min.js +6 -0
- package/docs/api/scripts/third-party/Apache-License-2.0.txt +202 -0
- package/docs/api/scripts/third-party/fuse.js +9 -0
- package/docs/api/scripts/third-party/hljs-line-num-original.js +369 -0
- package/docs/api/scripts/third-party/hljs-line-num.js +1 -0
- package/docs/api/scripts/third-party/hljs-original.js +5171 -0
- package/docs/api/scripts/third-party/hljs.js +1 -0
- package/docs/api/scripts/third-party/popper.js +5 -0
- package/docs/api/scripts/third-party/tippy.js +1 -0
- package/docs/api/scripts/third-party/tocbot.js +672 -0
- package/docs/api/scripts/third-party/tocbot.min.js +1 -0
- package/docs/api/spatial_h3-operations.js.html +129 -0
- package/docs/api/storage_backend-factory.js.html +133 -0
- package/docs/api/storage_backend-interface.js.html +164 -0
- package/docs/api/storage_backends_activitypub-backend.js.html +298 -0
- package/docs/api/storage_backends_activitypub_server.js.html +678 -0
- package/docs/api/storage_backends_gundb-backend.js.html +878 -0
- package/docs/api/storage_backends_nostr-backend.js.html +254 -0
- package/docs/api/storage_filesystem-storage-browser.js.html +83 -0
- package/docs/api/storage_filesystem-storage.js.html +207 -0
- package/docs/api/storage_global-tables.js.html +116 -0
- package/docs/api/storage_gun-async.js.html +344 -0
- package/docs/api/storage_gun-auth.js.html +376 -0
- package/docs/api/storage_gun-federation.js.html +788 -0
- package/docs/api/storage_gun-references.js.html +212 -0
- package/docs/api/storage_gun-schema.js.html +309 -0
- package/docs/api/storage_gun-wrapper.js.html +645 -0
- package/docs/api/storage_indexeddb-storage.js.html +224 -0
- package/docs/api/storage_key-storage-simple.js.html +102 -0
- package/docs/api/storage_key-storage.js.html +171 -0
- package/docs/api/storage_memory-storage.js.html +128 -0
- package/docs/api/storage_migration.js.html +354 -0
- package/docs/api/storage_nostr-async.js.html +1076 -0
- package/docs/api/storage_nostr-client.js.html +1598 -0
- package/docs/api/storage_nostr-wrapper.js.html +218 -0
- package/docs/api/storage_outbox-queue.js.html +248 -0
- package/docs/api/storage_persistent-storage.js.html +160 -0
- package/docs/api/storage_sync-service.js.html +201 -0
- package/docs/api/storage_unified-storage.js.html +157 -0
- package/docs/api/styles/clean-jsdoc-theme-base.css +1159 -0
- package/docs/api/styles/clean-jsdoc-theme-dark.css +412 -0
- package/docs/api/styles/clean-jsdoc-theme-light.css +482 -0
- package/docs/api/styles/clean-jsdoc-theme-scrollbar.css +30 -0
- package/docs/api/styles/clean-jsdoc-theme-without-scrollbar.min.css +1 -0
- package/docs/api/styles/clean-jsdoc-theme.min.css +1 -0
- package/docs/api/subscriptions_manager.js.html +162 -0
- package/docs/contracts/api-interface.md +793 -0
- package/docs/data-model.md +476 -0
- package/docs/gun-async-usage.md +338 -0
- package/docs/plan.md +349 -0
- package/docs/quickstart.md +674 -0
- package/docs/research.md +362 -0
- package/docs/spec.md +244 -0
- package/docs/storage-backends.md +326 -0
- package/docs/tasks.md +947 -0
- package/examples/demo.html +47 -0
- package/examples/holosphere-widget.js +1242 -0
- package/examples/widget-demo.html +274 -0
- package/examples/widget.html +703 -0
- package/jsdoc.json +26 -0
- package/package.json +25 -7
- package/src/ai/aggregation.js +13 -2
- package/src/ai/breakdown.js +12 -2
- package/src/ai/classifier.js +14 -3
- package/src/ai/council.js +22 -7
- package/src/ai/embeddings.js +37 -15
- package/src/ai/federation-ai.js +13 -2
- package/src/ai/h3-ai.js +14 -2
- package/src/ai/index.js +16 -7
- package/src/ai/json-ops.js +18 -5
- package/src/ai/llm-service.js +62 -31
- package/src/ai/nl-query.js +12 -2
- package/src/ai/relationships.js +13 -2
- package/src/ai/schema-extractor.js +24 -10
- package/src/ai/spatial.js +13 -2
- package/src/ai/tts.js +25 -8
- package/src/cdn-entry.js +22 -0
- package/src/content/social-protocols.js +34 -25
- package/src/contracts/abis/Appreciative.json +1280 -0
- package/src/contracts/abis/AppreciativeFactory.json +101 -0
- package/src/contracts/abis/Bundle.json +1438 -0
- package/src/contracts/abis/BundleFactory.json +106 -0
- package/src/contracts/abis/Holon.json +881 -0
- package/src/contracts/abis/Holons.json +330 -0
- package/src/contracts/abis/Managed.json +1262 -0
- package/src/contracts/abis/ManagedFactory.json +149 -0
- package/src/contracts/abis/Membrane.json +261 -0
- package/src/contracts/abis/Splitter.json +1624 -0
- package/src/contracts/abis/SplitterFactory.json +220 -0
- package/src/contracts/abis/TestToken.json +321 -0
- package/src/contracts/abis/Zoned.json +1461 -0
- package/src/contracts/abis/ZonedFactory.json +154 -0
- package/src/contracts/chain-manager.js +403 -0
- package/src/contracts/deployer.js +500 -0
- package/src/contracts/event-listener.js +539 -0
- package/src/contracts/holon-contracts.js +359 -0
- package/src/contracts/index.js +82 -0
- package/src/contracts/networks.js +229 -0
- package/src/contracts/operations.js +687 -0
- package/src/contracts/queries.js +638 -0
- package/src/core/holosphere.js +487 -6
- package/src/crypto/nostr-utils.js +303 -0
- package/src/crypto/secp256k1.js +7 -2
- package/src/federation/handshake.js +475 -0
- package/src/federation/hologram.js +117 -3
- package/src/hierarchical/upcast.js +40 -25
- package/src/index.js +1501 -1909
- package/src/lib/ai-methods.js +657 -0
- package/src/lib/contract-methods.js +442 -0
- package/src/lib/errors.js +53 -0
- package/src/lib/federation-methods.js +345 -0
- package/src/lib/index.js +30 -0
- package/src/schema/validator.js +22 -3
- package/src/spatial/h3-operations.js +19 -3
- package/src/storage/backend-factory.js +7 -2
- package/src/storage/backend-interface.js +21 -2
- package/src/storage/backends/activitypub/server.js +25 -3
- package/src/storage/backends/activitypub-backend.js +25 -2
- package/src/storage/backends/gundb-backend.js +692 -50
- package/src/storage/backends/nostr-backend.js +116 -1
- package/src/storage/filesystem-storage-browser.js +42 -2
- package/src/storage/filesystem-storage.js +72 -5
- package/src/storage/global-tables.js +35 -3
- package/src/storage/gun-async.js +75 -15
- package/src/storage/gun-auth.js +373 -0
- package/src/storage/gun-federation.js +785 -0
- package/src/storage/gun-references.js +209 -0
- package/src/storage/gun-schema.js +306 -0
- package/src/storage/gun-wrapper.js +475 -54
- package/src/storage/indexeddb-storage.js +112 -13
- package/src/storage/key-storage-simple.js +32 -9
- package/src/storage/key-storage.js +45 -13
- package/src/storage/memory-storage.js +68 -2
- package/src/storage/migration.js +20 -7
- package/src/storage/nostr-async.js +412 -122
- package/src/storage/nostr-client.js +749 -76
- package/src/storage/nostr-wrapper.js +6 -2
- package/src/storage/outbox-queue.js +55 -18
- package/src/storage/persistent-storage.js +62 -14
- package/src/storage/sync-service.js +51 -17
- package/src/storage/unified-storage.js +154 -0
- package/src/subscriptions/manager.js +34 -17
- package/types/index.d.ts +133 -0
- package/vite.config.cdn.js +60 -0
- package/tests/unit/ai/aggregation.test.js +0 -295
- package/tests/unit/ai/breakdown.test.js +0 -446
- package/tests/unit/ai/classifier.test.js +0 -294
- package/tests/unit/ai/council.test.js +0 -262
- package/tests/unit/ai/embeddings.test.js +0 -384
- package/tests/unit/ai/federation-ai.test.js +0 -344
- package/tests/unit/ai/h3-ai.test.js +0 -458
- package/tests/unit/ai/index.test.js +0 -304
- package/tests/unit/ai/json-ops.test.js +0 -307
- package/tests/unit/ai/llm-service.test.js +0 -390
- package/tests/unit/ai/nl-query.test.js +0 -383
- package/tests/unit/ai/relationships.test.js +0 -311
- package/tests/unit/ai/schema-extractor.test.js +0 -384
- package/tests/unit/ai/spatial.test.js +0 -279
- package/tests/unit/ai/tts.test.js +0 -279
- package/tests/unit/content.test.js +0 -332
- package/tests/unit/contract/core.test.js +0 -88
- package/tests/unit/contract/crypto.test.js +0 -198
- package/tests/unit/contract/data.test.js +0 -223
- package/tests/unit/contract/federation.test.js +0 -181
- package/tests/unit/contract/hierarchical.test.js +0 -113
- package/tests/unit/contract/schema.test.js +0 -114
- package/tests/unit/contract/social.test.js +0 -217
- package/tests/unit/contract/spatial.test.js +0 -110
- package/tests/unit/contract/subscriptions.test.js +0 -128
- package/tests/unit/contract/utils.test.js +0 -159
- package/tests/unit/core.test.js +0 -152
- package/tests/unit/crypto.test.js +0 -328
- package/tests/unit/federation.test.js +0 -234
- package/tests/unit/gun-async.test.js +0 -252
- package/tests/unit/hierarchical.test.js +0 -399
- package/tests/unit/integration/scenario-01-geographic-storage.test.js +0 -74
- package/tests/unit/integration/scenario-02-federation.test.js +0 -76
- package/tests/unit/integration/scenario-03-subscriptions.test.js +0 -102
- package/tests/unit/integration/scenario-04-validation.test.js +0 -129
- package/tests/unit/integration/scenario-05-hierarchy.test.js +0 -125
- package/tests/unit/integration/scenario-06-social.test.js +0 -135
- package/tests/unit/integration/scenario-07-persistence.test.js +0 -130
- package/tests/unit/integration/scenario-08-authorization.test.js +0 -161
- package/tests/unit/integration/scenario-09-cross-dimensional.test.js +0 -139
- package/tests/unit/integration/scenario-10-cross-holosphere-capabilities.test.js +0 -357
- package/tests/unit/integration/scenario-11-cross-holosphere-federation.test.js +0 -410
- package/tests/unit/integration/scenario-12-capability-federated-read.test.js +0 -719
- package/tests/unit/performance/benchmark.test.js +0 -85
- package/tests/unit/schema.test.js +0 -213
- package/tests/unit/spatial.test.js +0 -158
- package/tests/unit/storage.test.js +0 -195
- package/tests/unit/subscriptions.test.js +0 -328
- package/tests/unit/test-data-permanence-debug.js +0 -197
- package/tests/unit/test-data-permanence.js +0 -340
- package/tests/unit/test-key-persistence-fixed.js +0 -148
- package/tests/unit/test-key-persistence.js +0 -172
- package/tests/unit/test-relay-permanence.js +0 -376
- package/tests/unit/test-second-node.js +0 -95
- package/tests/unit/test-simple-write.js +0 -89
- /package/{cleanup-test-data.js → scripts/cleanup-test-data.js} +0 -0
- /package/{test-ai-real-api.js → scripts/test-ai-real-api.js} +0 -0
|
@@ -1,340 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Test Data Permanence Through Relays
|
|
3
|
-
*
|
|
4
|
-
* This comprehensive test validates:
|
|
5
|
-
* 1. Data persistence after writing
|
|
6
|
-
* 2. Data synchronization across nodes
|
|
7
|
-
* 3. Data permanence after node restart
|
|
8
|
-
* 4. Data updates and versioning
|
|
9
|
-
* 5. Data recovery from relays
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
|
-
import { HoloSphere } from './dist/esm/holosphere.js';
|
|
13
|
-
|
|
14
|
-
// Relay configuration - use env vars or these defaults
|
|
15
|
-
const RELAYS = process.env.HOLOSPHERE_RELAYS?.split(',') || [
|
|
16
|
-
'wss://relay.holons.io',
|
|
17
|
-
'wss://relay.nostr.band',
|
|
18
|
-
];
|
|
19
|
-
|
|
20
|
-
// Test configuration
|
|
21
|
-
const TEST_CONFIG = {
|
|
22
|
-
appName: 'permanence-test',
|
|
23
|
-
relays: RELAYS,
|
|
24
|
-
logLevel: 'INFO'
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
const TEST_HOLON = 'global://permanence-test';
|
|
28
|
-
const WAIT_FOR_SYNC = 3000; // 3 seconds for relay sync
|
|
29
|
-
|
|
30
|
-
// Colors for console output
|
|
31
|
-
const colors = {
|
|
32
|
-
reset: '\x1b[0m',
|
|
33
|
-
green: '\x1b[32m',
|
|
34
|
-
red: '\x1b[31m',
|
|
35
|
-
yellow: '\x1b[33m',
|
|
36
|
-
blue: '\x1b[34m',
|
|
37
|
-
cyan: '\x1b[36m'
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
function log(message, color = 'reset') {
|
|
41
|
-
console.log(`${colors[color]}${message}${colors.reset}`);
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
function logSection(title) {
|
|
45
|
-
console.log('\n' + '='.repeat(70));
|
|
46
|
-
log(` ${title}`, 'cyan');
|
|
47
|
-
console.log('='.repeat(70) + '\n');
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
function logTest(testName, passed, details = '') {
|
|
51
|
-
const icon = passed ? '✅' : '❌';
|
|
52
|
-
const color = passed ? 'green' : 'red';
|
|
53
|
-
log(`${icon} ${testName}`, color);
|
|
54
|
-
if (details) {
|
|
55
|
-
console.log(` ${details}`);
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
/**
|
|
60
|
-
* Test 1: Write data and verify immediate persistence
|
|
61
|
-
*/
|
|
62
|
-
async function test1_WritePersistence(hs) {
|
|
63
|
-
logSection('TEST 1: Write and Immediate Persistence');
|
|
64
|
-
|
|
65
|
-
const testData = {
|
|
66
|
-
id: `test-${Date.now()}`,
|
|
67
|
-
timestamp: Date.now(),
|
|
68
|
-
message: 'This is a permanence test',
|
|
69
|
-
metadata: {
|
|
70
|
-
test: 'write-persistence',
|
|
71
|
-
version: 1
|
|
72
|
-
}
|
|
73
|
-
};
|
|
74
|
-
|
|
75
|
-
log('Writing test data...', 'yellow');
|
|
76
|
-
const writeResult = await hs.write(TEST_HOLON, 'test-data', testData);
|
|
77
|
-
logTest('Data written successfully', writeResult, `ID: ${testData.id}`);
|
|
78
|
-
|
|
79
|
-
// Immediate read-back
|
|
80
|
-
log('\nReading data back immediately...', 'yellow');
|
|
81
|
-
const readData = await hs.read(TEST_HOLON, 'test-data');
|
|
82
|
-
|
|
83
|
-
const found = readData && readData.some(d => d.id === testData.id);
|
|
84
|
-
logTest('Data immediately readable', found, found ? `Found ${readData.length} record(s)` : 'Data not found');
|
|
85
|
-
|
|
86
|
-
if (found) {
|
|
87
|
-
const record = readData.find(d => d.id === testData.id);
|
|
88
|
-
const dataMatches = JSON.stringify(record) === JSON.stringify(testData);
|
|
89
|
-
logTest('Data content matches', dataMatches);
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
return { passed: writeResult && found, testData };
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
/**
|
|
96
|
-
* Test 2: Verify data persists after waiting (relay propagation)
|
|
97
|
-
*/
|
|
98
|
-
async function test2_RelayPersistence(hs, testData) {
|
|
99
|
-
logSection('TEST 2: Relay Propagation and Persistence');
|
|
100
|
-
|
|
101
|
-
log(`Waiting ${WAIT_FOR_SYNC / 1000} seconds for relay synchronization...`, 'yellow');
|
|
102
|
-
await new Promise(resolve => setTimeout(resolve, WAIT_FOR_SYNC));
|
|
103
|
-
|
|
104
|
-
log('Reading data after relay sync period...', 'yellow');
|
|
105
|
-
const readData = await hs.read(TEST_HOLON, 'test-data');
|
|
106
|
-
|
|
107
|
-
const found = readData && readData.some(d => d.id === testData.id);
|
|
108
|
-
logTest('Data persists after sync period', found, found ? `Found ${readData.length} record(s)` : 'Data not found');
|
|
109
|
-
|
|
110
|
-
return { passed: found };
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
/**
|
|
114
|
-
* Test 3: Create second node and verify sync
|
|
115
|
-
*/
|
|
116
|
-
async function test3_CrossNodeSync(testData) {
|
|
117
|
-
logSection('TEST 3: Cross-Node Synchronization');
|
|
118
|
-
|
|
119
|
-
log('Creating second node instance...', 'yellow');
|
|
120
|
-
const hs2 = new HoloSphere(TEST_CONFIG);
|
|
121
|
-
|
|
122
|
-
log(`Node 2 Public Key: ${hs2.client.publicKey}`, 'blue');
|
|
123
|
-
log(`Waiting ${WAIT_FOR_SYNC / 1000} seconds for relay connection...`, 'yellow');
|
|
124
|
-
await new Promise(resolve => setTimeout(resolve, WAIT_FOR_SYNC));
|
|
125
|
-
|
|
126
|
-
log('Node 2 reading data from relays...', 'yellow');
|
|
127
|
-
const readData = await hs2.read(TEST_HOLON, 'test-data');
|
|
128
|
-
|
|
129
|
-
const found = readData && readData.some(d => d.id === testData.id);
|
|
130
|
-
logTest('Data synced to second node', found, found ? `Found ${readData.length} record(s)` : 'Data not found');
|
|
131
|
-
|
|
132
|
-
return { passed: found, hs2 };
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
/**
|
|
136
|
-
* Test 4: Restart node and verify data recovery
|
|
137
|
-
*/
|
|
138
|
-
async function test4_NodeRestart(testData) {
|
|
139
|
-
logSection('TEST 4: Node Restart and Data Recovery');
|
|
140
|
-
|
|
141
|
-
log('Creating fresh node instance (simulating restart)...', 'yellow');
|
|
142
|
-
const hsRestart = new HoloSphere(TEST_CONFIG);
|
|
143
|
-
|
|
144
|
-
log(`Restarted Node Public Key: ${hsRestart.client.publicKey}`, 'blue');
|
|
145
|
-
log(`Waiting ${WAIT_FOR_SYNC / 1000} seconds for relay connection...`, 'yellow');
|
|
146
|
-
await new Promise(resolve => setTimeout(resolve, WAIT_FOR_SYNC));
|
|
147
|
-
|
|
148
|
-
log('Restarted node reading data from relays...', 'yellow');
|
|
149
|
-
const readData = await hsRestart.read(TEST_HOLON, 'test-data');
|
|
150
|
-
|
|
151
|
-
const found = readData && readData.some(d => d.id === testData.id);
|
|
152
|
-
logTest('Data recovered after restart', found, found ? `Found ${readData.length} record(s)` : 'Data not found');
|
|
153
|
-
|
|
154
|
-
return { passed: found, hsRestart };
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
/**
|
|
158
|
-
* Test 5: Update data and verify update persistence
|
|
159
|
-
*/
|
|
160
|
-
async function test5_UpdatePersistence(hs, testData) {
|
|
161
|
-
logSection('TEST 5: Update and Update Persistence');
|
|
162
|
-
|
|
163
|
-
const updatedData = {
|
|
164
|
-
...testData,
|
|
165
|
-
message: 'This data has been updated',
|
|
166
|
-
metadata: {
|
|
167
|
-
...testData.metadata,
|
|
168
|
-
version: 2,
|
|
169
|
-
updatedAt: Date.now()
|
|
170
|
-
}
|
|
171
|
-
};
|
|
172
|
-
|
|
173
|
-
log('Writing updated data...', 'yellow');
|
|
174
|
-
const writeResult = await hs.write(TEST_HOLON, 'test-data', updatedData);
|
|
175
|
-
logTest('Updated data written', writeResult);
|
|
176
|
-
|
|
177
|
-
log(`Waiting ${WAIT_FOR_SYNC / 1000} seconds for update propagation...`, 'yellow');
|
|
178
|
-
await new Promise(resolve => setTimeout(resolve, WAIT_FOR_SYNC));
|
|
179
|
-
|
|
180
|
-
log('Reading updated data...', 'yellow');
|
|
181
|
-
const readData = await hs.read(TEST_HOLON, 'test-data');
|
|
182
|
-
|
|
183
|
-
const found = readData && readData.find(d => d.id === testData.id);
|
|
184
|
-
const updatePersisted = found && found.metadata.version === 2;
|
|
185
|
-
|
|
186
|
-
logTest('Update persisted correctly', updatePersisted,
|
|
187
|
-
updatePersisted ? `Version: ${found.metadata.version}` : 'Update not found or incorrect');
|
|
188
|
-
|
|
189
|
-
return { passed: writeResult && updatePersisted };
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
/**
|
|
193
|
-
* Test 6: Verify update visible on second node
|
|
194
|
-
*/
|
|
195
|
-
async function test6_UpdateSync(hs2, testData) {
|
|
196
|
-
logSection('TEST 6: Update Synchronization Across Nodes');
|
|
197
|
-
|
|
198
|
-
log(`Waiting ${WAIT_FOR_SYNC / 1000} seconds for update to sync...`, 'yellow');
|
|
199
|
-
await new Promise(resolve => setTimeout(resolve, WAIT_FOR_SYNC));
|
|
200
|
-
|
|
201
|
-
log('Node 2 reading updated data...', 'yellow');
|
|
202
|
-
const readData = await hs2.read(TEST_HOLON, 'test-data');
|
|
203
|
-
|
|
204
|
-
const found = readData && readData.find(d => d.id === testData.id);
|
|
205
|
-
const updateSynced = found && found.metadata.version === 2;
|
|
206
|
-
|
|
207
|
-
logTest('Update synced to second node', updateSynced,
|
|
208
|
-
updateSynced ? `Version: ${found.metadata.version}, Message: ${found.message}` : 'Update not synced');
|
|
209
|
-
|
|
210
|
-
return { passed: updateSynced };
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
/**
|
|
214
|
-
* Test 7: Multiple writes and verify all persist
|
|
215
|
-
*/
|
|
216
|
-
async function test7_MultipleWrites(hs) {
|
|
217
|
-
logSection('TEST 7: Multiple Writes and Batch Persistence');
|
|
218
|
-
|
|
219
|
-
const records = [];
|
|
220
|
-
const count = 5;
|
|
221
|
-
|
|
222
|
-
log(`Writing ${count} records...`, 'yellow');
|
|
223
|
-
for (let i = 0; i < count; i++) {
|
|
224
|
-
const record = {
|
|
225
|
-
id: `batch-test-${Date.now()}-${i}`,
|
|
226
|
-
index: i,
|
|
227
|
-
timestamp: Date.now(),
|
|
228
|
-
message: `Batch record ${i}`
|
|
229
|
-
};
|
|
230
|
-
records.push(record);
|
|
231
|
-
await hs.write(TEST_HOLON, 'test-data', record);
|
|
232
|
-
log(` Written: ${record.id}`, 'blue');
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
log(`\nWaiting ${WAIT_FOR_SYNC / 1000} seconds for batch sync...`, 'yellow');
|
|
236
|
-
await new Promise(resolve => setTimeout(resolve, WAIT_FOR_SYNC));
|
|
237
|
-
|
|
238
|
-
log('Reading all records...', 'yellow');
|
|
239
|
-
const readData = await hs.read(TEST_HOLON, 'test-data');
|
|
240
|
-
|
|
241
|
-
const foundCount = records.filter(r => readData.some(d => d.id === r.id)).length;
|
|
242
|
-
const allFound = foundCount === count;
|
|
243
|
-
|
|
244
|
-
logTest('All batch records persisted', allFound, `Found ${foundCount}/${count} records`);
|
|
245
|
-
|
|
246
|
-
return { passed: allFound, records };
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
/**
|
|
250
|
-
* Main test runner
|
|
251
|
-
*/
|
|
252
|
-
async function runTests() {
|
|
253
|
-
log('\n╔═══════════════════════════════════════════════════════════════════╗', 'cyan');
|
|
254
|
-
log('║ HOLOSPHERE DATA PERMANENCE TEST SUITE ║', 'cyan');
|
|
255
|
-
log('╚═══════════════════════════════════════════════════════════════════╝', 'cyan');
|
|
256
|
-
|
|
257
|
-
log(`\nTest Configuration:`, 'yellow');
|
|
258
|
-
log(` App Name: ${TEST_CONFIG.appName}`, 'blue');
|
|
259
|
-
log(` Relays:`, 'blue');
|
|
260
|
-
TEST_CONFIG.relays.forEach(relay => log(` - ${relay}`, 'blue'));
|
|
261
|
-
log(` Sync Wait Time: ${WAIT_FOR_SYNC / 1000}s`, 'blue');
|
|
262
|
-
|
|
263
|
-
const results = {
|
|
264
|
-
passed: 0,
|
|
265
|
-
failed: 0,
|
|
266
|
-
tests: []
|
|
267
|
-
};
|
|
268
|
-
|
|
269
|
-
try {
|
|
270
|
-
// Initialize primary node
|
|
271
|
-
log('\nInitializing primary test node...', 'yellow');
|
|
272
|
-
const hs = new HoloSphere(TEST_CONFIG);
|
|
273
|
-
log(`Primary Node Public Key: ${hs.client.publicKey}`, 'blue');
|
|
274
|
-
|
|
275
|
-
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
276
|
-
|
|
277
|
-
// Run tests sequentially
|
|
278
|
-
const { passed: t1, testData } = await test1_WritePersistence(hs);
|
|
279
|
-
results.tests.push({ name: 'Write Persistence', passed: t1 });
|
|
280
|
-
|
|
281
|
-
const { passed: t2 } = await test2_RelayPersistence(hs, testData);
|
|
282
|
-
results.tests.push({ name: 'Relay Persistence', passed: t2 });
|
|
283
|
-
|
|
284
|
-
const { passed: t3, hs2 } = await test3_CrossNodeSync(testData);
|
|
285
|
-
results.tests.push({ name: 'Cross-Node Sync', passed: t3 });
|
|
286
|
-
|
|
287
|
-
const { passed: t4 } = await test4_NodeRestart(testData);
|
|
288
|
-
results.tests.push({ name: 'Node Restart Recovery', passed: t4 });
|
|
289
|
-
|
|
290
|
-
const { passed: t5 } = await test5_UpdatePersistence(hs, testData);
|
|
291
|
-
results.tests.push({ name: 'Update Persistence', passed: t5 });
|
|
292
|
-
|
|
293
|
-
const { passed: t6 } = await test6_UpdateSync(hs2, testData);
|
|
294
|
-
results.tests.push({ name: 'Update Sync', passed: t6 });
|
|
295
|
-
|
|
296
|
-
const { passed: t7 } = await test7_MultipleWrites(hs);
|
|
297
|
-
results.tests.push({ name: 'Batch Persistence', passed: t7 });
|
|
298
|
-
|
|
299
|
-
// Calculate results
|
|
300
|
-
results.passed = results.tests.filter(t => t.passed).length;
|
|
301
|
-
results.failed = results.tests.filter(t => !t.passed).length;
|
|
302
|
-
|
|
303
|
-
} catch (error) {
|
|
304
|
-
log('\n❌ TEST SUITE FAILED WITH ERROR:', 'red');
|
|
305
|
-
console.error(error);
|
|
306
|
-
results.failed++;
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
// Print summary
|
|
310
|
-
logSection('TEST SUMMARY');
|
|
311
|
-
|
|
312
|
-
results.tests.forEach(test => {
|
|
313
|
-
logTest(test.name, test.passed);
|
|
314
|
-
});
|
|
315
|
-
|
|
316
|
-
console.log('\n' + '-'.repeat(70));
|
|
317
|
-
log(`Total Tests: ${results.tests.length}`, 'blue');
|
|
318
|
-
log(`Passed: ${results.passed}`, 'green');
|
|
319
|
-
log(`Failed: ${results.failed}`, 'red');
|
|
320
|
-
log(`Success Rate: ${((results.passed / results.tests.length) * 100).toFixed(1)}%`,
|
|
321
|
-
results.failed === 0 ? 'green' : 'yellow');
|
|
322
|
-
console.log('-'.repeat(70) + '\n');
|
|
323
|
-
|
|
324
|
-
if (results.failed === 0) {
|
|
325
|
-
log('🎉 ALL TESTS PASSED! Data permanence is working correctly.', 'green');
|
|
326
|
-
} else {
|
|
327
|
-
log('⚠️ SOME TESTS FAILED. Please review the results above.', 'yellow');
|
|
328
|
-
}
|
|
329
|
-
|
|
330
|
-
log('\nTest complete. Press Ctrl+C to exit.\n');
|
|
331
|
-
|
|
332
|
-
// Exit after a moment
|
|
333
|
-
setTimeout(() => process.exit(results.failed === 0 ? 0 : 1), 2000);
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
// Run the test suite
|
|
337
|
-
runTests().catch(error => {
|
|
338
|
-
console.error('❌ Fatal error running tests:', error);
|
|
339
|
-
process.exit(1);
|
|
340
|
-
});
|
|
@@ -1,148 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Test Key Persistence Across Restarts
|
|
3
|
-
* Using explicit key management
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import { HoloSphere } from './dist/esm/holosphere.js';
|
|
7
|
-
import { loadKey, saveKey, getOrCreateKey } from './src/storage/key-storage-simple.js';
|
|
8
|
-
import { generateSecretKey } from 'nostr-tools';
|
|
9
|
-
|
|
10
|
-
// Relay configuration - use env vars or these defaults
|
|
11
|
-
const RELAYS = process.env.HOLOSPHERE_RELAYS?.split(',') || [
|
|
12
|
-
'wss://relay.holons.io',
|
|
13
|
-
'wss://relay.nostr.band',
|
|
14
|
-
];
|
|
15
|
-
|
|
16
|
-
const c = {
|
|
17
|
-
reset: '\x1b[0m',
|
|
18
|
-
green: '\x1b[32m',
|
|
19
|
-
red: '\x1b[31m',
|
|
20
|
-
yellow: '\x1b[33m',
|
|
21
|
-
blue: '\x1b[34m',
|
|
22
|
-
cyan: '\x1b[36m',
|
|
23
|
-
bold: '\x1b[1m'
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
function log(msg, color = 'reset') {
|
|
27
|
-
console.log(`${c[color]}${msg}${c.reset}`);
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
console.log('\n╔═══════════════════════════════════════════════════════════════════╗');
|
|
31
|
-
log('║ PRIVATE KEY PERSISTENCE TEST (FIXED) ║', 'cyan');
|
|
32
|
-
console.log('╚═══════════════════════════════════════════════════════════════════╝\n');
|
|
33
|
-
|
|
34
|
-
const APP_NAME = 'key-persist-test';
|
|
35
|
-
|
|
36
|
-
// Helper to generate hex key
|
|
37
|
-
function generatePrivateKey() {
|
|
38
|
-
const secretKey = generateSecretKey();
|
|
39
|
-
return Buffer.from(secretKey).toString('hex');
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
log('TEST 1: Load or create persistent key\n', 'yellow');
|
|
43
|
-
|
|
44
|
-
const privateKey = getOrCreateKey(APP_NAME, generatePrivateKey);
|
|
45
|
-
log(`Key loaded/created:`, 'blue');
|
|
46
|
-
log(` Private Key: ${privateKey.substring(0, 16)}...`, 'blue');
|
|
47
|
-
|
|
48
|
-
log('\nTEST 2: Create first instance with persistent key\n', 'yellow');
|
|
49
|
-
|
|
50
|
-
const hs1 = new HoloSphere({
|
|
51
|
-
appName: APP_NAME,
|
|
52
|
-
relays: RELAYS,
|
|
53
|
-
privateKey: privateKey, // IMPORTANT: Provide the key explicitly
|
|
54
|
-
logLevel: 'WARN'
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
log(`First Instance Created:`, 'blue');
|
|
58
|
-
log(` Public Key: ${hs1.client.publicKey}`, 'blue');
|
|
59
|
-
|
|
60
|
-
// Write some data
|
|
61
|
-
log('\nWriting test data...', 'yellow');
|
|
62
|
-
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
63
|
-
|
|
64
|
-
const testData = {
|
|
65
|
-
id: 'persist-test-1',
|
|
66
|
-
message: 'Testing key persistence',
|
|
67
|
-
timestamp: Date.now()
|
|
68
|
-
};
|
|
69
|
-
|
|
70
|
-
const writeResult = await hs1.write('global://persist', 'data', testData);
|
|
71
|
-
log(writeResult ? '✅ Data written' : '❌ Write failed', writeResult ? 'green' : 'red');
|
|
72
|
-
|
|
73
|
-
// Simulate restart by creating new instance
|
|
74
|
-
log('\n' + '─'.repeat(70), 'cyan');
|
|
75
|
-
log('TEST 3: Simulate restart (load same key, create new instance)\n', 'yellow');
|
|
76
|
-
|
|
77
|
-
const privateKey2 = loadKey(APP_NAME);
|
|
78
|
-
log(`Loaded key from storage: ${privateKey2.substring(0, 16)}...`, 'blue');
|
|
79
|
-
|
|
80
|
-
const hs2 = new HoloSphere({
|
|
81
|
-
appName: APP_NAME,
|
|
82
|
-
relays: RELAYS,
|
|
83
|
-
privateKey: privateKey2, // Use loaded key
|
|
84
|
-
logLevel: 'WARN'
|
|
85
|
-
});
|
|
86
|
-
|
|
87
|
-
log(`Second Instance Created:`, 'blue');
|
|
88
|
-
log(` Public Key: ${hs2.client.publicKey}`, 'blue');
|
|
89
|
-
|
|
90
|
-
// Check if keys match
|
|
91
|
-
log('\n' + '─'.repeat(70), 'cyan');
|
|
92
|
-
log('TEST 4: Verify keys match\n', 'yellow');
|
|
93
|
-
|
|
94
|
-
const keysMatch = (privateKey === privateKey2);
|
|
95
|
-
const pubKeysMatch = (hs1.client.publicKey === hs2.client.publicKey);
|
|
96
|
-
|
|
97
|
-
log(`Private keys match: ${keysMatch ? '✅ YES' : '❌ NO'}`, keysMatch ? 'green' : 'red');
|
|
98
|
-
log(`Public keys match: ${pubKeysMatch ? '✅ YES' : '❌ NO'}`, pubKeysMatch ? 'green' : 'red');
|
|
99
|
-
|
|
100
|
-
// Try to read the data from second instance
|
|
101
|
-
log('\n' + '─'.repeat(70), 'cyan');
|
|
102
|
-
log('TEST 5: Read data from second instance\n', 'yellow');
|
|
103
|
-
|
|
104
|
-
await new Promise(resolve => setTimeout(resolve, 3000));
|
|
105
|
-
|
|
106
|
-
const readData = await hs2.read('global://persist', 'data');
|
|
107
|
-
const found = readData && readData.find(d => d.id === testData.id);
|
|
108
|
-
|
|
109
|
-
log(found ? '✅ Data readable from second instance' : '❌ Data not found', found ? 'green' : 'red');
|
|
110
|
-
|
|
111
|
-
if (found) {
|
|
112
|
-
log(` Message: "${found.message}"`, 'blue');
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
// Summary
|
|
116
|
-
log('\n' + '═'.repeat(70), 'cyan');
|
|
117
|
-
log(' TEST SUMMARY', 'cyan');
|
|
118
|
-
log('═'.repeat(70), 'cyan');
|
|
119
|
-
|
|
120
|
-
const allPassed = keysMatch && pubKeysMatch && found;
|
|
121
|
-
|
|
122
|
-
log('', '');
|
|
123
|
-
log(`✓ Keys match across instances: ${keysMatch ? 'PASS' : 'FAIL'}`, keysMatch ? 'green' : 'red');
|
|
124
|
-
log(`✓ Public keys match: ${pubKeysMatch ? 'PASS' : 'FAIL'}`, pubKeysMatch ? 'green' : 'red');
|
|
125
|
-
log(`✓ Data readable across instances: ${found ? 'PASS' : 'FAIL'}`, found ? 'green' : 'red');
|
|
126
|
-
|
|
127
|
-
if (allPassed) {
|
|
128
|
-
log('\n🎉 ALL TESTS PASSED!', 'bold');
|
|
129
|
-
log('✓ Private keys persist across restarts', 'green');
|
|
130
|
-
log('✓ Same identity maintained with explicit key management', 'green');
|
|
131
|
-
log('\n🔑 Key storage location:', 'blue');
|
|
132
|
-
|
|
133
|
-
const os = await import('os');
|
|
134
|
-
const path = await import('path');
|
|
135
|
-
const keyDir = path.join(os.homedir(), '.config', 'holosphere', 'keys');
|
|
136
|
-
log(` ${keyDir}/${APP_NAME}.key`, 'blue');
|
|
137
|
-
|
|
138
|
-
log('\n📖 Usage pattern for persistence:', 'yellow');
|
|
139
|
-
log(` import { loadKey, saveKey, getOrCreateKey } from 'holosphere/key-storage';`, 'blue');
|
|
140
|
-
log(` const key = getOrCreateKey('my-app', generateKey);`, 'blue');
|
|
141
|
-
log(` const hs = new HoloSphere({ privateKey: key, ... });`, 'blue');
|
|
142
|
-
|
|
143
|
-
log('\n');
|
|
144
|
-
process.exit(0);
|
|
145
|
-
} else {
|
|
146
|
-
log('\n❌ SOME TESTS FAILED', 'red');
|
|
147
|
-
process.exit(1);
|
|
148
|
-
}
|
|
@@ -1,172 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Test Key Persistence Across Restarts
|
|
3
|
-
* Verifies that private keys are saved and loaded correctly
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import { HoloSphere } from './dist/esm/holosphere.js';
|
|
7
|
-
|
|
8
|
-
// Relay configuration - use env vars or these defaults
|
|
9
|
-
const RELAYS = process.env.HOLOSPHERE_RELAYS?.split(',') || [
|
|
10
|
-
'wss://relay.holons.io',
|
|
11
|
-
'wss://relay.nostr.band',
|
|
12
|
-
];
|
|
13
|
-
|
|
14
|
-
const c = {
|
|
15
|
-
reset: '\x1b[0m',
|
|
16
|
-
green: '\x1b[32m',
|
|
17
|
-
red: '\x1b[31m',
|
|
18
|
-
yellow: '\x1b[33m',
|
|
19
|
-
blue: '\x1b[34m',
|
|
20
|
-
cyan: '\x1b[36m',
|
|
21
|
-
bold: '\x1b[1m'
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
function log(msg, color = 'reset') {
|
|
25
|
-
console.log(`${c[color]}${msg}${c.reset}`);
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
console.log('\n╔═══════════════════════════════════════════════════════════════════╗');
|
|
29
|
-
log('║ PRIVATE KEY PERSISTENCE TEST ║', 'cyan');
|
|
30
|
-
console.log('╚═══════════════════════════════════════════════════════════════════╝\n');
|
|
31
|
-
|
|
32
|
-
const APP_NAME = 'key-persist-test';
|
|
33
|
-
|
|
34
|
-
log('TEST 1: Create first instance and check key\n', 'yellow');
|
|
35
|
-
|
|
36
|
-
const hs1 = new HoloSphere({
|
|
37
|
-
appName: APP_NAME,
|
|
38
|
-
relays: RELAYS,
|
|
39
|
-
logLevel: 'WARN'
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
const firstKey = hs1.client.privateKey;
|
|
43
|
-
const firstPubKey = hs1.client.publicKey;
|
|
44
|
-
|
|
45
|
-
log(`First Instance Created:`, 'blue');
|
|
46
|
-
log(` App Name: ${APP_NAME}`, 'blue');
|
|
47
|
-
log(` Private Key: ${firstKey.substring(0, 16)}...`, 'blue');
|
|
48
|
-
log(` Public Key: ${firstPubKey}`, 'blue');
|
|
49
|
-
|
|
50
|
-
// Write some data
|
|
51
|
-
log('\nWriting test data...', 'yellow');
|
|
52
|
-
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
53
|
-
|
|
54
|
-
const testData = {
|
|
55
|
-
id: 'persist-test-1',
|
|
56
|
-
message: 'Testing key persistence',
|
|
57
|
-
timestamp: Date.now()
|
|
58
|
-
};
|
|
59
|
-
|
|
60
|
-
const writeResult = await hs1.write('global://persist', 'data', testData);
|
|
61
|
-
log(writeResult ? '✅ Data written' : '❌ Write failed', writeResult ? 'green' : 'red');
|
|
62
|
-
|
|
63
|
-
// Create second instance (simulating restart)
|
|
64
|
-
log('\n' + '─'.repeat(70), 'cyan');
|
|
65
|
-
log('TEST 2: Create second instance (simulating restart)\n', 'yellow');
|
|
66
|
-
|
|
67
|
-
const hs2 = new HoloSphere({
|
|
68
|
-
appName: APP_NAME, // SAME app name
|
|
69
|
-
relays: RELAYS,
|
|
70
|
-
logLevel: 'WARN'
|
|
71
|
-
});
|
|
72
|
-
|
|
73
|
-
const secondKey = hs2.client.privateKey;
|
|
74
|
-
const secondPubKey = hs2.client.publicKey;
|
|
75
|
-
|
|
76
|
-
log(`Second Instance Created:`, 'blue');
|
|
77
|
-
log(` App Name: ${APP_NAME}`, 'blue');
|
|
78
|
-
log(` Private Key: ${secondKey.substring(0, 16)}...`, 'blue');
|
|
79
|
-
log(` Public Key: ${secondPubKey}`, 'blue');
|
|
80
|
-
|
|
81
|
-
// Check if keys match
|
|
82
|
-
log('\n' + '─'.repeat(70), 'cyan');
|
|
83
|
-
log('TEST 3: Verify keys match\n', 'yellow');
|
|
84
|
-
|
|
85
|
-
const keysMatch = (firstKey === secondKey);
|
|
86
|
-
const pubKeysMatch = (firstPubKey === secondPubKey);
|
|
87
|
-
|
|
88
|
-
log(`Private keys match: ${keysMatch ? '✅ YES' : '❌ NO'}`, keysMatch ? 'green' : 'red');
|
|
89
|
-
log(`Public keys match: ${pubKeysMatch ? '✅ YES' : '❌ NO'}`, pubKeysMatch ? 'green' : 'red');
|
|
90
|
-
|
|
91
|
-
if (!keysMatch) {
|
|
92
|
-
log('\n❌ FAILED: Keys do not match across restarts!', 'red');
|
|
93
|
-
log('First key: ' + firstKey, 'red');
|
|
94
|
-
log('Second key: ' + secondKey, 'red');
|
|
95
|
-
process.exit(1);
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
// Try to read the data from second instance
|
|
99
|
-
log('\n' + '─'.repeat(70), 'cyan');
|
|
100
|
-
log('TEST 4: Read data from second instance\n', 'yellow');
|
|
101
|
-
|
|
102
|
-
await new Promise(resolve => setTimeout(resolve, 3000));
|
|
103
|
-
|
|
104
|
-
const readData = await hs2.read('global://persist', 'data');
|
|
105
|
-
const found = readData && readData.find(d => d.id === testData.id);
|
|
106
|
-
|
|
107
|
-
log(found ? '✅ Data readable from second instance' : '❌ Data not found', found ? 'green' : 'red');
|
|
108
|
-
|
|
109
|
-
if (found) {
|
|
110
|
-
log(` Message: "${found.message}"`, 'blue');
|
|
111
|
-
log(` Timestamp: ${found.timestamp}`, 'blue');
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
// Test with different app name (should get different key)
|
|
115
|
-
log('\n' + '─'.repeat(70), 'cyan');
|
|
116
|
-
log('TEST 5: Different app name should get different key\n', 'yellow');
|
|
117
|
-
|
|
118
|
-
const hs3 = new HoloSphere({
|
|
119
|
-
appName: 'different-app', // DIFFERENT app name
|
|
120
|
-
relays: RELAYS,
|
|
121
|
-
logLevel: 'WARN'
|
|
122
|
-
});
|
|
123
|
-
|
|
124
|
-
const thirdKey = hs3.client.privateKey;
|
|
125
|
-
const thirdPubKey = hs3.client.publicKey;
|
|
126
|
-
|
|
127
|
-
log(`Third Instance (different app):`, 'blue');
|
|
128
|
-
log(` App Name: different-app`, 'blue');
|
|
129
|
-
log(` Private Key: ${thirdKey.substring(0, 16)}...`, 'blue');
|
|
130
|
-
log(` Public Key: ${thirdPubKey}`, 'blue');
|
|
131
|
-
|
|
132
|
-
const differentKeys = (firstKey !== thirdKey);
|
|
133
|
-
const differentPubKeys = (firstPubKey !== thirdPubKey);
|
|
134
|
-
|
|
135
|
-
log(`\nKeys are different: ${differentKeys ? '✅ YES' : '❌ NO'}`, differentKeys ? 'green' : 'red');
|
|
136
|
-
log(`Pub keys different: ${differentPubKeys ? '✅ YES' : '❌ NO'}`, differentPubKeys ? 'green' : 'red');
|
|
137
|
-
|
|
138
|
-
// Summary
|
|
139
|
-
log('\n' + '═'.repeat(70), 'cyan');
|
|
140
|
-
log(' TEST SUMMARY', 'cyan');
|
|
141
|
-
log('═'.repeat(70), 'cyan');
|
|
142
|
-
|
|
143
|
-
const allPassed = keysMatch && pubKeysMatch && found && differentKeys && differentPubKeys;
|
|
144
|
-
|
|
145
|
-
log('', '');
|
|
146
|
-
log(`✓ Same app name = same keys: ${keysMatch ? 'PASS' : 'FAIL'}`, keysMatch ? 'green' : 'red');
|
|
147
|
-
log(`✓ Data readable across instances: ${found ? 'PASS' : 'FAIL'}`, found ? 'green' : 'red');
|
|
148
|
-
log(`✓ Different app = different keys: ${differentKeys ? 'PASS' : 'FAIL'}`, differentKeys ? 'green' : 'red');
|
|
149
|
-
|
|
150
|
-
if (allPassed) {
|
|
151
|
-
log('\n🎉 ALL TESTS PASSED!', 'bold');
|
|
152
|
-
log('✓ Private keys persist across restarts', 'green');
|
|
153
|
-
log('✓ Same identity maintained for same app', 'green');
|
|
154
|
-
log('✓ Different apps get different identities', 'green');
|
|
155
|
-
log('\n🔑 Key storage location:', 'blue');
|
|
156
|
-
|
|
157
|
-
if (typeof window === 'undefined') {
|
|
158
|
-
const os = require('os');
|
|
159
|
-
const path = require('path');
|
|
160
|
-
const keyDir = path.join(os.homedir(), '.config', 'holosphere', 'keys');
|
|
161
|
-
log(` ${keyDir}`, 'blue');
|
|
162
|
-
log(` Files: ${APP_NAME}.key, different-app.key`, 'blue');
|
|
163
|
-
} else {
|
|
164
|
-
log(` Browser localStorage: holosphere_key_${APP_NAME}`, 'blue');
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
log('\n');
|
|
168
|
-
process.exit(0);
|
|
169
|
-
} else {
|
|
170
|
-
log('\n❌ SOME TESTS FAILED', 'red');
|
|
171
|
-
process.exit(1);
|
|
172
|
-
}
|