holosphere 1.1.20 → 2.0.0-alpha1
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/.env.example +36 -0
- package/.eslintrc.json +16 -0
- package/.prettierrc.json +7 -0
- package/LICENSE +162 -38
- package/README.md +483 -367
- package/bin/holosphere-activitypub.js +158 -0
- package/cleanup-test-data.js +204 -0
- package/examples/demo.html +1333 -0
- package/examples/example-bot.js +197 -0
- package/package.json +47 -87
- package/scripts/check-bundle-size.js +54 -0
- package/scripts/check-quest-ids.js +77 -0
- package/scripts/import-holons.js +578 -0
- package/scripts/publish-to-relay.js +101 -0
- package/scripts/read-example.js +186 -0
- package/scripts/relay-diagnostic.js +59 -0
- package/scripts/relay-example.js +179 -0
- package/scripts/resync-to-relay.js +245 -0
- package/scripts/revert-import.js +196 -0
- package/scripts/test-hybrid-mode.js +108 -0
- package/scripts/test-local-storage.js +63 -0
- package/scripts/test-nostr-direct.js +55 -0
- package/scripts/test-read-data.js +45 -0
- package/scripts/test-write-read.js +63 -0
- package/scripts/verify-import.js +95 -0
- package/scripts/verify-relay-data.js +139 -0
- package/src/ai/aggregation.js +319 -0
- package/src/ai/breakdown.js +511 -0
- package/src/ai/classifier.js +217 -0
- package/src/ai/council.js +228 -0
- package/src/ai/embeddings.js +279 -0
- package/src/ai/federation-ai.js +324 -0
- package/src/ai/h3-ai.js +955 -0
- package/src/ai/index.js +112 -0
- package/src/ai/json-ops.js +225 -0
- package/src/ai/llm-service.js +205 -0
- package/src/ai/nl-query.js +223 -0
- package/src/ai/relationships.js +353 -0
- package/src/ai/schema-extractor.js +218 -0
- package/src/ai/spatial.js +293 -0
- package/src/ai/tts.js +194 -0
- package/src/content/social-protocols.js +168 -0
- package/src/core/holosphere.js +273 -0
- package/src/crypto/secp256k1.js +259 -0
- package/src/federation/discovery.js +334 -0
- package/src/federation/hologram.js +1042 -0
- package/src/federation/registry.js +386 -0
- package/src/hierarchical/upcast.js +110 -0
- package/src/index.js +2669 -0
- package/src/schema/validator.js +91 -0
- package/src/spatial/h3-operations.js +110 -0
- package/src/storage/backend-factory.js +125 -0
- package/src/storage/backend-interface.js +142 -0
- package/src/storage/backends/activitypub/server.js +653 -0
- package/src/storage/backends/activitypub-backend.js +272 -0
- package/src/storage/backends/gundb-backend.js +233 -0
- package/src/storage/backends/nostr-backend.js +136 -0
- package/src/storage/filesystem-storage-browser.js +41 -0
- package/src/storage/filesystem-storage.js +138 -0
- package/src/storage/global-tables.js +81 -0
- package/src/storage/gun-async.js +281 -0
- package/src/storage/gun-wrapper.js +221 -0
- package/src/storage/indexeddb-storage.js +122 -0
- package/src/storage/key-storage-simple.js +76 -0
- package/src/storage/key-storage.js +136 -0
- package/src/storage/memory-storage.js +59 -0
- package/src/storage/migration.js +338 -0
- package/src/storage/nostr-async.js +811 -0
- package/src/storage/nostr-client.js +939 -0
- package/src/storage/nostr-wrapper.js +211 -0
- package/src/storage/outbox-queue.js +208 -0
- package/src/storage/persistent-storage.js +109 -0
- package/src/storage/sync-service.js +164 -0
- package/src/subscriptions/manager.js +142 -0
- package/test-ai-real-api.js +202 -0
- package/tests/unit/ai/aggregation.test.js +295 -0
- package/tests/unit/ai/breakdown.test.js +446 -0
- package/tests/unit/ai/classifier.test.js +294 -0
- package/tests/unit/ai/council.test.js +262 -0
- package/tests/unit/ai/embeddings.test.js +384 -0
- package/tests/unit/ai/federation-ai.test.js +344 -0
- package/tests/unit/ai/h3-ai.test.js +458 -0
- package/tests/unit/ai/index.test.js +304 -0
- package/tests/unit/ai/json-ops.test.js +307 -0
- package/tests/unit/ai/llm-service.test.js +390 -0
- package/tests/unit/ai/nl-query.test.js +383 -0
- package/tests/unit/ai/relationships.test.js +311 -0
- package/tests/unit/ai/schema-extractor.test.js +384 -0
- package/tests/unit/ai/spatial.test.js +279 -0
- package/tests/unit/ai/tts.test.js +279 -0
- package/tests/unit/content.test.js +332 -0
- package/tests/unit/contract/core.test.js +88 -0
- package/tests/unit/contract/crypto.test.js +198 -0
- package/tests/unit/contract/data.test.js +223 -0
- package/tests/unit/contract/federation.test.js +181 -0
- package/tests/unit/contract/hierarchical.test.js +113 -0
- package/tests/unit/contract/schema.test.js +114 -0
- package/tests/unit/contract/social.test.js +217 -0
- package/tests/unit/contract/spatial.test.js +110 -0
- package/tests/unit/contract/subscriptions.test.js +128 -0
- package/tests/unit/contract/utils.test.js +159 -0
- package/tests/unit/core.test.js +152 -0
- package/tests/unit/crypto.test.js +328 -0
- package/tests/unit/federation.test.js +234 -0
- package/tests/unit/gun-async.test.js +252 -0
- package/tests/unit/hierarchical.test.js +399 -0
- package/tests/unit/integration/scenario-01-geographic-storage.test.js +74 -0
- package/tests/unit/integration/scenario-02-federation.test.js +76 -0
- package/tests/unit/integration/scenario-03-subscriptions.test.js +102 -0
- package/tests/unit/integration/scenario-04-validation.test.js +129 -0
- package/tests/unit/integration/scenario-05-hierarchy.test.js +125 -0
- package/tests/unit/integration/scenario-06-social.test.js +135 -0
- package/tests/unit/integration/scenario-07-persistence.test.js +130 -0
- package/tests/unit/integration/scenario-08-authorization.test.js +161 -0
- package/tests/unit/integration/scenario-09-cross-dimensional.test.js +139 -0
- package/tests/unit/integration/scenario-10-cross-holosphere-capabilities.test.js +357 -0
- package/tests/unit/integration/scenario-11-cross-holosphere-federation.test.js +410 -0
- package/tests/unit/integration/scenario-12-capability-federated-read.test.js +719 -0
- package/tests/unit/performance/benchmark.test.js +85 -0
- package/tests/unit/schema.test.js +213 -0
- package/tests/unit/spatial.test.js +158 -0
- package/tests/unit/storage.test.js +195 -0
- package/tests/unit/subscriptions.test.js +328 -0
- package/tests/unit/test-data-permanence-debug.js +197 -0
- package/tests/unit/test-data-permanence.js +340 -0
- package/tests/unit/test-key-persistence-fixed.js +148 -0
- package/tests/unit/test-key-persistence.js +172 -0
- package/tests/unit/test-relay-permanence.js +376 -0
- package/tests/unit/test-second-node.js +95 -0
- package/tests/unit/test-simple-write.js +89 -0
- package/vite.config.js +49 -0
- package/vitest.config.js +20 -0
- package/FEDERATION.md +0 -213
- package/compute.js +0 -298
- package/content.js +0 -980
- package/federation.js +0 -1234
- package/global.js +0 -736
- package/hexlib.js +0 -335
- package/hologram.js +0 -183
- package/holosphere-bundle.esm.js +0 -33256
- package/holosphere-bundle.js +0 -33287
- package/holosphere-bundle.min.js +0 -39
- package/holosphere.d.ts +0 -601
- package/holosphere.js +0 -719
- package/node.js +0 -246
- package/schema.js +0 -139
- package/utils.js +0 -302
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Revert script to delete incorrectly imported data
|
|
5
|
+
*
|
|
6
|
+
* This script deletes data that was imported with quest IDs as lens names
|
|
7
|
+
* instead of using the subfolder as the holon ID.
|
|
8
|
+
*
|
|
9
|
+
* Usage:
|
|
10
|
+
* node scripts/revert-import.js [options]
|
|
11
|
+
*
|
|
12
|
+
* Options:
|
|
13
|
+
* --dry-run Show what would be deleted without actually deleting
|
|
14
|
+
* --verbose Show detailed progress
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import { HoloSphere } from '../src/index.js';
|
|
18
|
+
import dotenv from 'dotenv';
|
|
19
|
+
|
|
20
|
+
// Load environment variables
|
|
21
|
+
dotenv.config();
|
|
22
|
+
|
|
23
|
+
// Parse command line arguments
|
|
24
|
+
const args = process.argv.slice(2);
|
|
25
|
+
const options = {
|
|
26
|
+
dryRun: false,
|
|
27
|
+
verbose: true,
|
|
28
|
+
relays: ['wss://relay.holons.io'],
|
|
29
|
+
persistence: true
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
for (let i = 0; i < args.length; i++) {
|
|
33
|
+
switch (args[i]) {
|
|
34
|
+
case '--dry-run':
|
|
35
|
+
options.dryRun = true;
|
|
36
|
+
break;
|
|
37
|
+
case '--verbose':
|
|
38
|
+
options.verbose = true;
|
|
39
|
+
break;
|
|
40
|
+
case '--help':
|
|
41
|
+
console.log(`
|
|
42
|
+
Revert incorrectly imported data from holosphere
|
|
43
|
+
|
|
44
|
+
Usage: node scripts/revert-import.js [options]
|
|
45
|
+
|
|
46
|
+
Options:
|
|
47
|
+
--dry-run Show what would be deleted without actually deleting
|
|
48
|
+
--verbose Show detailed progress
|
|
49
|
+
--help Show this help message
|
|
50
|
+
`);
|
|
51
|
+
process.exit(0);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// These are the incorrect apps that were created (should have been lenses)
|
|
56
|
+
const incorrectApps = [
|
|
57
|
+
'3891', 'announcements', 'checklists', 'expenses', 'linked_quests',
|
|
58
|
+
'profile', 'roles', 'settings', 'users'
|
|
59
|
+
];
|
|
60
|
+
|
|
61
|
+
// These are the incorrect lenses that were created (should have been IDs)
|
|
62
|
+
const incorrectQuestLenses = [
|
|
63
|
+
'1002', '10026', '1005', '1011', '1017', '10177', '10213', '10231',
|
|
64
|
+
'1024', '1026', '10269', '10273', '1028', '10281', '1029', '10291',
|
|
65
|
+
'10310', '10313', '10316', '1033', '1035', '10362', '10385', '10393',
|
|
66
|
+
'10399', '10412', '10639', '10759', '10838', '11239', '11347', '11354',
|
|
67
|
+
'11361', '11367', '11431', '11435', '11452', '11455', '11468', '11484',
|
|
68
|
+
'11491', '11500', '11516', '11580', '11587', '11596', '11601', '11725',
|
|
69
|
+
'11971', '11974', '11977', '11981', '11984', '11987', '11994', '12283',
|
|
70
|
+
'12291', '12296', '12310', '12315', '12384', '13036', '15637', '15656',
|
|
71
|
+
'15789', '15908', '15913', '15916', '15921', '15981', '16282', '16296',
|
|
72
|
+
'16349', '16352', '16364', '16469', '16540', '16545', '16619', '16650',
|
|
73
|
+
'16653', '16656', '16659', '16662', '16665', '16671', '16690', '167',
|
|
74
|
+
'16712', '16717', '16753', '16758', '16769', '16782', '16793', '16818',
|
|
75
|
+
'16896', '16910', '173442588812194d9kcgiz', '1739201779001ug89uo3fh',
|
|
76
|
+
'1739201790600krobxpk5u', '17392021107016nn2xo6fr', '17392022587064gb5lwy1u',
|
|
77
|
+
'1739202266947zmjy6lmcr', '1739202303652q3csgus2f', '1739203',
|
|
78
|
+
'1739203388980mjeej5d9c', '17392034164678wpynqaxj', '1739203427753zeoqpuqmr',
|
|
79
|
+
'1739203441458vc6p1a5pg', '1747629817053', '1749241269564', '17621',
|
|
80
|
+
'17649', '17653', '17657', '18', '183', '19', '221', '224', '242', '252',
|
|
81
|
+
'274', '327', '358', '364', '367', '369', '380', '382', '383', '415',
|
|
82
|
+
'430', '44', '45', '46', '462', '463', '468', '475', '476', '48', '495',
|
|
83
|
+
'498', '501', '504', '518', '550', '551', '562', '631', '645', '646',
|
|
84
|
+
'661', '680', '685', '706', '749', '752', '786', '789', '795', '801',
|
|
85
|
+
'817', '82', '829', '843', '852'
|
|
86
|
+
];
|
|
87
|
+
|
|
88
|
+
// Additional lenses under Holons app that need to be cleaned
|
|
89
|
+
const holonsLenses = [
|
|
90
|
+
'1073', '1082', '1110', '1113', '14677', '14680', '1487', '14912',
|
|
91
|
+
'14958', '18610', '19454', '1948', '1750784563464', '1753288184361',
|
|
92
|
+
'1753288962009', '1753346754181', '1753347504071', '1753903926664'
|
|
93
|
+
];
|
|
94
|
+
|
|
95
|
+
const stats = {
|
|
96
|
+
deleted: 0,
|
|
97
|
+
errors: 0
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
async function main() {
|
|
101
|
+
console.log('Holosphere Revert Tool');
|
|
102
|
+
console.log('======================\n');
|
|
103
|
+
console.log(`Dry run: ${options.dryRun ? 'Yes' : 'No'}`);
|
|
104
|
+
console.log('');
|
|
105
|
+
|
|
106
|
+
// Initialize holosphere
|
|
107
|
+
console.log('Initializing holosphere...');
|
|
108
|
+
const hs = new HoloSphere({
|
|
109
|
+
appName: 'Holons',
|
|
110
|
+
relays: options.relays,
|
|
111
|
+
persistence: options.persistence,
|
|
112
|
+
logLevel: options.verbose ? 'DEBUG' : 'INFO',
|
|
113
|
+
privateKey: process.env.HOLOSPHERE_PRIVATE_KEY
|
|
114
|
+
});
|
|
115
|
+
console.log('Holosphere initialized.\n');
|
|
116
|
+
|
|
117
|
+
console.log('Starting revert...\n');
|
|
118
|
+
|
|
119
|
+
// Delete incorrect app entries
|
|
120
|
+
for (const appName of incorrectApps) {
|
|
121
|
+
try {
|
|
122
|
+
if (options.verbose) {
|
|
123
|
+
console.log(`Deleting app: ${appName} (holon=global)`);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
if (!options.dryRun) {
|
|
127
|
+
// Note: HoloSphere doesn't have a direct delete API yet
|
|
128
|
+
// We'll need to null out the data instead
|
|
129
|
+
await hs.writeGlobal(appName, null);
|
|
130
|
+
}
|
|
131
|
+
stats.deleted++;
|
|
132
|
+
} catch (error) {
|
|
133
|
+
console.error(`Error deleting app ${appName}:`, error.message);
|
|
134
|
+
stats.errors++;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// Delete incorrect quest lenses under 'quests' app
|
|
139
|
+
for (const lensName of incorrectQuestLenses) {
|
|
140
|
+
try {
|
|
141
|
+
if (options.verbose) {
|
|
142
|
+
console.log(`Deleting: app=quests, holon=global, lens=${lensName}`);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
if (!options.dryRun) {
|
|
146
|
+
// Switch to quests app context
|
|
147
|
+
const questsHs = new HoloSphere({
|
|
148
|
+
appName: 'quests',
|
|
149
|
+
relays: options.relays,
|
|
150
|
+
persistence: options.persistence,
|
|
151
|
+
logLevel: 'ERROR',
|
|
152
|
+
privateKey: process.env.HOLOSPHERE_PRIVATE_KEY
|
|
153
|
+
});
|
|
154
|
+
await questsHs.writeGlobal(lensName, null);
|
|
155
|
+
}
|
|
156
|
+
stats.deleted++;
|
|
157
|
+
} catch (error) {
|
|
158
|
+
console.error(`Error deleting lens ${lensName}:`, error.message);
|
|
159
|
+
stats.errors++;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// Delete incorrect quest lenses under 'Holons' app
|
|
164
|
+
for (const lensName of holonsLenses) {
|
|
165
|
+
try {
|
|
166
|
+
if (options.verbose) {
|
|
167
|
+
console.log(`Deleting: app=Holons, holon=global, lens=quests, id=${lensName}`);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
if (!options.dryRun) {
|
|
171
|
+
await hs.writeGlobal(`quests.${lensName}`, null);
|
|
172
|
+
}
|
|
173
|
+
stats.deleted++;
|
|
174
|
+
} catch (error) {
|
|
175
|
+
console.error(`Error deleting quest ${lensName}:`, error.message);
|
|
176
|
+
stats.errors++;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
console.log('\n======================');
|
|
181
|
+
console.log('Revert Complete');
|
|
182
|
+
console.log('======================');
|
|
183
|
+
console.log(`Items deleted: ${stats.deleted}`);
|
|
184
|
+
console.log(`Errors: ${stats.errors}`);
|
|
185
|
+
|
|
186
|
+
if (options.dryRun) {
|
|
187
|
+
console.log('\nThis was a dry run. No data was actually deleted.');
|
|
188
|
+
console.log('Run without --dry-run to perform the actual deletion.');
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// Run main function
|
|
193
|
+
main().catch(error => {
|
|
194
|
+
console.error('Fatal error:', error);
|
|
195
|
+
process.exit(1);
|
|
196
|
+
});
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Test hybrid mode (local + relay)
|
|
5
|
+
* Demonstrates that hybrid mode returns data from both sources
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { HoloSphere } from '../src/index.js';
|
|
9
|
+
import dotenv from 'dotenv';
|
|
10
|
+
|
|
11
|
+
dotenv.config();
|
|
12
|
+
|
|
13
|
+
async function main() {
|
|
14
|
+
console.log('Testing Hybrid Mode');
|
|
15
|
+
console.log('===================\n');
|
|
16
|
+
|
|
17
|
+
const holonId = process.argv[2] || '235114395';
|
|
18
|
+
const relayUrl = process.env.HOLOSPHERE_RELAY || 'wss://relay.holons.io';
|
|
19
|
+
|
|
20
|
+
// Test 1: Relay-only mode (old behavior)
|
|
21
|
+
console.log('Test 1: Relay-only mode (hybridMode: false)');
|
|
22
|
+
console.log('-'.repeat(60));
|
|
23
|
+
|
|
24
|
+
const hsRelayOnly = new HoloSphere({
|
|
25
|
+
appName: 'Holons',
|
|
26
|
+
relays: [relayUrl],
|
|
27
|
+
persistence: true,
|
|
28
|
+
logLevel: 'ERROR',
|
|
29
|
+
privateKey: process.env.HOLOSPHERE_PRIVATE_KEY,
|
|
30
|
+
hybridMode: false // Disable hybrid mode
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
34
|
+
|
|
35
|
+
const relayOnlyQuests = await hsRelayOnly.read(holonId, 'quests');
|
|
36
|
+
const relayOnlyCount = relayOnlyQuests ? relayOnlyQuests.length : 0;
|
|
37
|
+
|
|
38
|
+
console.log(`Quests retrieved: ${relayOnlyCount}`);
|
|
39
|
+
console.log(`Source: Relay only\n`);
|
|
40
|
+
|
|
41
|
+
// Test 2: Hybrid mode (new behavior - default)
|
|
42
|
+
console.log('Test 2: Hybrid mode (hybridMode: true - default)');
|
|
43
|
+
console.log('-'.repeat(60));
|
|
44
|
+
|
|
45
|
+
const hsHybrid = new HoloSphere({
|
|
46
|
+
appName: 'Holons',
|
|
47
|
+
relays: [relayUrl],
|
|
48
|
+
persistence: true,
|
|
49
|
+
logLevel: 'ERROR',
|
|
50
|
+
privateKey: process.env.HOLOSPHERE_PRIVATE_KEY,
|
|
51
|
+
hybridMode: true // Enable hybrid mode (default)
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
55
|
+
|
|
56
|
+
const hybridQuests = await hsHybrid.read(holonId, 'quests');
|
|
57
|
+
const hybridCount = hybridQuests ? hybridQuests.length : 0;
|
|
58
|
+
|
|
59
|
+
console.log(`Quests retrieved: ${hybridCount}`);
|
|
60
|
+
console.log(`Source: Local + Relay merged\n`);
|
|
61
|
+
|
|
62
|
+
// Test 3: Local-only mode
|
|
63
|
+
console.log('Test 3: Local-only mode (no relays)');
|
|
64
|
+
console.log('-'.repeat(60));
|
|
65
|
+
|
|
66
|
+
const hsLocal = new HoloSphere({
|
|
67
|
+
appName: 'Holons',
|
|
68
|
+
relays: [],
|
|
69
|
+
persistence: true,
|
|
70
|
+
logLevel: 'ERROR',
|
|
71
|
+
privateKey: process.env.HOLOSPHERE_PRIVATE_KEY
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
75
|
+
|
|
76
|
+
const localQuests = await hsLocal.read(holonId, 'quests');
|
|
77
|
+
const localCount = localQuests ? localQuests.length : 0;
|
|
78
|
+
|
|
79
|
+
console.log(`Quests retrieved: ${localCount}`);
|
|
80
|
+
console.log(`Source: Local only\n`);
|
|
81
|
+
|
|
82
|
+
// Summary
|
|
83
|
+
console.log('='.repeat(60));
|
|
84
|
+
console.log('Summary');
|
|
85
|
+
console.log('='.repeat(60));
|
|
86
|
+
console.log(`Relay-only: ${relayOnlyCount} quests`);
|
|
87
|
+
console.log(`Hybrid mode: ${hybridCount} quests ← BEST (merges local + relay)`);
|
|
88
|
+
console.log(`Local-only: ${localCount} quests`);
|
|
89
|
+
console.log('');
|
|
90
|
+
|
|
91
|
+
if (hybridCount >= localCount && hybridCount >= relayOnlyCount) {
|
|
92
|
+
console.log('✓ Hybrid mode returns the most data!');
|
|
93
|
+
console.log(' It merges local storage with relay data\n');
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
console.log('Benefits of Hybrid Mode:');
|
|
97
|
+
console.log(' - Returns data even if relay is down');
|
|
98
|
+
console.log(' - Includes locally-stored data not yet synced to relay');
|
|
99
|
+
console.log(' - Merges both sources for complete data set');
|
|
100
|
+
console.log(' - Prefers newer events when duplicates exist\n');
|
|
101
|
+
|
|
102
|
+
process.exit(0);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
main().catch(error => {
|
|
106
|
+
console.error('Error:', error);
|
|
107
|
+
process.exit(1);
|
|
108
|
+
});
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Test reading from local storage only (no relays)
|
|
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('Testing Local Storage (No Relays)');
|
|
14
|
+
console.log('==================================\n');
|
|
15
|
+
|
|
16
|
+
// Initialize WITHOUT relays to force local-only reads
|
|
17
|
+
const hs = new HoloSphere({
|
|
18
|
+
appName: 'Holons',
|
|
19
|
+
relays: [], // Empty - will read from local cache only
|
|
20
|
+
persistence: true,
|
|
21
|
+
logLevel: 'INFO',
|
|
22
|
+
privateKey: process.env.HOLOSPHERE_PRIVATE_KEY
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
const holonId = '235114395';
|
|
26
|
+
|
|
27
|
+
console.log('Waiting for storage to load...\n');
|
|
28
|
+
await new Promise(resolve => setTimeout(resolve, 3000));
|
|
29
|
+
|
|
30
|
+
// Read quests
|
|
31
|
+
console.log('Reading quests from local storage...\n');
|
|
32
|
+
const quests = await hs.read(holonId, 'quests');
|
|
33
|
+
|
|
34
|
+
const questCount = quests ? Object.keys(quests).length : 0;
|
|
35
|
+
console.log(`Found ${questCount} quests in local storage\n`);
|
|
36
|
+
|
|
37
|
+
if (questCount > 0) {
|
|
38
|
+
console.log('Sample quests:');
|
|
39
|
+
const questIds = Object.keys(quests).slice(0, 10);
|
|
40
|
+
for (const id of questIds) {
|
|
41
|
+
const quest = quests[id];
|
|
42
|
+
console.log(` - ${id}: ${quest.title || 'N/A'} (${quest.status || 'N/A'})`);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// Test other lenses
|
|
47
|
+
console.log('\nTesting all lenses:\n');
|
|
48
|
+
const lenses = ['3891', 'announcements', 'checklists', 'expenses', 'linked_quests',
|
|
49
|
+
'profile', 'quests', 'roles', 'settings', 'users'];
|
|
50
|
+
|
|
51
|
+
for (const lens of lenses) {
|
|
52
|
+
const data = await hs.read(holonId, lens);
|
|
53
|
+
const count = data ? Object.keys(data).length : 0;
|
|
54
|
+
console.log(` ${lens.padEnd(20)} ${count} items`);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
process.exit(0);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
main().catch(error => {
|
|
61
|
+
console.error('Error:', error);
|
|
62
|
+
process.exit(1);
|
|
63
|
+
});
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Test nostr-tools directly
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import WebSocket from 'ws';
|
|
8
|
+
// Polyfill WebSocket for Node.js
|
|
9
|
+
global.WebSocket = WebSocket;
|
|
10
|
+
|
|
11
|
+
import { SimplePool, finalizeEvent, generateSecretKey, getPublicKey } from 'nostr-tools';
|
|
12
|
+
|
|
13
|
+
async function main() {
|
|
14
|
+
console.log('Testing nostr-tools directly\n');
|
|
15
|
+
|
|
16
|
+
const sk = generateSecretKey();
|
|
17
|
+
const pk = getPublicKey(sk);
|
|
18
|
+
|
|
19
|
+
console.log('Public key:', pk);
|
|
20
|
+
|
|
21
|
+
const pool = new SimplePool();
|
|
22
|
+
const relays = ['wss://relay.holons.io'];
|
|
23
|
+
|
|
24
|
+
const event = {
|
|
25
|
+
kind: 1,
|
|
26
|
+
created_at: Math.floor(Date.now() / 1000),
|
|
27
|
+
tags: [],
|
|
28
|
+
content: 'Hello from HoloSphere test!'
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
const signedEvent = finalizeEvent(event, sk);
|
|
32
|
+
console.log('\nPublishing event...');
|
|
33
|
+
console.log('Event ID:', signedEvent.id);
|
|
34
|
+
|
|
35
|
+
try {
|
|
36
|
+
const results = await Promise.allSettled(pool.publish(relays, signedEvent));
|
|
37
|
+
console.log('\nResults:');
|
|
38
|
+
results.forEach((r, i) => {
|
|
39
|
+
console.log(`Relay ${i}:`, r.status, r.value || r.reason);
|
|
40
|
+
});
|
|
41
|
+
} catch (error) {
|
|
42
|
+
console.error('Error:', error);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
console.log('\nWaiting 2 seconds...');
|
|
46
|
+
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
47
|
+
|
|
48
|
+
console.log('\nQuerying event...');
|
|
49
|
+
const events = await pool.querySync(relays, { ids: [signedEvent.id] }, { timeout: 3000 });
|
|
50
|
+
console.log('Found events:', events.length);
|
|
51
|
+
|
|
52
|
+
pool.close(relays);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
main().catch(console.error);
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Test script to verify data structure after import
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { HoloSphere } from '../src/index.js';
|
|
8
|
+
import dotenv from 'dotenv';
|
|
9
|
+
|
|
10
|
+
// Load environment variables
|
|
11
|
+
dotenv.config();
|
|
12
|
+
|
|
13
|
+
async function main() {
|
|
14
|
+
console.log('Testing data structure...\n');
|
|
15
|
+
|
|
16
|
+
// Initialize holosphere
|
|
17
|
+
const hs = new HoloSphere({
|
|
18
|
+
appName: 'Holons',
|
|
19
|
+
relays: ['wss://relay.holons.io'],
|
|
20
|
+
persistence: true,
|
|
21
|
+
logLevel: 'INFO',
|
|
22
|
+
privateKey: process.env.HOLOSPHERE_PRIVATE_KEY
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
console.log('Reading quests from holon 235114395...\n');
|
|
26
|
+
|
|
27
|
+
// Try to read some quests
|
|
28
|
+
const quests = await hs.read('235114395', 'quests');
|
|
29
|
+
|
|
30
|
+
if (quests && quests.length > 0) {
|
|
31
|
+
console.log(`✓ Found ${quests.length} quests`);
|
|
32
|
+
console.log(`✓ Sample quest IDs: ${quests.slice(0, 5).map(q => q.id).join(', ')}`);
|
|
33
|
+
console.log('\n✓ Data structure is correct!');
|
|
34
|
+
console.log(` - app: Holons`);
|
|
35
|
+
console.log(` - holon: 235114395`);
|
|
36
|
+
console.log(` - lens: quests`);
|
|
37
|
+
} else {
|
|
38
|
+
console.log('✗ No quests found');
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
main().catch(error => {
|
|
43
|
+
console.error('Error:', error);
|
|
44
|
+
process.exit(1);
|
|
45
|
+
});
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Simple test to verify write/read cycle works
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { HoloSphere } from '../src/index.js';
|
|
8
|
+
import dotenv from 'dotenv';
|
|
9
|
+
|
|
10
|
+
// Load environment variables
|
|
11
|
+
dotenv.config();
|
|
12
|
+
|
|
13
|
+
async function main() {
|
|
14
|
+
console.log('Testing Write/Read Cycle');
|
|
15
|
+
console.log('========================\n');
|
|
16
|
+
|
|
17
|
+
const hs = new HoloSphere({
|
|
18
|
+
appName: 'test-app',
|
|
19
|
+
relays: ['wss://relay.holons.io', 'wss://relay.nostr.band'],
|
|
20
|
+
persistence: true,
|
|
21
|
+
logLevel: 'DEBUG',
|
|
22
|
+
privateKey: process.env.HOLOSPHERE_PRIVATE_KEY
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
console.log('Writing test data...');
|
|
26
|
+
|
|
27
|
+
// Write a test item
|
|
28
|
+
const testData = {
|
|
29
|
+
id: 'test-123',
|
|
30
|
+
title: 'Test Item',
|
|
31
|
+
value: 42,
|
|
32
|
+
timestamp: Date.now()
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
testData.id = 'test-123';
|
|
36
|
+
await hs.writeGlobal('test-lens', testData);
|
|
37
|
+
console.log('✓ Data written');
|
|
38
|
+
|
|
39
|
+
// Wait a moment for relay propagation
|
|
40
|
+
console.log('\nWaiting 2 seconds for relay propagation...');
|
|
41
|
+
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
42
|
+
|
|
43
|
+
// Try to read it back
|
|
44
|
+
console.log('\nReading data back...');
|
|
45
|
+
const result = await hs.readGlobal('test-lens', 'test-123');
|
|
46
|
+
|
|
47
|
+
if (result) {
|
|
48
|
+
console.log('✓ Data retrieved successfully:');
|
|
49
|
+
console.log(JSON.stringify(result, null, 2));
|
|
50
|
+
} else {
|
|
51
|
+
console.log('✗ No data found');
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Try reading all from the lens
|
|
55
|
+
console.log('\nReading all from test-lens...');
|
|
56
|
+
const allData = await hs.readGlobal('test-lens');
|
|
57
|
+
console.log('Result:', allData);
|
|
58
|
+
|
|
59
|
+
// Show metrics
|
|
60
|
+
console.log('\nMetrics:', hs.metrics());
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
main().catch(console.error);
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Verify imported data can be retrieved
|
|
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('Verifying Import Data');
|
|
14
|
+
console.log('=====================\n');
|
|
15
|
+
|
|
16
|
+
const hs = new HoloSphere({
|
|
17
|
+
appName: 'Holons',
|
|
18
|
+
relays: ['wss://relay.holons.io'],
|
|
19
|
+
persistence: true,
|
|
20
|
+
logLevel: 'INFO',
|
|
21
|
+
privateKey: process.env.HOLOSPHERE_PRIVATE_KEY
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
const holonId = '235114395';
|
|
25
|
+
const lenses = ['3891', 'announcements', 'checklists', 'expenses', 'linked_quests',
|
|
26
|
+
'profile', 'quests', 'roles', 'settings', 'users'];
|
|
27
|
+
|
|
28
|
+
console.log('Waiting for storage to initialize...\n');
|
|
29
|
+
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
30
|
+
|
|
31
|
+
// Test each lens
|
|
32
|
+
console.log('Testing data retrieval by lens:\n');
|
|
33
|
+
const results = {};
|
|
34
|
+
|
|
35
|
+
for (const lens of lenses) {
|
|
36
|
+
try {
|
|
37
|
+
const data = await hs.read(holonId, lens);
|
|
38
|
+
const count = data ? Object.keys(data).length : 0;
|
|
39
|
+
results[lens] = count;
|
|
40
|
+
console.log(`✓ ${lens.padEnd(20)} ${count} items`);
|
|
41
|
+
} catch (error) {
|
|
42
|
+
console.log(`✗ ${lens.padEnd(20)} Error: ${error.message}`);
|
|
43
|
+
results[lens] = 0;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
console.log('\n' + '='.repeat(50));
|
|
48
|
+
const totalItems = Object.values(results).reduce((sum, count) => sum + count, 0);
|
|
49
|
+
console.log(`Total items retrieved: ${totalItems}`);
|
|
50
|
+
console.log('='.repeat(50) + '\n');
|
|
51
|
+
|
|
52
|
+
// Test specific quest retrieval
|
|
53
|
+
console.log('Testing specific quest retrieval:\n');
|
|
54
|
+
|
|
55
|
+
const testQuests = ['1002', '10026', '1073', 'nonexistent-quest'];
|
|
56
|
+
|
|
57
|
+
for (const questId of testQuests) {
|
|
58
|
+
try {
|
|
59
|
+
const allQuests = await hs.read(holonId, 'quests');
|
|
60
|
+
const quest = allQuests ? allQuests[questId] : null;
|
|
61
|
+
|
|
62
|
+
if (quest) {
|
|
63
|
+
console.log(`✓ Quest ${questId}: Found`);
|
|
64
|
+
console.log(` Title: ${quest.title || 'N/A'}`);
|
|
65
|
+
console.log(` Status: ${quest.status || 'N/A'}`);
|
|
66
|
+
} else {
|
|
67
|
+
console.log(`✗ Quest ${questId}: Not found`);
|
|
68
|
+
console.log(` Returns: ${quest === null ? 'null' : typeof quest}`);
|
|
69
|
+
}
|
|
70
|
+
} catch (error) {
|
|
71
|
+
console.log(`✗ Quest ${questId}: Error - ${error.message}`);
|
|
72
|
+
}
|
|
73
|
+
console.log('');
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// Test what happens when reading non-existent lens
|
|
77
|
+
console.log('Testing non-existent lens:\n');
|
|
78
|
+
try {
|
|
79
|
+
const data = await hs.read(holonId, 'nonexistent-lens');
|
|
80
|
+
console.log(`Result: ${data === null ? 'null' : typeof data}`);
|
|
81
|
+
console.log(`Value: ${JSON.stringify(data)}`);
|
|
82
|
+
} catch (error) {
|
|
83
|
+
console.log(`Error: ${error.message}`);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
console.log('\n✓ Verification complete\n');
|
|
87
|
+
|
|
88
|
+
// Force exit since Nostr connections stay open
|
|
89
|
+
process.exit(0);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
main().catch(error => {
|
|
93
|
+
console.error('Error:', error);
|
|
94
|
+
process.exit(1);
|
|
95
|
+
});
|