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.
Files changed (327) hide show
  1. package/CHANGELOG.md +446 -0
  2. package/FEATURES.md +431 -0
  3. package/LICENSE +29 -166
  4. package/LICENSE-AGPL.md +180 -0
  5. package/dist/cdn/holosphere.min.js +55 -0
  6. package/dist/cdn/holosphere.min.js.map +1 -0
  7. package/dist/cjs/holosphere.cjs +1 -1
  8. package/dist/esm/holosphere.js +1 -1
  9. package/dist/{index-C-IlLYlk.cjs → index-DDGt_V9o.cjs} +2 -2
  10. package/dist/{index-C-IlLYlk.cjs.map → index-DDGt_V9o.cjs.map} +1 -1
  11. package/dist/{index-d6f4RJBM.js → index-DJXftyvB.js} +2253 -387
  12. package/dist/index-DJXftyvB.js.map +1 -0
  13. package/dist/index-DMbdcMtK.cjs +18 -0
  14. package/dist/index-DMbdcMtK.cjs.map +1 -0
  15. package/dist/{index-jmTHEbR2.js → index-DeZ1xz_s.js} +2 -2
  16. package/dist/{index-jmTHEbR2.js.map → index-DeZ1xz_s.js.map} +1 -1
  17. package/dist/{indexeddb-storage-D8kOl0oK.js → indexeddb-storage-BFt6hMeF.js} +48 -4
  18. package/dist/indexeddb-storage-BFt6hMeF.js.map +1 -0
  19. package/dist/{indexeddb-storage-a8GipaDr.cjs → indexeddb-storage-BK5tv4Sh.cjs} +2 -2
  20. package/dist/indexeddb-storage-BK5tv4Sh.cjs.map +1 -0
  21. package/dist/{memory-storage-DBQK622V.js → memory-storage-C9HuoL2E.js} +44 -4
  22. package/dist/memory-storage-C9HuoL2E.js.map +1 -0
  23. package/dist/{memory-storage-gfRovk2O.cjs → memory-storage-Dao7jfYG.cjs} +2 -2
  24. package/dist/memory-storage-Dao7jfYG.cjs.map +1 -0
  25. package/dist/{secp256k1-BCAPF45D.cjs → secp256k1-BbKzbLtD.cjs} +2 -2
  26. package/dist/{secp256k1-BCAPF45D.cjs.map → secp256k1-BbKzbLtD.cjs.map} +1 -1
  27. package/dist/{secp256k1-DYm_CMqW.js → secp256k1-CreY7Pcl.js} +2 -2
  28. package/dist/{secp256k1-DYm_CMqW.js.map → secp256k1-CreY7Pcl.js.map} +1 -1
  29. package/docs/api/ai_aggregation.js.html +333 -0
  30. package/docs/api/ai_breakdown.js.html +524 -0
  31. package/docs/api/ai_classifier.js.html +231 -0
  32. package/docs/api/ai_council.js.html +246 -0
  33. package/docs/api/ai_embeddings.js.html +304 -0
  34. package/docs/api/ai_federation-ai.js.html +338 -0
  35. package/docs/api/ai_h3-ai.js.html +970 -0
  36. package/docs/api/ai_index.js.html +124 -0
  37. package/docs/api/ai_json-ops.js.html +241 -0
  38. package/docs/api/ai_llm-service.js.html +239 -0
  39. package/docs/api/ai_nl-query.js.html +236 -0
  40. package/docs/api/ai_relationships.js.html +367 -0
  41. package/docs/api/ai_schema-extractor.js.html +235 -0
  42. package/docs/api/ai_spatial.js.html +307 -0
  43. package/docs/api/ai_tts.js.html +214 -0
  44. package/docs/api/content_social-protocols.js.html +180 -0
  45. package/docs/api/core_holosphere.js.html +757 -0
  46. package/docs/api/crypto_nostr-utils.js.html +306 -0
  47. package/docs/api/crypto_secp256k1.js.html +267 -0
  48. package/docs/api/data/search.json +1 -0
  49. package/docs/api/federation_discovery.js.html +337 -0
  50. package/docs/api/federation_handshake.js.html +478 -0
  51. package/docs/api/federation_hologram.js.html +1053 -0
  52. package/docs/api/federation_registry.js.html +389 -0
  53. package/docs/api/fonts/Inconsolata-Regular.ttf +0 -0
  54. package/docs/api/fonts/OpenSans-Regular.ttf +0 -0
  55. package/docs/api/fonts/WorkSans-Bold.ttf +0 -0
  56. package/docs/api/global.html +3 -0
  57. package/docs/api/hierarchical_upcast.js.html +128 -0
  58. package/docs/api/index.html +265 -0
  59. package/docs/api/index.js.html +1868 -0
  60. package/docs/api/lib_ai-methods.js.html +660 -0
  61. package/docs/api/lib_contract-methods.js.html +445 -0
  62. package/docs/api/lib_errors.js.html +56 -0
  63. package/docs/api/lib_federation-methods.js.html +348 -0
  64. package/docs/api/lib_index.js.html +33 -0
  65. package/docs/api/module-ai.html +5 -0
  66. package/docs/api/module-ai_aggregation-SmartAggregation.html +6 -0
  67. package/docs/api/module-ai_aggregation.SmartAggregation.html +3 -0
  68. package/docs/api/module-ai_aggregation.html +3 -0
  69. package/docs/api/module-ai_breakdown-TaskBreakdown.html +5 -0
  70. package/docs/api/module-ai_breakdown.TaskBreakdown.html +3 -0
  71. package/docs/api/module-ai_breakdown.html +3 -0
  72. package/docs/api/module-ai_classifier-Classifier.html +6 -0
  73. package/docs/api/module-ai_classifier.Classifier.html +3 -0
  74. package/docs/api/module-ai_classifier.html +3 -0
  75. package/docs/api/module-ai_council-Council.html +6 -0
  76. package/docs/api/module-ai_council.Council.html +3 -0
  77. package/docs/api/module-ai_council.html +3 -0
  78. package/docs/api/module-ai_embeddings-Embeddings.html +5 -0
  79. package/docs/api/module-ai_embeddings.Embeddings.html +3 -0
  80. package/docs/api/module-ai_embeddings.html +3 -0
  81. package/docs/api/module-ai_federation-ai-FederationAdvisor.html +6 -0
  82. package/docs/api/module-ai_federation-ai.FederationAdvisor.html +3 -0
  83. package/docs/api/module-ai_federation-ai.html +3 -0
  84. package/docs/api/module-ai_h3-ai-H3AI.html +6 -0
  85. package/docs/api/module-ai_h3-ai.H3AI.html +3 -0
  86. package/docs/api/module-ai_h3-ai.html +3 -0
  87. package/docs/api/module-ai_json-ops-JSONOps.html +5 -0
  88. package/docs/api/module-ai_json-ops.JSONOps.html +3 -0
  89. package/docs/api/module-ai_json-ops.html +3 -0
  90. package/docs/api/module-ai_llm-service-LLMService.html +5 -0
  91. package/docs/api/module-ai_llm-service.LLMService.html +3 -0
  92. package/docs/api/module-ai_llm-service.html +3 -0
  93. package/docs/api/module-ai_nl-query-NLQuery.html +5 -0
  94. package/docs/api/module-ai_nl-query.NLQuery.html +3 -0
  95. package/docs/api/module-ai_nl-query.html +3 -0
  96. package/docs/api/module-ai_relationships-RelationshipDiscovery.html +6 -0
  97. package/docs/api/module-ai_relationships.RelationshipDiscovery.html +3 -0
  98. package/docs/api/module-ai_relationships.html +3 -0
  99. package/docs/api/module-ai_schema-extractor-SchemaExtractor.html +5 -0
  100. package/docs/api/module-ai_schema-extractor.SchemaExtractor.html +3 -0
  101. package/docs/api/module-ai_schema-extractor.html +3 -0
  102. package/docs/api/module-ai_spatial-SpatialAnalysis.html +6 -0
  103. package/docs/api/module-ai_spatial.SpatialAnalysis.html +3 -0
  104. package/docs/api/module-ai_spatial.html +3 -0
  105. package/docs/api/module-ai_tts-TTS.html +5 -0
  106. package/docs/api/module-ai_tts.TTS.html +3 -0
  107. package/docs/api/module-ai_tts.html +3 -0
  108. package/docs/api/module-content_social-protocols.html +3 -0
  109. package/docs/api/module-core_holosphere-HoloSphere.html +6 -0
  110. package/docs/api/module-core_holosphere.HoloSphere.html +3 -0
  111. package/docs/api/module-core_holosphere.html +3 -0
  112. package/docs/api/module-crypto_nostr-utils.html +3 -0
  113. package/docs/api/module-crypto_secp256k1.html +3 -0
  114. package/docs/api/module-federation_hologram.html +3 -0
  115. package/docs/api/module-hierarchical_upcast.html +3 -0
  116. package/docs/api/module-holosphere-HoloSphereBase.html +3 -0
  117. package/docs/api/module-holosphere.html +3 -0
  118. package/docs/api/module-lib_ai-methods.html +3 -0
  119. package/docs/api/module-lib_contract-methods.html +3 -0
  120. package/docs/api/module-lib_errors-AuthorizationError.html +3 -0
  121. package/docs/api/module-lib_errors-ValidationError.html +3 -0
  122. package/docs/api/module-lib_errors.AuthorizationError.html +3 -0
  123. package/docs/api/module-lib_errors.ValidationError.html +3 -0
  124. package/docs/api/module-lib_errors.html +3 -0
  125. package/docs/api/module-lib_federation-methods.html +3 -0
  126. package/docs/api/module-lib_index.html +3 -0
  127. package/docs/api/module-schema_validator-ValidationError.html +3 -0
  128. package/docs/api/module-schema_validator.ValidationError.html +3 -0
  129. package/docs/api/module-schema_validator.html +3 -0
  130. package/docs/api/module-spatial_h3-operations.html +4 -0
  131. package/docs/api/module-storage_backend-factory.BackendFactory.html +3 -0
  132. package/docs/api/module-storage_backend-factory.html +3 -0
  133. package/docs/api/module-storage_backend-interface-StorageBackend.html +3 -0
  134. package/docs/api/module-storage_backend-interface.StorageBackend.html +3 -0
  135. package/docs/api/module-storage_backend-interface.html +3 -0
  136. package/docs/api/module-storage_backends_activitypub-backend-ActivityPubBackend.html +7 -0
  137. package/docs/api/module-storage_backends_activitypub-backend.ActivityPubBackend.html +3 -0
  138. package/docs/api/module-storage_backends_activitypub-backend.html +3 -0
  139. package/docs/api/module-storage_backends_activitypub_server-ActivityPubServer.html +8 -0
  140. package/docs/api/module-storage_backends_activitypub_server.ActivityPubServer.html +3 -0
  141. package/docs/api/module-storage_backends_activitypub_server.html +3 -0
  142. package/docs/api/module-storage_backends_gundb-backend-GunDBBackend.html +7 -0
  143. package/docs/api/module-storage_backends_gundb-backend.GunDBBackend.html +3 -0
  144. package/docs/api/module-storage_backends_gundb-backend.html +3 -0
  145. package/docs/api/module-storage_backends_nostr-backend-NostrBackend.html +8 -0
  146. package/docs/api/module-storage_backends_nostr-backend.NostrBackend.html +3 -0
  147. package/docs/api/module-storage_backends_nostr-backend.html +3 -0
  148. package/docs/api/module-storage_filesystem-storage-FileSystemStorage.html +5 -0
  149. package/docs/api/module-storage_filesystem-storage-browser-FileSystemStorage.html +3 -0
  150. package/docs/api/module-storage_filesystem-storage-browser.FileSystemStorage.html +3 -0
  151. package/docs/api/module-storage_filesystem-storage-browser.html +3 -0
  152. package/docs/api/module-storage_filesystem-storage.FileSystemStorage.html +3 -0
  153. package/docs/api/module-storage_filesystem-storage.html +3 -0
  154. package/docs/api/module-storage_global-tables.html +3 -0
  155. package/docs/api/module-storage_gun-async.html +3 -0
  156. package/docs/api/module-storage_gun-auth-GunAuth.html +5 -0
  157. package/docs/api/module-storage_gun-auth.GunAuth.html +3 -0
  158. package/docs/api/module-storage_gun-auth.html +3 -0
  159. package/docs/api/module-storage_gun-federation.html +3 -0
  160. package/docs/api/module-storage_gun-references-GunReferenceHandler.html +5 -0
  161. package/docs/api/module-storage_gun-references.GunReferenceHandler.html +3 -0
  162. package/docs/api/module-storage_gun-references.html +3 -0
  163. package/docs/api/module-storage_gun-schema-GunSchemaValidator.html +5 -0
  164. package/docs/api/module-storage_gun-schema.GunSchemaValidator.html +3 -0
  165. package/docs/api/module-storage_gun-schema.html +3 -0
  166. package/docs/api/module-storage_gun-wrapper.html +11 -0
  167. package/docs/api/module-storage_indexeddb-storage-IndexedDBStorage.html +5 -0
  168. package/docs/api/module-storage_indexeddb-storage.IndexedDBStorage.html +3 -0
  169. package/docs/api/module-storage_indexeddb-storage.html +3 -0
  170. package/docs/api/module-storage_key-storage-simple.html +3 -0
  171. package/docs/api/module-storage_key-storage.html +4 -0
  172. package/docs/api/module-storage_memory-storage-MemoryStorage.html +5 -0
  173. package/docs/api/module-storage_memory-storage.MemoryStorage.html +3 -0
  174. package/docs/api/module-storage_memory-storage.html +3 -0
  175. package/docs/api/module-storage_migration-MigrationTool.html +6 -0
  176. package/docs/api/module-storage_migration.MigrationTool.html +3 -0
  177. package/docs/api/module-storage_migration.html +3 -0
  178. package/docs/api/module-storage_nostr-async.html +18 -0
  179. package/docs/api/module-storage_nostr-client-LRUCache.html +3 -0
  180. package/docs/api/module-storage_nostr-client-NostrClient.html +7 -0
  181. package/docs/api/module-storage_nostr-client.NostrClient.html +15 -0
  182. package/docs/api/module-storage_nostr-client.html +6 -0
  183. package/docs/api/module-storage_nostr-wrapper.html +3 -0
  184. package/docs/api/module-storage_outbox-queue-OutboxQueue.html +4 -0
  185. package/docs/api/module-storage_outbox-queue.OutboxQueue.html +3 -0
  186. package/docs/api/module-storage_outbox-queue.html +3 -0
  187. package/docs/api/module-storage_persistent-storage-PersistentStorage.html +3 -0
  188. package/docs/api/module-storage_persistent-storage.html +4 -0
  189. package/docs/api/module-storage_sync-service-SyncService.html +5 -0
  190. package/docs/api/module-storage_sync-service.SyncService.html +3 -0
  191. package/docs/api/module-storage_sync-service.html +3 -0
  192. package/docs/api/module-storage_unified-storage.html +3 -0
  193. package/docs/api/module-subscriptions_manager.SubscriptionRegistry.html +3 -0
  194. package/docs/api/module-subscriptions_manager.html +3 -0
  195. package/docs/api/schema_validator.js.html +113 -0
  196. package/docs/api/scripts/core.js +726 -0
  197. package/docs/api/scripts/core.min.js +23 -0
  198. package/docs/api/scripts/resize.js +90 -0
  199. package/docs/api/scripts/search.js +265 -0
  200. package/docs/api/scripts/search.min.js +6 -0
  201. package/docs/api/scripts/third-party/Apache-License-2.0.txt +202 -0
  202. package/docs/api/scripts/third-party/fuse.js +9 -0
  203. package/docs/api/scripts/third-party/hljs-line-num-original.js +369 -0
  204. package/docs/api/scripts/third-party/hljs-line-num.js +1 -0
  205. package/docs/api/scripts/third-party/hljs-original.js +5171 -0
  206. package/docs/api/scripts/third-party/hljs.js +1 -0
  207. package/docs/api/scripts/third-party/popper.js +5 -0
  208. package/docs/api/scripts/third-party/tippy.js +1 -0
  209. package/docs/api/scripts/third-party/tocbot.js +672 -0
  210. package/docs/api/scripts/third-party/tocbot.min.js +1 -0
  211. package/docs/api/spatial_h3-operations.js.html +129 -0
  212. package/docs/api/storage_backend-factory.js.html +133 -0
  213. package/docs/api/storage_backend-interface.js.html +164 -0
  214. package/docs/api/storage_backends_activitypub-backend.js.html +298 -0
  215. package/docs/api/storage_backends_activitypub_server.js.html +678 -0
  216. package/docs/api/storage_backends_gundb-backend.js.html +878 -0
  217. package/docs/api/storage_backends_nostr-backend.js.html +254 -0
  218. package/docs/api/storage_filesystem-storage-browser.js.html +83 -0
  219. package/docs/api/storage_filesystem-storage.js.html +207 -0
  220. package/docs/api/storage_global-tables.js.html +116 -0
  221. package/docs/api/storage_gun-async.js.html +344 -0
  222. package/docs/api/storage_gun-auth.js.html +376 -0
  223. package/docs/api/storage_gun-federation.js.html +788 -0
  224. package/docs/api/storage_gun-references.js.html +212 -0
  225. package/docs/api/storage_gun-schema.js.html +309 -0
  226. package/docs/api/storage_gun-wrapper.js.html +645 -0
  227. package/docs/api/storage_indexeddb-storage.js.html +224 -0
  228. package/docs/api/storage_key-storage-simple.js.html +102 -0
  229. package/docs/api/storage_key-storage.js.html +171 -0
  230. package/docs/api/storage_memory-storage.js.html +128 -0
  231. package/docs/api/storage_migration.js.html +354 -0
  232. package/docs/api/storage_nostr-async.js.html +1076 -0
  233. package/docs/api/storage_nostr-client.js.html +1598 -0
  234. package/docs/api/storage_nostr-wrapper.js.html +218 -0
  235. package/docs/api/storage_outbox-queue.js.html +248 -0
  236. package/docs/api/storage_persistent-storage.js.html +160 -0
  237. package/docs/api/storage_sync-service.js.html +201 -0
  238. package/docs/api/storage_unified-storage.js.html +157 -0
  239. package/docs/api/styles/clean-jsdoc-theme-base.css +1159 -0
  240. package/docs/api/styles/clean-jsdoc-theme-dark.css +412 -0
  241. package/docs/api/styles/clean-jsdoc-theme-light.css +482 -0
  242. package/docs/api/styles/clean-jsdoc-theme-scrollbar.css +30 -0
  243. package/docs/api/styles/clean-jsdoc-theme-without-scrollbar.min.css +1 -0
  244. package/docs/api/styles/clean-jsdoc-theme.min.css +1 -0
  245. package/docs/api/subscriptions_manager.js.html +162 -0
  246. package/examples/holosphere-widget.js +1242 -0
  247. package/examples/widget-demo.html +274 -0
  248. package/examples/widget.html +703 -0
  249. package/jsdoc.json +26 -0
  250. package/package.json +16 -3
  251. package/src/ai/aggregation.js +13 -2
  252. package/src/ai/breakdown.js +12 -2
  253. package/src/ai/classifier.js +14 -3
  254. package/src/ai/council.js +22 -7
  255. package/src/ai/embeddings.js +37 -15
  256. package/src/ai/federation-ai.js +13 -2
  257. package/src/ai/h3-ai.js +14 -2
  258. package/src/ai/index.js +16 -7
  259. package/src/ai/json-ops.js +18 -5
  260. package/src/ai/llm-service.js +62 -31
  261. package/src/ai/nl-query.js +12 -2
  262. package/src/ai/relationships.js +13 -2
  263. package/src/ai/schema-extractor.js +24 -10
  264. package/src/ai/spatial.js +13 -2
  265. package/src/ai/tts.js +25 -8
  266. package/src/cdn-entry.js +22 -0
  267. package/src/content/social-protocols.js +34 -25
  268. package/src/contracts/chain-manager.js +68 -40
  269. package/src/contracts/deployer.js +70 -42
  270. package/src/contracts/event-listener.js +61 -29
  271. package/src/contracts/holon-contracts.js +46 -31
  272. package/src/contracts/index.js +5 -6
  273. package/src/contracts/networks.js +19 -14
  274. package/src/contracts/operations.js +58 -41
  275. package/src/contracts/queries.js +70 -21
  276. package/src/core/holosphere.js +37 -8
  277. package/src/crypto/nostr-utils.js +105 -65
  278. package/src/crypto/secp256k1.js +7 -2
  279. package/src/federation/handshake.js +23 -11
  280. package/src/federation/hologram.js +9 -1
  281. package/src/hierarchical/upcast.js +34 -20
  282. package/src/index.js +671 -7
  283. package/src/lib/ai-methods.js +352 -3
  284. package/src/lib/contract-methods.js +152 -3
  285. package/src/lib/errors.js +31 -1
  286. package/src/lib/federation-methods.js +110 -3
  287. package/src/lib/index.js +9 -5
  288. package/src/schema/validator.js +22 -3
  289. package/src/spatial/h3-operations.js +17 -1
  290. package/src/storage/backend-factory.js +7 -2
  291. package/src/storage/backend-interface.js +21 -2
  292. package/src/storage/backends/activitypub/server.js +25 -3
  293. package/src/storage/backends/activitypub-backend.js +25 -2
  294. package/src/storage/backends/gundb-backend.js +322 -11
  295. package/src/storage/backends/nostr-backend.js +116 -1
  296. package/src/storage/filesystem-storage-browser.js +42 -2
  297. package/src/storage/filesystem-storage.js +72 -5
  298. package/src/storage/global-tables.js +7 -2
  299. package/src/storage/gun-async.js +20 -11
  300. package/src/storage/gun-auth.js +15 -4
  301. package/src/storage/gun-federation.js +14 -5
  302. package/src/storage/gun-references.js +16 -5
  303. package/src/storage/gun-schema.js +25 -10
  304. package/src/storage/gun-wrapper.js +160 -49
  305. package/src/storage/indexeddb-storage.js +65 -4
  306. package/src/storage/key-storage-simple.js +32 -9
  307. package/src/storage/key-storage.js +45 -13
  308. package/src/storage/memory-storage.js +65 -4
  309. package/src/storage/migration.js +20 -7
  310. package/src/storage/nostr-async.js +195 -90
  311. package/src/storage/nostr-client.js +173 -49
  312. package/src/storage/nostr-wrapper.js +6 -2
  313. package/src/storage/outbox-queue.js +55 -18
  314. package/src/storage/persistent-storage.js +56 -13
  315. package/src/storage/sync-service.js +51 -17
  316. package/src/storage/unified-storage.js +38 -3
  317. package/src/subscriptions/manager.js +33 -16
  318. package/vite.config.cdn.js +60 -0
  319. package/dist/index-Bvwyvd0T.cjs +0 -5
  320. package/dist/index-Bvwyvd0T.cjs.map +0 -1
  321. package/dist/index-d6f4RJBM.js.map +0 -1
  322. package/dist/indexeddb-storage-D8kOl0oK.js.map +0 -1
  323. package/dist/indexeddb-storage-a8GipaDr.cjs.map +0 -1
  324. package/dist/memory-storage-DBQK622V.js.map +0 -1
  325. package/dist/memory-storage-gfRovk2O.cjs.map +0 -1
  326. /package/{cleanup-test-data.js → scripts/cleanup-test-data.js} +0 -0
  327. /package/{test-ai-real-api.js → scripts/test-ai-real-api.js} +0 -0
@@ -0,0 +1,703 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>HoloSphere Widget - Easy Integration Example</title>
7
+ <style>
8
+ * { margin: 0; padding: 0; box-sizing: border-box; }
9
+ body {
10
+ font-family: system-ui, -apple-system, sans-serif;
11
+ background: #f5f5f5;
12
+ padding: 20px;
13
+ line-height: 1.6;
14
+ }
15
+ .container { max-width: 900px; margin: 0 auto; }
16
+ h1 { color: #333; margin-bottom: 10px; }
17
+ .subtitle { color: #666; margin-bottom: 30px; }
18
+
19
+ /* Code blocks */
20
+ .code-block {
21
+ background: #1e1e1e;
22
+ color: #d4d4d4;
23
+ padding: 20px;
24
+ border-radius: 8px;
25
+ margin: 20px 0;
26
+ overflow-x: auto;
27
+ font-family: 'Monaco', 'Menlo', 'Consolas', monospace;
28
+ font-size: 14px;
29
+ }
30
+ .code-block .comment { color: #6a9955; }
31
+ .code-block .keyword { color: #569cd6; }
32
+ .code-block .string { color: #ce9178; }
33
+ .code-block .function { color: #dcdcaa; }
34
+ .code-block .variable { color: #9cdcfe; }
35
+
36
+ /* Demo section */
37
+ .demo-section {
38
+ background: white;
39
+ padding: 25px;
40
+ border-radius: 12px;
41
+ margin: 20px 0;
42
+ box-shadow: 0 2px 8px rgba(0,0,0,0.1);
43
+ }
44
+ .demo-section h2 { color: #333; margin-bottom: 15px; font-size: 1.3em; }
45
+ .demo-section h3 { color: #555; margin: 20px 0 10px; font-size: 1.1em; }
46
+
47
+ /* Form elements */
48
+ input, textarea, select {
49
+ padding: 10px 15px;
50
+ border: 2px solid #e0e0e0;
51
+ border-radius: 6px;
52
+ font-size: 14px;
53
+ width: 100%;
54
+ margin: 5px 0 15px;
55
+ }
56
+ input:focus, textarea:focus, select:focus {
57
+ outline: none;
58
+ border-color: #667eea;
59
+ }
60
+ textarea { min-height: 100px; font-family: monospace; }
61
+
62
+ button {
63
+ padding: 10px 20px;
64
+ background: linear-gradient(135deg, #667eea, #764ba2);
65
+ color: white;
66
+ border: none;
67
+ border-radius: 6px;
68
+ cursor: pointer;
69
+ font-size: 14px;
70
+ margin: 5px 5px 5px 0;
71
+ }
72
+ button:hover { opacity: 0.9; transform: translateY(-1px); }
73
+ button:disabled { opacity: 0.5; cursor: not-allowed; }
74
+
75
+ .btn-secondary {
76
+ background: #6c757d;
77
+ }
78
+
79
+ /* Output */
80
+ .output {
81
+ background: #1e1e1e;
82
+ color: #4ec9b0;
83
+ padding: 15px;
84
+ border-radius: 6px;
85
+ margin-top: 15px;
86
+ font-family: monospace;
87
+ font-size: 13px;
88
+ min-height: 80px;
89
+ max-height: 300px;
90
+ overflow-y: auto;
91
+ white-space: pre-wrap;
92
+ word-break: break-all;
93
+ }
94
+
95
+ /* Status indicators */
96
+ .status {
97
+ display: inline-block;
98
+ padding: 5px 12px;
99
+ border-radius: 20px;
100
+ font-size: 12px;
101
+ font-weight: 500;
102
+ }
103
+ .status.connected { background: #d4edda; color: #155724; }
104
+ .status.disconnected { background: #f8d7da; color: #721c24; }
105
+ .status.loading { background: #fff3cd; color: #856404; }
106
+
107
+ /* Grid */
108
+ .grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 15px; }
109
+ .grid-item { background: #f8f9fa; padding: 15px; border-radius: 8px; }
110
+
111
+ /* Tabs */
112
+ .tabs { display: flex; gap: 5px; margin-bottom: 20px; flex-wrap: wrap; }
113
+ .tab {
114
+ padding: 10px 20px;
115
+ background: #e0e0e0;
116
+ border: none;
117
+ cursor: pointer;
118
+ border-radius: 6px 6px 0 0;
119
+ font-size: 14px;
120
+ }
121
+ .tab.active { background: white; font-weight: 600; }
122
+ .tab-panel { display: none; }
123
+ .tab-panel.active { display: block; }
124
+
125
+ label { font-weight: 500; color: #333; display: block; margin-bottom: 5px; }
126
+ .row { display: flex; gap: 10px; flex-wrap: wrap; }
127
+ .row > * { flex: 1; min-width: 200px; }
128
+ </style>
129
+ </head>
130
+ <body>
131
+ <div class="container">
132
+ <h1>HoloSphere Widget</h1>
133
+ <p class="subtitle">Easily add decentralized geospatial storage to any website</p>
134
+
135
+ <!-- Installation Guide -->
136
+ <div class="demo-section">
137
+ <h2>Installation (Copy & Paste)</h2>
138
+ <p>Add this single line to your HTML to get all HoloSphere features:</p>
139
+ <div class="code-block">
140
+ <span class="comment">&lt;!-- Include HoloSphere from CDN (~400KB gzipped) --&gt;</span>
141
+ &lt;<span class="keyword">script</span> <span class="variable">src</span>=<span class="string">"https://cdn.jsdelivr.net/npm/holosphere@latest/dist/cdn/holosphere.min.js"</span>&gt;&lt;/<span class="keyword">script</span>&gt;
142
+
143
+ <span class="comment">&lt;!-- Or use a specific version --&gt;</span>
144
+ &lt;<span class="keyword">script</span> <span class="variable">src</span>=<span class="string">"https://cdn.jsdelivr.net/npm/holosphere@2.0.0/dist/cdn/holosphere.min.js"</span>&gt;&lt;/<span class="keyword">script</span>&gt;
145
+ </div>
146
+
147
+ <p>That's it! After loading, <code>HoloSphere</code> is available globally:</p>
148
+ <div class="code-block">
149
+ <span class="keyword">const</span> <span class="variable">hs</span> = <span class="keyword">new</span> <span class="function">HoloSphere</span>({ <span class="variable">appName</span>: <span class="string">'my-app'</span> });
150
+ </div>
151
+ </div>
152
+
153
+ <!-- Quick Start -->
154
+ <div class="demo-section">
155
+ <h2>Quick Start Code</h2>
156
+ <div class="code-block">
157
+ <span class="comment">// Initialize HoloSphere (all config is optional)</span>
158
+ <span class="keyword">const</span> <span class="variable">hs</span> = <span class="keyword">new</span> <span class="function">HoloSphere</span>({
159
+ <span class="variable">appName</span>: <span class="string">'my-app'</span>, <span class="comment">// Your app's namespace</span>
160
+ <span class="variable">relays</span>: [<span class="string">'wss://relay.holons.io'</span>] <span class="comment">// Optional: Nostr relays for P2P sync</span>
161
+ });
162
+
163
+ <span class="comment">// Convert any location to a holon ID (H3 hexagon)</span>
164
+ <span class="keyword">const</span> <span class="variable">holon</span> = <span class="keyword">await</span> <span class="variable">hs</span>.<span class="function">toHolon</span>(<span class="string">37.7749</span>, <span class="string">-122.4194</span>, <span class="string">9</span>);
165
+
166
+ <span class="comment">// Store data in that location</span>
167
+ <span class="keyword">await</span> <span class="variable">hs</span>.<span class="function">write</span>(<span class="variable">holon</span>, <span class="string">'events'</span>, {
168
+ <span class="variable">title</span>: <span class="string">'Local Meetup'</span>,
169
+ <span class="variable">time</span>: <span class="keyword">new</span> <span class="function">Date</span>().<span class="function">toISOString</span>()
170
+ });
171
+
172
+ <span class="comment">// Read data back</span>
173
+ <span class="keyword">const</span> <span class="variable">events</span> = <span class="keyword">await</span> <span class="variable">hs</span>.<span class="function">read</span>(<span class="variable">holon</span>, <span class="string">'events'</span>);
174
+ <span class="variable">console</span>.<span class="function">log</span>(<span class="variable">events</span>);
175
+
176
+ <span class="comment">// Subscribe to real-time updates</span>
177
+ <span class="variable">hs</span>.<span class="function">subscribe</span>(<span class="variable">holon</span>, <span class="string">'events'</span>, (<span class="variable">data</span>) => {
178
+ <span class="variable">console</span>.<span class="function">log</span>(<span class="string">'New event:'</span>, <span class="variable">data</span>);
179
+ });
180
+ </div>
181
+ </div>
182
+
183
+ <!-- Live Demo -->
184
+ <div class="demo-section">
185
+ <h2>Live Demo</h2>
186
+ <span class="status loading" id="status">Loading...</span>
187
+
188
+ <div class="tabs">
189
+ <button class="tab active" onclick="showPanel('basic')">Basic CRUD</button>
190
+ <button class="tab" onclick="showPanel('spatial')">Spatial</button>
191
+ <button class="tab" onclick="showPanel('federation')">Federation</button>
192
+ <button class="tab" onclick="showPanel('realtime')">Real-time</button>
193
+ <button class="tab" onclick="showPanel('crypto')">Crypto</button>
194
+ </div>
195
+
196
+ <!-- Basic CRUD Panel -->
197
+ <div id="panel-basic" class="tab-panel active">
198
+ <h3>Write Data</h3>
199
+ <div class="row">
200
+ <div>
201
+ <label>Holon ID</label>
202
+ <input type="text" id="writeHolon" placeholder="e.g., 89283470c27ffff">
203
+ </div>
204
+ <div>
205
+ <label>Lens (collection)</label>
206
+ <input type="text" id="writeLens" value="notes">
207
+ </div>
208
+ </div>
209
+ <label>Data (JSON)</label>
210
+ <textarea id="writeData">{"title": "My Note", "content": "Hello HoloSphere!"}</textarea>
211
+ <button onclick="doWrite()">Write</button>
212
+ <button class="btn-secondary" onclick="doRead()">Read</button>
213
+ <button class="btn-secondary" onclick="doGetAll()">Get All</button>
214
+ <div class="output" id="crudOutput">Results will appear here...</div>
215
+ </div>
216
+
217
+ <!-- Spatial Panel -->
218
+ <div id="panel-spatial" class="tab-panel">
219
+ <h3>Convert Coordinates to Holon</h3>
220
+ <div class="row">
221
+ <div>
222
+ <label>Latitude</label>
223
+ <input type="number" id="lat" value="37.7749" step="0.0001">
224
+ </div>
225
+ <div>
226
+ <label>Longitude</label>
227
+ <input type="number" id="lng" value="-122.4194" step="0.0001">
228
+ </div>
229
+ <div>
230
+ <label>Resolution (0-15)</label>
231
+ <input type="number" id="res" value="9" min="0" max="15">
232
+ </div>
233
+ </div>
234
+ <button onclick="doToHolon()">Convert to Holon</button>
235
+ <button class="btn-secondary" onclick="doGetParents()">Get Parents</button>
236
+ <button class="btn-secondary" onclick="doGetChildren()">Get Children</button>
237
+ <div class="output" id="spatialOutput">Results will appear here...</div>
238
+ </div>
239
+
240
+ <!-- Federation Panel -->
241
+ <div id="panel-federation" class="tab-panel">
242
+ <h3>Federation Setup</h3>
243
+ <p style="color:#666; margin-bottom:15px;">Connect two holons so data flows between them.</p>
244
+ <div class="row">
245
+ <div>
246
+ <label>Source Holon</label>
247
+ <input type="text" id="fedSource" placeholder="Source holon ID">
248
+ </div>
249
+ <div>
250
+ <label>Target Holon</label>
251
+ <input type="text" id="fedTarget" placeholder="Target holon ID">
252
+ </div>
253
+ </div>
254
+ <div class="row">
255
+ <div>
256
+ <label>Lens</label>
257
+ <input type="text" id="fedLens" value="shared">
258
+ </div>
259
+ <div>
260
+ <label>Direction</label>
261
+ <select id="fedDirection">
262
+ <option value="bidirectional">Bidirectional</option>
263
+ <option value="outbound">Outbound (source → target)</option>
264
+ <option value="inbound">Inbound (target → source)</option>
265
+ </select>
266
+ </div>
267
+ </div>
268
+ <button onclick="doFederate()">Setup Federation</button>
269
+ <button class="btn-secondary" onclick="doGetFederated()">Get Federated Data</button>
270
+ <div class="output" id="federationOutput">Results will appear here...</div>
271
+ </div>
272
+
273
+ <!-- Real-time Panel -->
274
+ <div id="panel-realtime" class="tab-panel">
275
+ <h3>Real-time Subscriptions</h3>
276
+ <div class="row">
277
+ <div>
278
+ <label>Holon ID</label>
279
+ <input type="text" id="subHolon" placeholder="Holon to subscribe to">
280
+ </div>
281
+ <div>
282
+ <label>Lens</label>
283
+ <input type="text" id="subLens" value="realtime">
284
+ </div>
285
+ </div>
286
+ <button onclick="doSubscribe()" id="btnSubscribe">Subscribe</button>
287
+ <button class="btn-secondary" onclick="doUnsubscribe()" id="btnUnsubscribe" disabled>Unsubscribe</button>
288
+ <button class="btn-secondary" onclick="doSendTest()">Send Test Message</button>
289
+ <div class="output" id="realtimeOutput">Subscription events will appear here...</div>
290
+ </div>
291
+
292
+ <!-- Crypto Panel -->
293
+ <div id="panel-crypto" class="tab-panel">
294
+ <h3>Cryptography</h3>
295
+ <button onclick="doGenKeys()">Generate New Keys</button>
296
+ <div class="grid" style="margin-top:15px;">
297
+ <div class="grid-item">
298
+ <label>Private Key</label>
299
+ <input type="text" id="privKey" placeholder="Will be generated">
300
+ </div>
301
+ <div class="grid-item">
302
+ <label>Public Key</label>
303
+ <input type="text" id="pubKey" placeholder="Will be generated">
304
+ </div>
305
+ </div>
306
+ <label>Message to Sign</label>
307
+ <input type="text" id="signMsg" value="Hello, HoloSphere!">
308
+ <button onclick="doSign()">Sign</button>
309
+ <button class="btn-secondary" onclick="doVerify()">Verify</button>
310
+ <div class="output" id="cryptoOutput">Results will appear here...</div>
311
+ </div>
312
+ </div>
313
+
314
+ <!-- More Examples -->
315
+ <div class="demo-section">
316
+ <h2>More Features</h2>
317
+ <div class="grid">
318
+ <div class="grid-item">
319
+ <h3>Schema Validation</h3>
320
+ <div class="code-block" style="font-size:12px;">
321
+ <span class="comment">// Define a schema</span>
322
+ <span class="keyword">await</span> <span class="variable">hs</span>.<span class="function">setSchema</span>(<span class="string">'users'</span>, {
323
+ <span class="variable">type</span>: <span class="string">'object'</span>,
324
+ <span class="variable">required</span>: [<span class="string">'name'</span>, <span class="string">'email'</span>],
325
+ <span class="variable">properties</span>: {
326
+ <span class="variable">name</span>: { <span class="variable">type</span>: <span class="string">'string'</span> },
327
+ <span class="variable">email</span>: { <span class="variable">type</span>: <span class="string">'string'</span> }
328
+ }
329
+ });
330
+ </div>
331
+ </div>
332
+ <div class="grid-item">
333
+ <h3>Nostr Publishing</h3>
334
+ <div class="code-block" style="font-size:12px;">
335
+ <span class="comment">// Publish to Nostr network</span>
336
+ <span class="keyword">await</span> <span class="variable">hs</span>.<span class="function">publishNostr</span>({
337
+ <span class="variable">kind</span>: <span class="string">1</span>,
338
+ <span class="variable">content</span>: <span class="string">'Hello Nostr!'</span>,
339
+ <span class="variable">tags</span>: []
340
+ }, <span class="variable">holon</span>);
341
+ </div>
342
+ </div>
343
+ <div class="grid-item">
344
+ <h3>Global Tables</h3>
345
+ <div class="code-block" style="font-size:12px;">
346
+ <span class="comment">// App-wide data (not tied to location)</span>
347
+ <span class="keyword">await</span> <span class="variable">hs</span>.<span class="function">writeGlobal</span>(<span class="string">'config'</span>, {
348
+ <span class="variable">theme</span>: <span class="string">'dark'</span>,
349
+ <span class="variable">lang</span>: <span class="string">'en'</span>
350
+ });
351
+
352
+ <span class="keyword">const</span> <span class="variable">config</span> = <span class="keyword">await</span> <span class="variable">hs</span>.<span class="function">readGlobal</span>(<span class="string">'config'</span>);
353
+ </div>
354
+ </div>
355
+ <div class="grid-item">
356
+ <h3>Holograms</h3>
357
+ <div class="code-block" style="font-size:12px;">
358
+ <span class="comment">// Create a reference to data</span>
359
+ <span class="keyword">const</span> <span class="variable">hologram</span> = <span class="variable">hs</span>.<span class="function">createHologram</span>(
360
+ <span class="variable">sourceHolon</span>, <span class="variable">targetHolon</span>,
361
+ <span class="string">'events'</span>, <span class="variable">dataId</span>, <span class="string">'my-app'</span>
362
+ );
363
+
364
+ <span class="comment">// Resolve to get actual data</span>
365
+ <span class="keyword">const</span> <span class="variable">data</span> = <span class="keyword">await</span> <span class="variable">hs</span>.<span class="function">resolveHologram</span>(<span class="variable">hologram</span>);
366
+ </div>
367
+ </div>
368
+ </div>
369
+ </div>
370
+
371
+ <!-- Configuration Options -->
372
+ <div class="demo-section">
373
+ <h2>Configuration Options</h2>
374
+ <div class="code-block">
375
+ <span class="keyword">const</span> <span class="variable">hs</span> = <span class="keyword">new</span> <span class="function">HoloSphere</span>({
376
+ <span class="comment">// Required</span>
377
+ <span class="variable">appName</span>: <span class="string">'my-app'</span>, <span class="comment">// Namespace for your app</span>
378
+
379
+ <span class="comment">// Network (all optional)</span>
380
+ <span class="variable">relays</span>: [ <span class="comment">// Nostr relays for P2P sync</span>
381
+ <span class="string">'wss://relay.holons.io'</span>,
382
+ <span class="string">'wss://nos.lol'</span>
383
+ ],
384
+ <span class="variable">backend</span>: <span class="string">'nostr'</span>, <span class="comment">// 'nostr', 'gundb', or 'activitypub'</span>
385
+
386
+ <span class="comment">// Local-first settings</span>
387
+ <span class="variable">persistence</span>: <span class="keyword">true</span>, <span class="comment">// Persist data locally (IndexedDB)</span>
388
+ <span class="variable">backgroundSync</span>: <span class="keyword">true</span>, <span class="comment">// Auto-sync in background</span>
389
+ <span class="variable">syncInterval</span>: <span class="string">10000</span>, <span class="comment">// Sync every 10s</span>
390
+
391
+ <span class="comment">// Security (optional)</span>
392
+ <span class="variable">privateKey</span>: <span class="string">'hex-private-key'</span>, <span class="comment">// For signing data</span>
393
+
394
+ <span class="comment">// AI features (optional)</span>
395
+ <span class="variable">openaiKey</span>: <span class="string">'sk-...'</span>, <span class="comment">// Enable AI features</span>
396
+
397
+ <span class="comment">// Logging</span>
398
+ <span class="variable">logLevel</span>: <span class="string">'INFO'</span> <span class="comment">// 'ERROR', 'WARN', 'INFO', 'DEBUG'</span>
399
+ });
400
+ </div>
401
+ </div>
402
+ </div>
403
+
404
+ <!--
405
+ Load HoloSphere from CDN. For local development, use:
406
+ <script src="../dist/cdn/holosphere.min.js"></script>
407
+
408
+ For production, use:
409
+ <script src="https://cdn.jsdelivr.net/npm/holosphere@latest/dist/cdn/holosphere.min.js"></script>
410
+ -->
411
+ <script src="../dist/cdn/holosphere.min.js"></script>
412
+
413
+ <script>
414
+ // Global HoloSphere instance (HoloSphere is available directly from the CDN bundle)
415
+ let hs;
416
+ let subscription = null;
417
+
418
+ // Initialize on page load
419
+ document.addEventListener('DOMContentLoaded', async () => {
420
+ try {
421
+ updateStatus('loading', 'Initializing...');
422
+
423
+ // Initialize HoloSphere
424
+ hs = new HoloSphere({
425
+ appName: 'holosphere-widget-demo',
426
+ relays: [] // Local only for demo
427
+ });
428
+
429
+ window.hs = hs; // For console debugging
430
+
431
+ // Get a default holon for demo purposes
432
+ const defaultHolon = await hs.toHolon(37.7749, -122.4194, 9);
433
+
434
+ // Pre-fill holon fields
435
+ document.getElementById('writeHolon').value = defaultHolon;
436
+ document.getElementById('subHolon').value = defaultHolon;
437
+ document.getElementById('fedSource').value = defaultHolon;
438
+
439
+ // Get a nearby holon for federation target
440
+ const targetHolon = await hs.toHolon(37.7849, -122.4094, 9);
441
+ document.getElementById('fedTarget').value = targetHolon;
442
+
443
+ updateStatus('connected', 'Ready');
444
+ log('crudOutput', 'HoloSphere initialized! Default holon: ' + defaultHolon);
445
+
446
+ } catch (error) {
447
+ updateStatus('disconnected', 'Error');
448
+ console.error('Init error:', error);
449
+ }
450
+ });
451
+
452
+ // Tab switching
453
+ function showPanel(name) {
454
+ document.querySelectorAll('.tab').forEach(t => t.classList.remove('active'));
455
+ document.querySelectorAll('.tab-panel').forEach(p => p.classList.remove('active'));
456
+ event.target.classList.add('active');
457
+ document.getElementById('panel-' + name).classList.add('active');
458
+ }
459
+
460
+ // Status update
461
+ function updateStatus(type, text) {
462
+ const el = document.getElementById('status');
463
+ el.className = 'status ' + type;
464
+ el.textContent = text;
465
+ }
466
+
467
+ // Log to output
468
+ function log(outputId, message, isError = false) {
469
+ const el = document.getElementById(outputId);
470
+ const time = new Date().toLocaleTimeString();
471
+ const prefix = isError ? '[ERROR] ' : '';
472
+ const content = typeof message === 'object' ? JSON.stringify(message, null, 2) : message;
473
+ el.textContent = `[${time}] ${prefix}${content}\n\n${el.textContent}`;
474
+ }
475
+
476
+ // === CRUD Operations ===
477
+ async function doWrite() {
478
+ try {
479
+ const holon = document.getElementById('writeHolon').value;
480
+ const lens = document.getElementById('writeLens').value;
481
+ const data = JSON.parse(document.getElementById('writeData').value);
482
+
483
+ const result = await hs.write(holon, lens, data);
484
+ log('crudOutput', `Written successfully!\nID: ${data.id}\nResult: ${result}`);
485
+ } catch (e) {
486
+ log('crudOutput', e.message, true);
487
+ }
488
+ }
489
+
490
+ async function doRead() {
491
+ try {
492
+ const holon = document.getElementById('writeHolon').value;
493
+ const lens = document.getElementById('writeLens').value;
494
+
495
+ const data = await hs.read(holon, lens);
496
+ log('crudOutput', data);
497
+ } catch (e) {
498
+ log('crudOutput', e.message, true);
499
+ }
500
+ }
501
+
502
+ async function doGetAll() {
503
+ try {
504
+ const holon = document.getElementById('writeHolon').value;
505
+ const lens = document.getElementById('writeLens').value;
506
+
507
+ const data = await hs.getAll(holon, lens);
508
+ log('crudOutput', { count: data.length, items: data });
509
+ } catch (e) {
510
+ log('crudOutput', e.message, true);
511
+ }
512
+ }
513
+
514
+ // === Spatial Operations ===
515
+ async function doToHolon() {
516
+ try {
517
+ const lat = parseFloat(document.getElementById('lat').value);
518
+ const lng = parseFloat(document.getElementById('lng').value);
519
+ const res = parseInt(document.getElementById('res').value);
520
+
521
+ const holon = await hs.toHolon(lat, lng, res);
522
+ const isValid = hs.isValidH3(holon);
523
+
524
+ // Update other inputs with this holon
525
+ document.getElementById('writeHolon').value = holon;
526
+ document.getElementById('subHolon').value = holon;
527
+
528
+ log('spatialOutput', {
529
+ holon: holon,
530
+ coordinates: { lat, lng },
531
+ resolution: res,
532
+ valid: isValid
533
+ });
534
+ } catch (e) {
535
+ log('spatialOutput', e.message, true);
536
+ }
537
+ }
538
+
539
+ async function doGetParents() {
540
+ try {
541
+ const lat = parseFloat(document.getElementById('lat').value);
542
+ const lng = parseFloat(document.getElementById('lng').value);
543
+ const res = parseInt(document.getElementById('res').value);
544
+
545
+ const holon = await hs.toHolon(lat, lng, res);
546
+ const parents = await hs.getParents(holon, 0);
547
+
548
+ log('spatialOutput', { holon, parents });
549
+ } catch (e) {
550
+ log('spatialOutput', e.message, true);
551
+ }
552
+ }
553
+
554
+ async function doGetChildren() {
555
+ try {
556
+ const lat = parseFloat(document.getElementById('lat').value);
557
+ const lng = parseFloat(document.getElementById('lng').value);
558
+ const res = parseInt(document.getElementById('res').value);
559
+
560
+ const holon = await hs.toHolon(lat, lng, res);
561
+ const children = await hs.getChildren(holon);
562
+
563
+ log('spatialOutput', { holon, childCount: children.length, children: children.slice(0, 10) });
564
+ } catch (e) {
565
+ log('spatialOutput', e.message, true);
566
+ }
567
+ }
568
+
569
+ // === Federation Operations ===
570
+ async function doFederate() {
571
+ try {
572
+ const source = document.getElementById('fedSource').value;
573
+ const target = document.getElementById('fedTarget').value;
574
+ const lens = document.getElementById('fedLens').value;
575
+ const direction = document.getElementById('fedDirection').value;
576
+
577
+ const result = await hs.federate(source, target, lens, { direction });
578
+ log('federationOutput', {
579
+ success: true,
580
+ source, target, lens, direction
581
+ });
582
+ } catch (e) {
583
+ log('federationOutput', e.message, true);
584
+ }
585
+ }
586
+
587
+ async function doGetFederated() {
588
+ try {
589
+ const holon = document.getElementById('fedSource').value;
590
+ const lens = document.getElementById('fedLens').value;
591
+
592
+ const data = await hs.getFederatedData(holon, lens, { resolveHolograms: true });
593
+ log('federationOutput', data);
594
+ } catch (e) {
595
+ log('federationOutput', e.message, true);
596
+ }
597
+ }
598
+
599
+ // === Real-time Operations ===
600
+ function doSubscribe() {
601
+ try {
602
+ const holon = document.getElementById('subHolon').value;
603
+ const lens = document.getElementById('subLens').value;
604
+
605
+ subscription = hs.subscribe(holon, lens, (data, key) => {
606
+ log('realtimeOutput', { event: 'data_change', key, data });
607
+ });
608
+
609
+ document.getElementById('btnSubscribe').disabled = true;
610
+ document.getElementById('btnUnsubscribe').disabled = false;
611
+ log('realtimeOutput', `Subscribed to ${holon}/${lens}`);
612
+ } catch (e) {
613
+ log('realtimeOutput', e.message, true);
614
+ }
615
+ }
616
+
617
+ function doUnsubscribe() {
618
+ if (subscription) {
619
+ subscription.unsubscribe();
620
+ subscription = null;
621
+
622
+ document.getElementById('btnSubscribe').disabled = false;
623
+ document.getElementById('btnUnsubscribe').disabled = true;
624
+ log('realtimeOutput', 'Unsubscribed');
625
+ }
626
+ }
627
+
628
+ async function doSendTest() {
629
+ try {
630
+ const holon = document.getElementById('subHolon').value;
631
+ const lens = document.getElementById('subLens').value;
632
+
633
+ await hs.write(holon, lens, {
634
+ type: 'test',
635
+ message: 'Test message at ' + new Date().toISOString(),
636
+ random: Math.random()
637
+ });
638
+ log('realtimeOutput', 'Test message sent');
639
+ } catch (e) {
640
+ log('realtimeOutput', e.message, true);
641
+ }
642
+ }
643
+
644
+ // === Crypto Operations ===
645
+ async function doGenKeys() {
646
+ try {
647
+ // Generate random private key
648
+ const bytes = new Uint8Array(32);
649
+ crypto.getRandomValues(bytes);
650
+ const privateKey = Array.from(bytes, b => b.toString(16).padStart(2, '0')).join('');
651
+
652
+ const publicKey = await hs.getPublicKey(privateKey);
653
+
654
+ document.getElementById('privKey').value = privateKey;
655
+ document.getElementById('pubKey').value = publicKey;
656
+
657
+ log('cryptoOutput', {
658
+ generated: true,
659
+ publicKey: publicKey.substring(0, 20) + '...'
660
+ });
661
+ } catch (e) {
662
+ log('cryptoOutput', e.message, true);
663
+ }
664
+ }
665
+
666
+ async function doSign() {
667
+ try {
668
+ const privateKey = document.getElementById('privKey').value;
669
+ const message = document.getElementById('signMsg').value;
670
+
671
+ if (!privateKey) {
672
+ throw new Error('Generate keys first');
673
+ }
674
+
675
+ const signature = await hs.sign(message, privateKey);
676
+ log('cryptoOutput', { message, signature });
677
+ } catch (e) {
678
+ log('cryptoOutput', e.message, true);
679
+ }
680
+ }
681
+
682
+ async function doVerify() {
683
+ try {
684
+ const publicKey = document.getElementById('pubKey').value;
685
+ const message = document.getElementById('signMsg').value;
686
+
687
+ if (!publicKey) {
688
+ throw new Error('Generate keys first');
689
+ }
690
+
691
+ // First sign, then verify
692
+ const privateKey = document.getElementById('privKey').value;
693
+ const signature = await hs.sign(message, privateKey);
694
+ const valid = await hs.verify(message, signature, publicKey);
695
+
696
+ log('cryptoOutput', { message, valid, signature: signature.substring(0, 30) + '...' });
697
+ } catch (e) {
698
+ log('cryptoOutput', e.message, true);
699
+ }
700
+ }
701
+ </script>
702
+ </body>
703
+ </html>