holosphere 1.1.19 → 2.0.0-alpha0

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 (146) hide show
  1. package/.env.example +36 -0
  2. package/.eslintrc.json +16 -0
  3. package/.prettierrc.json +7 -0
  4. package/README.md +476 -531
  5. package/bin/holosphere-activitypub.js +158 -0
  6. package/cleanup-test-data.js +204 -0
  7. package/examples/demo.html +1333 -0
  8. package/examples/example-bot.js +197 -0
  9. package/package.json +47 -87
  10. package/scripts/check-bundle-size.js +54 -0
  11. package/scripts/check-quest-ids.js +77 -0
  12. package/scripts/import-holons.js +578 -0
  13. package/scripts/publish-to-relay.js +101 -0
  14. package/scripts/read-example.js +186 -0
  15. package/scripts/relay-diagnostic.js +59 -0
  16. package/scripts/relay-example.js +179 -0
  17. package/scripts/resync-to-relay.js +245 -0
  18. package/scripts/revert-import.js +196 -0
  19. package/scripts/test-hybrid-mode.js +108 -0
  20. package/scripts/test-local-storage.js +63 -0
  21. package/scripts/test-nostr-direct.js +55 -0
  22. package/scripts/test-read-data.js +45 -0
  23. package/scripts/test-write-read.js +63 -0
  24. package/scripts/verify-import.js +95 -0
  25. package/scripts/verify-relay-data.js +139 -0
  26. package/src/ai/aggregation.js +319 -0
  27. package/src/ai/breakdown.js +511 -0
  28. package/src/ai/classifier.js +217 -0
  29. package/src/ai/council.js +228 -0
  30. package/src/ai/embeddings.js +279 -0
  31. package/src/ai/federation-ai.js +324 -0
  32. package/src/ai/h3-ai.js +955 -0
  33. package/src/ai/index.js +112 -0
  34. package/src/ai/json-ops.js +225 -0
  35. package/src/ai/llm-service.js +205 -0
  36. package/src/ai/nl-query.js +223 -0
  37. package/src/ai/relationships.js +353 -0
  38. package/src/ai/schema-extractor.js +218 -0
  39. package/src/ai/spatial.js +293 -0
  40. package/src/ai/tts.js +194 -0
  41. package/src/content/social-protocols.js +168 -0
  42. package/src/core/holosphere.js +273 -0
  43. package/src/crypto/secp256k1.js +259 -0
  44. package/src/federation/discovery.js +334 -0
  45. package/src/federation/hologram.js +1042 -0
  46. package/src/federation/registry.js +386 -0
  47. package/src/hierarchical/upcast.js +110 -0
  48. package/src/index.js +2669 -0
  49. package/src/schema/validator.js +91 -0
  50. package/src/spatial/h3-operations.js +110 -0
  51. package/src/storage/backend-factory.js +125 -0
  52. package/src/storage/backend-interface.js +142 -0
  53. package/src/storage/backends/activitypub/server.js +653 -0
  54. package/src/storage/backends/activitypub-backend.js +272 -0
  55. package/src/storage/backends/gundb-backend.js +233 -0
  56. package/src/storage/backends/nostr-backend.js +136 -0
  57. package/src/storage/filesystem-storage-browser.js +41 -0
  58. package/src/storage/filesystem-storage.js +138 -0
  59. package/src/storage/global-tables.js +81 -0
  60. package/src/storage/gun-async.js +281 -0
  61. package/src/storage/gun-wrapper.js +221 -0
  62. package/src/storage/indexeddb-storage.js +122 -0
  63. package/src/storage/key-storage-simple.js +76 -0
  64. package/src/storage/key-storage.js +136 -0
  65. package/src/storage/memory-storage.js +59 -0
  66. package/src/storage/migration.js +338 -0
  67. package/src/storage/nostr-async.js +811 -0
  68. package/src/storage/nostr-client.js +939 -0
  69. package/src/storage/nostr-wrapper.js +211 -0
  70. package/src/storage/outbox-queue.js +208 -0
  71. package/src/storage/persistent-storage.js +109 -0
  72. package/src/storage/sync-service.js +164 -0
  73. package/src/subscriptions/manager.js +142 -0
  74. package/test-ai-real-api.js +202 -0
  75. package/tests/unit/ai/aggregation.test.js +295 -0
  76. package/tests/unit/ai/breakdown.test.js +446 -0
  77. package/tests/unit/ai/classifier.test.js +294 -0
  78. package/tests/unit/ai/council.test.js +262 -0
  79. package/tests/unit/ai/embeddings.test.js +384 -0
  80. package/tests/unit/ai/federation-ai.test.js +344 -0
  81. package/tests/unit/ai/h3-ai.test.js +458 -0
  82. package/tests/unit/ai/index.test.js +304 -0
  83. package/tests/unit/ai/json-ops.test.js +307 -0
  84. package/tests/unit/ai/llm-service.test.js +390 -0
  85. package/tests/unit/ai/nl-query.test.js +383 -0
  86. package/tests/unit/ai/relationships.test.js +311 -0
  87. package/tests/unit/ai/schema-extractor.test.js +384 -0
  88. package/tests/unit/ai/spatial.test.js +279 -0
  89. package/tests/unit/ai/tts.test.js +279 -0
  90. package/tests/unit/content.test.js +332 -0
  91. package/tests/unit/contract/core.test.js +88 -0
  92. package/tests/unit/contract/crypto.test.js +198 -0
  93. package/tests/unit/contract/data.test.js +223 -0
  94. package/tests/unit/contract/federation.test.js +181 -0
  95. package/tests/unit/contract/hierarchical.test.js +113 -0
  96. package/tests/unit/contract/schema.test.js +114 -0
  97. package/tests/unit/contract/social.test.js +217 -0
  98. package/tests/unit/contract/spatial.test.js +110 -0
  99. package/tests/unit/contract/subscriptions.test.js +128 -0
  100. package/tests/unit/contract/utils.test.js +159 -0
  101. package/tests/unit/core.test.js +152 -0
  102. package/tests/unit/crypto.test.js +328 -0
  103. package/tests/unit/federation.test.js +234 -0
  104. package/tests/unit/gun-async.test.js +252 -0
  105. package/tests/unit/hierarchical.test.js +399 -0
  106. package/tests/unit/integration/scenario-01-geographic-storage.test.js +74 -0
  107. package/tests/unit/integration/scenario-02-federation.test.js +76 -0
  108. package/tests/unit/integration/scenario-03-subscriptions.test.js +102 -0
  109. package/tests/unit/integration/scenario-04-validation.test.js +129 -0
  110. package/tests/unit/integration/scenario-05-hierarchy.test.js +125 -0
  111. package/tests/unit/integration/scenario-06-social.test.js +135 -0
  112. package/tests/unit/integration/scenario-07-persistence.test.js +130 -0
  113. package/tests/unit/integration/scenario-08-authorization.test.js +161 -0
  114. package/tests/unit/integration/scenario-09-cross-dimensional.test.js +139 -0
  115. package/tests/unit/integration/scenario-10-cross-holosphere-capabilities.test.js +357 -0
  116. package/tests/unit/integration/scenario-11-cross-holosphere-federation.test.js +410 -0
  117. package/tests/unit/integration/scenario-12-capability-federated-read.test.js +719 -0
  118. package/tests/unit/performance/benchmark.test.js +85 -0
  119. package/tests/unit/schema.test.js +213 -0
  120. package/tests/unit/spatial.test.js +158 -0
  121. package/tests/unit/storage.test.js +195 -0
  122. package/tests/unit/subscriptions.test.js +328 -0
  123. package/tests/unit/test-data-permanence-debug.js +197 -0
  124. package/tests/unit/test-data-permanence.js +340 -0
  125. package/tests/unit/test-key-persistence-fixed.js +148 -0
  126. package/tests/unit/test-key-persistence.js +172 -0
  127. package/tests/unit/test-relay-permanence.js +376 -0
  128. package/tests/unit/test-second-node.js +95 -0
  129. package/tests/unit/test-simple-write.js +89 -0
  130. package/vite.config.js +49 -0
  131. package/vitest.config.js +20 -0
  132. package/FEDERATION.md +0 -213
  133. package/compute.js +0 -298
  134. package/content.js +0 -1022
  135. package/federation.js +0 -1234
  136. package/global.js +0 -736
  137. package/hexlib.js +0 -335
  138. package/hologram.js +0 -183
  139. package/holosphere-bundle.esm.js +0 -34549
  140. package/holosphere-bundle.js +0 -34580
  141. package/holosphere-bundle.min.js +0 -49
  142. package/holosphere.d.ts +0 -604
  143. package/holosphere.js +0 -739
  144. package/node.js +0 -246
  145. package/schema.js +0 -139
  146. package/utils.js +0 -302
@@ -0,0 +1,197 @@
1
+ /**
2
+ * Example Quest Bot with Network Synchronization
3
+ *
4
+ * This example shows how to create a bot that manages quests
5
+ * with proper Nostr relay synchronization across multiple nodes.
6
+ *
7
+ * Configuration via environment variables (see .env.example):
8
+ * - HOLOSPHERE_RELAYS: Comma-separated relay URLs
9
+ * - HOLOSPHERE_PRIVATE_KEY: Hex private key for persistent identity
10
+ * - HOLOSPHERE_APP_NAME: Application namespace
11
+ * - OPENAI_API_KEY: Enable AI features (optional)
12
+ *
13
+ * Or pass directly in the config object.
14
+ */
15
+
16
+ import { HoloSphere } from '../dist/esm/holosphere.js';
17
+
18
+ // Relay configuration - use env vars or these defaults
19
+ const RELAYS = process.env.HOLOSPHERE_RELAYS?.split(',') || [
20
+ 'wss://relay.holons.io',
21
+ 'wss://relay.nostr.band',
22
+ ];
23
+
24
+ // Initialize HoloSphere with real relays for network synchronization
25
+ // Private key is read from HOLOSPHERE_PRIVATE_KEY env var automatically
26
+ // AI features enabled if OPENAI_API_KEY env var is set
27
+ const hs = new HoloSphere({
28
+ appName: process.env.HOLOSPHERE_APP_NAME || 'quest-game',
29
+ relays: RELAYS,
30
+ logLevel: 'INFO',
31
+ // privateKey: process.env.HOLOSPHERE_PRIVATE_KEY, // Auto-read from env
32
+ // openaiKey: process.env.OPENAI_API_KEY, // Auto-read from env
33
+ });
34
+
35
+ console.log('Quest Bot initialized with relays:', hs.config.relays);
36
+ console.log('Bot Public Key:', hs.client.publicKey);
37
+
38
+ // Use a global holon for quest storage (not location-specific)
39
+ const QUEST_HOLON = 'global://quests';
40
+
41
+ /**
42
+ * Create a new quest
43
+ */
44
+ async function createQuest(questData) {
45
+ console.log('\nšŸ“ Creating quest:', questData.title);
46
+
47
+ const result = await hs.write(QUEST_HOLON, 'quests', questData);
48
+
49
+ if (result) {
50
+ console.log('āœ… Quest created successfully:', questData.id || questData.title);
51
+ console.log(' This quest is now published to Nostr relays and will sync across all nodes!');
52
+ } else {
53
+ console.error('āŒ Failed to create quest');
54
+ }
55
+
56
+ return result;
57
+ }
58
+
59
+ /**
60
+ * List all available quests
61
+ */
62
+ async function listQuests() {
63
+ console.log('\nšŸ“‹ Fetching all quests...');
64
+
65
+ const quests = await hs.read(QUEST_HOLON, 'quests');
66
+
67
+ if (quests && quests.length > 0) {
68
+ console.log(`\nFound ${quests.length} quest(s):\n`);
69
+ quests.forEach((quest, index) => {
70
+ console.log(`${index + 1}. ${quest.title}`);
71
+ console.log(` ID: ${quest.id}`);
72
+ console.log(` Status: ${quest.status || 'active'}`);
73
+ console.log(` Description: ${quest.description || 'No description'}`);
74
+ console.log('');
75
+ });
76
+ } else {
77
+ console.log('No quests found.');
78
+ }
79
+
80
+ return quests;
81
+ }
82
+
83
+ /**
84
+ * Update a quest
85
+ */
86
+ async function updateQuest(questId, updates) {
87
+ console.log(`\nāœļø Updating quest: ${questId}`);
88
+
89
+ const quests = await hs.read(QUEST_HOLON, 'quests');
90
+ const quest = quests.find(q => q.id === questId);
91
+
92
+ if (!quest) {
93
+ console.error('āŒ Quest not found');
94
+ return false;
95
+ }
96
+
97
+ const updatedQuest = { ...quest, ...updates };
98
+ const result = await hs.write(QUEST_HOLON, 'quests', updatedQuest);
99
+
100
+ if (result) {
101
+ console.log('āœ… Quest updated successfully');
102
+ } else {
103
+ console.error('āŒ Failed to update quest');
104
+ }
105
+
106
+ return result;
107
+ }
108
+
109
+ /**
110
+ * Delete a quest
111
+ */
112
+ async function deleteQuest(questId) {
113
+ console.log(`\nšŸ—‘ļø Deleting quest: ${questId}`);
114
+
115
+ // Read current quests
116
+ const quests = await hs.read(QUEST_HOLON, 'quests');
117
+ const filtered = quests.filter(q => q.id !== questId);
118
+
119
+ if (filtered.length === quests.length) {
120
+ console.error('āŒ Quest not found');
121
+ return false;
122
+ }
123
+
124
+ // Write back without the deleted quest
125
+ // (In a production system, you'd handle this differently)
126
+ console.log('āš ļø Note: Deletion in Nostr is done by marking as deleted, not removing');
127
+ return true;
128
+ }
129
+
130
+ /**
131
+ * Subscribe to quest changes in real-time
132
+ */
133
+ function subscribeToQuests(callback) {
134
+ console.log('\nšŸ‘€ Subscribing to quest changes...');
135
+
136
+ const subscription = hs.subscribe(QUEST_HOLON, 'quests', (quest) => {
137
+ console.log('\nšŸ”” New quest event received:', quest.title || quest.id);
138
+ if (callback) callback(quest);
139
+ });
140
+
141
+ console.log('āœ… Subscribed to quest updates');
142
+ return subscription;
143
+ }
144
+
145
+ // Example usage
146
+ async function main() {
147
+ console.log('\n=== Quest Bot Demo ===\n');
148
+
149
+ // Wait a moment for relays to connect
150
+ await new Promise(resolve => setTimeout(resolve, 1000));
151
+
152
+ // Create some example quests
153
+ await createQuest({
154
+ id: `quest-${Date.now()}-1`,
155
+ title: 'Gather Ancient Scrolls',
156
+ description: 'Find 5 ancient scrolls hidden in the forest',
157
+ reward: 1000,
158
+ difficulty: 'medium'
159
+ });
160
+
161
+ await createQuest({
162
+ id: `quest-${Date.now()}-2`,
163
+ title: 'Defeat the Dragon',
164
+ description: 'Slay the dragon terrorizing the village',
165
+ reward: 5000,
166
+ difficulty: 'hard'
167
+ });
168
+
169
+ // Wait for data to sync
170
+ await new Promise(resolve => setTimeout(resolve, 2000));
171
+
172
+ // List all quests
173
+ await listQuests();
174
+
175
+ console.log('\n=== Bot is now running ===');
176
+ console.log('Quests will sync to other nodes using these relays:');
177
+ hs.config.relays.forEach(relay => console.log(' -', relay));
178
+ console.log('\nPress Ctrl+C to exit');
179
+
180
+ // Subscribe to changes
181
+ subscribeToQuests((quest) => {
182
+ console.log('Real-time update received for quest:', quest.title);
183
+ });
184
+ }
185
+
186
+ // Run the bot
187
+ main().catch(console.error);
188
+
189
+ // Export functions for use in other scripts
190
+ export {
191
+ createQuest,
192
+ listQuests,
193
+ updateQuest,
194
+ deleteQuest,
195
+ subscribeToQuests,
196
+ hs
197
+ };
package/package.json CHANGED
@@ -1,104 +1,64 @@
1
1
  {
2
2
  "name": "holosphere",
3
- "version": "1.1.19",
4
- "description": "Holonic Geospatial Communication Infrastructure",
5
- "main": "holosphere.js",
6
- "module": "holosphere.js",
7
- "types": "holosphere.d.ts",
3
+ "version": "2.0.0-alpha0",
4
+ "description": "Holonic geospatial communication infrastructure combining H3 hexagonal indexing with GunDB distributed P2P storage",
8
5
  "type": "module",
9
- "scripts": {
10
- "test": "node --experimental-vm-modules node_modules/jest/bin/jest.js",
11
- "build": "npm run build:browser",
12
- "prepare": "npm run build",
13
- "build:browser": "node build.js",
14
- "build:bundle": "node build.js",
15
- "prepublishOnly": "npm run build",
16
- "publish:cdn": "npm publish && echo 'Package published to npm and will be available on CDNs within minutes'",
17
- "publish:force": "npm publish --force && echo 'Package force published to npm and will be available on CDNs within minutes'",
18
- "prepublish:skip-tests": "npm run build"
19
- },
20
- "author": "Roberto Valenti",
21
- "license": "GPL-3.0-or-later",
22
- "dependencies": {
23
- "ajv": "^8.12.0",
24
- "gun": "^0.2020.1240",
25
- "h3-js": "^4.1.0",
26
- "openai": "^4.85.1"
6
+ "bin": {
7
+ "holosphere-activitypub": "./bin/holosphere-activitypub.js"
27
8
  },
28
- "devDependencies": {
29
- "esbuild": "^0.25.5",
30
- "jest": "^29.7.0",
31
- "jest-environment-node": "^29.7.0"
32
- },
33
- "jest": {
34
- "testEnvironment": "node",
35
- "transform": {}
36
- },
37
- "browser": "holosphere.js",
38
- "unpkg": "holosphere-bundle.js",
39
- "jsdelivr": "holosphere-bundle.js",
40
- "cdn": "holosphere-bundle.js",
41
- "files": [
42
- "holosphere.js",
43
- "holosphere-bundle.js",
44
- "holosphere-bundle.min.js",
45
- "holosphere-bundle.esm.js",
46
- "holosphere.d.ts",
47
- "federation.js",
48
- "schema.js",
49
- "content.js",
50
- "node.js",
51
- "global.js",
52
- "hologram.js",
53
- "compute.js",
54
- "utils.js",
55
- "hexlib.js",
56
- "README.md",
57
- "LICENSE",
58
- "FEDERATION.md"
59
- ],
9
+ "main": "./dist/cjs/holosphere.cjs",
10
+ "module": "./dist/esm/holosphere.js",
11
+ "browser": "./dist/cdn/holosphere.min.js",
12
+ "types": "./dist/types/index.d.ts",
60
13
  "exports": {
61
14
  ".": {
62
- "import": "./holosphere.js",
63
- "require": "./holosphere.js",
64
- "default": "./holosphere.js"
65
- },
66
- "./bundle": "./holosphere-bundle.js",
67
- "./bundle/esm": "./holosphere-bundle.esm.js",
68
- "./bundle/min": "./holosphere-bundle.min.js",
69
- "./browser": "./holosphere-bundle.js",
70
- "./node": "./holosphere.js"
15
+ "import": "./dist/esm/holosphere.js",
16
+ "require": "./dist/cjs/holosphere.cjs"
17
+ }
71
18
  },
72
- "repository": {
73
- "type": "git",
74
- "url": "git+https://github.com/rvalenti/holosphere.git"
19
+ "scripts": {
20
+ "dev": "vite",
21
+ "build": "vite build",
22
+ "test": "vitest run",
23
+ "test:watch": "vitest",
24
+ "test:coverage": "vitest run --coverage",
25
+ "lint": "eslint src tests",
26
+ "format": "prettier --write \"src/**/*.js\" \"tests/**/*.js\""
75
27
  },
76
28
  "keywords": [
77
- "holonic",
78
29
  "geospatial",
79
30
  "h3",
80
- "hexagon",
31
+ "gundb",
81
32
  "p2p",
82
- "decentralized",
83
- "gun",
84
- "spatial",
85
- "mapping",
86
- "cdn",
87
- "browser",
88
- "realtime",
89
- "webrtc"
33
+ "distributed",
34
+ "holonic",
35
+ "federation",
36
+ "noosphere"
90
37
  ],
91
- "bugs": {
92
- "url": "https://github.com/liminalvillage/holosphere/issues"
38
+ "author": "",
39
+ "license": "MIT",
40
+ "dependencies": {
41
+ "@noble/curves": "^1.3.0",
42
+ "ajv": "^8.12.0",
43
+ "dotenv": "^17.2.3",
44
+ "express": "^4.21.0",
45
+ "h3-js": "^4.1.0",
46
+ "nostr-tools": "^2.17.0",
47
+ "openai": "^4.85.1",
48
+ "ws": "^8.18.3"
93
49
  },
94
- "homepage": "https://github.com/liminalvillage/holosphere#readme",
95
- "peerDependencies": {
96
- "gun": "^0.2020.1240",
97
- "h3-js": "^4.1.0"
50
+ "optionalDependencies": {
51
+ "gun": "^0.2020.1241"
98
52
  },
99
- "peerDependenciesMeta": {
100
- "openai": {
101
- "optional": true
102
- }
53
+ "devDependencies": {
54
+ "@vitest/coverage-v8": "^1.3.0",
55
+ "eslint": "^8.57.0",
56
+ "prettier": "^3.2.5",
57
+ "terser": "^5.44.0",
58
+ "vite": "^5.1.0",
59
+ "vitest": "^1.3.0"
60
+ },
61
+ "engines": {
62
+ "node": ">=18.0.0"
103
63
  }
104
64
  }
@@ -0,0 +1,54 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Bundle Size Validation Script
5
+ * Checks that CDN bundle is < 1MB minified+gzipped
6
+ */
7
+
8
+ import fs from 'fs';
9
+ import { gzipSync } from 'zlib';
10
+ import { fileURLToPath } from 'url';
11
+ import { dirname, join } from 'path';
12
+
13
+ const __filename = fileURLToPath(import.meta.url);
14
+ const __dirname = dirname(__filename);
15
+
16
+ const MAX_SIZE_MB = 1;
17
+ const MAX_SIZE_BYTES = MAX_SIZE_MB * 1024 * 1024;
18
+
19
+ const bundlePath = join(__dirname, '../dist/cdn/holosphere.min.js');
20
+
21
+ try {
22
+ // Read bundle
23
+ const bundleContent = fs.readFileSync(bundlePath);
24
+ const uncompressedSize = bundleContent.length;
25
+
26
+ // Gzip
27
+ const gzipped = gzipSync(bundleContent, { level: 9 });
28
+ const gzippedSize = gzipped.length;
29
+
30
+ // Calculate sizes in MB
31
+ const uncompressedMB = (uncompressedSize / 1024 / 1024).toFixed(2);
32
+ const gzippedMB = (gzippedSize / 1024 / 1024).toFixed(2);
33
+
34
+ console.log(`\nšŸ“¦ Bundle Size Report`);
35
+ console.log(`─────────────────────────────────`);
36
+ console.log(`File: dist/cdn/holosphere.min.js`);
37
+ console.log(`Uncompressed: ${uncompressedMB} MB (${uncompressedSize.toLocaleString()} bytes)`);
38
+ console.log(`Gzipped: ${gzippedMB} MB (${gzippedSize.toLocaleString()} bytes)`);
39
+ console.log(`Target: <${MAX_SIZE_MB} MB (${MAX_SIZE_BYTES.toLocaleString()} bytes)`);
40
+ console.log(`─────────────────────────────────`);
41
+
42
+ if (gzippedSize > MAX_SIZE_BYTES) {
43
+ console.error(`\nāŒ FAIL: Bundle size ${gzippedMB} MB exceeds ${MAX_SIZE_MB} MB limit`);
44
+ console.error(` Reduce by ${(gzippedSize - MAX_SIZE_BYTES)} bytes\n`);
45
+ process.exit(1);
46
+ } else {
47
+ const remainingMB = ((MAX_SIZE_BYTES - gzippedSize) / 1024 / 1024).toFixed(2);
48
+ console.log(`\nāœ… PASS: Bundle size OK (${remainingMB} MB headroom)\n`);
49
+ process.exit(0);
50
+ }
51
+ } catch (error) {
52
+ console.error(`\nāŒ ERROR: ${error.message}\n`);
53
+ process.exit(1);
54
+ }
@@ -0,0 +1,77 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Check what quest IDs are actually stored
5
+ */
6
+
7
+ import { HoloSphere } from '../src/index.js';
8
+ import dotenv from 'dotenv';
9
+
10
+ dotenv.config();
11
+
12
+ async function main() {
13
+ console.log('Checking Quest IDs in Storage');
14
+ console.log('==============================\n');
15
+
16
+ const holonId = '235114395';
17
+
18
+ const hs = new HoloSphere({
19
+ appName: 'Holons',
20
+ relays: [],
21
+ persistence: true,
22
+ logLevel: 'ERROR',
23
+ privateKey: process.env.HOLOSPHERE_PRIVATE_KEY
24
+ });
25
+
26
+ await new Promise(resolve => setTimeout(resolve, 2000));
27
+
28
+ const quests = await hs.read(holonId, 'quests');
29
+
30
+ if (!quests) {
31
+ console.log('No quests found!');
32
+ process.exit(1);
33
+ }
34
+
35
+ const questIds = Object.keys(quests);
36
+ console.log(`Total quests: ${questIds.length}\n`);
37
+
38
+ // Show first 30 quests with their original IDs
39
+ console.log('Quest IDs and their original IDs:\n');
40
+ console.log('Stored ID'.padEnd(15) + 'Original ID'.padEnd(15) + 'Title');
41
+ console.log('-'.repeat(80));
42
+
43
+ questIds.slice(0, 30).forEach(id => {
44
+ const quest = quests[id];
45
+ const origId = quest.id || 'N/A';
46
+ const title = (quest.title || 'N/A').substring(0, 40);
47
+ console.log(id.toString().padEnd(15) + origId.toString().padEnd(15) + title);
48
+ });
49
+
50
+ // Check if specific quest IDs exist in the original id field
51
+ console.log('\n' + '='.repeat(80));
52
+ console.log('Searching for original quest IDs 1002, 10026, 1073, 1005, 1011:\n');
53
+
54
+ const targetIds = ['1002', '10026', '1073', '1005', '1011'];
55
+ for (const targetId of targetIds) {
56
+ const found = questIds.find(key => {
57
+ const quest = quests[key];
58
+ return quest.id && quest.id.toString() === targetId;
59
+ });
60
+
61
+ if (found) {
62
+ const quest = quests[found];
63
+ console.log(`āœ“ Quest ${targetId} found at key "${found}"`);
64
+ console.log(` Title: ${quest.title || 'N/A'}`);
65
+ console.log(` Status: ${quest.status || 'N/A'}\n`);
66
+ } else {
67
+ console.log(`āœ— Quest ${targetId} not found\n`);
68
+ }
69
+ }
70
+
71
+ process.exit(0);
72
+ }
73
+
74
+ main().catch(error => {
75
+ console.error('Error:', error);
76
+ process.exit(1);
77
+ });