holosphere 2.0.0-alpha8 → 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-CKffQDmQ.cjs → index-DDGt_V9o.cjs} +2 -2
- package/dist/{index-CKffQDmQ.cjs.map → index-DDGt_V9o.cjs.map} +1 -1
- package/dist/{index-4XHHKe6S.js → index-DJXftyvB.js} +1905 -337
- package/dist/index-DJXftyvB.js.map +1 -0
- package/dist/{index-Dz5kOZMI.cjs → index-DMbdcMtK.cjs} +17 -4
- package/dist/index-DMbdcMtK.cjs.map +1 -0
- package/dist/{index-BjP1TXGz.js → index-DeZ1xz_s.js} +2 -2
- package/dist/{index-BjP1TXGz.js.map → index-DeZ1xz_s.js.map} +1 -1
- package/dist/{indexeddb-storage-lExjjFlV.js → indexeddb-storage-BFt6hMeF.js} +48 -4
- package/dist/indexeddb-storage-BFt6hMeF.js.map +1 -0
- package/dist/{indexeddb-storage-DD7EFBVc.cjs → indexeddb-storage-BK5tv4Sh.cjs} +2 -2
- package/dist/indexeddb-storage-BK5tv4Sh.cjs.map +1 -0
- package/dist/{memory-storage-C68adso2.js → memory-storage-C9HuoL2E.js} +44 -4
- package/dist/memory-storage-C9HuoL2E.js.map +1 -0
- package/dist/{memory-storage-DD_6yyXT.cjs → memory-storage-Dao7jfYG.cjs} +2 -2
- package/dist/memory-storage-Dao7jfYG.cjs.map +1 -0
- package/dist/{secp256k1-DYELiqgx.cjs → secp256k1-BbKzbLtD.cjs} +2 -2
- package/dist/{secp256k1-DYELiqgx.cjs.map → secp256k1-BbKzbLtD.cjs.map} +1 -1
- package/dist/{secp256k1-OM8siPyy.js → secp256k1-CreY7Pcl.js} +2 -2
- package/dist/{secp256k1-OM8siPyy.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/jsdoc.json +26 -0
- package/package.json +14 -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/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 +54 -20
- package/src/core/holosphere.js +35 -6
- package/src/crypto/nostr-utils.js +82 -76
- package/src/crypto/secp256k1.js +7 -2
- package/src/federation/handshake.js +7 -7
- package/src/federation/hologram.js +9 -1
- package/src/hierarchical/upcast.js +34 -20
- package/src/index.js +655 -5
- 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 +29 -2
- 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 +99 -36
- 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 +157 -67
- 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 +7 -2
- package/src/subscriptions/manager.js +33 -16
- package/dist/index-4XHHKe6S.js.map +0 -1
- package/dist/index-Dz5kOZMI.cjs.map +0 -1
- package/dist/indexeddb-storage-DD7EFBVc.cjs.map +0 -1
- package/dist/indexeddb-storage-lExjjFlV.js.map +0 -1
- package/dist/memory-storage-C68adso2.js.map +0 -1
- package/dist/memory-storage-DD_6yyXT.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,9 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Nostr
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* Apps can use these without directly importing nostr-tools.
|
|
2
|
+
* @fileoverview Browser-compatible Nostr utility functions for key handling, encryption, and event management.
|
|
3
|
+
* Provides NIP-04 (legacy) and NIP-44 (modern, audited) encryption support, key conversion utilities,
|
|
4
|
+
* and event creation helpers. Applications can use these utilities without directly importing nostr-tools.
|
|
5
|
+
* @module crypto/nostr-utils
|
|
7
6
|
*/
|
|
8
7
|
|
|
9
8
|
import { nip04, nip44, nip19, getPublicKey as nostrGetPublicKey, finalizeEvent, verifyEvent as nostrVerifyEvent } from 'nostr-tools';
|
|
@@ -13,9 +12,9 @@ import { nip04, nip44, nip19, getPublicKey as nostrGetPublicKey, finalizeEvent,
|
|
|
13
12
|
// ============================================================================
|
|
14
13
|
|
|
15
14
|
/**
|
|
16
|
-
* Convert hex string to Uint8Array
|
|
17
|
-
* @param {string} hex -
|
|
18
|
-
* @returns {Uint8Array} Byte array
|
|
15
|
+
* Convert hex string to Uint8Array.
|
|
16
|
+
* @param {string} hex - Hexadecimal string (even length)
|
|
17
|
+
* @returns {Uint8Array} Byte array representation
|
|
19
18
|
*/
|
|
20
19
|
export function hexToBytes(hex) {
|
|
21
20
|
const bytes = new Uint8Array(hex.length / 2);
|
|
@@ -26,9 +25,9 @@ export function hexToBytes(hex) {
|
|
|
26
25
|
}
|
|
27
26
|
|
|
28
27
|
/**
|
|
29
|
-
* Convert Uint8Array to hex string
|
|
30
|
-
* @param {Uint8Array} bytes - Byte array
|
|
31
|
-
* @returns {string}
|
|
28
|
+
* Convert Uint8Array to hex string.
|
|
29
|
+
* @param {Uint8Array} bytes - Byte array to convert
|
|
30
|
+
* @returns {string} Hexadecimal string representation
|
|
32
31
|
*/
|
|
33
32
|
export function bytesToHex(bytes) {
|
|
34
33
|
return Array.from(bytes)
|
|
@@ -37,9 +36,10 @@ export function bytesToHex(bytes) {
|
|
|
37
36
|
}
|
|
38
37
|
|
|
39
38
|
/**
|
|
40
|
-
* Parse an npub or hex public key string into hex format
|
|
41
|
-
*
|
|
42
|
-
* @
|
|
39
|
+
* Parse an npub or hex public key string into hex format.
|
|
40
|
+
* Handles nostr: URI prefix and validates both npub and hex formats.
|
|
41
|
+
* @param {string} input - npub string (npub1...) or 64-character hex public key
|
|
42
|
+
* @returns {Object} Validation result with valid, hexPubKey (if valid), error (if invalid)
|
|
43
43
|
*/
|
|
44
44
|
export function parseNpubOrHex(input) {
|
|
45
45
|
const trimmed = input?.trim();
|
|
@@ -76,9 +76,9 @@ export function parseNpubOrHex(input) {
|
|
|
76
76
|
}
|
|
77
77
|
|
|
78
78
|
/**
|
|
79
|
-
* Convert a hex public key to npub format
|
|
80
|
-
* @param {string} hexPubKey - Hex public key (64
|
|
81
|
-
* @returns {string} npub
|
|
79
|
+
* Convert a hex public key to npub format.
|
|
80
|
+
* @param {string} hexPubKey - Hex public key (64 characters)
|
|
81
|
+
* @returns {string} npub-encoded public key (npub1...)
|
|
82
82
|
*/
|
|
83
83
|
export function hexToNpub(hexPubKey) {
|
|
84
84
|
try {
|
|
@@ -90,9 +90,9 @@ export function hexToNpub(hexPubKey) {
|
|
|
90
90
|
}
|
|
91
91
|
|
|
92
92
|
/**
|
|
93
|
-
* Convert npub to hex public key
|
|
94
|
-
* @param {string} npub - npub string
|
|
95
|
-
* @returns {string|null}
|
|
93
|
+
* Convert npub to hex public key.
|
|
94
|
+
* @param {string} npub - npub-encoded public key string
|
|
95
|
+
* @returns {string|null} 64-character hex public key or null if invalid
|
|
96
96
|
*/
|
|
97
97
|
export function npubToHex(npub) {
|
|
98
98
|
try {
|
|
@@ -107,9 +107,9 @@ export function npubToHex(npub) {
|
|
|
107
107
|
}
|
|
108
108
|
|
|
109
109
|
/**
|
|
110
|
-
* Shorten a public key for display (first 8 and last 8 chars)
|
|
111
|
-
* @param {string} pubKey - Public key
|
|
112
|
-
* @returns {string} Shortened key
|
|
110
|
+
* Shorten a public key for display (first 8 and last 8 chars).
|
|
111
|
+
* @param {string} pubKey - Public key in hex or npub format
|
|
112
|
+
* @returns {string} Shortened key with ellipsis (e.g., 'abcd1234...wxyz9876')
|
|
113
113
|
*/
|
|
114
114
|
export function shortenPubKey(pubKey) {
|
|
115
115
|
if (!pubKey || pubKey.length <= 20) return pubKey || '';
|
|
@@ -117,9 +117,9 @@ export function shortenPubKey(pubKey) {
|
|
|
117
117
|
}
|
|
118
118
|
|
|
119
119
|
/**
|
|
120
|
-
* Shorten an npub for display
|
|
121
|
-
* @param {string} npub - npub
|
|
122
|
-
* @returns {string} Shortened npub
|
|
120
|
+
* Shorten an npub for display (first 12 and last 8 chars).
|
|
121
|
+
* @param {string} npub - npub-encoded public key
|
|
122
|
+
* @returns {string} Shortened npub with ellipsis
|
|
123
123
|
*/
|
|
124
124
|
export function shortenNpub(npub) {
|
|
125
125
|
if (!npub || npub.length <= 20) return npub || '';
|
|
@@ -127,9 +127,10 @@ export function shortenNpub(npub) {
|
|
|
127
127
|
}
|
|
128
128
|
|
|
129
129
|
/**
|
|
130
|
-
*
|
|
131
|
-
*
|
|
132
|
-
* @
|
|
130
|
+
* Derive public key from private key using secp256k1.
|
|
131
|
+
* Matches nostr-tools getPublicKey API.
|
|
132
|
+
* @param {string} privateKey - 64-character hex private key
|
|
133
|
+
* @returns {string} Derived 64-character hex public key
|
|
133
134
|
*/
|
|
134
135
|
export function getPublicKey(privateKey) {
|
|
135
136
|
return nostrGetPublicKey(hexToBytes(privateKey));
|
|
@@ -140,22 +141,23 @@ export function getPublicKey(privateKey) {
|
|
|
140
141
|
// ============================================================================
|
|
141
142
|
|
|
142
143
|
/**
|
|
143
|
-
* Encrypt a message using NIP-04 (
|
|
144
|
-
*
|
|
145
|
-
* @param {string}
|
|
146
|
-
* @param {string}
|
|
147
|
-
* @
|
|
144
|
+
* Encrypt a message using NIP-04 (legacy DM encryption).
|
|
145
|
+
* Uses AES-256-CBC with base64 encoding. Consider using NIP-44 for new implementations.
|
|
146
|
+
* @param {string} privateKey - Sender's 64-character hex private key
|
|
147
|
+
* @param {string} recipientPubKey - Recipient's 64-character hex public key
|
|
148
|
+
* @param {string} content - Plain text message content
|
|
149
|
+
* @returns {Promise<string>} NIP-04 encrypted content string
|
|
148
150
|
*/
|
|
149
151
|
export async function encryptNIP04(privateKey, recipientPubKey, content) {
|
|
150
152
|
return await nip04.encrypt(privateKey, recipientPubKey, content);
|
|
151
153
|
}
|
|
152
154
|
|
|
153
155
|
/**
|
|
154
|
-
* Decrypt a NIP-04 encrypted message
|
|
155
|
-
* @param {string} privateKey - Recipient's hex private key
|
|
156
|
-
* @param {string} senderPubKey - Sender's hex public key
|
|
157
|
-
* @param {string} encryptedContent -
|
|
158
|
-
* @returns {Promise<string>} Decrypted content
|
|
156
|
+
* Decrypt a NIP-04 encrypted message.
|
|
157
|
+
* @param {string} privateKey - Recipient's 64-character hex private key
|
|
158
|
+
* @param {string} senderPubKey - Sender's 64-character hex public key
|
|
159
|
+
* @param {string} encryptedContent - NIP-04 encrypted content string
|
|
160
|
+
* @returns {Promise<string>} Decrypted plain text content
|
|
159
161
|
*/
|
|
160
162
|
export async function decryptNIP04(privateKey, senderPubKey, encryptedContent) {
|
|
161
163
|
return await nip04.decrypt(privateKey, senderPubKey, encryptedContent);
|
|
@@ -166,12 +168,12 @@ export async function decryptNIP04(privateKey, senderPubKey, encryptedContent) {
|
|
|
166
168
|
// ============================================================================
|
|
167
169
|
|
|
168
170
|
/**
|
|
169
|
-
* Encrypt a message using NIP-44 (modern encryption standard)
|
|
170
|
-
* Uses ChaCha20 + HMAC-SHA256, audited by Cure53
|
|
171
|
-
* @param {string} privateKey - Sender's hex private key
|
|
172
|
-
* @param {string} recipientPubKey - Recipient's hex public key
|
|
173
|
-
* @param {string} content - Plain text content
|
|
174
|
-
* @returns {string}
|
|
171
|
+
* Encrypt a message using NIP-44 (modern, audited encryption standard).
|
|
172
|
+
* Uses ChaCha20-Poly1305 + HMAC-SHA256, audited by Cure53. Recommended for new implementations.
|
|
173
|
+
* @param {string} privateKey - Sender's 64-character hex private key
|
|
174
|
+
* @param {string} recipientPubKey - Recipient's 64-character hex public key
|
|
175
|
+
* @param {string} content - Plain text message content
|
|
176
|
+
* @returns {string} NIP-44 encrypted content (base64-encoded)
|
|
175
177
|
*/
|
|
176
178
|
export function encryptNIP44(privateKey, recipientPubKey, content) {
|
|
177
179
|
const privKeyBytes = hexToBytes(privateKey);
|
|
@@ -181,11 +183,11 @@ export function encryptNIP44(privateKey, recipientPubKey, content) {
|
|
|
181
183
|
}
|
|
182
184
|
|
|
183
185
|
/**
|
|
184
|
-
* Decrypt a NIP-44 encrypted message
|
|
185
|
-
* @param {string} privateKey - Recipient's hex private key
|
|
186
|
-
* @param {string} senderPubKey - Sender's hex public key
|
|
187
|
-
* @param {string} encryptedContent -
|
|
188
|
-
* @returns {string} Decrypted content
|
|
186
|
+
* Decrypt a NIP-44 encrypted message.
|
|
187
|
+
* @param {string} privateKey - Recipient's 64-character hex private key
|
|
188
|
+
* @param {string} senderPubKey - Sender's 64-character hex public key
|
|
189
|
+
* @param {string} encryptedContent - NIP-44 encrypted content (base64-encoded)
|
|
190
|
+
* @returns {string} Decrypted plain text content
|
|
189
191
|
*/
|
|
190
192
|
export function decryptNIP44(privateKey, senderPubKey, encryptedContent) {
|
|
191
193
|
const privKeyBytes = hexToBytes(privateKey);
|
|
@@ -199,12 +201,13 @@ export function decryptNIP44(privateKey, senderPubKey, encryptedContent) {
|
|
|
199
201
|
// ============================================================================
|
|
200
202
|
|
|
201
203
|
/**
|
|
202
|
-
* Create and sign a Nostr event
|
|
203
|
-
*
|
|
204
|
-
* @param {
|
|
205
|
-
* @param {string
|
|
206
|
-
* @param {string}
|
|
207
|
-
* @
|
|
204
|
+
* Create and sign a Nostr event.
|
|
205
|
+
* Automatically adds created_at timestamp, computes event ID, and generates signature.
|
|
206
|
+
* @param {number} kind - Event kind (e.g., 1 for text note, 4 for DM)
|
|
207
|
+
* @param {string} content - Event content string
|
|
208
|
+
* @param {string[][]} tags - Array of tag arrays (e.g., [['p', 'pubkey'], ['e', 'eventId']])
|
|
209
|
+
* @param {string} privateKey - 64-character hex private key for signing
|
|
210
|
+
* @returns {Object} Signed Nostr event with id, pubkey, sig, and all fields
|
|
208
211
|
*/
|
|
209
212
|
export function createSignedEvent(kind, content, tags, privateKey) {
|
|
210
213
|
const event = {
|
|
@@ -218,11 +221,12 @@ export function createSignedEvent(kind, content, tags, privateKey) {
|
|
|
218
221
|
}
|
|
219
222
|
|
|
220
223
|
/**
|
|
221
|
-
* Create a NIP-04 encrypted DM event (kind 4)
|
|
222
|
-
*
|
|
223
|
-
* @param {string}
|
|
224
|
-
* @param {string}
|
|
225
|
-
* @
|
|
224
|
+
* Create a NIP-04 encrypted DM event (kind 4).
|
|
225
|
+
* Creates and signs a direct message event with proper recipient tagging.
|
|
226
|
+
* @param {string} recipientPubKey - Recipient's 64-character hex public key
|
|
227
|
+
* @param {string} encryptedContent - NIP-04 encrypted message content
|
|
228
|
+
* @param {string} privateKey - Sender's 64-character hex private key
|
|
229
|
+
* @returns {Object} Signed Nostr DM event (kind 4) with ['p', recipientPubKey] tag
|
|
226
230
|
*/
|
|
227
231
|
export function createDMEvent(recipientPubKey, encryptedContent, privateKey) {
|
|
228
232
|
return createSignedEvent(
|
|
@@ -238,18 +242,18 @@ export function createDMEvent(recipientPubKey, encryptedContent, privateKey) {
|
|
|
238
242
|
// ============================================================================
|
|
239
243
|
|
|
240
244
|
/**
|
|
241
|
-
* Check if a string is a valid hex public key
|
|
242
|
-
* @param {string} str - String to
|
|
243
|
-
* @returns {boolean}
|
|
245
|
+
* Check if a string is a valid hex public key (64 hex characters).
|
|
246
|
+
* @param {string} str - String to validate
|
|
247
|
+
* @returns {boolean} True if valid 64-character hex string
|
|
244
248
|
*/
|
|
245
249
|
export function isValidHexPubKey(str) {
|
|
246
250
|
return typeof str === 'string' && /^[0-9a-fA-F]{64}$/.test(str);
|
|
247
251
|
}
|
|
248
252
|
|
|
249
253
|
/**
|
|
250
|
-
* Check if a string is a valid npub
|
|
251
|
-
* @param {string} str - String to
|
|
252
|
-
* @returns {boolean}
|
|
254
|
+
* Check if a string is a valid npub (starts with npub1 and decodes correctly).
|
|
255
|
+
* @param {string} str - String to validate
|
|
256
|
+
* @returns {boolean} True if valid npub format
|
|
253
257
|
*/
|
|
254
258
|
export function isValidNpub(str) {
|
|
255
259
|
if (typeof str !== 'string' || !str.startsWith('npub1')) {
|
|
@@ -264,18 +268,19 @@ export function isValidNpub(str) {
|
|
|
264
268
|
}
|
|
265
269
|
|
|
266
270
|
/**
|
|
267
|
-
* Generate a unique nonce
|
|
268
|
-
* @returns {string} Unique nonce
|
|
271
|
+
* Generate a unique nonce using timestamp and random value.
|
|
272
|
+
* @returns {string} Unique nonce string combining base36 timestamp and random suffix
|
|
269
273
|
*/
|
|
270
274
|
export function generateNonce() {
|
|
271
275
|
return Date.now().toString(36) + Math.random().toString(36).substring(2, 15);
|
|
272
276
|
}
|
|
273
277
|
|
|
274
278
|
/**
|
|
275
|
-
* Sign a Nostr event
|
|
276
|
-
*
|
|
277
|
-
* @param {
|
|
278
|
-
* @
|
|
279
|
+
* Sign a Nostr event object.
|
|
280
|
+
* Accepts an event object instead of individual parameters. Adds created_at if missing.
|
|
281
|
+
* @param {Object} event - Unsigned event object with kind, content, and tags
|
|
282
|
+
* @param {string} privateKey - 64-character hex private key for signing
|
|
283
|
+
* @returns {Object} Signed Nostr event with id, pubkey, and sig fields added
|
|
279
284
|
*/
|
|
280
285
|
export function signEvent(event, privateKey) {
|
|
281
286
|
const eventToSign = {
|
|
@@ -288,9 +293,10 @@ export function signEvent(event, privateKey) {
|
|
|
288
293
|
}
|
|
289
294
|
|
|
290
295
|
/**
|
|
291
|
-
* Verify a Nostr event signature
|
|
292
|
-
*
|
|
293
|
-
* @
|
|
296
|
+
* Verify a Nostr event signature using secp256k1.
|
|
297
|
+
* Validates that the event ID matches the event data and the signature is valid.
|
|
298
|
+
* @param {Object} event - Signed Nostr event with id, pubkey, and sig fields
|
|
299
|
+
* @returns {boolean} True if event signature is cryptographically valid
|
|
294
300
|
*/
|
|
295
301
|
export function verifyEvent(event) {
|
|
296
302
|
return nostrVerifyEvent(event);
|
package/src/crypto/secp256k1.js
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Cryptographic Operations
|
|
3
|
-
*
|
|
2
|
+
* @fileoverview Cryptographic Operations using secp256k1.
|
|
3
|
+
*
|
|
4
|
+
* Provides signing, verification, and capability token operations using
|
|
5
|
+
* the secp256k1 elliptic curve (same curve used by Bitcoin and Nostr).
|
|
6
|
+
* Uses lazy loading for the crypto module to improve startup performance.
|
|
7
|
+
*
|
|
8
|
+
* @module crypto/secp256k1
|
|
4
9
|
*/
|
|
5
10
|
|
|
6
11
|
import { sha256 } from '@noble/hashes/sha256';
|
|
@@ -300,7 +300,7 @@ export function subscribeToFederationDMs(client, privateKey, publicKey, handlers
|
|
|
300
300
|
* @param {string} params.holonName - Current holon name
|
|
301
301
|
* @param {Object} [params.lensConfig] - Lens configuration
|
|
302
302
|
* @param {string} [params.message] - Optional message
|
|
303
|
-
* @returns {Promise<
|
|
303
|
+
* @returns {Promise<Object>} Result with success, requestId (if successful), error (if failed)
|
|
304
304
|
*/
|
|
305
305
|
export async function initiateFederationHandshake(holosphere, privateKey, params) {
|
|
306
306
|
const {
|
|
@@ -359,7 +359,7 @@ export async function initiateFederationHandshake(holosphere, privateKey, params
|
|
|
359
359
|
* @param {string} params.holonName - Current holon name
|
|
360
360
|
* @param {Object} [params.lensConfig] - Our lens configuration
|
|
361
361
|
* @param {string} [params.message] - Optional message
|
|
362
|
-
* @returns {Promise<
|
|
362
|
+
* @returns {Promise<Object>} Result with success and optional error
|
|
363
363
|
*/
|
|
364
364
|
export async function acceptFederationRequest(holosphere, privateKey, params) {
|
|
365
365
|
const {
|
|
@@ -432,7 +432,7 @@ export async function acceptFederationRequest(holosphere, privateKey, params) {
|
|
|
432
432
|
* @param {string} params.requestId - Original request ID
|
|
433
433
|
* @param {string} params.senderPubKey - Original sender's public key
|
|
434
434
|
* @param {string} [params.message] - Optional rejection message
|
|
435
|
-
* @returns {Promise<
|
|
435
|
+
* @returns {Promise<Object>} Result with success and optional error
|
|
436
436
|
*/
|
|
437
437
|
export async function rejectFederationRequest(holosphere, privateKey, params) {
|
|
438
438
|
const { requestId, senderPubKey, message } = params;
|
|
@@ -458,8 +458,8 @@ export async function rejectFederationRequest(holosphere, privateKey, params) {
|
|
|
458
458
|
|
|
459
459
|
/**
|
|
460
460
|
* Check if payload is a federation request
|
|
461
|
-
* @param {
|
|
462
|
-
* @returns {payload is FederationRequestPayload
|
|
461
|
+
* @param {*} payload - Payload to check
|
|
462
|
+
* @returns {boolean} True if payload is a FederationRequestPayload
|
|
463
463
|
*/
|
|
464
464
|
export function isFederationRequest(payload) {
|
|
465
465
|
return payload?.type === 'federation_request' && payload?.version === '1.0';
|
|
@@ -467,8 +467,8 @@ export function isFederationRequest(payload) {
|
|
|
467
467
|
|
|
468
468
|
/**
|
|
469
469
|
* Check if payload is a federation response
|
|
470
|
-
* @param {
|
|
471
|
-
* @returns {payload is FederationResponsePayload
|
|
470
|
+
* @param {*} payload - Payload to check
|
|
471
|
+
* @returns {boolean} True if payload is a FederationResponsePayload
|
|
472
472
|
*/
|
|
473
473
|
export function isFederationResponse(payload) {
|
|
474
474
|
return payload?.type === 'federation_response' && payload?.version === '1.0';
|
|
@@ -1,11 +1,19 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Federation and Hologram (
|
|
2
|
+
* @fileoverview Federation and Hologram (Reference) Management.
|
|
3
|
+
*
|
|
4
|
+
* Provides hologram (lightweight reference) creation, resolution, and management.
|
|
5
|
+
* Holograms enable data to appear in multiple holons while maintaining a single
|
|
6
|
+
* source of truth. Supports circular reference detection and cross-holosphere
|
|
7
|
+
* federation with capability-based access control.
|
|
8
|
+
*
|
|
9
|
+
* @module federation/hologram
|
|
3
10
|
*/
|
|
4
11
|
|
|
5
12
|
import { buildPath, write, read, update } from '../storage/unified-storage.js';
|
|
6
13
|
import { verifyCapability } from '../crypto/secp256k1.js';
|
|
7
14
|
import { getCapabilityForAuthor } from './registry.js';
|
|
8
15
|
|
|
16
|
+
/** @constant {number} Maximum depth for hologram resolution chain */
|
|
9
17
|
const MAX_RESOLUTION_DEPTH = 10;
|
|
10
18
|
|
|
11
19
|
/**
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Hierarchical
|
|
3
|
-
* FR-025 to FR-027
|
|
2
|
+
* @fileoverview Hierarchical aggregation (upcast) operations for propagating data to parent holons.
|
|
3
|
+
* Implements upcast operations (FR-025 to FR-027) for H3-based geographic hierarchies.
|
|
4
|
+
* @module hierarchical/upcast
|
|
4
5
|
*/
|
|
5
6
|
|
|
6
7
|
import { getParents, isValidH3 } from '../spatial/h3-operations.js';
|
|
@@ -8,15 +9,17 @@ import { createHologram } from '../federation/hologram.js';
|
|
|
8
9
|
import { write } from '../storage/unified-storage.js';
|
|
9
10
|
|
|
10
11
|
/**
|
|
11
|
-
* Upcast data to parent holons in hierarchy
|
|
12
|
+
* Upcast data to parent holons in the H3 hierarchy.
|
|
13
|
+
* Creates holograms in parent holons referencing the source data.
|
|
12
14
|
* @param {Object} hs - HoloSphere instance
|
|
13
|
-
* @param {string} holonId - Source holon ID (must be H3)
|
|
14
|
-
* @param {string} lensName - Lens name
|
|
15
|
-
* @param {string} dataId - Data
|
|
16
|
-
* @param {Object} options - Upcast options
|
|
17
|
-
* @param {number} options.maxLevel - Maximum levels to propagate
|
|
18
|
-
* @param {string} options.operation - 'summarize', 'aggregate', or 'concatenate'
|
|
19
|
-
* @returns {Promise<boolean>}
|
|
15
|
+
* @param {string} holonId - Source holon ID (must be valid H3 index)
|
|
16
|
+
* @param {string} lensName - Lens name for the data
|
|
17
|
+
* @param {string} dataId - Data identifier to upcast
|
|
18
|
+
* @param {Object} [options={}] - Upcast configuration options
|
|
19
|
+
* @param {number} [options.maxLevel=3] - Maximum levels to propagate upward
|
|
20
|
+
* @param {string} [options.operation='concatenate'] - Aggregation operation: 'summarize', 'aggregate', or 'concatenate'
|
|
21
|
+
* @returns {Promise<boolean>} True if upcast succeeded
|
|
22
|
+
* @throws {Error} If holonId is not a valid H3 index
|
|
20
23
|
*/
|
|
21
24
|
export async function upcast(hs, holonId, lensName, dataId, options = {}) {
|
|
22
25
|
const { maxLevel = 3, operation = 'concatenate' } = options;
|
|
@@ -46,8 +49,16 @@ export async function upcast(hs, holonId, lensName, dataId, options = {}) {
|
|
|
46
49
|
}
|
|
47
50
|
|
|
48
51
|
/**
|
|
49
|
-
* Propagate data to parent holon
|
|
52
|
+
* Propagate data to a parent holon by creating a hologram reference.
|
|
50
53
|
* @private
|
|
54
|
+
* @param {Object} client - Nostr client instance
|
|
55
|
+
* @param {string} appname - Application name
|
|
56
|
+
* @param {string} sourceHolon - Source holon ID
|
|
57
|
+
* @param {string} parentHolon - Parent holon ID to propagate to
|
|
58
|
+
* @param {string} lensName - Lens name
|
|
59
|
+
* @param {string} dataId - Data identifier
|
|
60
|
+
* @param {string} operation - Aggregation operation type
|
|
61
|
+
* @returns {Promise<Object>} Write operation result
|
|
51
62
|
*/
|
|
52
63
|
async function propagateToParent(
|
|
53
64
|
client,
|
|
@@ -71,9 +82,10 @@ async function propagateToParent(
|
|
|
71
82
|
}
|
|
72
83
|
|
|
73
84
|
/**
|
|
74
|
-
* Summarize operation
|
|
75
|
-
*
|
|
76
|
-
* @
|
|
85
|
+
* Summarize operation for count-based aggregation.
|
|
86
|
+
* Returns a summary object with the count of items.
|
|
87
|
+
* @param {Object[]} items - Array of data items to summarize
|
|
88
|
+
* @returns {Object} Summary object with operation type, count, and summary flag
|
|
77
89
|
*/
|
|
78
90
|
export function summarize(items) {
|
|
79
91
|
return {
|
|
@@ -84,9 +96,10 @@ export function summarize(items) {
|
|
|
84
96
|
}
|
|
85
97
|
|
|
86
98
|
/**
|
|
87
|
-
* Aggregate operation
|
|
88
|
-
*
|
|
89
|
-
* @
|
|
99
|
+
* Aggregate operation for merging objects.
|
|
100
|
+
* Combines all items into a single object using Object.assign.
|
|
101
|
+
* @param {Object[]} items - Array of objects to merge
|
|
102
|
+
* @returns {Object} Aggregated object with all properties merged
|
|
90
103
|
*/
|
|
91
104
|
export function aggregate(items) {
|
|
92
105
|
const result = { operation: 'aggregate' };
|
|
@@ -99,9 +112,10 @@ export function aggregate(items) {
|
|
|
99
112
|
}
|
|
100
113
|
|
|
101
114
|
/**
|
|
102
|
-
* Concatenate operation
|
|
103
|
-
*
|
|
104
|
-
* @
|
|
115
|
+
* Concatenate operation for flattening nested arrays.
|
|
116
|
+
* Flattens all input arrays into a single array.
|
|
117
|
+
* @param {Array[]} items - Array of arrays to concatenate
|
|
118
|
+
* @returns {Object} Object with operation type and flattened items array
|
|
105
119
|
*/
|
|
106
120
|
export function concatenate(items) {
|
|
107
121
|
return {
|