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,129 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, beforeEach } from 'vitest';
|
|
2
|
-
import HoloSphere from '../../../src/index.js';
|
|
3
|
-
|
|
4
|
-
describe('Integration: Scenario 4 - Schema Validation (Strict and Permissive)', () => {
|
|
5
|
-
let hs;
|
|
6
|
-
|
|
7
|
-
beforeEach(() => {
|
|
8
|
-
hs = new HoloSphere({ relays: [], appName: 'scenario-04' });
|
|
9
|
-
});
|
|
10
|
-
|
|
11
|
-
it('should complete schema validation workflow', async () => {
|
|
12
|
-
// Step 1: Define schema for temperature data
|
|
13
|
-
const temperatureSchema = {
|
|
14
|
-
type: 'object',
|
|
15
|
-
properties: {
|
|
16
|
-
id: { type: 'string' },
|
|
17
|
-
celsius: { type: 'number', minimum: -50, maximum: 60 },
|
|
18
|
-
timestamp: { type: 'number' }
|
|
19
|
-
},
|
|
20
|
-
required: ['id', 'celsius']
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
const holon = await hs.toHolon(37.7749, -122.4194, 9);
|
|
24
|
-
|
|
25
|
-
// Step 2: Set schema in permissive mode (default)
|
|
26
|
-
await hs.setSchema('temperature', temperatureSchema, false);
|
|
27
|
-
|
|
28
|
-
// Step 3: Write invalid data - succeeds with warning logged
|
|
29
|
-
const permissiveResult = await hs.write(holon, 'temperature', {
|
|
30
|
-
id: 'bad-sensor',
|
|
31
|
-
celsius: 'very hot' // Invalid: string instead of number
|
|
32
|
-
});
|
|
33
|
-
expect(permissiveResult).toBe(true);
|
|
34
|
-
|
|
35
|
-
// Step 4: Enable strict mode
|
|
36
|
-
await hs.setSchema('temperature', temperatureSchema, true);
|
|
37
|
-
|
|
38
|
-
// Step 5: Write invalid data - throws ValidationError
|
|
39
|
-
await expect(
|
|
40
|
-
hs.write(holon, 'temperature', {
|
|
41
|
-
id: 'bad-sensor-2',
|
|
42
|
-
celsius: 'freezing'
|
|
43
|
-
}, { strict: true })
|
|
44
|
-
).rejects.toThrow('ValidationError');
|
|
45
|
-
|
|
46
|
-
// Step 6: Write valid data - succeeds
|
|
47
|
-
const validResult = await hs.write(holon, 'temperature', {
|
|
48
|
-
id: 'good-sensor',
|
|
49
|
-
celsius: 22.5,
|
|
50
|
-
timestamp: Date.now()
|
|
51
|
-
}, { strict: true });
|
|
52
|
-
expect(validResult).toBe(true);
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
it('should validate schemas support URI references', async () => {
|
|
56
|
-
// URI schemas can be set and will skip validation
|
|
57
|
-
await expect(
|
|
58
|
-
hs.setSchema('test', 'test://schemas/valid.json')
|
|
59
|
-
).resolves.toBeUndefined();
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
it('should validate permissive mode logs but allows invalid data', async () => {
|
|
63
|
-
const holon = await hs.toHolon(37.7749, -122.4194, 9);
|
|
64
|
-
const testSchema = {
|
|
65
|
-
type: 'object',
|
|
66
|
-
properties: {
|
|
67
|
-
id: { type: 'string' },
|
|
68
|
-
value: { type: 'number' }
|
|
69
|
-
},
|
|
70
|
-
required: ['id', 'value']
|
|
71
|
-
};
|
|
72
|
-
await hs.setSchema('test', testSchema, false);
|
|
73
|
-
|
|
74
|
-
const result = await hs.write(holon, 'test', {
|
|
75
|
-
id: 'invalid',
|
|
76
|
-
value: 'not-a-number'
|
|
77
|
-
});
|
|
78
|
-
|
|
79
|
-
expect(result).toBe(true);
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
it('should validate strict mode blocks invalid data with ValidationError', async () => {
|
|
83
|
-
const holon = await hs.toHolon(37.7749, -122.4194, 9);
|
|
84
|
-
const strictSchema = {
|
|
85
|
-
type: 'object',
|
|
86
|
-
properties: {
|
|
87
|
-
id: { type: 'string' },
|
|
88
|
-
value: { type: 'number' }
|
|
89
|
-
},
|
|
90
|
-
required: ['id', 'value']
|
|
91
|
-
};
|
|
92
|
-
await hs.setSchema('strict-test', strictSchema, true);
|
|
93
|
-
|
|
94
|
-
await expect(
|
|
95
|
-
hs.write(holon, 'strict-test', {
|
|
96
|
-
id: 'bad',
|
|
97
|
-
value: 'invalid'
|
|
98
|
-
}, { strict: true })
|
|
99
|
-
).rejects.toThrow('ValidationError');
|
|
100
|
-
});
|
|
101
|
-
|
|
102
|
-
it('should validate valid data succeeds in both modes', async () => {
|
|
103
|
-
const holon = await hs.toHolon(37.7749, -122.4194, 9);
|
|
104
|
-
const tempSchema = {
|
|
105
|
-
type: 'object',
|
|
106
|
-
properties: {
|
|
107
|
-
id: { type: 'string' },
|
|
108
|
-
celsius: { type: 'number' },
|
|
109
|
-
timestamp: { type: 'number' }
|
|
110
|
-
},
|
|
111
|
-
required: ['id', 'celsius']
|
|
112
|
-
};
|
|
113
|
-
const validData = {
|
|
114
|
-
id: 'sensor-001',
|
|
115
|
-
celsius: 25.5,
|
|
116
|
-
timestamp: Date.now()
|
|
117
|
-
};
|
|
118
|
-
|
|
119
|
-
// Permissive mode
|
|
120
|
-
await hs.setSchema('temp1', tempSchema, false);
|
|
121
|
-
const permissive = await hs.write(holon, 'temp1', validData);
|
|
122
|
-
expect(permissive).toBe(true);
|
|
123
|
-
|
|
124
|
-
// Strict mode
|
|
125
|
-
await hs.setSchema('temp2', tempSchema, true);
|
|
126
|
-
const strict = await hs.write(holon, 'temp2', validData, { strict: true });
|
|
127
|
-
expect(strict).toBe(true);
|
|
128
|
-
});
|
|
129
|
-
});
|
|
@@ -1,125 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, beforeEach } from 'vitest';
|
|
2
|
-
import HoloSphere from '../../../src/index.js';
|
|
3
|
-
|
|
4
|
-
describe('Integration: Scenario 5 - Multi-Scale Hierarchical Queries', () => {
|
|
5
|
-
let hs;
|
|
6
|
-
|
|
7
|
-
beforeEach(() => {
|
|
8
|
-
hs = new HoloSphere({ relays: [], appName: 'scenario-05' });
|
|
9
|
-
});
|
|
10
|
-
|
|
11
|
-
it('should complete multi-scale hierarchical query workflow', async () => {
|
|
12
|
-
// Step 1: Create data at high resolution (local street level, res 12)
|
|
13
|
-
const localHolon = await hs.toHolon(37.7749, -122.4194, 12);
|
|
14
|
-
await hs.write(localHolon, 'events', {
|
|
15
|
-
id: 'meetup-001',
|
|
16
|
-
name: 'JavaScript Meetup',
|
|
17
|
-
attendees: 25
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
// Step 2: Upcast to parent hierarchy (propagate to neighborhood, city, region)
|
|
21
|
-
const upcastSuccess = await hs.upcast(localHolon, 'events', 'meetup-001', {
|
|
22
|
-
maxLevel: 3
|
|
23
|
-
});
|
|
24
|
-
expect(upcastSuccess).toBe(true);
|
|
25
|
-
|
|
26
|
-
// Step 3: Query at different scales
|
|
27
|
-
const parents = await hs.getParents(localHolon);
|
|
28
|
-
expect(parents.length).toBeGreaterThan(0);
|
|
29
|
-
|
|
30
|
-
// Find neighborhood level (estimate resolution 9)
|
|
31
|
-
const neighborhood = parents.find(p => {
|
|
32
|
-
// Get resolution somehow or just use first parent
|
|
33
|
-
return true;
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
if (neighborhood) {
|
|
37
|
-
const neighborhoodEvents = await hs.read(neighborhood, 'events');
|
|
38
|
-
expect(Array.isArray(neighborhoodEvents)).toBe(true);
|
|
39
|
-
// Should include upcast data
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
// City level (lower resolution parent)
|
|
43
|
-
if (parents.length > 1) {
|
|
44
|
-
const city = parents[1];
|
|
45
|
-
const cityEvents = await hs.read(city, 'events');
|
|
46
|
-
expect(Array.isArray(cityEvents)).toBe(true);
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
// Regional level
|
|
50
|
-
if (parents.length > 2) {
|
|
51
|
-
const region = parents[2];
|
|
52
|
-
const regionEvents = await hs.read(region, 'events');
|
|
53
|
-
expect(Array.isArray(regionEvents)).toBe(true);
|
|
54
|
-
}
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
it('should validate hierarchical parent-child relationships maintained', async () => {
|
|
58
|
-
const child = await hs.toHolon(37.7749, -122.4194, 10);
|
|
59
|
-
const parents = await hs.getParents(child);
|
|
60
|
-
|
|
61
|
-
expect(parents.length).toBeGreaterThan(0);
|
|
62
|
-
|
|
63
|
-
// Each parent should be valid H3
|
|
64
|
-
parents.forEach(parent => {
|
|
65
|
-
expect(hs.isValidH3(parent)).toBe(true);
|
|
66
|
-
});
|
|
67
|
-
});
|
|
68
|
-
|
|
69
|
-
it('should validate data propagates up hierarchy (upcast)', async () => {
|
|
70
|
-
const local = await hs.toHolon(40.7128, -74.0060, 11);
|
|
71
|
-
|
|
72
|
-
await hs.write(local, 'alerts', {
|
|
73
|
-
id: 'alert-001',
|
|
74
|
-
type: 'weather',
|
|
75
|
-
severity: 'high'
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
await hs.upcast(local, 'alerts', 'alert-001', { maxLevel: 2 });
|
|
79
|
-
|
|
80
|
-
const parents = await hs.getParents(local);
|
|
81
|
-
if (parents.length > 0) {
|
|
82
|
-
const parentData = await hs.read(parents[0], 'alerts');
|
|
83
|
-
expect(Array.isArray(parentData)).toBe(true);
|
|
84
|
-
}
|
|
85
|
-
});
|
|
86
|
-
|
|
87
|
-
it('should validate multi-scale queries work at different resolutions', async () => {
|
|
88
|
-
// Create data at resolution 12
|
|
89
|
-
const res12 = await hs.toHolon(37.7749, -122.4194, 12);
|
|
90
|
-
await hs.write(res12, 'data', { id: 'item-1', value: 'high-res' });
|
|
91
|
-
|
|
92
|
-
// Get data at resolution 9 (parent)
|
|
93
|
-
const parents = await hs.getParents(res12);
|
|
94
|
-
const res9 = parents.find(p => hs.isValidH3(p));
|
|
95
|
-
|
|
96
|
-
if (res9) {
|
|
97
|
-
// Should be able to query at this resolution
|
|
98
|
-
const data = await hs.read(res9, 'data');
|
|
99
|
-
expect(Array.isArray(data)).toBe(true);
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
// Resolution 7 (grandparent)
|
|
103
|
-
if (parents.length > 1) {
|
|
104
|
-
const res7 = parents[1];
|
|
105
|
-
const data = await hs.read(res7, 'data');
|
|
106
|
-
expect(Array.isArray(data)).toBe(true);
|
|
107
|
-
}
|
|
108
|
-
});
|
|
109
|
-
|
|
110
|
-
it('should validate upcast with different operation modes', async () => {
|
|
111
|
-
const holon = await hs.toHolon(37.7749, -122.4194, 10);
|
|
112
|
-
|
|
113
|
-
// Summarize mode
|
|
114
|
-
await hs.write(holon, 'counts', { id: 'count-1', value: 5 });
|
|
115
|
-
await hs.upcast(holon, 'counts', 'count-1', { operation: 'summarize' });
|
|
116
|
-
|
|
117
|
-
// Aggregate mode
|
|
118
|
-
await hs.write(holon, 'totals', { id: 'total-1', amount: 100 });
|
|
119
|
-
await hs.upcast(holon, 'totals', 'total-1', { operation: 'aggregate' });
|
|
120
|
-
|
|
121
|
-
// Concatenate mode (default)
|
|
122
|
-
await hs.write(holon, 'lists', { id: 'list-1', items: [1, 2, 3] });
|
|
123
|
-
await hs.upcast(holon, 'lists', 'list-1', { operation: 'concatenate' });
|
|
124
|
-
});
|
|
125
|
-
});
|
|
@@ -1,135 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, beforeEach } from 'vitest';
|
|
2
|
-
import HoloSphere from '../../../src/index.js';
|
|
3
|
-
|
|
4
|
-
describe('Integration: Scenario 6 - Cross-Protocol Social Content', () => {
|
|
5
|
-
let hs;
|
|
6
|
-
|
|
7
|
-
beforeEach(() => {
|
|
8
|
-
hs = new HoloSphere({ relays: [], appName: 'scenario-06' });
|
|
9
|
-
});
|
|
10
|
-
|
|
11
|
-
it('should complete cross-protocol social content workflow', async () => {
|
|
12
|
-
// Step 1: Publish Nostr event to geographic holon
|
|
13
|
-
const holon = await hs.toHolon(37.7749, -122.4194, 9);
|
|
14
|
-
|
|
15
|
-
const nostrEvent = {
|
|
16
|
-
kind: 1, // Text note
|
|
17
|
-
content: 'Building with HoloSphere!',
|
|
18
|
-
tags: [['t', 'holosphere'], ['t', 'geospatial']],
|
|
19
|
-
created_at: Math.floor(Date.now() / 1000)
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
const nostrSuccess = await hs.publishNostr(nostrEvent, holon);
|
|
23
|
-
expect(nostrSuccess).toBe(true);
|
|
24
|
-
|
|
25
|
-
// Step 2: Publish ActivityPub object to noospheric holon
|
|
26
|
-
const apObject = {
|
|
27
|
-
'@context': 'https://www.w3.org/ns/activitystreams',
|
|
28
|
-
type: 'Note',
|
|
29
|
-
content: 'Exploring federated social on HoloSphere',
|
|
30
|
-
published: new Date().toISOString()
|
|
31
|
-
};
|
|
32
|
-
|
|
33
|
-
const apSuccess = await hs.publishActivityPub(
|
|
34
|
-
apObject,
|
|
35
|
-
'ap://community/holosphere-devs'
|
|
36
|
-
);
|
|
37
|
-
expect(apSuccess).toBe(true);
|
|
38
|
-
|
|
39
|
-
// Step 3: Query all social content (unified interface)
|
|
40
|
-
const allSocial = await hs.querySocial(holon, { protocol: 'all' });
|
|
41
|
-
expect(Array.isArray(allSocial)).toBe(true);
|
|
42
|
-
expect(allSocial.length).toBeGreaterThanOrEqual(1);
|
|
43
|
-
|
|
44
|
-
// Step 4: Filter by protocol
|
|
45
|
-
const nostrOnly = await hs.querySocial(holon, { protocol: 'nostr' });
|
|
46
|
-
expect(Array.isArray(nostrOnly)).toBe(true);
|
|
47
|
-
expect(nostrOnly.length).toBeGreaterThanOrEqual(1);
|
|
48
|
-
|
|
49
|
-
// Step 5: Verify cryptographic signature
|
|
50
|
-
if (nostrOnly.length > 0) {
|
|
51
|
-
const event = nostrOnly[0];
|
|
52
|
-
expect(event).toHaveProperty('sig');
|
|
53
|
-
expect(event).toHaveProperty('pubkey');
|
|
54
|
-
|
|
55
|
-
// Use verifyNostrEvent for proper Nostr signature verification
|
|
56
|
-
const isValid = await hs.verifyNostrEvent(event);
|
|
57
|
-
expect(isValid).toBe(true);
|
|
58
|
-
}
|
|
59
|
-
});
|
|
60
|
-
|
|
61
|
-
it('should validate Nostr and ActivityPub unified under common interface', async () => {
|
|
62
|
-
const holon = await hs.toHolon(40.7128, -74.0060, 9);
|
|
63
|
-
|
|
64
|
-
// Publish both types
|
|
65
|
-
await hs.publishNostr({
|
|
66
|
-
kind: 1,
|
|
67
|
-
content: 'Nostr post',
|
|
68
|
-
tags: [],
|
|
69
|
-
created_at: Math.floor(Date.now() / 1000)
|
|
70
|
-
}, holon);
|
|
71
|
-
|
|
72
|
-
await hs.publishActivityPub({
|
|
73
|
-
'@context': 'https://www.w3.org/ns/activitystreams',
|
|
74
|
-
type: 'Note',
|
|
75
|
-
content: 'ActivityPub note'
|
|
76
|
-
}, holon);
|
|
77
|
-
|
|
78
|
-
// Query should return both
|
|
79
|
-
const all = await hs.querySocial(holon, { protocol: 'all' });
|
|
80
|
-
expect(all.length).toBeGreaterThanOrEqual(2);
|
|
81
|
-
});
|
|
82
|
-
|
|
83
|
-
it('should validate protocol-specific content validation', async () => {
|
|
84
|
-
const holon = await hs.toHolon(37.7749, -122.4194, 9);
|
|
85
|
-
|
|
86
|
-
// Invalid Nostr event should be rejected
|
|
87
|
-
await expect(
|
|
88
|
-
hs.publishNostr({ invalid: 'event' }, holon)
|
|
89
|
-
).rejects.toThrow('ValidationError');
|
|
90
|
-
|
|
91
|
-
// Invalid ActivityPub object should be rejected
|
|
92
|
-
await expect(
|
|
93
|
-
hs.publishActivityPub({ invalid: 'object' }, holon)
|
|
94
|
-
).rejects.toThrow('ValidationError');
|
|
95
|
-
});
|
|
96
|
-
|
|
97
|
-
it('should validate cryptographic signature verification', async () => {
|
|
98
|
-
const holon = await hs.toHolon(37.7749, -122.4194, 9);
|
|
99
|
-
|
|
100
|
-
const event = {
|
|
101
|
-
kind: 1,
|
|
102
|
-
content: 'Signed content',
|
|
103
|
-
tags: [],
|
|
104
|
-
created_at: Math.floor(Date.now() / 1000)
|
|
105
|
-
};
|
|
106
|
-
|
|
107
|
-
await hs.publishNostr(event, holon);
|
|
108
|
-
|
|
109
|
-
const published = await hs.querySocial(holon, { protocol: 'nostr' });
|
|
110
|
-
if (published.length > 0) {
|
|
111
|
-
const signedEvent = published[0];
|
|
112
|
-
expect(signedEvent).toHaveProperty('sig');
|
|
113
|
-
expect(signedEvent).toHaveProperty('pubkey');
|
|
114
|
-
}
|
|
115
|
-
});
|
|
116
|
-
|
|
117
|
-
it('should validate filter by protocol and access level', async () => {
|
|
118
|
-
const holon = await hs.toHolon(37.7749, -122.4194, 9);
|
|
119
|
-
|
|
120
|
-
await hs.publishNostr({
|
|
121
|
-
kind: 1,
|
|
122
|
-
content: 'Public post',
|
|
123
|
-
tags: [],
|
|
124
|
-
created_at: Math.floor(Date.now() / 1000)
|
|
125
|
-
}, holon);
|
|
126
|
-
|
|
127
|
-
// Filter by protocol
|
|
128
|
-
const nostrPosts = await hs.querySocial(holon, { protocol: 'nostr' });
|
|
129
|
-
expect(Array.isArray(nostrPosts)).toBe(true);
|
|
130
|
-
|
|
131
|
-
// Filter by access level
|
|
132
|
-
const publicPosts = await hs.querySocial(holon, { accessLevel: 'public' });
|
|
133
|
-
expect(Array.isArray(publicPosts)).toBe(true);
|
|
134
|
-
});
|
|
135
|
-
});
|
|
@@ -1,130 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, beforeEach } from 'vitest';
|
|
2
|
-
import HoloSphere from '../../../src/index.js';
|
|
3
|
-
|
|
4
|
-
describe('Integration: Scenario 7 - Offline Persistence and Recovery', () => {
|
|
5
|
-
let hs;
|
|
6
|
-
|
|
7
|
-
beforeEach(() => {
|
|
8
|
-
hs = new HoloSphere({
|
|
9
|
-
appName: 'scenario-07',
|
|
10
|
-
radisk: true // Enabled by default
|
|
11
|
-
});
|
|
12
|
-
});
|
|
13
|
-
|
|
14
|
-
it('should complete offline persistence and recovery workflow', async () => {
|
|
15
|
-
const holon = await hs.toHolon(37.7749, -122.4194, 9);
|
|
16
|
-
|
|
17
|
-
// Step 1: Write data to persistent storage
|
|
18
|
-
await hs.write(holon, 'notes', {
|
|
19
|
-
id: 'note-001',
|
|
20
|
-
text: 'This persists across sessions'
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
// Verify write succeeded
|
|
24
|
-
const written = await hs.read(holon, 'notes', 'note-001');
|
|
25
|
-
expect(written.text).toBe('This persists across sessions');
|
|
26
|
-
|
|
27
|
-
// Step 2: Simulate app restart (create new instance)
|
|
28
|
-
const hs2 = new HoloSphere({
|
|
29
|
-
appName: 'scenario-07',
|
|
30
|
-
radisk: true
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
// Step 3: Read previously written data - recovered from disk
|
|
34
|
-
const recovered = await hs2.read(holon, 'notes', 'note-001');
|
|
35
|
-
expect(recovered).not.toBe(null);
|
|
36
|
-
expect(recovered.text).toBe('This persists across sessions');
|
|
37
|
-
|
|
38
|
-
// Step 4: Offline operation - write without network
|
|
39
|
-
await hs2.write(holon, 'notes', {
|
|
40
|
-
id: 'note-002',
|
|
41
|
-
text: 'Written while offline'
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
// Step 5: Data available immediately from local storage
|
|
45
|
-
const offline = await hs2.read(holon, 'notes', 'note-002');
|
|
46
|
-
expect(offline).not.toBe(null);
|
|
47
|
-
expect(offline.text).toBe('Written while offline');
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
it('should validate radisk persistence enabled by default', () => {
|
|
51
|
-
const hs = new HoloSphere({ relays: [], appName: 'test-radisk' });
|
|
52
|
-
// Should initialize without error with radisk enabled
|
|
53
|
-
expect(hs).toBeDefined();
|
|
54
|
-
});
|
|
55
|
-
|
|
56
|
-
it.skip('should validate data persists across app restarts (requires persistent storage)', async () => {
|
|
57
|
-
const appName = 'persistence-test-' + Date.now();
|
|
58
|
-
const holon = await hs.toHolon(40.7128, -74.0060, 9);
|
|
59
|
-
|
|
60
|
-
// First instance
|
|
61
|
-
const hs1 = new HoloSphere({ appName, radisk: true });
|
|
62
|
-
await hs1.write(holon, 'persistent', {
|
|
63
|
-
id: 'persistent-001',
|
|
64
|
-
value: 'must persist'
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
// Second instance (simulated restart)
|
|
68
|
-
const hs2 = new HoloSphere({ appName, radisk: true });
|
|
69
|
-
const recovered = await hs2.read(holon, 'persistent', 'persistent-001');
|
|
70
|
-
|
|
71
|
-
expect(recovered).not.toBe(null);
|
|
72
|
-
expect(recovered.value).toBe('must persist');
|
|
73
|
-
});
|
|
74
|
-
|
|
75
|
-
it('should validate offline writes succeed and are recoverable', async () => {
|
|
76
|
-
const holon = await hs.toHolon(37.7749, -122.4194, 9);
|
|
77
|
-
|
|
78
|
-
// Write while potentially offline (radisk handles this)
|
|
79
|
-
const success = await hs.write(holon, 'offline-data', {
|
|
80
|
-
id: 'offline-001',
|
|
81
|
-
timestamp: Date.now(),
|
|
82
|
-
status: 'offline-write'
|
|
83
|
-
});
|
|
84
|
-
|
|
85
|
-
expect(success).toBe(true);
|
|
86
|
-
|
|
87
|
-
// Verify immediately available
|
|
88
|
-
const data = await hs.read(holon, 'offline-data', 'offline-001');
|
|
89
|
-
expect(data).not.toBe(null);
|
|
90
|
-
expect(data.status).toBe('offline-write');
|
|
91
|
-
});
|
|
92
|
-
|
|
93
|
-
it.skip('should validate no data loss during crashes (requires persistent storage)', async () => {
|
|
94
|
-
const appName = 'crash-test-' + Date.now();
|
|
95
|
-
const holon = await hs.toHolon(37.7749, -122.4194, 9);
|
|
96
|
-
|
|
97
|
-
const hs1 = new HoloSphere({ appName, radisk: true });
|
|
98
|
-
|
|
99
|
-
// Write multiple items
|
|
100
|
-
await hs1.write(holon, 'crash-test', { id: 'item-1', data: 'A' });
|
|
101
|
-
await hs1.write(holon, 'crash-test', { id: 'item-2', data: 'B' });
|
|
102
|
-
await hs1.write(holon, 'crash-test', { id: 'item-3', data: 'C' });
|
|
103
|
-
|
|
104
|
-
// Simulate crash and restart
|
|
105
|
-
const hs2 = new HoloSphere({ appName, radisk: true });
|
|
106
|
-
|
|
107
|
-
// All data should be recoverable
|
|
108
|
-
const item1 = await hs2.read(holon, 'crash-test', 'item-1');
|
|
109
|
-
const item2 = await hs2.read(holon, 'crash-test', 'item-2');
|
|
110
|
-
const item3 = await hs2.read(holon, 'crash-test', 'item-3');
|
|
111
|
-
|
|
112
|
-
expect(item1?.data).toBe('A');
|
|
113
|
-
expect(item2?.data).toBe('B');
|
|
114
|
-
expect(item3?.data).toBe('C');
|
|
115
|
-
});
|
|
116
|
-
|
|
117
|
-
it.skip('should validate persistence works with updates (requires persistent storage)', async () => {
|
|
118
|
-
const appName = 'update-persist-' + Date.now();
|
|
119
|
-
const holon = await hs.toHolon(37.7749, -122.4194, 9);
|
|
120
|
-
|
|
121
|
-
const hs1 = new HoloSphere({ appName, radisk: true });
|
|
122
|
-
await hs1.write(holon, 'updatable', { id: 'item-1', version: 1 });
|
|
123
|
-
await hs1.update(holon, 'updatable', 'item-1', { version: 2 });
|
|
124
|
-
|
|
125
|
-
const hs2 = new HoloSphere({ appName, radisk: true });
|
|
126
|
-
const recovered = await hs2.read(holon, 'updatable', 'item-1');
|
|
127
|
-
|
|
128
|
-
expect(recovered.version).toBe(2); // Updated version persisted
|
|
129
|
-
});
|
|
130
|
-
});
|
|
@@ -1,161 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, beforeEach } from 'vitest';
|
|
2
|
-
import HoloSphere from '../../../src/index.js';
|
|
3
|
-
|
|
4
|
-
describe('Integration: Scenario 8 - Authorization with Capability Tokens', () => {
|
|
5
|
-
let hs;
|
|
6
|
-
let userAPrivateKey;
|
|
7
|
-
let userAPublicKey;
|
|
8
|
-
let userBPublicKey;
|
|
9
|
-
|
|
10
|
-
beforeEach(() => {
|
|
11
|
-
hs = new HoloSphere({ relays: [], appName: 'scenario-08' });
|
|
12
|
-
|
|
13
|
-
// Mock keys (in real implementation, would use proper key generation)
|
|
14
|
-
userAPrivateKey = '0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef';
|
|
15
|
-
userAPublicKey = '04' + '0123456789abcdef'.repeat(8);
|
|
16
|
-
userBPublicKey = '04' + 'fedcba9876543210'.repeat(8);
|
|
17
|
-
});
|
|
18
|
-
|
|
19
|
-
it('should complete authorization with capability tokens workflow', async () => {
|
|
20
|
-
const holon = await hs.toHolon(37.7749, -122.4194, 9);
|
|
21
|
-
|
|
22
|
-
// Step 1: User A creates data
|
|
23
|
-
await hs.write(holon, 'documents', {
|
|
24
|
-
id: 'doc-001',
|
|
25
|
-
title: 'User A Document',
|
|
26
|
-
_creator: userAPublicKey
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
// Step 2: User B attempts to delete without authorization
|
|
30
|
-
try {
|
|
31
|
-
await hs.delete(holon, 'documents', 'doc-001');
|
|
32
|
-
// Should throw, but if not, fail the test
|
|
33
|
-
expect(true).toBe(false);
|
|
34
|
-
} catch (err) {
|
|
35
|
-
expect(err.constructor.name).toBe('AuthorizationError');
|
|
36
|
-
expect(err.requiredPermission).toBe('delete');
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
// Step 3: User A issues capability token to User B
|
|
40
|
-
const token = await hs.issueCapability(
|
|
41
|
-
['delete'],
|
|
42
|
-
{ holonId: holon, lensName: 'documents' },
|
|
43
|
-
userBPublicKey,
|
|
44
|
-
{ expiresIn: 3600000, issuerKey: userAPrivateKey }
|
|
45
|
-
);
|
|
46
|
-
|
|
47
|
-
expect(typeof token).toBe('string');
|
|
48
|
-
|
|
49
|
-
// Step 4: User B deletes with valid token
|
|
50
|
-
const deleted = await hs.delete(holon, 'documents', 'doc-001', {
|
|
51
|
-
capability: token
|
|
52
|
-
});
|
|
53
|
-
expect(deleted).toBe(true);
|
|
54
|
-
|
|
55
|
-
// Step 5: Verify data is deleted
|
|
56
|
-
const gone = await hs.read(holon, 'documents', 'doc-001');
|
|
57
|
-
expect(gone).toBe(null);
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
it('should validate delete without capability token is rejected', async () => {
|
|
61
|
-
const holon = await hs.toHolon(40.7128, -74.0060, 9);
|
|
62
|
-
|
|
63
|
-
await hs.write(holon, 'protected', {
|
|
64
|
-
id: 'protected-001',
|
|
65
|
-
owner: userAPublicKey
|
|
66
|
-
});
|
|
67
|
-
|
|
68
|
-
await expect(
|
|
69
|
-
hs.delete(holon, 'protected', 'protected-001')
|
|
70
|
-
).rejects.toThrow('AuthorizationError');
|
|
71
|
-
});
|
|
72
|
-
|
|
73
|
-
it('should validate capability tokens grant specific permissions', async () => {
|
|
74
|
-
const holon = await hs.toHolon(37.7749, -122.4194, 9);
|
|
75
|
-
|
|
76
|
-
// Issue token with only 'read' permission
|
|
77
|
-
const readToken = await hs.issueCapability(
|
|
78
|
-
['read'],
|
|
79
|
-
{ holonId: holon, lensName: 'test' },
|
|
80
|
-
userBPublicKey,
|
|
81
|
-
{ issuerKey: userAPrivateKey }
|
|
82
|
-
);
|
|
83
|
-
|
|
84
|
-
// Verify token has 'read' permission
|
|
85
|
-
const hasRead = await hs.verifyCapability(
|
|
86
|
-
readToken,
|
|
87
|
-
'read',
|
|
88
|
-
{ holonId: holon, lensName: 'test' }
|
|
89
|
-
);
|
|
90
|
-
expect(hasRead).toBe(true);
|
|
91
|
-
|
|
92
|
-
// Verify token does NOT have 'delete' permission
|
|
93
|
-
const hasDelete = await hs.verifyCapability(
|
|
94
|
-
readToken,
|
|
95
|
-
'delete',
|
|
96
|
-
{ holonId: holon, lensName: 'test' }
|
|
97
|
-
);
|
|
98
|
-
expect(hasDelete).toBe(false);
|
|
99
|
-
});
|
|
100
|
-
|
|
101
|
-
it('should validate token expiration is enforced', async () => {
|
|
102
|
-
const holon = await hs.toHolon(37.7749, -122.4194, 9);
|
|
103
|
-
|
|
104
|
-
// Issue expired token
|
|
105
|
-
const expiredToken = await hs.issueCapability(
|
|
106
|
-
['delete'],
|
|
107
|
-
{ holonId: holon, lensName: 'test' },
|
|
108
|
-
userBPublicKey,
|
|
109
|
-
{ expiresIn: -1000, issuerKey: userAPrivateKey }
|
|
110
|
-
);
|
|
111
|
-
|
|
112
|
-
// Expired token should not be valid
|
|
113
|
-
const isValid = await hs.verifyCapability(
|
|
114
|
-
expiredToken,
|
|
115
|
-
'delete',
|
|
116
|
-
{ holonId: holon, lensName: 'test' }
|
|
117
|
-
);
|
|
118
|
-
expect(isValid).toBe(false);
|
|
119
|
-
});
|
|
120
|
-
|
|
121
|
-
it('should validate data creators can delete their own data', async () => {
|
|
122
|
-
const holon = await hs.toHolon(37.7749, -122.4194, 9);
|
|
123
|
-
|
|
124
|
-
await hs.write(holon, 'my-data', {
|
|
125
|
-
id: 'my-item-001',
|
|
126
|
-
content: 'My content'
|
|
127
|
-
});
|
|
128
|
-
|
|
129
|
-
// Owner should be able to delete without capability token
|
|
130
|
-
const deleted = await hs.delete(holon, 'my-data', 'my-item-001');
|
|
131
|
-
expect(deleted).toBe(true);
|
|
132
|
-
});
|
|
133
|
-
|
|
134
|
-
it('should validate capability tokens work across different lenses', async () => {
|
|
135
|
-
const holon = await hs.toHolon(37.7749, -122.4194, 9);
|
|
136
|
-
|
|
137
|
-
// Token for lens 'documents'
|
|
138
|
-
const docToken = await hs.issueCapability(
|
|
139
|
-
['delete'],
|
|
140
|
-
{ holonId: holon, lensName: 'documents' },
|
|
141
|
-
userBPublicKey,
|
|
142
|
-
{ issuerKey: userAPrivateKey }
|
|
143
|
-
);
|
|
144
|
-
|
|
145
|
-
// Should be valid for 'documents' lens
|
|
146
|
-
const validForDocs = await hs.verifyCapability(
|
|
147
|
-
docToken,
|
|
148
|
-
'delete',
|
|
149
|
-
{ holonId: holon, lensName: 'documents' }
|
|
150
|
-
);
|
|
151
|
-
expect(validForDocs).toBe(true);
|
|
152
|
-
|
|
153
|
-
// Should NOT be valid for 'photos' lens
|
|
154
|
-
const validForPhotos = await hs.verifyCapability(
|
|
155
|
-
docToken,
|
|
156
|
-
'delete',
|
|
157
|
-
{ holonId: holon, lensName: 'photos' }
|
|
158
|
-
);
|
|
159
|
-
expect(validForPhotos).toBe(false);
|
|
160
|
-
});
|
|
161
|
-
});
|