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,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;
|