holosphere 2.0.0-alpha7 → 2.0.0-alpha9
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 +446 -0
- package/FEATURES.md +431 -0
- package/LICENSE +29 -166
- package/LICENSE-AGPL.md +180 -0
- package/dist/cdn/holosphere.min.js +55 -0
- package/dist/cdn/holosphere.min.js.map +1 -0
- package/dist/cjs/holosphere.cjs +1 -1
- package/dist/esm/holosphere.js +1 -1
- package/dist/{index-C-IlLYlk.cjs → index-DDGt_V9o.cjs} +2 -2
- package/dist/{index-C-IlLYlk.cjs.map → index-DDGt_V9o.cjs.map} +1 -1
- package/dist/{index-d6f4RJBM.js → index-DJXftyvB.js} +2253 -387
- 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-jmTHEbR2.js → index-DeZ1xz_s.js} +2 -2
- package/dist/{index-jmTHEbR2.js.map → index-DeZ1xz_s.js.map} +1 -1
- package/dist/{indexeddb-storage-D8kOl0oK.js → indexeddb-storage-BFt6hMeF.js} +48 -4
- package/dist/indexeddb-storage-BFt6hMeF.js.map +1 -0
- package/dist/{indexeddb-storage-a8GipaDr.cjs → indexeddb-storage-BK5tv4Sh.cjs} +2 -2
- package/dist/indexeddb-storage-BK5tv4Sh.cjs.map +1 -0
- package/dist/{memory-storage-DBQK622V.js → memory-storage-C9HuoL2E.js} +44 -4
- package/dist/memory-storage-C9HuoL2E.js.map +1 -0
- package/dist/{memory-storage-gfRovk2O.cjs → memory-storage-Dao7jfYG.cjs} +2 -2
- package/dist/memory-storage-Dao7jfYG.cjs.map +1 -0
- package/dist/{secp256k1-BCAPF45D.cjs → secp256k1-BbKzbLtD.cjs} +2 -2
- package/dist/{secp256k1-BCAPF45D.cjs.map → secp256k1-BbKzbLtD.cjs.map} +1 -1
- package/dist/{secp256k1-DYm_CMqW.js → secp256k1-CreY7Pcl.js} +2 -2
- package/dist/{secp256k1-DYm_CMqW.js.map → secp256k1-CreY7Pcl.js.map} +1 -1
- 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/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 +16 -3
- 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/chain-manager.js +68 -40
- package/src/contracts/deployer.js +70 -42
- package/src/contracts/event-listener.js +61 -29
- package/src/contracts/holon-contracts.js +46 -31
- package/src/contracts/index.js +5 -6
- package/src/contracts/networks.js +19 -14
- package/src/contracts/operations.js +58 -41
- package/src/contracts/queries.js +70 -21
- package/src/core/holosphere.js +37 -8
- package/src/crypto/nostr-utils.js +105 -65
- package/src/crypto/secp256k1.js +7 -2
- package/src/federation/handshake.js +23 -11
- package/src/federation/hologram.js +9 -1
- package/src/hierarchical/upcast.js +34 -20
- package/src/index.js +671 -7
- package/src/lib/ai-methods.js +352 -3
- package/src/lib/contract-methods.js +152 -3
- package/src/lib/errors.js +31 -1
- package/src/lib/federation-methods.js +110 -3
- package/src/lib/index.js +9 -5
- package/src/schema/validator.js +22 -3
- package/src/spatial/h3-operations.js +17 -1
- 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 +322 -11
- 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 +7 -2
- package/src/storage/gun-async.js +20 -11
- package/src/storage/gun-auth.js +15 -4
- package/src/storage/gun-federation.js +14 -5
- package/src/storage/gun-references.js +16 -5
- package/src/storage/gun-schema.js +25 -10
- package/src/storage/gun-wrapper.js +160 -49
- package/src/storage/indexeddb-storage.js +65 -4
- package/src/storage/key-storage-simple.js +32 -9
- package/src/storage/key-storage.js +45 -13
- package/src/storage/memory-storage.js +65 -4
- package/src/storage/migration.js +20 -7
- package/src/storage/nostr-async.js +195 -90
- package/src/storage/nostr-client.js +173 -49
- package/src/storage/nostr-wrapper.js +6 -2
- package/src/storage/outbox-queue.js +55 -18
- package/src/storage/persistent-storage.js +56 -13
- package/src/storage/sync-service.js +51 -17
- package/src/storage/unified-storage.js +38 -3
- package/src/subscriptions/manager.js +33 -16
- package/vite.config.cdn.js +60 -0
- package/dist/index-Bvwyvd0T.cjs +0 -5
- package/dist/index-Bvwyvd0T.cjs.map +0 -1
- package/dist/index-d6f4RJBM.js.map +0 -1
- package/dist/indexeddb-storage-D8kOl0oK.js.map +0 -1
- package/dist/indexeddb-storage-a8GipaDr.cjs.map +0 -1
- package/dist/memory-storage-DBQK622V.js.map +0 -1
- package/dist/memory-storage-gfRovk2O.cjs.map +0 -1
- /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,34 +1,52 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Nostr Async Utilities
|
|
3
|
-
*
|
|
2
|
+
* @fileoverview Nostr Async Utilities.
|
|
3
|
+
*
|
|
4
|
+
* Provides Promise-based wrappers and async patterns for Nostr operations.
|
|
5
|
+
* Includes local-first data access, query deduplication, subscription management,
|
|
6
|
+
* and background refresh capabilities for optimal performance.
|
|
7
|
+
*
|
|
8
|
+
* @module storage/nostr-async
|
|
4
9
|
*/
|
|
5
10
|
|
|
6
11
|
/**
|
|
7
|
-
* Global subscription manager to prevent duplicate subscriptions
|
|
12
|
+
* Global subscription manager to prevent duplicate subscriptions.
|
|
8
13
|
* Maps: subscriptionKey -> subscription object
|
|
14
|
+
* @private
|
|
9
15
|
*/
|
|
10
16
|
const globalSubscriptions = new Map();
|
|
11
17
|
|
|
12
18
|
/**
|
|
13
|
-
* Single-path subscription manager (for nostrSubscribe)
|
|
19
|
+
* Single-path subscription manager (for nostrSubscribe).
|
|
14
20
|
* Maps: subscriptionKey -> { subscription, callbacks: [] }
|
|
21
|
+
* @private
|
|
15
22
|
*/
|
|
16
23
|
const singlePathSubscriptions = new Map();
|
|
17
24
|
|
|
18
25
|
/**
|
|
19
|
-
* Query deduplication for nostrGet - prevents duplicate relay queries
|
|
26
|
+
* Query deduplication for nostrGet - prevents duplicate relay queries.
|
|
20
27
|
* Maps: queryKey -> { promise, timestamp, callbacks: [] }
|
|
28
|
+
* @private
|
|
21
29
|
*/
|
|
22
30
|
const pendingQueries = new Map();
|
|
23
|
-
const QUERY_DEDUP_WINDOW = 2000; // 2 second window for deduplication
|
|
24
31
|
|
|
25
32
|
/**
|
|
26
|
-
*
|
|
33
|
+
* Time window for query deduplication (2 seconds).
|
|
34
|
+
* @private
|
|
35
|
+
* @constant {number}
|
|
36
|
+
*/
|
|
37
|
+
const QUERY_DEDUP_WINDOW = 2000;
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Write data as Nostr event (parameterized replaceable event).
|
|
41
|
+
*
|
|
27
42
|
* @param {Object} client - NostrClient instance
|
|
28
43
|
* @param {string} path - Path identifier (encoded in d-tag)
|
|
29
44
|
* @param {Object} data - Data to store
|
|
30
|
-
* @param {number} kind - Event kind (default: 30000 for parameterized replaceable)
|
|
31
|
-
* @returns {Promise<Object>} Published event result
|
|
45
|
+
* @param {number} [kind=30000] - Event kind (default: 30000 for parameterized replaceable)
|
|
46
|
+
* @returns {Promise<Object>} Published event result with relay responses
|
|
47
|
+
* @example
|
|
48
|
+
* const result = await nostrPut(client, 'myapp/holon123/items/item1', { name: 'Test' });
|
|
49
|
+
* console.log(result.event.id); // Event ID
|
|
32
50
|
*/
|
|
33
51
|
export async function nostrPut(client, path, data, kind = 30000) {
|
|
34
52
|
const dataEvent = {
|
|
@@ -45,17 +63,25 @@ export async function nostrPut(client, path, data, kind = 30000) {
|
|
|
45
63
|
}
|
|
46
64
|
|
|
47
65
|
/**
|
|
48
|
-
* Read data from Nostr (query by d-tag)
|
|
49
|
-
*
|
|
50
|
-
*
|
|
66
|
+
* Read data from Nostr (query by d-tag).
|
|
67
|
+
*
|
|
68
|
+
* LOCAL-FIRST: Checks persistent storage first, never blocks on network.
|
|
69
|
+
* Uses query deduplication to prevent duplicate relay queries within a time window.
|
|
70
|
+
*
|
|
51
71
|
* @param {Object} client - NostrClient instance
|
|
52
72
|
* @param {string} path - Path identifier
|
|
53
|
-
* @param {number} kind - Event kind (default: 30000)
|
|
54
|
-
* @param {Object} options - Query options
|
|
55
|
-
* @param {string[]} options.authors - Array of public keys to query (default: [client.publicKey])
|
|
56
|
-
* @param {boolean} options.includeAuthor - If true, adds _author field to returned data
|
|
57
|
-
* @param {boolean} options.skipPersistent - If true, skip persistent storage check
|
|
73
|
+
* @param {number} [kind=30000] - Event kind (default: 30000)
|
|
74
|
+
* @param {Object} [options={}] - Query options
|
|
75
|
+
* @param {string[]} [options.authors] - Array of public keys to query (default: [client.publicKey])
|
|
76
|
+
* @param {boolean} [options.includeAuthor=false] - If true, adds _author field to returned data
|
|
77
|
+
* @param {boolean} [options.skipPersistent=false] - If true, skip persistent storage check
|
|
78
|
+
* @param {number} [options.timeout=30000] - Query timeout in milliseconds
|
|
58
79
|
* @returns {Promise<Object|null>} Data or null if not found
|
|
80
|
+
* @example
|
|
81
|
+
* const data = await nostrGet(client, 'myapp/holon1/items/item1');
|
|
82
|
+
* if (data) {
|
|
83
|
+
* console.log(data.name);
|
|
84
|
+
* }
|
|
59
85
|
*/
|
|
60
86
|
export async function nostrGet(client, path, kind = 30000, options = {}) {
|
|
61
87
|
const timeout = options.timeout !== undefined ? options.timeout : 30000;
|
|
@@ -65,28 +91,33 @@ export async function nostrGet(client, path, kind = 30000, options = {}) {
|
|
|
65
91
|
if (!options.skipPersistent && client.persistentGet) {
|
|
66
92
|
const persistedEvent = await client.persistentGet(path);
|
|
67
93
|
if (persistedEvent && persistedEvent.content) {
|
|
68
|
-
|
|
69
|
-
|
|
94
|
+
// Verify author is in requested authors list (persistent storage may have cached events from other authors)
|
|
95
|
+
if (!authors.includes(persistedEvent.pubkey)) {
|
|
96
|
+
// Author mismatch - fall through to relay query
|
|
97
|
+
} else {
|
|
98
|
+
try {
|
|
99
|
+
const data = JSON.parse(persistedEvent.content);
|
|
70
100
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
101
|
+
// Skip null/undefined or deleted items
|
|
102
|
+
if (!data || data._deleted) {
|
|
103
|
+
return null;
|
|
104
|
+
}
|
|
75
105
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
106
|
+
// Optionally include author information
|
|
107
|
+
if (options.includeAuthor) {
|
|
108
|
+
data._author = persistedEvent.pubkey;
|
|
109
|
+
}
|
|
80
110
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
111
|
+
// Trigger background refresh from relays (fire-and-forget)
|
|
112
|
+
if (client.refreshPathInBackground) {
|
|
113
|
+
client.refreshPathInBackground(path, kind, { authors, timeout });
|
|
114
|
+
}
|
|
85
115
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
116
|
+
return data;
|
|
117
|
+
} catch (error) {
|
|
118
|
+
// Fall through to relay query if parsing fails
|
|
119
|
+
console.warn('[nostrGet] Failed to parse persisted event:', error);
|
|
120
|
+
}
|
|
90
121
|
}
|
|
91
122
|
}
|
|
92
123
|
}
|
|
@@ -123,8 +154,16 @@ export async function nostrGet(client, path, kind = 30000, options = {}) {
|
|
|
123
154
|
}
|
|
124
155
|
|
|
125
156
|
/**
|
|
126
|
-
* Internal function to execute nostrGet query
|
|
157
|
+
* Internal function to execute nostrGet query.
|
|
158
|
+
*
|
|
127
159
|
* @private
|
|
160
|
+
* @param {Object} client - NostrClient instance
|
|
161
|
+
* @param {string} path - Path identifier
|
|
162
|
+
* @param {number} kind - Event kind
|
|
163
|
+
* @param {string[]} authors - Array of author public keys
|
|
164
|
+
* @param {number} timeout - Query timeout
|
|
165
|
+
* @param {Object} options - Query options
|
|
166
|
+
* @returns {Promise<Object|null>} Data or null
|
|
128
167
|
*/
|
|
129
168
|
async function _executeNostrGet(client, path, kind, authors, timeout, options) {
|
|
130
169
|
const filter = {
|
|
@@ -136,17 +175,20 @@ async function _executeNostrGet(client, path, kind, authors, timeout, options) {
|
|
|
136
175
|
|
|
137
176
|
const events = await client.query(filter, { timeout });
|
|
138
177
|
|
|
139
|
-
|
|
178
|
+
// Filter by author (relays may not respect authors filter)
|
|
179
|
+
const authoredEvents = events.filter(event => authors.includes(event.pubkey));
|
|
180
|
+
|
|
181
|
+
if (authoredEvents.length === 0) {
|
|
140
182
|
return null;
|
|
141
183
|
}
|
|
142
184
|
|
|
143
|
-
// Get most recent event (across
|
|
144
|
-
const event =
|
|
185
|
+
// Get most recent event (across allowed authors)
|
|
186
|
+
const event = authoredEvents.sort((a, b) => b.created_at - a.created_at)[0];
|
|
145
187
|
|
|
146
188
|
try {
|
|
147
189
|
const data = JSON.parse(event.content);
|
|
148
|
-
// Skip deleted items
|
|
149
|
-
if (data._deleted) {
|
|
190
|
+
// Skip null/undefined or deleted items
|
|
191
|
+
if (!data || data._deleted) {
|
|
150
192
|
return null;
|
|
151
193
|
}
|
|
152
194
|
// Optionally include author information
|
|
@@ -161,17 +203,24 @@ async function _executeNostrGet(client, path, kind, authors, timeout, options) {
|
|
|
161
203
|
}
|
|
162
204
|
|
|
163
205
|
/**
|
|
164
|
-
* Query all events under a path prefix
|
|
165
|
-
*
|
|
166
|
-
*
|
|
206
|
+
* Query all events under a path prefix.
|
|
207
|
+
*
|
|
208
|
+
* LOCAL-FIRST: Checks persistent storage first, never blocks on network.
|
|
209
|
+
* Uses query deduplication to prevent duplicate relay queries within a time window.
|
|
210
|
+
*
|
|
167
211
|
* @param {Object} client - NostrClient instance
|
|
168
212
|
* @param {string} pathPrefix - Path prefix to match
|
|
169
|
-
* @param {number} kind - Event kind (default: 30000)
|
|
170
|
-
* @param {Object} options - Query options
|
|
171
|
-
* @param {string[]} options.authors - Array of public keys to query (default: [client.publicKey])
|
|
172
|
-
* @param {boolean} options.includeAuthor - If true, adds _author field to returned data
|
|
173
|
-
* @param {boolean} options.skipPersistent - If true, skip persistent storage check
|
|
213
|
+
* @param {number} [kind=30000] - Event kind (default: 30000)
|
|
214
|
+
* @param {Object} [options={}] - Query options
|
|
215
|
+
* @param {string[]} [options.authors] - Array of public keys to query (default: [client.publicKey])
|
|
216
|
+
* @param {boolean} [options.includeAuthor=false] - If true, adds _author field to returned data
|
|
217
|
+
* @param {boolean} [options.skipPersistent=false] - If true, skip persistent storage check
|
|
218
|
+
* @param {number} [options.timeout=30000] - Query timeout in milliseconds
|
|
219
|
+
* @param {number} [options.limit=1000] - Maximum number of events to retrieve
|
|
174
220
|
* @returns {Promise<Array>} Array of data objects
|
|
221
|
+
* @example
|
|
222
|
+
* const items = await nostrGetAll(client, 'myapp/holon1/items/');
|
|
223
|
+
* console.log(`Found ${items.length} items`);
|
|
175
224
|
*/
|
|
176
225
|
export async function nostrGetAll(client, pathPrefix, kind = 30000, options = {}) {
|
|
177
226
|
const timeout = options.timeout !== undefined ? options.timeout : 30000;
|
|
@@ -187,6 +236,9 @@ export async function nostrGetAll(client, pathPrefix, kind = 30000, options = {}
|
|
|
187
236
|
for (const event of persistedEvents) {
|
|
188
237
|
if (!event || !event.tags) continue;
|
|
189
238
|
|
|
239
|
+
// Verify author is in requested authors list (persistent storage may have cached events from other authors)
|
|
240
|
+
if (!authors.includes(event.pubkey)) continue;
|
|
241
|
+
|
|
190
242
|
const dTag = event.tags.find(t => t[0] === 'd');
|
|
191
243
|
if (!dTag || !dTag[1] || !dTag[1].startsWith(pathPrefix)) continue;
|
|
192
244
|
|
|
@@ -197,8 +249,8 @@ export async function nostrGetAll(client, pathPrefix, kind = 30000, options = {}
|
|
|
197
249
|
try {
|
|
198
250
|
const data = JSON.parse(event.content);
|
|
199
251
|
|
|
200
|
-
// Handle deleted items - remove from map if this is newer
|
|
201
|
-
if (data._deleted) {
|
|
252
|
+
// Handle null/undefined or deleted items - remove from map if this is newer
|
|
253
|
+
if (!data || data._deleted) {
|
|
202
254
|
byPath.delete(path);
|
|
203
255
|
continue;
|
|
204
256
|
}
|
|
@@ -255,8 +307,17 @@ export async function nostrGetAll(client, pathPrefix, kind = 30000, options = {}
|
|
|
255
307
|
}
|
|
256
308
|
|
|
257
309
|
/**
|
|
258
|
-
* Internal function to execute nostrGetAll query
|
|
310
|
+
* Internal function to execute nostrGetAll query.
|
|
311
|
+
*
|
|
259
312
|
* @private
|
|
313
|
+
* @param {Object} client - NostrClient instance
|
|
314
|
+
* @param {string} pathPrefix - Path prefix to match
|
|
315
|
+
* @param {number} kind - Event kind
|
|
316
|
+
* @param {string[]} authors - Array of author public keys
|
|
317
|
+
* @param {number} timeout - Query timeout
|
|
318
|
+
* @param {number} limit - Maximum results
|
|
319
|
+
* @param {Object} options - Query options
|
|
320
|
+
* @returns {Promise<Array>} Array of data objects
|
|
260
321
|
*/
|
|
261
322
|
async function _executeNostrGetAll(client, pathPrefix, kind, authors, timeout, limit, options) {
|
|
262
323
|
const filter = {
|
|
@@ -267,10 +328,12 @@ async function _executeNostrGetAll(client, pathPrefix, kind, authors, timeout, l
|
|
|
267
328
|
|
|
268
329
|
const events = await client.query(filter, { timeout });
|
|
269
330
|
|
|
270
|
-
// Filter by path prefix
|
|
331
|
+
// Filter by path prefix AND verify author (relays may not respect authors filter)
|
|
271
332
|
const matching = events.filter(event => {
|
|
272
333
|
const dTag = event.tags.find(t => t[0] === 'd');
|
|
273
|
-
|
|
334
|
+
const pathMatches = dTag && dTag[1] && dTag[1].startsWith(pathPrefix);
|
|
335
|
+
const authorAllowed = authors.includes(event.pubkey);
|
|
336
|
+
return pathMatches && authorAllowed;
|
|
274
337
|
});
|
|
275
338
|
|
|
276
339
|
// Parse content and group by d-tag (keep latest only, across all authors)
|
|
@@ -283,8 +346,8 @@ async function _executeNostrGetAll(client, pathPrefix, kind, authors, timeout, l
|
|
|
283
346
|
try {
|
|
284
347
|
const data = JSON.parse(event.content);
|
|
285
348
|
|
|
286
|
-
// Handle deleted items - remove from map if this is newer
|
|
287
|
-
if (data._deleted) {
|
|
349
|
+
// Handle null/undefined or deleted items - remove from map if this is newer
|
|
350
|
+
if (!data || data._deleted) {
|
|
288
351
|
byPath.delete(dTag);
|
|
289
352
|
continue;
|
|
290
353
|
}
|
|
@@ -305,14 +368,18 @@ async function _executeNostrGetAll(client, pathPrefix, kind, authors, timeout, l
|
|
|
305
368
|
}
|
|
306
369
|
|
|
307
370
|
/**
|
|
308
|
-
* Query all events under a path prefix (HYBRID MODE - local + relay)
|
|
309
|
-
*
|
|
371
|
+
* Query all events under a path prefix (HYBRID MODE - local + relay).
|
|
372
|
+
*
|
|
373
|
+
* Checks local cache first, then merges with relay data.
|
|
374
|
+
*
|
|
310
375
|
* @param {Object} client - NostrClient instance
|
|
311
376
|
* @param {string} pathPrefix - Path prefix to match
|
|
312
|
-
* @param {number} kind - Event kind (default: 30000)
|
|
313
|
-
* @param {Object} options - Query options
|
|
314
|
-
* @param {string[]} options.authors - Array of public keys to query (default: [client.publicKey])
|
|
315
|
-
* @param {boolean} options.includeAuthor - If true, adds _author field to returned data
|
|
377
|
+
* @param {number} [kind=30000] - Event kind (default: 30000)
|
|
378
|
+
* @param {Object} [options={}] - Query options
|
|
379
|
+
* @param {string[]} [options.authors] - Array of public keys to query (default: [client.publicKey])
|
|
380
|
+
* @param {boolean} [options.includeAuthor=false] - If true, adds _author field to returned data
|
|
381
|
+
* @param {number} [options.timeout=30000] - Query timeout in milliseconds
|
|
382
|
+
* @param {number} [options.limit=1000] - Maximum number of events to retrieve
|
|
316
383
|
* @returns {Promise<Array>} Array of data objects (merged from local + relay)
|
|
317
384
|
*/
|
|
318
385
|
export async function nostrGetAllHybrid(client, pathPrefix, kind = 30000, options = {}) {
|
|
@@ -331,10 +398,12 @@ export async function nostrGetAllHybrid(client, pathPrefix, kind = 30000, option
|
|
|
331
398
|
|
|
332
399
|
const events = await queryMethod.call(client, filter, { timeout });
|
|
333
400
|
|
|
334
|
-
// Filter by path prefix
|
|
401
|
+
// Filter by path prefix AND verify author (relays may not respect authors filter)
|
|
335
402
|
const matching = events.filter(event => {
|
|
336
403
|
const dTag = event.tags.find(t => t[0] === 'd');
|
|
337
|
-
|
|
404
|
+
const pathMatches = dTag && dTag[1] && dTag[1].startsWith(pathPrefix);
|
|
405
|
+
const authorAllowed = authors.includes(event.pubkey);
|
|
406
|
+
return pathMatches && authorAllowed;
|
|
338
407
|
});
|
|
339
408
|
|
|
340
409
|
// Parse content and group by d-tag (keep latest only)
|
|
@@ -371,11 +440,19 @@ export async function nostrGetAllHybrid(client, pathPrefix, kind = 30000, option
|
|
|
371
440
|
}
|
|
372
441
|
|
|
373
442
|
/**
|
|
374
|
-
* Delete data (publish deletion event - NIP-09)
|
|
443
|
+
* Delete data (publish deletion event - NIP-09).
|
|
444
|
+
*
|
|
445
|
+
* Publishes a tombstone event and a NIP-09 deletion event to mark data as deleted.
|
|
446
|
+
*
|
|
375
447
|
* @param {Object} client - NostrClient instance
|
|
376
448
|
* @param {string} path - Path identifier
|
|
377
|
-
* @param {number} kind - Original event kind (default: 30000)
|
|
378
|
-
* @returns {Promise<Object>} Deletion event result
|
|
449
|
+
* @param {number} [kind=30000] - Original event kind (default: 30000)
|
|
450
|
+
* @returns {Promise<Object>} Deletion event result with status
|
|
451
|
+
* @example
|
|
452
|
+
* const result = await nostrDelete(client, 'myapp/holon1/items/item1');
|
|
453
|
+
* if (result.reason !== 'not_found') {
|
|
454
|
+
* console.log('Item deleted successfully');
|
|
455
|
+
* }
|
|
379
456
|
*/
|
|
380
457
|
export async function nostrDelete(client, path, kind = 30000) {
|
|
381
458
|
// Read existing data first
|
|
@@ -432,11 +509,15 @@ export async function nostrDelete(client, path, kind = 30000) {
|
|
|
432
509
|
}
|
|
433
510
|
|
|
434
511
|
/**
|
|
435
|
-
* Delete all data with path prefix (publish deletion events - NIP-09)
|
|
512
|
+
* Delete all data with path prefix (publish deletion events - NIP-09).
|
|
513
|
+
*
|
|
436
514
|
* @param {Object} client - NostrClient instance
|
|
437
515
|
* @param {string} pathPrefix - Path prefix to delete all items under
|
|
438
|
-
* @param {number} kind - Original event kind (default: 30000)
|
|
439
|
-
* @returns {Promise<Object>} Deletion results
|
|
516
|
+
* @param {number} [kind=30000] - Original event kind (default: 30000)
|
|
517
|
+
* @returns {Promise<Object>} Deletion results with success count
|
|
518
|
+
* @example
|
|
519
|
+
* const result = await nostrDeleteAll(client, 'myapp/holon1/items/');
|
|
520
|
+
* console.log(`Deleted ${result.count} items`);
|
|
440
521
|
*/
|
|
441
522
|
export async function nostrDeleteAll(client, pathPrefix, kind = 30000) {
|
|
442
523
|
// Query events from relay
|
|
@@ -551,13 +632,21 @@ export async function nostrDeleteAll(client, pathPrefix, kind = 30000) {
|
|
|
551
632
|
}
|
|
552
633
|
|
|
553
634
|
/**
|
|
554
|
-
* Subscribe to path changes
|
|
555
|
-
*
|
|
635
|
+
* Subscribe to path changes.
|
|
636
|
+
*
|
|
637
|
+
* Uses subscription deduplication - multiple subscribers to same path share one relay subscription.
|
|
638
|
+
*
|
|
556
639
|
* @param {Object} client - NostrClient instance
|
|
557
640
|
* @param {string} path - Path to subscribe to
|
|
558
641
|
* @param {Function} callback - Callback function (data, event) => void
|
|
559
|
-
* @param {Object} options - Subscription options
|
|
642
|
+
* @param {Object} [options={}] - Subscription options
|
|
643
|
+
* @param {number} [options.kind=30000] - Event kind to subscribe to
|
|
560
644
|
* @returns {Object} Subscription object with unsubscribe method
|
|
645
|
+
* @example
|
|
646
|
+
* const sub = nostrSubscribe(client, 'myapp/holon1/items/item1', (data, event) => {
|
|
647
|
+
* console.log('Item updated:', data);
|
|
648
|
+
* });
|
|
649
|
+
* // Later: sub.unsubscribe();
|
|
561
650
|
*/
|
|
562
651
|
export function nostrSubscribe(client, path, callback, options = {}) {
|
|
563
652
|
const kind = options.kind || 30000;
|
|
@@ -616,8 +705,8 @@ export function nostrSubscribe(client, path, callback, options = {}) {
|
|
|
616
705
|
try {
|
|
617
706
|
const data = JSON.parse(event.content);
|
|
618
707
|
|
|
619
|
-
// Skip deleted items - don't send tombstones to subscribers
|
|
620
|
-
if (data._deleted) {
|
|
708
|
+
// Skip null/undefined or deleted items - don't send tombstones to subscribers
|
|
709
|
+
if (!data || data._deleted) {
|
|
621
710
|
return;
|
|
622
711
|
}
|
|
623
712
|
|
|
@@ -659,7 +748,7 @@ export function nostrSubscribe(client, path, callback, options = {}) {
|
|
|
659
748
|
}
|
|
660
749
|
|
|
661
750
|
/**
|
|
662
|
-
* Subscribe to path prefix (multiple paths)
|
|
751
|
+
* Subscribe to path prefix (multiple paths).
|
|
663
752
|
*
|
|
664
753
|
* Subscribes to data events and uses Page Visibility API to refresh when tab becomes visible.
|
|
665
754
|
* Note: Nostr relays do not broadcast replaceable event updates to active subscriptions.
|
|
@@ -667,8 +756,14 @@ export function nostrSubscribe(client, path, callback, options = {}) {
|
|
|
667
756
|
* @param {Object} client - NostrClient instance
|
|
668
757
|
* @param {string} pathPrefix - Path prefix to match
|
|
669
758
|
* @param {Function} callback - Callback function (data, path, event) => void
|
|
670
|
-
* @param {Object} options - Subscription options
|
|
759
|
+
* @param {Object} [options={}] - Subscription options
|
|
760
|
+
* @param {number} [options.kind=30000] - Event kind to subscribe to
|
|
671
761
|
* @returns {Promise<Object>} Subscription object with unsubscribe method
|
|
762
|
+
* @example
|
|
763
|
+
* const sub = await nostrSubscribeMany(client, 'myapp/holon1/items/', (data, path, event) => {
|
|
764
|
+
* console.log('Item event:', data);
|
|
765
|
+
* });
|
|
766
|
+
* // Later: sub.unsubscribe();
|
|
672
767
|
*/
|
|
673
768
|
export async function nostrSubscribeMany(client, pathPrefix, callback, options = {}) {
|
|
674
769
|
const kind = options.kind || 30000;
|
|
@@ -743,8 +838,8 @@ export async function nostrSubscribeMany(client, pathPrefix, callback, options =
|
|
|
743
838
|
try {
|
|
744
839
|
const data = JSON.parse(event.content);
|
|
745
840
|
|
|
746
|
-
// Skip deleted items - don't send tombstones to subscribers
|
|
747
|
-
if (data._deleted) {
|
|
841
|
+
// Skip null/undefined data or deleted items - don't send tombstones to subscribers
|
|
842
|
+
if (!data || data._deleted) {
|
|
748
843
|
return;
|
|
749
844
|
}
|
|
750
845
|
|
|
@@ -829,12 +924,16 @@ export async function nostrSubscribeMany(client, pathPrefix, callback, options =
|
|
|
829
924
|
}
|
|
830
925
|
|
|
831
926
|
/**
|
|
832
|
-
* Update data (merge with existing)
|
|
927
|
+
* Update data (merge with existing).
|
|
928
|
+
*
|
|
833
929
|
* @param {Object} client - NostrClient instance
|
|
834
930
|
* @param {string} path - Path identifier
|
|
835
931
|
* @param {Object} updates - Fields to update
|
|
836
|
-
* @param {number} kind - Event kind (default: 30000)
|
|
932
|
+
* @param {number} [kind=30000] - Event kind (default: 30000)
|
|
837
933
|
* @returns {Promise<Object>} Updated event result
|
|
934
|
+
* @throws {Error} If no data found at path
|
|
935
|
+
* @example
|
|
936
|
+
* await nostrUpdate(client, 'myapp/holon1/items/item1', { status: 'completed' });
|
|
838
937
|
*/
|
|
839
938
|
export async function nostrUpdate(client, path, updates, kind = 30000) {
|
|
840
939
|
// Read existing data
|
|
@@ -852,10 +951,11 @@ export async function nostrUpdate(client, path, updates, kind = 30000) {
|
|
|
852
951
|
}
|
|
853
952
|
|
|
854
953
|
/**
|
|
855
|
-
* Batch read multiple paths
|
|
954
|
+
* Batch read multiple paths.
|
|
955
|
+
*
|
|
856
956
|
* @param {Object} client - NostrClient instance
|
|
857
957
|
* @param {string[]} paths - Array of paths
|
|
858
|
-
* @param {number} kind - Event kind (default: 30000)
|
|
958
|
+
* @param {number} [kind=30000] - Event kind (default: 30000)
|
|
859
959
|
* @returns {Promise<Object>} Object mapping paths to data
|
|
860
960
|
*/
|
|
861
961
|
export async function nostrBatchGet(client, paths, kind = 30000) {
|
|
@@ -896,10 +996,11 @@ export async function nostrBatchGet(client, paths, kind = 30000) {
|
|
|
896
996
|
}
|
|
897
997
|
|
|
898
998
|
/**
|
|
899
|
-
* Batch write multiple paths
|
|
999
|
+
* Batch write multiple paths.
|
|
1000
|
+
*
|
|
900
1001
|
* @param {Object} client - NostrClient instance
|
|
901
1002
|
* @param {Object} pathDataMap - Object mapping paths to data
|
|
902
|
-
* @param {number} kind - Event kind (default: 30000)
|
|
1003
|
+
* @param {number} [kind=30000] - Event kind (default: 30000)
|
|
903
1004
|
* @returns {Promise<Array>} Array of publish results
|
|
904
1005
|
*/
|
|
905
1006
|
export async function nostrBatchPut(client, pathDataMap, kind = 30000) {
|
|
@@ -911,11 +1012,13 @@ export async function nostrBatchPut(client, pathDataMap, kind = 30000) {
|
|
|
911
1012
|
}
|
|
912
1013
|
|
|
913
1014
|
/**
|
|
914
|
-
* Retry operation with exponential backoff
|
|
1015
|
+
* Retry operation with exponential backoff.
|
|
1016
|
+
*
|
|
915
1017
|
* @param {Function} operation - Async function to retry
|
|
916
|
-
* @param {number} maxRetries - Max retry attempts
|
|
917
|
-
* @param {number} baseDelay - Base delay in ms
|
|
1018
|
+
* @param {number} [maxRetries=3] - Max retry attempts
|
|
1019
|
+
* @param {number} [baseDelay=100] - Base delay in ms
|
|
918
1020
|
* @returns {Promise<any>} Promise resolving to operation result
|
|
1021
|
+
* @throws {Error} Last error if all retries fail
|
|
919
1022
|
*/
|
|
920
1023
|
export async function nostrRetry(operation, maxRetries = 3, baseDelay = 100) {
|
|
921
1024
|
let lastError;
|
|
@@ -936,12 +1039,14 @@ export async function nostrRetry(operation, maxRetries = 3, baseDelay = 100) {
|
|
|
936
1039
|
}
|
|
937
1040
|
|
|
938
1041
|
/**
|
|
939
|
-
* Wait for specific condition on data
|
|
1042
|
+
* Wait for specific condition on data.
|
|
1043
|
+
*
|
|
940
1044
|
* @param {Object} client - NostrClient instance
|
|
941
1045
|
* @param {string} path - Path to watch
|
|
942
1046
|
* @param {Function} predicate - Condition function (data) => boolean
|
|
943
|
-
* @param {number} timeout - Timeout in ms
|
|
1047
|
+
* @param {number} [timeout=5000] - Timeout in ms
|
|
944
1048
|
* @returns {Promise<any>} Promise resolving when condition is met
|
|
1049
|
+
* @throws {Error} If timeout occurs before condition is met
|
|
945
1050
|
*/
|
|
946
1051
|
export async function nostrWaitFor(client, path, predicate, timeout = 5000) {
|
|
947
1052
|
return new Promise((resolve, reject) => {
|