@noosphere/registry 0.1.0-alpha.4 → 0.1.0-alpha.6
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/dist/index.cjs +41 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +14 -1
- package/dist/index.d.ts +14 -1
- package/dist/index.js +41 -2
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -53,8 +53,11 @@ var RegistryManager = class {
|
|
|
53
53
|
}
|
|
54
54
|
/**
|
|
55
55
|
* Load registry from local and optionally sync from remote
|
|
56
|
+
* Retries if 0 containers are loaded
|
|
56
57
|
*/
|
|
57
|
-
async load() {
|
|
58
|
+
async load(retryCount = 0) {
|
|
59
|
+
const maxRetries = 3;
|
|
60
|
+
const retryDelayMs = 5e3;
|
|
58
61
|
await this.loadLocal();
|
|
59
62
|
if (this.config.autoSync) {
|
|
60
63
|
try {
|
|
@@ -64,6 +67,18 @@ var RegistryManager = class {
|
|
|
64
67
|
console.log("Continuing with local registry only");
|
|
65
68
|
}
|
|
66
69
|
}
|
|
70
|
+
if (this.containers.size === 0 && retryCount < maxRetries) {
|
|
71
|
+
console.warn(`\u26A0\uFE0F Loaded 0 containers, attempting recovery (attempt ${retryCount + 1}/${maxRetries})...`);
|
|
72
|
+
await new Promise((resolve) => setTimeout(resolve, retryDelayMs));
|
|
73
|
+
try {
|
|
74
|
+
await this.forceSync();
|
|
75
|
+
} catch (error) {
|
|
76
|
+
console.warn("Force sync failed:", error);
|
|
77
|
+
}
|
|
78
|
+
if (this.containers.size === 0) {
|
|
79
|
+
return this.load(retryCount + 1);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
67
82
|
console.log(`\u2713 Loaded ${this.containers.size} containers and ${this.verifiers.size} verifiers`);
|
|
68
83
|
}
|
|
69
84
|
/**
|
|
@@ -98,6 +113,30 @@ var RegistryManager = class {
|
|
|
98
113
|
console.log("Registry cache is fresh, skipping sync");
|
|
99
114
|
return;
|
|
100
115
|
}
|
|
116
|
+
await this.fetchRemote();
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Force sync from remote, bypassing cache TTL
|
|
120
|
+
*/
|
|
121
|
+
async forceSync() {
|
|
122
|
+
console.log("Force syncing registry (bypassing cache)...");
|
|
123
|
+
this.lastSync = 0;
|
|
124
|
+
await this.fetchRemote();
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Reload registry completely (clear and reload from local + remote)
|
|
128
|
+
*/
|
|
129
|
+
async reload() {
|
|
130
|
+
console.log("Reloading registry...");
|
|
131
|
+
this.containers.clear();
|
|
132
|
+
this.verifiers.clear();
|
|
133
|
+
this.lastSync = 0;
|
|
134
|
+
await this.load();
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Fetch and merge remote registry
|
|
138
|
+
*/
|
|
139
|
+
async fetchRemote() {
|
|
101
140
|
console.log(`Syncing registry from ${this.config.remotePath}...`);
|
|
102
141
|
try {
|
|
103
142
|
const response = await (0, import_node_fetch.default)(this.config.remotePath);
|
|
@@ -115,7 +154,7 @@ var RegistryManager = class {
|
|
|
115
154
|
this.verifiers.set(id, metadata);
|
|
116
155
|
}
|
|
117
156
|
});
|
|
118
|
-
this.lastSync = now;
|
|
157
|
+
this.lastSync = Date.now();
|
|
119
158
|
console.log(`\u2713 Synced registry (version: ${registry.version})`);
|
|
120
159
|
} catch (error) {
|
|
121
160
|
console.error("Failed to sync remote registry:", error);
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/RegistryManager.ts"],"sourcesContent":["export { RegistryManager } from './RegistryManager';\nexport * from './types';\n","import fs from 'fs/promises';\nimport path from 'path';\nimport fetch from 'node-fetch';\nimport type { ContainerMetadata, VerifierMetadata, RegistryConfig, RegistryIndex } from './types';\n\nexport class RegistryManager {\n private containers = new Map<string, ContainerMetadata>();\n private verifiers = new Map<string, VerifierMetadata>();\n private config: Required<RegistryConfig>;\n private lastSync: number = 0;\n\n constructor(config: RegistryConfig = {}) {\n this.config = {\n localPath: config.localPath || path.join(process.cwd(), '.noosphere', 'registry.json'),\n remotePath:\n config.remotePath ||\n 'https://raw.githubusercontent.com/hpp-io/noosphere-registry/main/registry.json',\n autoSync: config.autoSync ?? true,\n cacheTTL: config.cacheTTL || 3600000, // 1 hour default\n };\n }\n\n /**\n * Load registry from local and optionally sync from remote\n */\n async load(): Promise<void> {\n // Load local registry\n await this.loadLocal();\n\n // Sync from remote if enabled\n if (this.config.autoSync) {\n try {\n await this.sync();\n } catch (error) {\n console.warn('Failed to sync remote registry:', error);\n console.log('Continuing with local registry only');\n }\n }\n\n console.log(`✓ Loaded ${this.containers.size} containers and ${this.verifiers.size} verifiers`);\n }\n\n /**\n * Load local registry file\n */\n private async loadLocal(): Promise<void> {\n try {\n const data = await fs.readFile(this.config.localPath, 'utf-8');\n const registry: RegistryIndex = JSON.parse(data);\n\n // Load containers\n Object.entries(registry.containers || {}).forEach(([id, metadata]) => {\n this.containers.set(id, metadata);\n });\n\n // Load verifiers\n Object.entries(registry.verifiers || {}).forEach(([id, metadata]) => {\n this.verifiers.set(id, metadata);\n });\n\n console.log(`✓ Loaded local registry from ${this.config.localPath}`);\n } catch (error: any) {\n if (error.code === 'ENOENT') {\n console.log('No local registry found, will create default');\n await this.createDefaultRegistry();\n } else {\n throw error;\n }\n }\n }\n\n /**\n * Sync registry from remote GitHub repository\n */\n async sync(): Promise<void> {\n const now = Date.now();\n\n // Check cache TTL\n if (now - this.lastSync < this.config.cacheTTL) {\n console.log('Registry cache is fresh, skipping sync');\n return;\n }\n\n console.log(`Syncing registry from ${this.config.remotePath}...`);\n\n try {\n const response = await fetch(this.config.remotePath);\n if (!response.ok) {\n throw new Error(`HTTP ${response.status}: ${response.statusText}`);\n }\n\n const registry = (await response.json()) as RegistryIndex;\n\n // Merge remote registry (remote entries are added, local overrides are kept)\n Object.entries(registry.containers || {}).forEach(([id, metadata]) => {\n if (!this.containers.has(id)) {\n // Only add if not already in local registry (local takes precedence)\n this.containers.set(id, metadata);\n }\n });\n\n Object.entries(registry.verifiers || {}).forEach(([id, metadata]) => {\n if (!this.verifiers.has(id)) {\n this.verifiers.set(id, metadata);\n }\n });\n\n this.lastSync = now;\n console.log(`✓ Synced registry (version: ${registry.version})`);\n } catch (error) {\n console.error('Failed to sync remote registry:', error);\n throw error;\n }\n }\n\n /**\n * Get container by ID\n */\n getContainer(id: string): ContainerMetadata | undefined {\n return this.containers.get(id);\n }\n\n /**\n * Get all containers\n */\n listContainers(): ContainerMetadata[] {\n return Array.from(this.containers.values()).filter((c) => c.statusCode === 'ACTIVE');\n }\n\n /**\n * Search containers by name or tag\n */\n searchContainers(query: string): ContainerMetadata[] {\n const lowerQuery = query.toLowerCase();\n return this.listContainers().filter(\n (c) =>\n c.name.toLowerCase().includes(lowerQuery) ||\n c.description?.toLowerCase().includes(lowerQuery) ||\n c.tags?.some((tag) => tag.toLowerCase().includes(lowerQuery))\n );\n }\n\n /**\n * Get verifier by contract address\n */\n getVerifier(verifierAddress: string): VerifierMetadata | undefined {\n return this.verifiers.get(verifierAddress);\n }\n\n /**\n * Get verifier by ID\n */\n getVerifierById(id: string): VerifierMetadata | undefined {\n return Array.from(this.verifiers.values()).find((v) => v.id === id);\n }\n\n /**\n * Get all verifiers\n */\n listVerifiers(): VerifierMetadata[] {\n return Array.from(this.verifiers.values()).filter((v) => v.statusCode === 'ACTIVE');\n }\n\n /**\n * Add custom container to local registry\n */\n async addContainer(container: ContainerMetadata): Promise<void> {\n this.containers.set(container.id, container);\n await this.saveLocal();\n console.log(`✓ Added container: ${container.name} (${container.id})`);\n }\n\n /**\n * Add custom verifier to local registry\n */\n async addVerifier(verifier: VerifierMetadata): Promise<void> {\n this.verifiers.set(verifier.verifierAddress, verifier);\n await this.saveLocal();\n console.log(`✓ Added verifier: ${verifier.name} (${verifier.verifierAddress})`);\n }\n\n /**\n * Remove container from local registry\n */\n async removeContainer(id: string): Promise<void> {\n if (this.containers.delete(id)) {\n await this.saveLocal();\n console.log(`✓ Removed container: ${id}`);\n }\n }\n\n /**\n * Remove verifier from local registry\n */\n async removeVerifier(verifierAddress: string): Promise<void> {\n if (this.verifiers.delete(verifierAddress)) {\n await this.saveLocal();\n console.log(`✓ Removed verifier: ${verifierAddress}`);\n }\n }\n\n /**\n * Save local registry to disk\n */\n private async saveLocal(): Promise<void> {\n const registry: RegistryIndex = {\n containers: Object.fromEntries(this.containers),\n verifiers: Object.fromEntries(this.verifiers),\n version: '1.0.0',\n updatedAt: new Date().toISOString(),\n };\n\n await fs.mkdir(path.dirname(this.config.localPath), { recursive: true });\n await fs.writeFile(this.config.localPath, JSON.stringify(registry, null, 2));\n }\n\n /**\n * Create default registry with example entries\n */\n private async createDefaultRegistry(): Promise<void> {\n // Create empty registry - will be populated from remote sync\n // No default containers or verifiers\n await this.saveLocal();\n console.log('✓ Created empty local registry (will sync from remote)');\n }\n\n /**\n * Get registry statistics\n */\n getStats(): {\n totalContainers: number;\n activeContainers: number;\n totalVerifiers: number;\n activeVerifiers: number;\n lastSync: string;\n } {\n return {\n totalContainers: this.containers.size,\n activeContainers: this.listContainers().length,\n totalVerifiers: this.verifiers.size,\n activeVerifiers: this.listVerifiers().length,\n lastSync: this.lastSync ? new Date(this.lastSync).toISOString() : 'Never',\n };\n }\n}\n"],"mappings":"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","names":["path","fs","fetch"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/RegistryManager.ts"],"sourcesContent":["export { RegistryManager } from './RegistryManager';\nexport * from './types';\n","import fs from 'fs/promises';\nimport path from 'path';\nimport fetch from 'node-fetch';\nimport type { ContainerMetadata, VerifierMetadata, RegistryConfig, RegistryIndex } from './types';\n\nexport class RegistryManager {\n private containers = new Map<string, ContainerMetadata>();\n private verifiers = new Map<string, VerifierMetadata>();\n private config: Required<RegistryConfig>;\n private lastSync: number = 0;\n\n constructor(config: RegistryConfig = {}) {\n this.config = {\n localPath: config.localPath || path.join(process.cwd(), '.noosphere', 'registry.json'),\n remotePath:\n config.remotePath ||\n 'https://raw.githubusercontent.com/hpp-io/noosphere-registry/main/registry.json',\n autoSync: config.autoSync ?? true,\n cacheTTL: config.cacheTTL || 3600000, // 1 hour default\n };\n }\n\n /**\n * Load registry from local and optionally sync from remote\n * Retries if 0 containers are loaded\n */\n async load(retryCount: number = 0): Promise<void> {\n const maxRetries = 3;\n const retryDelayMs = 5000;\n\n // Load local registry\n await this.loadLocal();\n\n // Sync from remote if enabled\n if (this.config.autoSync) {\n try {\n await this.sync();\n } catch (error) {\n console.warn('Failed to sync remote registry:', error);\n console.log('Continuing with local registry only');\n }\n }\n\n // Check if we have 0 containers and should retry\n if (this.containers.size === 0 && retryCount < maxRetries) {\n console.warn(`⚠️ Loaded 0 containers, attempting recovery (attempt ${retryCount + 1}/${maxRetries})...`);\n\n // Wait before retry\n await new Promise(resolve => setTimeout(resolve, retryDelayMs));\n\n // Try force sync from remote\n try {\n await this.forceSync();\n } catch (error) {\n console.warn('Force sync failed:', error);\n }\n\n // If still 0, recurse with incremented retry count\n if (this.containers.size === 0) {\n return this.load(retryCount + 1);\n }\n }\n\n console.log(`✓ Loaded ${this.containers.size} containers and ${this.verifiers.size} verifiers`);\n }\n\n /**\n * Load local registry file\n */\n private async loadLocal(): Promise<void> {\n try {\n const data = await fs.readFile(this.config.localPath, 'utf-8');\n const registry: RegistryIndex = JSON.parse(data);\n\n // Load containers\n Object.entries(registry.containers || {}).forEach(([id, metadata]) => {\n this.containers.set(id, metadata);\n });\n\n // Load verifiers\n Object.entries(registry.verifiers || {}).forEach(([id, metadata]) => {\n this.verifiers.set(id, metadata);\n });\n\n console.log(`✓ Loaded local registry from ${this.config.localPath}`);\n } catch (error: any) {\n if (error.code === 'ENOENT') {\n console.log('No local registry found, will create default');\n await this.createDefaultRegistry();\n } else {\n throw error;\n }\n }\n }\n\n /**\n * Sync registry from remote GitHub repository\n */\n async sync(): Promise<void> {\n const now = Date.now();\n\n // Check cache TTL\n if (now - this.lastSync < this.config.cacheTTL) {\n console.log('Registry cache is fresh, skipping sync');\n return;\n }\n\n await this.fetchRemote();\n }\n\n /**\n * Force sync from remote, bypassing cache TTL\n */\n async forceSync(): Promise<void> {\n console.log('Force syncing registry (bypassing cache)...');\n this.lastSync = 0; // Reset cache\n await this.fetchRemote();\n }\n\n /**\n * Reload registry completely (clear and reload from local + remote)\n */\n async reload(): Promise<void> {\n console.log('Reloading registry...');\n this.containers.clear();\n this.verifiers.clear();\n this.lastSync = 0;\n await this.load();\n }\n\n /**\n * Fetch and merge remote registry\n */\n private async fetchRemote(): Promise<void> {\n console.log(`Syncing registry from ${this.config.remotePath}...`);\n\n try {\n const response = await fetch(this.config.remotePath);\n if (!response.ok) {\n throw new Error(`HTTP ${response.status}: ${response.statusText}`);\n }\n\n const registry = (await response.json()) as RegistryIndex;\n\n // Merge remote registry (remote entries are added, local overrides are kept)\n Object.entries(registry.containers || {}).forEach(([id, metadata]) => {\n if (!this.containers.has(id)) {\n // Only add if not already in local registry (local takes precedence)\n this.containers.set(id, metadata);\n }\n });\n\n Object.entries(registry.verifiers || {}).forEach(([id, metadata]) => {\n if (!this.verifiers.has(id)) {\n this.verifiers.set(id, metadata);\n }\n });\n\n this.lastSync = Date.now();\n console.log(`✓ Synced registry (version: ${registry.version})`);\n } catch (error) {\n console.error('Failed to sync remote registry:', error);\n throw error;\n }\n }\n\n /**\n * Get container by ID\n */\n getContainer(id: string): ContainerMetadata | undefined {\n return this.containers.get(id);\n }\n\n /**\n * Get all containers\n */\n listContainers(): ContainerMetadata[] {\n return Array.from(this.containers.values()).filter((c) => c.statusCode === 'ACTIVE');\n }\n\n /**\n * Search containers by name or tag\n */\n searchContainers(query: string): ContainerMetadata[] {\n const lowerQuery = query.toLowerCase();\n return this.listContainers().filter(\n (c) =>\n c.name.toLowerCase().includes(lowerQuery) ||\n c.description?.toLowerCase().includes(lowerQuery) ||\n c.tags?.some((tag) => tag.toLowerCase().includes(lowerQuery))\n );\n }\n\n /**\n * Get verifier by contract address\n */\n getVerifier(verifierAddress: string): VerifierMetadata | undefined {\n return this.verifiers.get(verifierAddress);\n }\n\n /**\n * Get verifier by ID\n */\n getVerifierById(id: string): VerifierMetadata | undefined {\n return Array.from(this.verifiers.values()).find((v) => v.id === id);\n }\n\n /**\n * Get all verifiers\n */\n listVerifiers(): VerifierMetadata[] {\n return Array.from(this.verifiers.values()).filter((v) => v.statusCode === 'ACTIVE');\n }\n\n /**\n * Add custom container to local registry\n */\n async addContainer(container: ContainerMetadata): Promise<void> {\n this.containers.set(container.id, container);\n await this.saveLocal();\n console.log(`✓ Added container: ${container.name} (${container.id})`);\n }\n\n /**\n * Add custom verifier to local registry\n */\n async addVerifier(verifier: VerifierMetadata): Promise<void> {\n this.verifiers.set(verifier.verifierAddress, verifier);\n await this.saveLocal();\n console.log(`✓ Added verifier: ${verifier.name} (${verifier.verifierAddress})`);\n }\n\n /**\n * Remove container from local registry\n */\n async removeContainer(id: string): Promise<void> {\n if (this.containers.delete(id)) {\n await this.saveLocal();\n console.log(`✓ Removed container: ${id}`);\n }\n }\n\n /**\n * Remove verifier from local registry\n */\n async removeVerifier(verifierAddress: string): Promise<void> {\n if (this.verifiers.delete(verifierAddress)) {\n await this.saveLocal();\n console.log(`✓ Removed verifier: ${verifierAddress}`);\n }\n }\n\n /**\n * Save local registry to disk\n */\n private async saveLocal(): Promise<void> {\n const registry: RegistryIndex = {\n containers: Object.fromEntries(this.containers),\n verifiers: Object.fromEntries(this.verifiers),\n version: '1.0.0',\n updatedAt: new Date().toISOString(),\n };\n\n await fs.mkdir(path.dirname(this.config.localPath), { recursive: true });\n await fs.writeFile(this.config.localPath, JSON.stringify(registry, null, 2));\n }\n\n /**\n * Create default registry with example entries\n */\n private async createDefaultRegistry(): Promise<void> {\n // Create empty registry - will be populated from remote sync\n // No default containers or verifiers\n await this.saveLocal();\n console.log('✓ Created empty local registry (will sync from remote)');\n }\n\n /**\n * Get registry statistics\n */\n getStats(): {\n totalContainers: number;\n activeContainers: number;\n totalVerifiers: number;\n activeVerifiers: number;\n lastSync: string;\n } {\n return {\n totalContainers: this.containers.size,\n activeContainers: this.listContainers().length,\n totalVerifiers: this.verifiers.size,\n activeVerifiers: this.listVerifiers().length,\n lastSync: this.lastSync ? new Date(this.lastSync).toISOString() : 'Never',\n };\n }\n}\n"],"mappings":"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","names":["path","fs","fetch"]}
|
package/dist/index.d.mts
CHANGED
|
@@ -78,8 +78,9 @@ declare class RegistryManager {
|
|
|
78
78
|
constructor(config?: RegistryConfig);
|
|
79
79
|
/**
|
|
80
80
|
* Load registry from local and optionally sync from remote
|
|
81
|
+
* Retries if 0 containers are loaded
|
|
81
82
|
*/
|
|
82
|
-
load(): Promise<void>;
|
|
83
|
+
load(retryCount?: number): Promise<void>;
|
|
83
84
|
/**
|
|
84
85
|
* Load local registry file
|
|
85
86
|
*/
|
|
@@ -88,6 +89,18 @@ declare class RegistryManager {
|
|
|
88
89
|
* Sync registry from remote GitHub repository
|
|
89
90
|
*/
|
|
90
91
|
sync(): Promise<void>;
|
|
92
|
+
/**
|
|
93
|
+
* Force sync from remote, bypassing cache TTL
|
|
94
|
+
*/
|
|
95
|
+
forceSync(): Promise<void>;
|
|
96
|
+
/**
|
|
97
|
+
* Reload registry completely (clear and reload from local + remote)
|
|
98
|
+
*/
|
|
99
|
+
reload(): Promise<void>;
|
|
100
|
+
/**
|
|
101
|
+
* Fetch and merge remote registry
|
|
102
|
+
*/
|
|
103
|
+
private fetchRemote;
|
|
91
104
|
/**
|
|
92
105
|
* Get container by ID
|
|
93
106
|
*/
|
package/dist/index.d.ts
CHANGED
|
@@ -78,8 +78,9 @@ declare class RegistryManager {
|
|
|
78
78
|
constructor(config?: RegistryConfig);
|
|
79
79
|
/**
|
|
80
80
|
* Load registry from local and optionally sync from remote
|
|
81
|
+
* Retries if 0 containers are loaded
|
|
81
82
|
*/
|
|
82
|
-
load(): Promise<void>;
|
|
83
|
+
load(retryCount?: number): Promise<void>;
|
|
83
84
|
/**
|
|
84
85
|
* Load local registry file
|
|
85
86
|
*/
|
|
@@ -88,6 +89,18 @@ declare class RegistryManager {
|
|
|
88
89
|
* Sync registry from remote GitHub repository
|
|
89
90
|
*/
|
|
90
91
|
sync(): Promise<void>;
|
|
92
|
+
/**
|
|
93
|
+
* Force sync from remote, bypassing cache TTL
|
|
94
|
+
*/
|
|
95
|
+
forceSync(): Promise<void>;
|
|
96
|
+
/**
|
|
97
|
+
* Reload registry completely (clear and reload from local + remote)
|
|
98
|
+
*/
|
|
99
|
+
reload(): Promise<void>;
|
|
100
|
+
/**
|
|
101
|
+
* Fetch and merge remote registry
|
|
102
|
+
*/
|
|
103
|
+
private fetchRemote;
|
|
91
104
|
/**
|
|
92
105
|
* Get container by ID
|
|
93
106
|
*/
|
package/dist/index.js
CHANGED
|
@@ -17,8 +17,11 @@ var RegistryManager = class {
|
|
|
17
17
|
}
|
|
18
18
|
/**
|
|
19
19
|
* Load registry from local and optionally sync from remote
|
|
20
|
+
* Retries if 0 containers are loaded
|
|
20
21
|
*/
|
|
21
|
-
async load() {
|
|
22
|
+
async load(retryCount = 0) {
|
|
23
|
+
const maxRetries = 3;
|
|
24
|
+
const retryDelayMs = 5e3;
|
|
22
25
|
await this.loadLocal();
|
|
23
26
|
if (this.config.autoSync) {
|
|
24
27
|
try {
|
|
@@ -28,6 +31,18 @@ var RegistryManager = class {
|
|
|
28
31
|
console.log("Continuing with local registry only");
|
|
29
32
|
}
|
|
30
33
|
}
|
|
34
|
+
if (this.containers.size === 0 && retryCount < maxRetries) {
|
|
35
|
+
console.warn(`\u26A0\uFE0F Loaded 0 containers, attempting recovery (attempt ${retryCount + 1}/${maxRetries})...`);
|
|
36
|
+
await new Promise((resolve) => setTimeout(resolve, retryDelayMs));
|
|
37
|
+
try {
|
|
38
|
+
await this.forceSync();
|
|
39
|
+
} catch (error) {
|
|
40
|
+
console.warn("Force sync failed:", error);
|
|
41
|
+
}
|
|
42
|
+
if (this.containers.size === 0) {
|
|
43
|
+
return this.load(retryCount + 1);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
31
46
|
console.log(`\u2713 Loaded ${this.containers.size} containers and ${this.verifiers.size} verifiers`);
|
|
32
47
|
}
|
|
33
48
|
/**
|
|
@@ -62,6 +77,30 @@ var RegistryManager = class {
|
|
|
62
77
|
console.log("Registry cache is fresh, skipping sync");
|
|
63
78
|
return;
|
|
64
79
|
}
|
|
80
|
+
await this.fetchRemote();
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Force sync from remote, bypassing cache TTL
|
|
84
|
+
*/
|
|
85
|
+
async forceSync() {
|
|
86
|
+
console.log("Force syncing registry (bypassing cache)...");
|
|
87
|
+
this.lastSync = 0;
|
|
88
|
+
await this.fetchRemote();
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Reload registry completely (clear and reload from local + remote)
|
|
92
|
+
*/
|
|
93
|
+
async reload() {
|
|
94
|
+
console.log("Reloading registry...");
|
|
95
|
+
this.containers.clear();
|
|
96
|
+
this.verifiers.clear();
|
|
97
|
+
this.lastSync = 0;
|
|
98
|
+
await this.load();
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Fetch and merge remote registry
|
|
102
|
+
*/
|
|
103
|
+
async fetchRemote() {
|
|
65
104
|
console.log(`Syncing registry from ${this.config.remotePath}...`);
|
|
66
105
|
try {
|
|
67
106
|
const response = await fetch(this.config.remotePath);
|
|
@@ -79,7 +118,7 @@ var RegistryManager = class {
|
|
|
79
118
|
this.verifiers.set(id, metadata);
|
|
80
119
|
}
|
|
81
120
|
});
|
|
82
|
-
this.lastSync = now;
|
|
121
|
+
this.lastSync = Date.now();
|
|
83
122
|
console.log(`\u2713 Synced registry (version: ${registry.version})`);
|
|
84
123
|
} catch (error) {
|
|
85
124
|
console.error("Failed to sync remote registry:", error);
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/RegistryManager.ts"],"sourcesContent":["import fs from 'fs/promises';\nimport path from 'path';\nimport fetch from 'node-fetch';\nimport type { ContainerMetadata, VerifierMetadata, RegistryConfig, RegistryIndex } from './types';\n\nexport class RegistryManager {\n private containers = new Map<string, ContainerMetadata>();\n private verifiers = new Map<string, VerifierMetadata>();\n private config: Required<RegistryConfig>;\n private lastSync: number = 0;\n\n constructor(config: RegistryConfig = {}) {\n this.config = {\n localPath: config.localPath || path.join(process.cwd(), '.noosphere', 'registry.json'),\n remotePath:\n config.remotePath ||\n 'https://raw.githubusercontent.com/hpp-io/noosphere-registry/main/registry.json',\n autoSync: config.autoSync ?? true,\n cacheTTL: config.cacheTTL || 3600000, // 1 hour default\n };\n }\n\n /**\n * Load registry from local and optionally sync from remote\n */\n async load(): Promise<void> {\n // Load local registry\n await this.loadLocal();\n\n // Sync from remote if enabled\n if (this.config.autoSync) {\n try {\n await this.sync();\n } catch (error) {\n console.warn('Failed to sync remote registry:', error);\n console.log('Continuing with local registry only');\n }\n }\n\n console.log(`✓ Loaded ${this.containers.size} containers and ${this.verifiers.size} verifiers`);\n }\n\n /**\n * Load local registry file\n */\n private async loadLocal(): Promise<void> {\n try {\n const data = await fs.readFile(this.config.localPath, 'utf-8');\n const registry: RegistryIndex = JSON.parse(data);\n\n // Load containers\n Object.entries(registry.containers || {}).forEach(([id, metadata]) => {\n this.containers.set(id, metadata);\n });\n\n // Load verifiers\n Object.entries(registry.verifiers || {}).forEach(([id, metadata]) => {\n this.verifiers.set(id, metadata);\n });\n\n console.log(`✓ Loaded local registry from ${this.config.localPath}`);\n } catch (error: any) {\n if (error.code === 'ENOENT') {\n console.log('No local registry found, will create default');\n await this.createDefaultRegistry();\n } else {\n throw error;\n }\n }\n }\n\n /**\n * Sync registry from remote GitHub repository\n */\n async sync(): Promise<void> {\n const now = Date.now();\n\n // Check cache TTL\n if (now - this.lastSync < this.config.cacheTTL) {\n console.log('Registry cache is fresh, skipping sync');\n return;\n }\n\n console.log(`Syncing registry from ${this.config.remotePath}...`);\n\n try {\n const response = await fetch(this.config.remotePath);\n if (!response.ok) {\n throw new Error(`HTTP ${response.status}: ${response.statusText}`);\n }\n\n const registry = (await response.json()) as RegistryIndex;\n\n // Merge remote registry (remote entries are added, local overrides are kept)\n Object.entries(registry.containers || {}).forEach(([id, metadata]) => {\n if (!this.containers.has(id)) {\n // Only add if not already in local registry (local takes precedence)\n this.containers.set(id, metadata);\n }\n });\n\n Object.entries(registry.verifiers || {}).forEach(([id, metadata]) => {\n if (!this.verifiers.has(id)) {\n this.verifiers.set(id, metadata);\n }\n });\n\n this.lastSync = now;\n console.log(`✓ Synced registry (version: ${registry.version})`);\n } catch (error) {\n console.error('Failed to sync remote registry:', error);\n throw error;\n }\n }\n\n /**\n * Get container by ID\n */\n getContainer(id: string): ContainerMetadata | undefined {\n return this.containers.get(id);\n }\n\n /**\n * Get all containers\n */\n listContainers(): ContainerMetadata[] {\n return Array.from(this.containers.values()).filter((c) => c.statusCode === 'ACTIVE');\n }\n\n /**\n * Search containers by name or tag\n */\n searchContainers(query: string): ContainerMetadata[] {\n const lowerQuery = query.toLowerCase();\n return this.listContainers().filter(\n (c) =>\n c.name.toLowerCase().includes(lowerQuery) ||\n c.description?.toLowerCase().includes(lowerQuery) ||\n c.tags?.some((tag) => tag.toLowerCase().includes(lowerQuery))\n );\n }\n\n /**\n * Get verifier by contract address\n */\n getVerifier(verifierAddress: string): VerifierMetadata | undefined {\n return this.verifiers.get(verifierAddress);\n }\n\n /**\n * Get verifier by ID\n */\n getVerifierById(id: string): VerifierMetadata | undefined {\n return Array.from(this.verifiers.values()).find((v) => v.id === id);\n }\n\n /**\n * Get all verifiers\n */\n listVerifiers(): VerifierMetadata[] {\n return Array.from(this.verifiers.values()).filter((v) => v.statusCode === 'ACTIVE');\n }\n\n /**\n * Add custom container to local registry\n */\n async addContainer(container: ContainerMetadata): Promise<void> {\n this.containers.set(container.id, container);\n await this.saveLocal();\n console.log(`✓ Added container: ${container.name} (${container.id})`);\n }\n\n /**\n * Add custom verifier to local registry\n */\n async addVerifier(verifier: VerifierMetadata): Promise<void> {\n this.verifiers.set(verifier.verifierAddress, verifier);\n await this.saveLocal();\n console.log(`✓ Added verifier: ${verifier.name} (${verifier.verifierAddress})`);\n }\n\n /**\n * Remove container from local registry\n */\n async removeContainer(id: string): Promise<void> {\n if (this.containers.delete(id)) {\n await this.saveLocal();\n console.log(`✓ Removed container: ${id}`);\n }\n }\n\n /**\n * Remove verifier from local registry\n */\n async removeVerifier(verifierAddress: string): Promise<void> {\n if (this.verifiers.delete(verifierAddress)) {\n await this.saveLocal();\n console.log(`✓ Removed verifier: ${verifierAddress}`);\n }\n }\n\n /**\n * Save local registry to disk\n */\n private async saveLocal(): Promise<void> {\n const registry: RegistryIndex = {\n containers: Object.fromEntries(this.containers),\n verifiers: Object.fromEntries(this.verifiers),\n version: '1.0.0',\n updatedAt: new Date().toISOString(),\n };\n\n await fs.mkdir(path.dirname(this.config.localPath), { recursive: true });\n await fs.writeFile(this.config.localPath, JSON.stringify(registry, null, 2));\n }\n\n /**\n * Create default registry with example entries\n */\n private async createDefaultRegistry(): Promise<void> {\n // Create empty registry - will be populated from remote sync\n // No default containers or verifiers\n await this.saveLocal();\n console.log('✓ Created empty local registry (will sync from remote)');\n }\n\n /**\n * Get registry statistics\n */\n getStats(): {\n totalContainers: number;\n activeContainers: number;\n totalVerifiers: number;\n activeVerifiers: number;\n lastSync: string;\n } {\n return {\n totalContainers: this.containers.size,\n activeContainers: this.listContainers().length,\n totalVerifiers: this.verifiers.size,\n activeVerifiers: this.listVerifiers().length,\n lastSync: this.lastSync ? new Date(this.lastSync).toISOString() : 'Never',\n };\n }\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/RegistryManager.ts"],"sourcesContent":["import fs from 'fs/promises';\nimport path from 'path';\nimport fetch from 'node-fetch';\nimport type { ContainerMetadata, VerifierMetadata, RegistryConfig, RegistryIndex } from './types';\n\nexport class RegistryManager {\n private containers = new Map<string, ContainerMetadata>();\n private verifiers = new Map<string, VerifierMetadata>();\n private config: Required<RegistryConfig>;\n private lastSync: number = 0;\n\n constructor(config: RegistryConfig = {}) {\n this.config = {\n localPath: config.localPath || path.join(process.cwd(), '.noosphere', 'registry.json'),\n remotePath:\n config.remotePath ||\n 'https://raw.githubusercontent.com/hpp-io/noosphere-registry/main/registry.json',\n autoSync: config.autoSync ?? true,\n cacheTTL: config.cacheTTL || 3600000, // 1 hour default\n };\n }\n\n /**\n * Load registry from local and optionally sync from remote\n * Retries if 0 containers are loaded\n */\n async load(retryCount: number = 0): Promise<void> {\n const maxRetries = 3;\n const retryDelayMs = 5000;\n\n // Load local registry\n await this.loadLocal();\n\n // Sync from remote if enabled\n if (this.config.autoSync) {\n try {\n await this.sync();\n } catch (error) {\n console.warn('Failed to sync remote registry:', error);\n console.log('Continuing with local registry only');\n }\n }\n\n // Check if we have 0 containers and should retry\n if (this.containers.size === 0 && retryCount < maxRetries) {\n console.warn(`⚠️ Loaded 0 containers, attempting recovery (attempt ${retryCount + 1}/${maxRetries})...`);\n\n // Wait before retry\n await new Promise(resolve => setTimeout(resolve, retryDelayMs));\n\n // Try force sync from remote\n try {\n await this.forceSync();\n } catch (error) {\n console.warn('Force sync failed:', error);\n }\n\n // If still 0, recurse with incremented retry count\n if (this.containers.size === 0) {\n return this.load(retryCount + 1);\n }\n }\n\n console.log(`✓ Loaded ${this.containers.size} containers and ${this.verifiers.size} verifiers`);\n }\n\n /**\n * Load local registry file\n */\n private async loadLocal(): Promise<void> {\n try {\n const data = await fs.readFile(this.config.localPath, 'utf-8');\n const registry: RegistryIndex = JSON.parse(data);\n\n // Load containers\n Object.entries(registry.containers || {}).forEach(([id, metadata]) => {\n this.containers.set(id, metadata);\n });\n\n // Load verifiers\n Object.entries(registry.verifiers || {}).forEach(([id, metadata]) => {\n this.verifiers.set(id, metadata);\n });\n\n console.log(`✓ Loaded local registry from ${this.config.localPath}`);\n } catch (error: any) {\n if (error.code === 'ENOENT') {\n console.log('No local registry found, will create default');\n await this.createDefaultRegistry();\n } else {\n throw error;\n }\n }\n }\n\n /**\n * Sync registry from remote GitHub repository\n */\n async sync(): Promise<void> {\n const now = Date.now();\n\n // Check cache TTL\n if (now - this.lastSync < this.config.cacheTTL) {\n console.log('Registry cache is fresh, skipping sync');\n return;\n }\n\n await this.fetchRemote();\n }\n\n /**\n * Force sync from remote, bypassing cache TTL\n */\n async forceSync(): Promise<void> {\n console.log('Force syncing registry (bypassing cache)...');\n this.lastSync = 0; // Reset cache\n await this.fetchRemote();\n }\n\n /**\n * Reload registry completely (clear and reload from local + remote)\n */\n async reload(): Promise<void> {\n console.log('Reloading registry...');\n this.containers.clear();\n this.verifiers.clear();\n this.lastSync = 0;\n await this.load();\n }\n\n /**\n * Fetch and merge remote registry\n */\n private async fetchRemote(): Promise<void> {\n console.log(`Syncing registry from ${this.config.remotePath}...`);\n\n try {\n const response = await fetch(this.config.remotePath);\n if (!response.ok) {\n throw new Error(`HTTP ${response.status}: ${response.statusText}`);\n }\n\n const registry = (await response.json()) as RegistryIndex;\n\n // Merge remote registry (remote entries are added, local overrides are kept)\n Object.entries(registry.containers || {}).forEach(([id, metadata]) => {\n if (!this.containers.has(id)) {\n // Only add if not already in local registry (local takes precedence)\n this.containers.set(id, metadata);\n }\n });\n\n Object.entries(registry.verifiers || {}).forEach(([id, metadata]) => {\n if (!this.verifiers.has(id)) {\n this.verifiers.set(id, metadata);\n }\n });\n\n this.lastSync = Date.now();\n console.log(`✓ Synced registry (version: ${registry.version})`);\n } catch (error) {\n console.error('Failed to sync remote registry:', error);\n throw error;\n }\n }\n\n /**\n * Get container by ID\n */\n getContainer(id: string): ContainerMetadata | undefined {\n return this.containers.get(id);\n }\n\n /**\n * Get all containers\n */\n listContainers(): ContainerMetadata[] {\n return Array.from(this.containers.values()).filter((c) => c.statusCode === 'ACTIVE');\n }\n\n /**\n * Search containers by name or tag\n */\n searchContainers(query: string): ContainerMetadata[] {\n const lowerQuery = query.toLowerCase();\n return this.listContainers().filter(\n (c) =>\n c.name.toLowerCase().includes(lowerQuery) ||\n c.description?.toLowerCase().includes(lowerQuery) ||\n c.tags?.some((tag) => tag.toLowerCase().includes(lowerQuery))\n );\n }\n\n /**\n * Get verifier by contract address\n */\n getVerifier(verifierAddress: string): VerifierMetadata | undefined {\n return this.verifiers.get(verifierAddress);\n }\n\n /**\n * Get verifier by ID\n */\n getVerifierById(id: string): VerifierMetadata | undefined {\n return Array.from(this.verifiers.values()).find((v) => v.id === id);\n }\n\n /**\n * Get all verifiers\n */\n listVerifiers(): VerifierMetadata[] {\n return Array.from(this.verifiers.values()).filter((v) => v.statusCode === 'ACTIVE');\n }\n\n /**\n * Add custom container to local registry\n */\n async addContainer(container: ContainerMetadata): Promise<void> {\n this.containers.set(container.id, container);\n await this.saveLocal();\n console.log(`✓ Added container: ${container.name} (${container.id})`);\n }\n\n /**\n * Add custom verifier to local registry\n */\n async addVerifier(verifier: VerifierMetadata): Promise<void> {\n this.verifiers.set(verifier.verifierAddress, verifier);\n await this.saveLocal();\n console.log(`✓ Added verifier: ${verifier.name} (${verifier.verifierAddress})`);\n }\n\n /**\n * Remove container from local registry\n */\n async removeContainer(id: string): Promise<void> {\n if (this.containers.delete(id)) {\n await this.saveLocal();\n console.log(`✓ Removed container: ${id}`);\n }\n }\n\n /**\n * Remove verifier from local registry\n */\n async removeVerifier(verifierAddress: string): Promise<void> {\n if (this.verifiers.delete(verifierAddress)) {\n await this.saveLocal();\n console.log(`✓ Removed verifier: ${verifierAddress}`);\n }\n }\n\n /**\n * Save local registry to disk\n */\n private async saveLocal(): Promise<void> {\n const registry: RegistryIndex = {\n containers: Object.fromEntries(this.containers),\n verifiers: Object.fromEntries(this.verifiers),\n version: '1.0.0',\n updatedAt: new Date().toISOString(),\n };\n\n await fs.mkdir(path.dirname(this.config.localPath), { recursive: true });\n await fs.writeFile(this.config.localPath, JSON.stringify(registry, null, 2));\n }\n\n /**\n * Create default registry with example entries\n */\n private async createDefaultRegistry(): Promise<void> {\n // Create empty registry - will be populated from remote sync\n // No default containers or verifiers\n await this.saveLocal();\n console.log('✓ Created empty local registry (will sync from remote)');\n }\n\n /**\n * Get registry statistics\n */\n getStats(): {\n totalContainers: number;\n activeContainers: number;\n totalVerifiers: number;\n activeVerifiers: number;\n lastSync: string;\n } {\n return {\n totalContainers: this.containers.size,\n activeContainers: this.listContainers().length,\n totalVerifiers: this.verifiers.size,\n activeVerifiers: this.listVerifiers().length,\n lastSync: this.lastSync ? new Date(this.lastSync).toISOString() : 'Never',\n };\n }\n}\n"],"mappings":"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","names":[]}
|