holosphere 2.0.0-alpha1 → 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 -166
- 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,198 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, beforeEach } from 'vitest';
|
|
2
|
-
import HoloSphere from '../../../src/index.js';
|
|
3
|
-
|
|
4
|
-
describe('Contract: Cryptographic Operations', () => {
|
|
5
|
-
let hs;
|
|
6
|
-
let privateKey;
|
|
7
|
-
let publicKey;
|
|
8
|
-
|
|
9
|
-
beforeEach(async () => {
|
|
10
|
-
hs = new HoloSphere({ relays: [], appName: 'test-crypto' });
|
|
11
|
-
// Generate valid secp256k1 keys
|
|
12
|
-
privateKey = '0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef';
|
|
13
|
-
publicKey = await hs.getPublicKey(privateKey);
|
|
14
|
-
});
|
|
15
|
-
|
|
16
|
-
describe('sign()', () => {
|
|
17
|
-
it('should sign object content and return hex signature', async () => {
|
|
18
|
-
const content = { message: 'Hello, HoloSphere!' };
|
|
19
|
-
const signature = await hs.sign(content, privateKey);
|
|
20
|
-
|
|
21
|
-
expect(typeof signature).toBe('string');
|
|
22
|
-
expect(signature).toMatch(/^[0-9a-f]+$/);
|
|
23
|
-
});
|
|
24
|
-
|
|
25
|
-
it('should sign string content', async () => {
|
|
26
|
-
const content = 'Hello, HoloSphere!';
|
|
27
|
-
const signature = await hs.sign(content, privateKey);
|
|
28
|
-
|
|
29
|
-
expect(typeof signature).toBe('string');
|
|
30
|
-
expect(signature).toMatch(/^[0-9a-f]+$/);
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
it('should throw Error for invalid private key', async () => {
|
|
34
|
-
await expect(
|
|
35
|
-
hs.sign({ message: 'Test' }, 'invalid-key')
|
|
36
|
-
).rejects.toThrow(Error);
|
|
37
|
-
});
|
|
38
|
-
|
|
39
|
-
it('should lazy load crypto module on first call', async () => {
|
|
40
|
-
// First call should trigger lazy load
|
|
41
|
-
const signature = await hs.sign({ message: 'Test' }, privateKey);
|
|
42
|
-
expect(typeof signature).toBe('string');
|
|
43
|
-
});
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
describe('verify()', () => {
|
|
47
|
-
it('should return true for valid signature', async () => {
|
|
48
|
-
const content = { message: 'Hello, HoloSphere!' };
|
|
49
|
-
const signature = await hs.sign(content, privateKey);
|
|
50
|
-
|
|
51
|
-
const isValid = await hs.verify(content, signature, publicKey);
|
|
52
|
-
expect(isValid).toBe(true);
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
it('should return false for tampered content', async () => {
|
|
56
|
-
const content = { message: 'Hello, HoloSphere!' };
|
|
57
|
-
const signature = await hs.sign(content, privateKey);
|
|
58
|
-
|
|
59
|
-
const tamperedContent = { message: 'Tampered message' };
|
|
60
|
-
const isValid = await hs.verify(tamperedContent, signature, publicKey);
|
|
61
|
-
expect(isValid).toBe(false);
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
it('should return false for invalid signature', async () => {
|
|
65
|
-
const content = { message: 'Hello, HoloSphere!' };
|
|
66
|
-
const invalidSignature = 'invalid';
|
|
67
|
-
|
|
68
|
-
const isValid = await hs.verify(content, invalidSignature, publicKey);
|
|
69
|
-
expect(isValid).toBe(false);
|
|
70
|
-
});
|
|
71
|
-
|
|
72
|
-
it('should return false for wrong public key', async () => {
|
|
73
|
-
const content = { message: 'Hello, HoloSphere!' };
|
|
74
|
-
const signature = await hs.sign(content, privateKey);
|
|
75
|
-
|
|
76
|
-
const wrongPublicKey = '04' + 'fedcba9876543210'.repeat(8);
|
|
77
|
-
const isValid = await hs.verify(content, signature, wrongPublicKey);
|
|
78
|
-
expect(isValid).toBe(false);
|
|
79
|
-
});
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
describe('issueCapability()', () => {
|
|
83
|
-
it('should issue capability token with permissions', async () => {
|
|
84
|
-
const token = await hs.issueCapability(
|
|
85
|
-
['read', 'write'],
|
|
86
|
-
{ holonId: '8928342e20fffff', lensName: 'temperature' },
|
|
87
|
-
publicKey
|
|
88
|
-
);
|
|
89
|
-
|
|
90
|
-
expect(typeof token).toBe('string');
|
|
91
|
-
expect(token.length).toBeGreaterThan(0);
|
|
92
|
-
});
|
|
93
|
-
|
|
94
|
-
it('should accept expiresIn option', async () => {
|
|
95
|
-
const token = await hs.issueCapability(
|
|
96
|
-
['read'],
|
|
97
|
-
{ holonId: '8928342e20fffff', lensName: 'temperature' },
|
|
98
|
-
publicKey,
|
|
99
|
-
{ expiresIn: 86400000 } // 24 hours
|
|
100
|
-
);
|
|
101
|
-
|
|
102
|
-
expect(typeof token).toBe('string');
|
|
103
|
-
});
|
|
104
|
-
|
|
105
|
-
it('should accept issuerKey option', async () => {
|
|
106
|
-
const token = await hs.issueCapability(
|
|
107
|
-
['delete'],
|
|
108
|
-
{ holonId: '8928342e20fffff', lensName: 'temperature' },
|
|
109
|
-
publicKey,
|
|
110
|
-
{ issuerKey: privateKey }
|
|
111
|
-
);
|
|
112
|
-
|
|
113
|
-
expect(typeof token).toBe('string');
|
|
114
|
-
});
|
|
115
|
-
|
|
116
|
-
it('should throw Error for invalid issuer key', async () => {
|
|
117
|
-
await expect(
|
|
118
|
-
hs.issueCapability(
|
|
119
|
-
['read'],
|
|
120
|
-
{ holonId: '8928342e20fffff', lensName: 'temperature' },
|
|
121
|
-
publicKey,
|
|
122
|
-
{ issuerKey: 'invalid-key' }
|
|
123
|
-
)
|
|
124
|
-
).rejects.toThrow(Error);
|
|
125
|
-
});
|
|
126
|
-
|
|
127
|
-
it('should support multiple permissions', async () => {
|
|
128
|
-
const token = await hs.issueCapability(
|
|
129
|
-
['read', 'write', 'delete'],
|
|
130
|
-
{ holonId: '8928342e20fffff', lensName: 'temperature' },
|
|
131
|
-
publicKey
|
|
132
|
-
);
|
|
133
|
-
|
|
134
|
-
expect(typeof token).toBe('string');
|
|
135
|
-
});
|
|
136
|
-
});
|
|
137
|
-
|
|
138
|
-
describe('verifyCapability()', () => {
|
|
139
|
-
it('should return true for valid token with required permission', async () => {
|
|
140
|
-
const token = await hs.issueCapability(
|
|
141
|
-
['read', 'write', 'delete'],
|
|
142
|
-
{ holonId: '8928342e20fffff', lensName: 'temperature' },
|
|
143
|
-
publicKey
|
|
144
|
-
);
|
|
145
|
-
|
|
146
|
-
const isValid = await hs.verifyCapability(
|
|
147
|
-
token,
|
|
148
|
-
'delete',
|
|
149
|
-
{ holonId: '8928342e20fffff', lensName: 'temperature' }
|
|
150
|
-
);
|
|
151
|
-
|
|
152
|
-
expect(isValid).toBe(true);
|
|
153
|
-
});
|
|
154
|
-
|
|
155
|
-
it('should return false for token without required permission', async () => {
|
|
156
|
-
const token = await hs.issueCapability(
|
|
157
|
-
['read', 'write'],
|
|
158
|
-
{ holonId: '8928342e20fffff', lensName: 'temperature' },
|
|
159
|
-
publicKey
|
|
160
|
-
);
|
|
161
|
-
|
|
162
|
-
const isValid = await hs.verifyCapability(
|
|
163
|
-
token,
|
|
164
|
-
'delete',
|
|
165
|
-
{ holonId: '8928342e20fffff', lensName: 'temperature' }
|
|
166
|
-
);
|
|
167
|
-
|
|
168
|
-
expect(isValid).toBe(false);
|
|
169
|
-
});
|
|
170
|
-
|
|
171
|
-
it('should return false for expired token', async () => {
|
|
172
|
-
const token = await hs.issueCapability(
|
|
173
|
-
['read'],
|
|
174
|
-
{ holonId: '8928342e20fffff', lensName: 'temperature' },
|
|
175
|
-
publicKey,
|
|
176
|
-
{ expiresIn: -1000 } // Already expired
|
|
177
|
-
);
|
|
178
|
-
|
|
179
|
-
const isValid = await hs.verifyCapability(
|
|
180
|
-
token,
|
|
181
|
-
'read',
|
|
182
|
-
{ holonId: '8928342e20fffff', lensName: 'temperature' }
|
|
183
|
-
);
|
|
184
|
-
|
|
185
|
-
expect(isValid).toBe(false);
|
|
186
|
-
});
|
|
187
|
-
|
|
188
|
-
it('should return false for invalid token format', async () => {
|
|
189
|
-
const isValid = await hs.verifyCapability(
|
|
190
|
-
'invalid-token',
|
|
191
|
-
'read',
|
|
192
|
-
{ holonId: '8928342e20fffff', lensName: 'temperature' }
|
|
193
|
-
);
|
|
194
|
-
|
|
195
|
-
expect(isValid).toBe(false);
|
|
196
|
-
});
|
|
197
|
-
});
|
|
198
|
-
});
|
|
@@ -1,223 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, beforeEach } from 'vitest';
|
|
2
|
-
import HoloSphere from '../../../src/index.js';
|
|
3
|
-
|
|
4
|
-
describe('Contract: Data Operations (CRUD)', () => {
|
|
5
|
-
let hs;
|
|
6
|
-
let testHolonId;
|
|
7
|
-
|
|
8
|
-
beforeEach(async () => {
|
|
9
|
-
hs = new HoloSphere({ relays: [], appName: 'test-data' });
|
|
10
|
-
testHolonId = await hs.toHolon(37.7749, -122.4194, 9);
|
|
11
|
-
});
|
|
12
|
-
|
|
13
|
-
describe('write()', () => {
|
|
14
|
-
it('should write data with explicit ID', async () => {
|
|
15
|
-
const success = await hs.write(testHolonId, 'temperature', {
|
|
16
|
-
id: 'sensor-001',
|
|
17
|
-
value: 72.5,
|
|
18
|
-
unit: 'F'
|
|
19
|
-
});
|
|
20
|
-
expect(success).toBe(true);
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
it('should write data without ID (auto-generated)', async () => {
|
|
24
|
-
const success = await hs.write(testHolonId, 'temperature', {
|
|
25
|
-
value: 73.0,
|
|
26
|
-
unit: 'F'
|
|
27
|
-
});
|
|
28
|
-
expect(success).toBe(true);
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
it('should accept options parameter', async () => {
|
|
32
|
-
const success = await hs.write(
|
|
33
|
-
testHolonId,
|
|
34
|
-
'temperature',
|
|
35
|
-
{ id: 'sensor-002', value: 74.0 },
|
|
36
|
-
{ validate: false, strict: false }
|
|
37
|
-
);
|
|
38
|
-
expect(success).toBe(true);
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
it('should throw ValidationError in strict mode with invalid data', async () => {
|
|
42
|
-
const schema = {
|
|
43
|
-
type: 'object',
|
|
44
|
-
properties: {
|
|
45
|
-
id: { type: 'string' },
|
|
46
|
-
value: { type: 'number' }
|
|
47
|
-
},
|
|
48
|
-
required: ['id', 'value']
|
|
49
|
-
};
|
|
50
|
-
await hs.setSchema('temperature', schema, true);
|
|
51
|
-
await expect(
|
|
52
|
-
hs.write(
|
|
53
|
-
testHolonId,
|
|
54
|
-
'temperature',
|
|
55
|
-
{ id: 'bad', value: 'invalid' },
|
|
56
|
-
{ strict: true }
|
|
57
|
-
)
|
|
58
|
-
).rejects.toThrow('ValidationError');
|
|
59
|
-
});
|
|
60
|
-
|
|
61
|
-
it('should throw AuthorizationError with invalid capability token', async () => {
|
|
62
|
-
await expect(
|
|
63
|
-
hs.write(
|
|
64
|
-
testHolonId,
|
|
65
|
-
'temperature',
|
|
66
|
-
{ id: 'sensor-003', value: 75.0 },
|
|
67
|
-
{ capability: 'invalid-token' }
|
|
68
|
-
)
|
|
69
|
-
).rejects.toThrow('AuthorizationError');
|
|
70
|
-
});
|
|
71
|
-
|
|
72
|
-
it('should throw ValidationError with invalid holonId', async () => {
|
|
73
|
-
// Test with invalid holonId to trigger validation error
|
|
74
|
-
await expect(
|
|
75
|
-
hs.write('', 'temperature', { id: 'x' })
|
|
76
|
-
).rejects.toThrow('ValidationError');
|
|
77
|
-
});
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
describe('read()', () => {
|
|
81
|
-
it('should read specific data item by ID', async () => {
|
|
82
|
-
await hs.write(testHolonId, 'temperature', {
|
|
83
|
-
id: 'sensor-001',
|
|
84
|
-
value: 72.5
|
|
85
|
-
});
|
|
86
|
-
|
|
87
|
-
const data = await hs.read(testHolonId, 'temperature', 'sensor-001');
|
|
88
|
-
expect(data).toMatchObject({ id: 'sensor-001', value: 72.5 });
|
|
89
|
-
});
|
|
90
|
-
|
|
91
|
-
it('should read all items in lens when dataId omitted', async () => {
|
|
92
|
-
await hs.write(testHolonId, 'temperature', { id: 'sensor-001', value: 72.5 });
|
|
93
|
-
await hs.write(testHolonId, 'temperature', { id: 'sensor-002', value: 73.0 });
|
|
94
|
-
|
|
95
|
-
const data = await hs.read(testHolonId, 'temperature');
|
|
96
|
-
expect(Array.isArray(data)).toBe(true);
|
|
97
|
-
expect(data.length).toBeGreaterThanOrEqual(2);
|
|
98
|
-
});
|
|
99
|
-
|
|
100
|
-
it('should return null for non-existent data', async () => {
|
|
101
|
-
const data = await hs.read(testHolonId, 'temperature', 'nonexistent');
|
|
102
|
-
expect(data).toBe(null);
|
|
103
|
-
});
|
|
104
|
-
|
|
105
|
-
it('should throw Error for invalid holonId', async () => {
|
|
106
|
-
await expect(hs.read('', 'temperature')).rejects.toThrow(Error);
|
|
107
|
-
});
|
|
108
|
-
|
|
109
|
-
it('should throw Error for invalid lensName', async () => {
|
|
110
|
-
await expect(hs.read(testHolonId, '')).rejects.toThrow(Error);
|
|
111
|
-
});
|
|
112
|
-
});
|
|
113
|
-
|
|
114
|
-
describe('update()', () => {
|
|
115
|
-
it('should update existing data by merging updates', async () => {
|
|
116
|
-
await hs.write(testHolonId, 'temperature', {
|
|
117
|
-
id: 'sensor-001',
|
|
118
|
-
value: 72.5,
|
|
119
|
-
unit: 'F'
|
|
120
|
-
});
|
|
121
|
-
|
|
122
|
-
const success = await hs.update(
|
|
123
|
-
testHolonId,
|
|
124
|
-
'temperature',
|
|
125
|
-
'sensor-001',
|
|
126
|
-
{ value: 73.0 }
|
|
127
|
-
);
|
|
128
|
-
expect(success).toBe(true);
|
|
129
|
-
|
|
130
|
-
const updated = await hs.read(testHolonId, 'temperature', 'sensor-001');
|
|
131
|
-
expect(updated.value).toBe(73.0);
|
|
132
|
-
expect(updated.unit).toBe('F'); // Original field preserved
|
|
133
|
-
});
|
|
134
|
-
|
|
135
|
-
it('should return false for non-existent item', async () => {
|
|
136
|
-
const success = await hs.update(
|
|
137
|
-
testHolonId,
|
|
138
|
-
'temperature',
|
|
139
|
-
'nonexistent',
|
|
140
|
-
{ value: 99 }
|
|
141
|
-
);
|
|
142
|
-
expect(success).toBe(false);
|
|
143
|
-
});
|
|
144
|
-
|
|
145
|
-
it('should accept options parameter', async () => {
|
|
146
|
-
await hs.write(testHolonId, 'temperature', { id: 'sensor-001', value: 72 });
|
|
147
|
-
|
|
148
|
-
const success = await hs.update(
|
|
149
|
-
testHolonId,
|
|
150
|
-
'temperature',
|
|
151
|
-
'sensor-001',
|
|
152
|
-
{ value: 73 },
|
|
153
|
-
{ validate: true, strict: false }
|
|
154
|
-
);
|
|
155
|
-
expect(success).toBe(true);
|
|
156
|
-
});
|
|
157
|
-
|
|
158
|
-
it('should throw ValidationError in strict mode', async () => {
|
|
159
|
-
const schema = {
|
|
160
|
-
type: 'object',
|
|
161
|
-
properties: {
|
|
162
|
-
id: { type: 'string' },
|
|
163
|
-
value: { type: 'number' }
|
|
164
|
-
},
|
|
165
|
-
required: ['id', 'value']
|
|
166
|
-
};
|
|
167
|
-
await hs.setSchema('temperature', schema, true);
|
|
168
|
-
await hs.write(testHolonId, 'temperature', { id: 'sensor-001', value: 72 });
|
|
169
|
-
|
|
170
|
-
await expect(
|
|
171
|
-
hs.update(
|
|
172
|
-
testHolonId,
|
|
173
|
-
'temperature',
|
|
174
|
-
'sensor-001',
|
|
175
|
-
{ value: 'invalid' },
|
|
176
|
-
{ strict: true }
|
|
177
|
-
)
|
|
178
|
-
).rejects.toThrow('ValidationError');
|
|
179
|
-
});
|
|
180
|
-
});
|
|
181
|
-
|
|
182
|
-
describe('delete()', () => {
|
|
183
|
-
it('should delete own data without capability token', async () => {
|
|
184
|
-
await hs.write(testHolonId, 'temperature', { id: 'sensor-001', value: 72 });
|
|
185
|
-
|
|
186
|
-
const success = await hs.delete(testHolonId, 'temperature', 'sensor-001');
|
|
187
|
-
expect(success).toBe(true);
|
|
188
|
-
|
|
189
|
-
const deleted = await hs.read(testHolonId, 'temperature', 'sensor-001');
|
|
190
|
-
expect(deleted).toBe(null);
|
|
191
|
-
});
|
|
192
|
-
|
|
193
|
-
it('should return false when deleting non-existent data', async () => {
|
|
194
|
-
// Deleting non-existent data returns false
|
|
195
|
-
const success = await hs.delete(testHolonId, 'temperature', 'others-data');
|
|
196
|
-
expect(success).toBe(false);
|
|
197
|
-
});
|
|
198
|
-
|
|
199
|
-
it('should delete with valid capability token', async () => {
|
|
200
|
-
// First create the data to delete
|
|
201
|
-
await hs.write(testHolonId, 'temperature', { id: 'sensor-001', value: 72 });
|
|
202
|
-
|
|
203
|
-
const token = await hs.issueCapability(
|
|
204
|
-
['delete'],
|
|
205
|
-
{ holonId: testHolonId, lensName: 'temperature' },
|
|
206
|
-
hs.client.publicKey
|
|
207
|
-
);
|
|
208
|
-
|
|
209
|
-
const success = await hs.delete(
|
|
210
|
-
testHolonId,
|
|
211
|
-
'temperature',
|
|
212
|
-
'sensor-001',
|
|
213
|
-
{ capability: token }
|
|
214
|
-
);
|
|
215
|
-
expect(success).toBe(true);
|
|
216
|
-
});
|
|
217
|
-
|
|
218
|
-
it('should return false on delete failure', async () => {
|
|
219
|
-
const success = await hs.delete(testHolonId, 'temperature', 'nonexistent');
|
|
220
|
-
expect(success).toBe(false);
|
|
221
|
-
});
|
|
222
|
-
});
|
|
223
|
-
});
|
|
@@ -1,181 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, beforeEach } from 'vitest';
|
|
2
|
-
import HoloSphere from '../../../src/index.js';
|
|
3
|
-
|
|
4
|
-
describe('Contract: Federation Operations', () => {
|
|
5
|
-
let hs;
|
|
6
|
-
let sourceHolon;
|
|
7
|
-
let targetHolon;
|
|
8
|
-
|
|
9
|
-
beforeEach(async () => {
|
|
10
|
-
hs = new HoloSphere({ relays: [], appName: 'test-federation' });
|
|
11
|
-
sourceHolon = await hs.toHolon(37.7749, -122.4194, 9);
|
|
12
|
-
targetHolon = await hs.toHolon(37.7749, -122.4194, 7);
|
|
13
|
-
});
|
|
14
|
-
|
|
15
|
-
describe('federate()', () => {
|
|
16
|
-
it('should establish federation between two holons', async () => {
|
|
17
|
-
const success = await hs.federate(sourceHolon, targetHolon, 'events');
|
|
18
|
-
expect(success).toBe(true);
|
|
19
|
-
});
|
|
20
|
-
|
|
21
|
-
it('should accept direction option: outbound', async () => {
|
|
22
|
-
const success = await hs.federate(
|
|
23
|
-
sourceHolon,
|
|
24
|
-
targetHolon,
|
|
25
|
-
'events',
|
|
26
|
-
{ direction: 'outbound' }
|
|
27
|
-
);
|
|
28
|
-
expect(success).toBe(true);
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
it('should accept direction option: inbound', async () => {
|
|
32
|
-
const success = await hs.federate(
|
|
33
|
-
sourceHolon,
|
|
34
|
-
targetHolon,
|
|
35
|
-
'events',
|
|
36
|
-
{ direction: 'inbound' }
|
|
37
|
-
);
|
|
38
|
-
expect(success).toBe(true);
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
it('should accept direction option: bidirectional', async () => {
|
|
42
|
-
const success = await hs.federate(
|
|
43
|
-
sourceHolon,
|
|
44
|
-
targetHolon,
|
|
45
|
-
'events',
|
|
46
|
-
{ direction: 'bidirectional' }
|
|
47
|
-
);
|
|
48
|
-
expect(success).toBe(true);
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
it('should accept mode option: reference (default)', async () => {
|
|
52
|
-
const success = await hs.federate(
|
|
53
|
-
sourceHolon,
|
|
54
|
-
targetHolon,
|
|
55
|
-
'events',
|
|
56
|
-
{ mode: 'reference' }
|
|
57
|
-
);
|
|
58
|
-
expect(success).toBe(true);
|
|
59
|
-
});
|
|
60
|
-
|
|
61
|
-
it('should accept mode option: copy', async () => {
|
|
62
|
-
const success = await hs.federate(
|
|
63
|
-
sourceHolon,
|
|
64
|
-
targetHolon,
|
|
65
|
-
'events',
|
|
66
|
-
{ mode: 'copy' }
|
|
67
|
-
);
|
|
68
|
-
expect(success).toBe(true);
|
|
69
|
-
});
|
|
70
|
-
|
|
71
|
-
it('should accept filter function option', async () => {
|
|
72
|
-
const success = await hs.federate(
|
|
73
|
-
sourceHolon,
|
|
74
|
-
targetHolon,
|
|
75
|
-
'events',
|
|
76
|
-
{ filter: (data) => data.priority === 'high' }
|
|
77
|
-
);
|
|
78
|
-
expect(success).toBe(true);
|
|
79
|
-
});
|
|
80
|
-
|
|
81
|
-
it('should throw Error when source equals target', async () => {
|
|
82
|
-
await expect(
|
|
83
|
-
hs.federate(sourceHolon, sourceHolon, 'events')
|
|
84
|
-
).rejects.toThrow(Error);
|
|
85
|
-
});
|
|
86
|
-
|
|
87
|
-
it('should succeed even with non-standard holonId', async () => {
|
|
88
|
-
// Federation setup writes config data, which succeeds even for non-H3 IDs
|
|
89
|
-
const success = await hs.federate('invalid', targetHolon, 'events');
|
|
90
|
-
expect(success).toBe(true);
|
|
91
|
-
});
|
|
92
|
-
|
|
93
|
-
it('should support cross-dimensional federation (geographic to noospheric)', async () => {
|
|
94
|
-
const noospheric = 'nostr://topic/climate';
|
|
95
|
-
const success = await hs.federate(sourceHolon, noospheric, 'temperature');
|
|
96
|
-
expect(success).toBe(true);
|
|
97
|
-
});
|
|
98
|
-
});
|
|
99
|
-
|
|
100
|
-
describe('getFederatedData()', () => {
|
|
101
|
-
it('should return combined local and federated data', async () => {
|
|
102
|
-
await hs.write(sourceHolon, 'events', { id: 'local-1', name: 'Local Event' });
|
|
103
|
-
await hs.federate(sourceHolon, targetHolon, 'events');
|
|
104
|
-
|
|
105
|
-
const data = await hs.getFederatedData(targetHolon, 'events');
|
|
106
|
-
expect(Array.isArray(data)).toBe(true);
|
|
107
|
-
expect(data.length).toBeGreaterThanOrEqual(1);
|
|
108
|
-
});
|
|
109
|
-
|
|
110
|
-
it('should accept resolveHolograms option (default: true)', async () => {
|
|
111
|
-
await hs.federate(sourceHolon, targetHolon, 'events');
|
|
112
|
-
|
|
113
|
-
const data = await hs.getFederatedData(
|
|
114
|
-
targetHolon,
|
|
115
|
-
'events',
|
|
116
|
-
{ resolveHolograms: true }
|
|
117
|
-
);
|
|
118
|
-
expect(Array.isArray(data)).toBe(true);
|
|
119
|
-
});
|
|
120
|
-
|
|
121
|
-
it('should accept deduplicate option (default: true)', async () => {
|
|
122
|
-
await hs.federate(sourceHolon, targetHolon, 'events');
|
|
123
|
-
|
|
124
|
-
const data = await hs.getFederatedData(
|
|
125
|
-
targetHolon,
|
|
126
|
-
'events',
|
|
127
|
-
{ deduplicate: true }
|
|
128
|
-
);
|
|
129
|
-
expect(Array.isArray(data)).toBe(true);
|
|
130
|
-
});
|
|
131
|
-
|
|
132
|
-
it('should return empty array if no data exists', async () => {
|
|
133
|
-
const data = await hs.getFederatedData(targetHolon, 'nonexistent');
|
|
134
|
-
expect(data).toEqual([]);
|
|
135
|
-
});
|
|
136
|
-
|
|
137
|
-
it('should include _meta field with source holon for federated data', async () => {
|
|
138
|
-
await hs.write(sourceHolon, 'events', { id: 'event-1', name: 'Test' });
|
|
139
|
-
await hs.federate(sourceHolon, targetHolon, 'events');
|
|
140
|
-
|
|
141
|
-
const data = await hs.getFederatedData(targetHolon, 'events');
|
|
142
|
-
const federatedItem = data.find(item => item._meta);
|
|
143
|
-
|
|
144
|
-
if (federatedItem) {
|
|
145
|
-
expect(federatedItem._meta).toHaveProperty('source');
|
|
146
|
-
}
|
|
147
|
-
});
|
|
148
|
-
|
|
149
|
-
it('should return local-only data for non-federated holon', async () => {
|
|
150
|
-
await hs.write(sourceHolon, 'events', { id: 'local-1', name: 'Local' });
|
|
151
|
-
|
|
152
|
-
const data = await hs.getFederatedData(sourceHolon, 'events');
|
|
153
|
-
expect(Array.isArray(data)).toBe(true);
|
|
154
|
-
});
|
|
155
|
-
});
|
|
156
|
-
|
|
157
|
-
describe('unfederate()', () => {
|
|
158
|
-
it('should remove federation relationship', async () => {
|
|
159
|
-
await hs.federate(sourceHolon, targetHolon, 'events');
|
|
160
|
-
|
|
161
|
-
const success = await hs.unfederate(sourceHolon, targetHolon, 'events');
|
|
162
|
-
expect(success).toBe(true);
|
|
163
|
-
});
|
|
164
|
-
|
|
165
|
-
it('should be idempotent (no error if not federated)', async () => {
|
|
166
|
-
const success = await hs.unfederate(sourceHolon, targetHolon, 'events');
|
|
167
|
-
expect(success).toBe(true);
|
|
168
|
-
});
|
|
169
|
-
|
|
170
|
-
it('should keep existing holograms after unfederate', async () => {
|
|
171
|
-
await hs.write(sourceHolon, 'events', { id: 'event-1', name: 'Test' });
|
|
172
|
-
await hs.federate(sourceHolon, targetHolon, 'events');
|
|
173
|
-
await hs.unfederate(sourceHolon, targetHolon, 'events');
|
|
174
|
-
|
|
175
|
-
// Unfederate removes federation config but doesn't delete already-propagated holograms
|
|
176
|
-
const data = await hs.getFederatedData(targetHolon, 'events');
|
|
177
|
-
const hasFederatedData = data.some(item => item._meta?.source === sourceHolon);
|
|
178
|
-
expect(hasFederatedData).toBe(true); // Holograms remain
|
|
179
|
-
});
|
|
180
|
-
});
|
|
181
|
-
});
|