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.
Files changed (147) hide show
  1. package/.env.example +36 -0
  2. package/.eslintrc.json +16 -0
  3. package/.prettierrc.json +7 -0
  4. package/LICENSE +162 -38
  5. package/README.md +483 -367
  6. package/bin/holosphere-activitypub.js +158 -0
  7. package/cleanup-test-data.js +204 -0
  8. package/examples/demo.html +1333 -0
  9. package/examples/example-bot.js +197 -0
  10. package/package.json +47 -87
  11. package/scripts/check-bundle-size.js +54 -0
  12. package/scripts/check-quest-ids.js +77 -0
  13. package/scripts/import-holons.js +578 -0
  14. package/scripts/publish-to-relay.js +101 -0
  15. package/scripts/read-example.js +186 -0
  16. package/scripts/relay-diagnostic.js +59 -0
  17. package/scripts/relay-example.js +179 -0
  18. package/scripts/resync-to-relay.js +245 -0
  19. package/scripts/revert-import.js +196 -0
  20. package/scripts/test-hybrid-mode.js +108 -0
  21. package/scripts/test-local-storage.js +63 -0
  22. package/scripts/test-nostr-direct.js +55 -0
  23. package/scripts/test-read-data.js +45 -0
  24. package/scripts/test-write-read.js +63 -0
  25. package/scripts/verify-import.js +95 -0
  26. package/scripts/verify-relay-data.js +139 -0
  27. package/src/ai/aggregation.js +319 -0
  28. package/src/ai/breakdown.js +511 -0
  29. package/src/ai/classifier.js +217 -0
  30. package/src/ai/council.js +228 -0
  31. package/src/ai/embeddings.js +279 -0
  32. package/src/ai/federation-ai.js +324 -0
  33. package/src/ai/h3-ai.js +955 -0
  34. package/src/ai/index.js +112 -0
  35. package/src/ai/json-ops.js +225 -0
  36. package/src/ai/llm-service.js +205 -0
  37. package/src/ai/nl-query.js +223 -0
  38. package/src/ai/relationships.js +353 -0
  39. package/src/ai/schema-extractor.js +218 -0
  40. package/src/ai/spatial.js +293 -0
  41. package/src/ai/tts.js +194 -0
  42. package/src/content/social-protocols.js +168 -0
  43. package/src/core/holosphere.js +273 -0
  44. package/src/crypto/secp256k1.js +259 -0
  45. package/src/federation/discovery.js +334 -0
  46. package/src/federation/hologram.js +1042 -0
  47. package/src/federation/registry.js +386 -0
  48. package/src/hierarchical/upcast.js +110 -0
  49. package/src/index.js +2669 -0
  50. package/src/schema/validator.js +91 -0
  51. package/src/spatial/h3-operations.js +110 -0
  52. package/src/storage/backend-factory.js +125 -0
  53. package/src/storage/backend-interface.js +142 -0
  54. package/src/storage/backends/activitypub/server.js +653 -0
  55. package/src/storage/backends/activitypub-backend.js +272 -0
  56. package/src/storage/backends/gundb-backend.js +233 -0
  57. package/src/storage/backends/nostr-backend.js +136 -0
  58. package/src/storage/filesystem-storage-browser.js +41 -0
  59. package/src/storage/filesystem-storage.js +138 -0
  60. package/src/storage/global-tables.js +81 -0
  61. package/src/storage/gun-async.js +281 -0
  62. package/src/storage/gun-wrapper.js +221 -0
  63. package/src/storage/indexeddb-storage.js +122 -0
  64. package/src/storage/key-storage-simple.js +76 -0
  65. package/src/storage/key-storage.js +136 -0
  66. package/src/storage/memory-storage.js +59 -0
  67. package/src/storage/migration.js +338 -0
  68. package/src/storage/nostr-async.js +811 -0
  69. package/src/storage/nostr-client.js +939 -0
  70. package/src/storage/nostr-wrapper.js +211 -0
  71. package/src/storage/outbox-queue.js +208 -0
  72. package/src/storage/persistent-storage.js +109 -0
  73. package/src/storage/sync-service.js +164 -0
  74. package/src/subscriptions/manager.js +142 -0
  75. package/test-ai-real-api.js +202 -0
  76. package/tests/unit/ai/aggregation.test.js +295 -0
  77. package/tests/unit/ai/breakdown.test.js +446 -0
  78. package/tests/unit/ai/classifier.test.js +294 -0
  79. package/tests/unit/ai/council.test.js +262 -0
  80. package/tests/unit/ai/embeddings.test.js +384 -0
  81. package/tests/unit/ai/federation-ai.test.js +344 -0
  82. package/tests/unit/ai/h3-ai.test.js +458 -0
  83. package/tests/unit/ai/index.test.js +304 -0
  84. package/tests/unit/ai/json-ops.test.js +307 -0
  85. package/tests/unit/ai/llm-service.test.js +390 -0
  86. package/tests/unit/ai/nl-query.test.js +383 -0
  87. package/tests/unit/ai/relationships.test.js +311 -0
  88. package/tests/unit/ai/schema-extractor.test.js +384 -0
  89. package/tests/unit/ai/spatial.test.js +279 -0
  90. package/tests/unit/ai/tts.test.js +279 -0
  91. package/tests/unit/content.test.js +332 -0
  92. package/tests/unit/contract/core.test.js +88 -0
  93. package/tests/unit/contract/crypto.test.js +198 -0
  94. package/tests/unit/contract/data.test.js +223 -0
  95. package/tests/unit/contract/federation.test.js +181 -0
  96. package/tests/unit/contract/hierarchical.test.js +113 -0
  97. package/tests/unit/contract/schema.test.js +114 -0
  98. package/tests/unit/contract/social.test.js +217 -0
  99. package/tests/unit/contract/spatial.test.js +110 -0
  100. package/tests/unit/contract/subscriptions.test.js +128 -0
  101. package/tests/unit/contract/utils.test.js +159 -0
  102. package/tests/unit/core.test.js +152 -0
  103. package/tests/unit/crypto.test.js +328 -0
  104. package/tests/unit/federation.test.js +234 -0
  105. package/tests/unit/gun-async.test.js +252 -0
  106. package/tests/unit/hierarchical.test.js +399 -0
  107. package/tests/unit/integration/scenario-01-geographic-storage.test.js +74 -0
  108. package/tests/unit/integration/scenario-02-federation.test.js +76 -0
  109. package/tests/unit/integration/scenario-03-subscriptions.test.js +102 -0
  110. package/tests/unit/integration/scenario-04-validation.test.js +129 -0
  111. package/tests/unit/integration/scenario-05-hierarchy.test.js +125 -0
  112. package/tests/unit/integration/scenario-06-social.test.js +135 -0
  113. package/tests/unit/integration/scenario-07-persistence.test.js +130 -0
  114. package/tests/unit/integration/scenario-08-authorization.test.js +161 -0
  115. package/tests/unit/integration/scenario-09-cross-dimensional.test.js +139 -0
  116. package/tests/unit/integration/scenario-10-cross-holosphere-capabilities.test.js +357 -0
  117. package/tests/unit/integration/scenario-11-cross-holosphere-federation.test.js +410 -0
  118. package/tests/unit/integration/scenario-12-capability-federated-read.test.js +719 -0
  119. package/tests/unit/performance/benchmark.test.js +85 -0
  120. package/tests/unit/schema.test.js +213 -0
  121. package/tests/unit/spatial.test.js +158 -0
  122. package/tests/unit/storage.test.js +195 -0
  123. package/tests/unit/subscriptions.test.js +328 -0
  124. package/tests/unit/test-data-permanence-debug.js +197 -0
  125. package/tests/unit/test-data-permanence.js +340 -0
  126. package/tests/unit/test-key-persistence-fixed.js +148 -0
  127. package/tests/unit/test-key-persistence.js +172 -0
  128. package/tests/unit/test-relay-permanence.js +376 -0
  129. package/tests/unit/test-second-node.js +95 -0
  130. package/tests/unit/test-simple-write.js +89 -0
  131. package/vite.config.js +49 -0
  132. package/vitest.config.js +20 -0
  133. package/FEDERATION.md +0 -213
  134. package/compute.js +0 -298
  135. package/content.js +0 -980
  136. package/federation.js +0 -1234
  137. package/global.js +0 -736
  138. package/hexlib.js +0 -335
  139. package/hologram.js +0 -183
  140. package/holosphere-bundle.esm.js +0 -33256
  141. package/holosphere-bundle.js +0 -33287
  142. package/holosphere-bundle.min.js +0 -39
  143. package/holosphere.d.ts +0 -601
  144. package/holosphere.js +0 -719
  145. package/node.js +0 -246
  146. package/schema.js +0 -139
  147. package/utils.js +0 -302
@@ -0,0 +1,122 @@
1
+ /**
2
+ * IndexedDB storage adapter for browsers
3
+ * Provides persistent storage with good performance
4
+ */
5
+
6
+ import { PersistentStorage } from './persistent-storage.js';
7
+
8
+ export class IndexedDBStorage extends PersistentStorage {
9
+ constructor() {
10
+ super();
11
+ this.db = null;
12
+ this.dbName = null;
13
+ this.storeName = 'events';
14
+ }
15
+
16
+ async init(namespace) {
17
+ this.dbName = `holosphere_${namespace}`;
18
+
19
+ return new Promise((resolve, reject) => {
20
+ const request = indexedDB.open(this.dbName, 1);
21
+
22
+ request.onerror = () => reject(request.error);
23
+ request.onsuccess = () => {
24
+ this.db = request.result;
25
+ resolve();
26
+ };
27
+
28
+ request.onupgradeneeded = (event) => {
29
+ const db = event.target.result;
30
+
31
+ // Create object store if it doesn't exist
32
+ if (!db.objectStoreNames.contains(this.storeName)) {
33
+ const objectStore = db.createObjectStore(this.storeName, { keyPath: 'key' });
34
+ // Create index for prefix queries
35
+ objectStore.createIndex('key', 'key', { unique: false });
36
+ }
37
+ };
38
+ });
39
+ }
40
+
41
+ async put(key, event) {
42
+ return new Promise((resolve, reject) => {
43
+ const transaction = this.db.transaction([this.storeName], 'readwrite');
44
+ const objectStore = transaction.objectStore(this.storeName);
45
+
46
+ const request = objectStore.put({ key, event, timestamp: Date.now() });
47
+
48
+ request.onsuccess = () => resolve();
49
+ request.onerror = () => reject(request.error);
50
+ });
51
+ }
52
+
53
+ async get(key) {
54
+ return new Promise((resolve, reject) => {
55
+ const transaction = this.db.transaction([this.storeName], 'readonly');
56
+ const objectStore = transaction.objectStore(this.storeName);
57
+
58
+ const request = objectStore.get(key);
59
+
60
+ request.onsuccess = () => {
61
+ const result = request.result;
62
+ resolve(result ? result.event : null);
63
+ };
64
+ request.onerror = () => reject(request.error);
65
+ });
66
+ }
67
+
68
+ async getAll(prefix) {
69
+ return new Promise((resolve, reject) => {
70
+ const transaction = this.db.transaction([this.storeName], 'readonly');
71
+ const objectStore = transaction.objectStore(this.storeName);
72
+
73
+ const results = [];
74
+ const request = objectStore.openCursor();
75
+
76
+ request.onsuccess = (event) => {
77
+ const cursor = event.target.result;
78
+ if (cursor) {
79
+ if (cursor.value.key.startsWith(prefix)) {
80
+ results.push(cursor.value.event);
81
+ }
82
+ cursor.continue();
83
+ } else {
84
+ resolve(results);
85
+ }
86
+ };
87
+
88
+ request.onerror = () => reject(request.error);
89
+ });
90
+ }
91
+
92
+ async delete(key) {
93
+ return new Promise((resolve, reject) => {
94
+ const transaction = this.db.transaction([this.storeName], 'readwrite');
95
+ const objectStore = transaction.objectStore(this.storeName);
96
+
97
+ const request = objectStore.delete(key);
98
+
99
+ request.onsuccess = () => resolve();
100
+ request.onerror = () => reject(request.error);
101
+ });
102
+ }
103
+
104
+ async clear() {
105
+ return new Promise((resolve, reject) => {
106
+ const transaction = this.db.transaction([this.storeName], 'readwrite');
107
+ const objectStore = transaction.objectStore(this.storeName);
108
+
109
+ const request = objectStore.clear();
110
+
111
+ request.onsuccess = () => resolve();
112
+ request.onerror = () => reject(request.error);
113
+ });
114
+ }
115
+
116
+ async close() {
117
+ if (this.db) {
118
+ this.db.close();
119
+ this.db = null;
120
+ }
121
+ }
122
+ }
@@ -0,0 +1,76 @@
1
+ /**
2
+ * Simple Key Storage for Node.js
3
+ * Basic filesystem-based key management
4
+ *
5
+ * NOTE: This only works in Node.js, not browsers
6
+ * For browsers, keys are managed in localStorage
7
+ */
8
+
9
+ import fs from 'fs';
10
+ import path from 'path';
11
+ import os from 'os';
12
+
13
+ /**
14
+ * Get key storage directory
15
+ */
16
+ function getKeyDir() {
17
+ const configDir = process.env.XDG_CONFIG_HOME ||
18
+ (process.platform === 'win32'
19
+ ? path.join(process.env.APPDATA || path.join(os.homedir(), 'AppData', 'Roaming'))
20
+ : path.join(os.homedir(), '.config'));
21
+
22
+ return path.join(configDir, 'holosphere', 'keys');
23
+ }
24
+
25
+ /**
26
+ * Get key file path for an app
27
+ */
28
+ function getKeyPath(appName) {
29
+ const safeName = appName.replace(/[^a-zA-Z0-9-_]/g, '_');
30
+ return path.join(getKeyDir(), `${safeName}.key`);
31
+ }
32
+
33
+ /**
34
+ * Load private key
35
+ */
36
+ export function loadKey(appName) {
37
+ const keyPath = getKeyPath(appName);
38
+ if (fs.existsSync(keyPath)) {
39
+ const key = fs.readFileSync(keyPath, 'utf8').trim();
40
+ if (/^[0-9a-f]{64}$/i.test(key)) {
41
+ return key;
42
+ }
43
+ }
44
+ return null;
45
+ }
46
+
47
+ /**
48
+ * Save private key
49
+ */
50
+ export function saveKey(appName, privateKey) {
51
+ if (!/^[0-9a-f]{64}$/i.test(privateKey)) {
52
+ throw new Error('Invalid private key format');
53
+ }
54
+
55
+ const keyPath = getKeyPath(appName);
56
+ const dir = path.dirname(keyPath);
57
+
58
+ if (!fs.existsSync(dir)) {
59
+ fs.mkdirSync(dir, { recursive: true, mode: 0o700 });
60
+ }
61
+
62
+ fs.writeFileSync(keyPath, privateKey, { mode: 0o600 });
63
+ return keyPath;
64
+ }
65
+
66
+ /**
67
+ * Get or create key
68
+ */
69
+ export function getOrCreateKey(appName, generateFn) {
70
+ const existing = loadKey(appName);
71
+ if (existing) return existing;
72
+
73
+ const newKey = generateFn();
74
+ saveKey(appName, newKey);
75
+ return newKey;
76
+ }
@@ -0,0 +1,136 @@
1
+ /**
2
+ * Key Storage - Universal API
3
+ * Automatically uses Node.js or Browser implementation
4
+ */
5
+
6
+ /**
7
+ * Lazy-loaded Node.js modules
8
+ */
9
+ let nodeModules = null;
10
+
11
+ function getNodeModules() {
12
+ if (!nodeModules) {
13
+ try {
14
+ // Use globalThis to access Node.js built-ins
15
+ const fs = globalThis.require?.('fs') || eval('require')('fs');
16
+ const path = globalThis.require?.('path') || eval('require')('path');
17
+ const os = globalThis.require?.('os') || eval('require')('os');
18
+
19
+ const getKeyPath = (appName, keyDir) => {
20
+ const configDir = process.env.XDG_CONFIG_HOME ||
21
+ (process.platform === 'win32'
22
+ ? path.join(process.env.APPDATA || path.join(os.homedir(), 'AppData', 'Roaming'))
23
+ : path.join(os.homedir(), '.config'));
24
+ const dir = keyDir || path.join(configDir, 'holosphere', 'keys');
25
+ const safeName = appName.replace(/[^a-zA-Z0-9-_]/g, '_');
26
+ return path.join(dir, `${safeName}.key`);
27
+ };
28
+
29
+ nodeModules = { fs, path, os, getKeyPath };
30
+ } catch (error) {
31
+ console.warn('Failed to load Node.js modules:', error);
32
+ nodeModules = null;
33
+ }
34
+ }
35
+ return nodeModules;
36
+ }
37
+
38
+ /**
39
+ * Load private key from storage
40
+ * @param {string} appName - Application name
41
+ * @param {Object} options - Options
42
+ * @returns {string|null} Private key or null
43
+ */
44
+ export function loadPrivateKey(appName, options = {}) {
45
+ // Browser environment
46
+ if (typeof window !== 'undefined' && window.localStorage) {
47
+ try {
48
+ const key = window.localStorage.getItem(`holosphere_key_${appName}`);
49
+ if (key && /^[0-9a-f]{64}$/i.test(key)) return key;
50
+ return null;
51
+ } catch (error) {
52
+ return null;
53
+ }
54
+ }
55
+
56
+ // Node.js environment
57
+ const node = getNodeModules();
58
+ if (!node) return null;
59
+
60
+ try {
61
+ const keyPath = node.getKeyPath(appName, options.keyDir);
62
+ if (node.fs.existsSync(keyPath)) {
63
+ const key = node.fs.readFileSync(keyPath, 'utf8').trim();
64
+ if (/^[0-9a-f]{64}$/i.test(key)) return key;
65
+ }
66
+ return null;
67
+ } catch (error) {
68
+ return null;
69
+ }
70
+ }
71
+
72
+ /**
73
+ * Save private key to storage
74
+ * @param {string} appName - Application name
75
+ * @param {string} privateKey - Private key (hex)
76
+ * @param {Object} options - Options
77
+ * @returns {boolean} Success
78
+ */
79
+ export function savePrivateKey(appName, privateKey, options = {}) {
80
+ if (!/^[0-9a-f]{64}$/i.test(privateKey)) {
81
+ throw new Error('Invalid private key format');
82
+ }
83
+
84
+ // Browser environment
85
+ if (typeof window !== 'undefined' && window.localStorage) {
86
+ try {
87
+ window.localStorage.setItem(`holosphere_key_${appName}`, privateKey);
88
+ return true;
89
+ } catch (error) {
90
+ console.error('Failed to save key:', error);
91
+ return false;
92
+ }
93
+ }
94
+
95
+ // Node.js environment
96
+ const node = getNodeModules();
97
+ if (!node) return false;
98
+
99
+ try {
100
+ const keyPath = node.getKeyPath(appName, options.keyDir);
101
+ const dir = node.path.dirname(keyPath);
102
+
103
+ if (!node.fs.existsSync(dir)) {
104
+ node.fs.mkdirSync(dir, { recursive: true, mode: 0o700 });
105
+ }
106
+
107
+ node.fs.writeFileSync(keyPath, privateKey, { mode: 0o600 });
108
+ return true;
109
+ } catch (error) {
110
+ console.error('Failed to save key:', error);
111
+ return false;
112
+ }
113
+ }
114
+
115
+ /**
116
+ * Get or create private key for an app
117
+ * @param {string} appName - Application name
118
+ * @param {Function} generateFn - Function to generate new key
119
+ * @param {Object} options - Options
120
+ * @returns {string} Private key (hex)
121
+ */
122
+ export function getOrCreatePrivateKey(appName, generateFn, options = {}) {
123
+ const existingKey = loadPrivateKey(appName, options);
124
+ if (existingKey) {
125
+ return existingKey;
126
+ }
127
+
128
+ const newKey = generateFn();
129
+ const saved = savePrivateKey(appName, newKey, options);
130
+
131
+ if (!saved) {
132
+ console.warn('Failed to save private key - key will not persist across restarts');
133
+ }
134
+
135
+ return newKey;
136
+ }
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Memory-only storage adapter (fallback, no actual persistence)
3
+ */
4
+
5
+ import { PersistentStorage } from './persistent-storage.js';
6
+
7
+ export class MemoryStorage extends PersistentStorage {
8
+ constructor() {
9
+ super();
10
+ this.data = new Map();
11
+ this.namespace = null;
12
+ }
13
+
14
+ async init(namespace) {
15
+ this.namespace = namespace;
16
+ // Check if there's existing data for this namespace
17
+ if (!MemoryStorage._globalStore) {
18
+ MemoryStorage._globalStore = new Map();
19
+ }
20
+ if (!MemoryStorage._globalStore.has(namespace)) {
21
+ MemoryStorage._globalStore.set(namespace, new Map());
22
+ }
23
+ this.data = MemoryStorage._globalStore.get(namespace);
24
+ }
25
+
26
+ async put(key, event) {
27
+ this.data.set(key, JSON.parse(JSON.stringify(event))); // Deep clone
28
+ }
29
+
30
+ async get(key) {
31
+ const data = this.data.get(key);
32
+ return data ? JSON.parse(JSON.stringify(data)) : null; // Deep clone
33
+ }
34
+
35
+ async getAll(prefix) {
36
+ const results = [];
37
+ for (const [key, value] of this.data.entries()) {
38
+ if (key.startsWith(prefix)) {
39
+ results.push(JSON.parse(JSON.stringify(value)));
40
+ }
41
+ }
42
+ return results;
43
+ }
44
+
45
+ async delete(key) {
46
+ this.data.delete(key);
47
+ }
48
+
49
+ async clear() {
50
+ this.data.clear();
51
+ }
52
+
53
+ async close() {
54
+ // Nothing to close for memory storage
55
+ }
56
+ }
57
+
58
+ // Global store shared across instances with same namespace
59
+ MemoryStorage._globalStore = null;