resourcexjs 2.14.1 → 2.15.0

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/arp.js CHANGED
@@ -526,7 +526,7 @@ class ARP {
526
526
  function createARP(config) {
527
527
  return new ARP(config);
528
528
  }
529
- var VERSION = "2.14.1";
529
+ var VERSION = "2.15.0";
530
530
  export {
531
531
  textSemantic,
532
532
  httpsTransport,
@@ -546,4 +546,4 @@ export {
546
546
  ARP
547
547
  };
548
548
 
549
- //# debugId=599016E14854407A64756E2164756E21
549
+ //# debugId=DAE75374296EF27C64756E2164756E21
package/dist/arp.js.map CHANGED
@@ -2,9 +2,9 @@
2
2
  "version": 3,
3
3
  "sources": ["../../arp/dist/index.js"],
4
4
  "sourcesContent": [
5
- "// src/errors.ts\nclass ARPError extends Error {\n constructor(message, options) {\n super(message, options);\n this.name = \"ARPError\";\n }\n}\n\nclass ParseError extends ARPError {\n url;\n constructor(message, url) {\n super(message);\n this.url = url;\n this.name = \"ParseError\";\n }\n}\n\nclass TransportError extends ARPError {\n transport;\n constructor(message, transport, options) {\n super(message, options);\n this.transport = transport;\n this.name = \"TransportError\";\n }\n}\n\nclass SemanticError extends ARPError {\n semantic;\n constructor(message, semantic, options) {\n super(message, options);\n this.semantic = semantic;\n this.name = \"SemanticError\";\n }\n}\n\n// src/ARL.ts\nclass ARL {\n semantic;\n transport;\n location;\n resolver;\n constructor(semantic, transport, location, resolver) {\n this.semantic = semantic;\n this.transport = transport;\n this.location = location;\n this.resolver = resolver;\n }\n createContext(params) {\n return {\n url: this.toString(),\n semantic: this.semantic,\n transport: this.transport,\n location: this.location,\n timestamp: new Date,\n params\n };\n }\n async resolve(params) {\n const transport = this.resolver.getTransportHandler(this.transport);\n const semantic = this.resolver.getSemanticHandler(this.semantic);\n const context = this.createContext(params);\n return semantic.resolve(transport, this.location, context);\n }\n async deposit(data, params) {\n const transport = this.resolver.getTransportHandler(this.transport);\n const semantic = this.resolver.getSemanticHandler(this.semantic);\n const context = this.createContext(params);\n if (!semantic.deposit) {\n throw new SemanticError(`Semantic \"${semantic.name}\" does not support deposit operation`, this.semantic);\n }\n await semantic.deposit(transport, this.location, data, context);\n }\n async exists() {\n const transport = this.resolver.getTransportHandler(this.transport);\n const semantic = this.resolver.getSemanticHandler(this.semantic);\n const context = this.createContext();\n if (semantic.exists) {\n return semantic.exists(transport, this.location, context);\n }\n return transport.exists(this.location);\n }\n async delete() {\n const transport = this.resolver.getTransportHandler(this.transport);\n const semantic = this.resolver.getSemanticHandler(this.semantic);\n const context = this.createContext();\n if (semantic.delete) {\n return semantic.delete(transport, this.location, context);\n }\n await transport.delete(this.location);\n }\n async list(options) {\n const transport = this.resolver.getTransportHandler(this.transport);\n if (!transport.list) {\n throw new TransportError(`Transport \"${transport.name}\" does not support list operation`, this.transport);\n }\n return transport.list(this.location, options);\n }\n async mkdir() {\n const transport = this.resolver.getTransportHandler(this.transport);\n if (!transport.mkdir) {\n throw new TransportError(`Transport \"${transport.name}\" does not support mkdir operation`, this.transport);\n }\n await transport.mkdir(this.location);\n }\n toString() {\n return `arp:${this.semantic}:${this.transport}://${this.location}`;\n }\n}\n\n// src/semantic/binary.ts\nfunction toBuffer(data) {\n if (Buffer.isBuffer(data)) {\n return data;\n }\n if (data instanceof Uint8Array) {\n return Buffer.from(data);\n }\n if (data instanceof ArrayBuffer) {\n return Buffer.from(data);\n }\n if (Array.isArray(data)) {\n return Buffer.from(data);\n }\n throw new SemanticError(`Unsupported binary input type`, \"binary\");\n}\n\nclass BinarySemanticHandler {\n name = \"binary\";\n async resolve(transport, location, context) {\n const result = await transport.get(location, context.params);\n const meta = {\n url: context.url,\n semantic: context.semantic,\n transport: context.transport,\n location: context.location,\n size: result.metadata?.size ?? result.content.length,\n resolvedAt: context.timestamp.toISOString(),\n type: result.metadata?.type\n };\n return {\n type: \"binary\",\n content: result.content,\n meta\n };\n }\n async deposit(transport, location, data, context) {\n const buffer = toBuffer(data);\n try {\n await transport.set(location, buffer, context.params);\n } catch (error) {\n throw new SemanticError(`Failed to deposit binary to \"${location}\": ${error.message}`, this.name, { cause: error });\n }\n }\n async exists(transport, location, _context) {\n return transport.exists(location);\n }\n async delete(transport, location, _context) {\n try {\n await transport.delete(location);\n } catch (error) {\n throw new SemanticError(`Failed to delete \"${location}\": ${error.message}`, this.name, { cause: error });\n }\n }\n}\nvar binarySemantic = new BinarySemanticHandler;\n// src/semantic/text.ts\nclass TextSemanticHandler {\n name = \"text\";\n async resolve(transport, location, context) {\n const result = await transport.get(location, context.params);\n if (result.metadata?.type === \"directory\") {\n const meta2 = {\n url: context.url,\n semantic: context.semantic,\n transport: context.transport,\n location: context.location,\n size: result.content.length,\n encoding: \"utf-8\",\n mimeType: \"application/json\",\n resolvedAt: context.timestamp.toISOString(),\n type: \"directory\"\n };\n return {\n type: \"text\",\n content: result.content.toString(\"utf-8\"),\n meta: meta2\n };\n }\n const text = result.content.toString(\"utf-8\");\n const meta = {\n url: context.url,\n semantic: context.semantic,\n transport: context.transport,\n location: context.location,\n size: result.metadata?.size ?? result.content.length,\n encoding: \"utf-8\",\n mimeType: \"text/plain\",\n resolvedAt: context.timestamp.toISOString(),\n type: \"file\"\n };\n return {\n type: \"text\",\n content: text,\n meta\n };\n }\n async deposit(transport, location, data, context) {\n const buffer = Buffer.from(data, \"utf-8\");\n try {\n await transport.set(location, buffer, context.params);\n } catch (error) {\n throw new SemanticError(`Failed to deposit text to \"${location}\": ${error.message}`, this.name, { cause: error });\n }\n }\n async exists(transport, location, _context) {\n return transport.exists(location);\n }\n async delete(transport, location, _context) {\n try {\n await transport.delete(location);\n } catch (error) {\n throw new SemanticError(`Failed to delete \"${location}\": ${error.message}`, this.name, { cause: error });\n }\n }\n}\nvar textSemantic = new TextSemanticHandler;\n// src/transport/file.ts\nimport { access, mkdir, readdir, readFile, rm, stat, writeFile } from \"node:fs/promises\";\nimport { dirname, join, resolve } from \"node:path\";\nclass FileTransportHandler {\n name = \"file\";\n resolvePath(location) {\n return resolve(process.cwd(), location);\n }\n async get(location, params) {\n const filePath = this.resolvePath(location);\n try {\n const stats = await stat(filePath);\n if (stats.isDirectory()) {\n return this.getDirectory(filePath, stats, params);\n } else {\n return this.getFile(filePath, stats);\n }\n } catch (error) {\n const err = error;\n throw new TransportError(`File get error: ${err.code} - ${filePath}`, this.name, {\n cause: err\n });\n }\n }\n async getFile(filePath, stats) {\n const content = await readFile(filePath);\n return {\n content,\n metadata: {\n type: \"file\",\n size: Number(stats.size),\n modifiedAt: stats.mtime\n }\n };\n }\n async getDirectory(dirPath, stats, params) {\n const recursive = params?.recursive === \"true\";\n const pattern = params?.pattern;\n let entries;\n if (recursive) {\n entries = await this.listRecursive(dirPath, dirPath);\n } else {\n entries = await readdir(dirPath);\n }\n if (pattern) {\n entries = this.filterByPattern(entries, pattern);\n }\n const content = Buffer.from(JSON.stringify(entries));\n return {\n content,\n metadata: {\n type: \"directory\",\n modifiedAt: stats.mtime\n }\n };\n }\n async listRecursive(basePath, currentPath) {\n const entries = await readdir(currentPath, { withFileTypes: true });\n const results = [];\n for (const entry of entries) {\n const fullPath = join(currentPath, entry.name);\n const relativePath = fullPath.substring(basePath.length + 1);\n if (entry.isDirectory()) {\n const subEntries = await this.listRecursive(basePath, fullPath);\n results.push(...subEntries);\n } else {\n results.push(relativePath);\n }\n }\n return results;\n }\n filterByPattern(entries, pattern) {\n const regexPattern = pattern.replace(/\\./g, \"\\\\.\").replace(/\\*/g, \".*\").replace(/\\?/g, \".\");\n const regex = new RegExp(`^${regexPattern}$`);\n return entries.filter((entry) => {\n const filename = entry.split(\"/\").pop() || entry;\n return regex.test(filename);\n });\n }\n async set(location, content, _params) {\n const filePath = this.resolvePath(location);\n try {\n await mkdir(dirname(filePath), { recursive: true });\n await writeFile(filePath, content);\n } catch (error) {\n const err = error;\n throw new TransportError(`File set error: ${err.code} - ${filePath}`, this.name, {\n cause: err\n });\n }\n }\n async exists(location) {\n const filePath = this.resolvePath(location);\n try {\n await access(filePath);\n return true;\n } catch {\n return false;\n }\n }\n async delete(location) {\n const filePath = this.resolvePath(location);\n try {\n await rm(filePath, { recursive: true });\n } catch (error) {\n const err = error;\n if (err.code === \"ENOENT\") {\n return;\n }\n throw new TransportError(`File delete error: ${err.code} - ${filePath}`, this.name, {\n cause: err\n });\n }\n }\n async list(location, options) {\n const dirPath = this.resolvePath(location);\n try {\n let entries;\n if (options?.recursive) {\n entries = await this.listRecursive(dirPath, dirPath);\n } else {\n entries = await readdir(dirPath);\n }\n if (options?.pattern) {\n entries = this.filterByPattern(entries, options.pattern);\n }\n return entries;\n } catch (error) {\n const err = error;\n throw new TransportError(`File list error: ${err.code} - ${dirPath}`, this.name, {\n cause: err\n });\n }\n }\n async mkdir(location) {\n const dirPath = this.resolvePath(location);\n try {\n await mkdir(dirPath, { recursive: true });\n } catch (error) {\n const err = error;\n throw new TransportError(`File mkdir error: ${err.code} - ${dirPath}`, this.name, {\n cause: err\n });\n }\n }\n}\nvar fileTransport = new FileTransportHandler;\n// src/transport/http.ts\nclass HttpTransportHandler {\n name;\n protocol;\n constructor(protocol = \"https\") {\n this.protocol = protocol;\n this.name = protocol;\n }\n async get(location, params) {\n const url = this.buildUrl(location, params);\n try {\n const response = await fetch(url);\n if (!response.ok) {\n throw new TransportError(`HTTP ${response.status}: ${response.statusText} - ${url}`, this.name);\n }\n const arrayBuffer = await response.arrayBuffer();\n const content = Buffer.from(arrayBuffer);\n const contentType = response.headers.get(\"content-type\");\n const contentLength = response.headers.get(\"content-length\");\n const lastModified = response.headers.get(\"last-modified\");\n return {\n content,\n metadata: {\n type: \"file\",\n size: contentLength ? parseInt(contentLength, 10) : content.length,\n modifiedAt: lastModified ? new Date(lastModified) : undefined,\n contentType\n }\n };\n } catch (error) {\n if (error instanceof TransportError) {\n throw error;\n }\n throw new TransportError(`Network error: ${url}`, this.name, {\n cause: error\n });\n }\n }\n buildUrl(location, params) {\n const url = new URL(`${this.protocol}://${location}`);\n if (params) {\n for (const [key, value] of Object.entries(params)) {\n url.searchParams.set(key, value);\n }\n }\n return url.toString();\n }\n async set(_location, _content, _params) {\n throw new TransportError(\"HTTP transport is read-only, set not supported\", this.name);\n }\n async exists(location) {\n const url = `${this.protocol}://${location}`;\n try {\n const response = await fetch(url, { method: \"HEAD\" });\n return response.ok;\n } catch {\n return false;\n }\n }\n async delete(_location) {\n throw new TransportError(\"HTTP transport is read-only, delete not supported\", this.name);\n }\n}\nvar httpsTransport = new HttpTransportHandler(\"https\");\nvar httpTransport = new HttpTransportHandler(\"http\");\n// src/ARP.ts\nclass ARP {\n transports;\n semantics;\n constructor(config = {}) {\n this.transports = new Map;\n this.semantics = new Map;\n const defaultTransports = [fileTransport, httpTransport, httpsTransport];\n const defaultSemantics = [textSemantic, binarySemantic];\n for (const handler of defaultTransports) {\n this.transports.set(handler.name, handler);\n }\n for (const handler of defaultSemantics) {\n this.semantics.set(handler.name, handler);\n }\n if (config.transports) {\n for (const handler of config.transports) {\n this.transports.set(handler.name, handler);\n }\n }\n if (config.semantics) {\n for (const handler of config.semantics) {\n this.semantics.set(handler.name, handler);\n }\n }\n }\n registerTransport(handler) {\n this.transports.set(handler.name, handler);\n }\n registerSemantic(handler) {\n this.semantics.set(handler.name, handler);\n }\n getTransportHandler(name) {\n const handler = this.transports.get(name);\n if (!handler) {\n throw new TransportError(`Unsupported transport type: ${name}`, name);\n }\n return handler;\n }\n getSemanticHandler(name) {\n const handler = this.semantics.get(name);\n if (!handler) {\n throw new SemanticError(`Unsupported semantic type: ${name}`, name);\n }\n return handler;\n }\n parse(url) {\n if (!url.startsWith(\"arp:\")) {\n throw new ParseError(`Invalid ARP URL: must start with \"arp:\"`, url);\n }\n const content = url.substring(4);\n const separatorIndex = content.indexOf(\"://\");\n if (separatorIndex === -1) {\n throw new ParseError(`Invalid ARP URL: missing \"://\"`, url);\n }\n const typePart = content.substring(0, separatorIndex);\n const location = content.substring(separatorIndex + 3);\n const colonIndex = typePart.indexOf(\":\");\n if (colonIndex === -1) {\n throw new ParseError(`Invalid ARP URL: must have exactly 2 types (semantic:transport)`, url);\n }\n const semantic = typePart.substring(0, colonIndex);\n const transport = typePart.substring(colonIndex + 1);\n if (!semantic) {\n throw new ParseError(`Invalid ARP URL: semantic type cannot be empty`, url);\n }\n if (!transport) {\n throw new ParseError(`Invalid ARP URL: transport type cannot be empty`, url);\n }\n if (!location) {\n throw new ParseError(`Invalid ARP URL: location cannot be empty`, url);\n }\n this.getTransportHandler(transport);\n this.getSemanticHandler(semantic);\n return new ARL(semantic, transport, location, this);\n }\n}\nfunction createARP(config) {\n return new ARP(config);\n}\n\n// src/index.ts\nvar VERSION = \"2.14.1\";\nexport {\n textSemantic,\n httpsTransport,\n httpTransport,\n fileTransport,\n createARP,\n binarySemantic,\n VERSION,\n TransportError,\n TextSemanticHandler,\n SemanticError,\n ParseError,\n HttpTransportHandler,\n FileTransportHandler,\n BinarySemanticHandler,\n ARPError,\n ARP\n};\n\n//# debugId=4F3FF7105E65FD8E64756E2164756E21\n"
5
+ "// src/errors.ts\nclass ARPError extends Error {\n constructor(message, options) {\n super(message, options);\n this.name = \"ARPError\";\n }\n}\n\nclass ParseError extends ARPError {\n url;\n constructor(message, url) {\n super(message);\n this.url = url;\n this.name = \"ParseError\";\n }\n}\n\nclass TransportError extends ARPError {\n transport;\n constructor(message, transport, options) {\n super(message, options);\n this.transport = transport;\n this.name = \"TransportError\";\n }\n}\n\nclass SemanticError extends ARPError {\n semantic;\n constructor(message, semantic, options) {\n super(message, options);\n this.semantic = semantic;\n this.name = \"SemanticError\";\n }\n}\n\n// src/ARL.ts\nclass ARL {\n semantic;\n transport;\n location;\n resolver;\n constructor(semantic, transport, location, resolver) {\n this.semantic = semantic;\n this.transport = transport;\n this.location = location;\n this.resolver = resolver;\n }\n createContext(params) {\n return {\n url: this.toString(),\n semantic: this.semantic,\n transport: this.transport,\n location: this.location,\n timestamp: new Date,\n params\n };\n }\n async resolve(params) {\n const transport = this.resolver.getTransportHandler(this.transport);\n const semantic = this.resolver.getSemanticHandler(this.semantic);\n const context = this.createContext(params);\n return semantic.resolve(transport, this.location, context);\n }\n async deposit(data, params) {\n const transport = this.resolver.getTransportHandler(this.transport);\n const semantic = this.resolver.getSemanticHandler(this.semantic);\n const context = this.createContext(params);\n if (!semantic.deposit) {\n throw new SemanticError(`Semantic \"${semantic.name}\" does not support deposit operation`, this.semantic);\n }\n await semantic.deposit(transport, this.location, data, context);\n }\n async exists() {\n const transport = this.resolver.getTransportHandler(this.transport);\n const semantic = this.resolver.getSemanticHandler(this.semantic);\n const context = this.createContext();\n if (semantic.exists) {\n return semantic.exists(transport, this.location, context);\n }\n return transport.exists(this.location);\n }\n async delete() {\n const transport = this.resolver.getTransportHandler(this.transport);\n const semantic = this.resolver.getSemanticHandler(this.semantic);\n const context = this.createContext();\n if (semantic.delete) {\n return semantic.delete(transport, this.location, context);\n }\n await transport.delete(this.location);\n }\n async list(options) {\n const transport = this.resolver.getTransportHandler(this.transport);\n if (!transport.list) {\n throw new TransportError(`Transport \"${transport.name}\" does not support list operation`, this.transport);\n }\n return transport.list(this.location, options);\n }\n async mkdir() {\n const transport = this.resolver.getTransportHandler(this.transport);\n if (!transport.mkdir) {\n throw new TransportError(`Transport \"${transport.name}\" does not support mkdir operation`, this.transport);\n }\n await transport.mkdir(this.location);\n }\n toString() {\n return `arp:${this.semantic}:${this.transport}://${this.location}`;\n }\n}\n\n// src/semantic/binary.ts\nfunction toBuffer(data) {\n if (Buffer.isBuffer(data)) {\n return data;\n }\n if (data instanceof Uint8Array) {\n return Buffer.from(data);\n }\n if (data instanceof ArrayBuffer) {\n return Buffer.from(data);\n }\n if (Array.isArray(data)) {\n return Buffer.from(data);\n }\n throw new SemanticError(`Unsupported binary input type`, \"binary\");\n}\n\nclass BinarySemanticHandler {\n name = \"binary\";\n async resolve(transport, location, context) {\n const result = await transport.get(location, context.params);\n const meta = {\n url: context.url,\n semantic: context.semantic,\n transport: context.transport,\n location: context.location,\n size: result.metadata?.size ?? result.content.length,\n resolvedAt: context.timestamp.toISOString(),\n type: result.metadata?.type\n };\n return {\n type: \"binary\",\n content: result.content,\n meta\n };\n }\n async deposit(transport, location, data, context) {\n const buffer = toBuffer(data);\n try {\n await transport.set(location, buffer, context.params);\n } catch (error) {\n throw new SemanticError(`Failed to deposit binary to \"${location}\": ${error.message}`, this.name, { cause: error });\n }\n }\n async exists(transport, location, _context) {\n return transport.exists(location);\n }\n async delete(transport, location, _context) {\n try {\n await transport.delete(location);\n } catch (error) {\n throw new SemanticError(`Failed to delete \"${location}\": ${error.message}`, this.name, { cause: error });\n }\n }\n}\nvar binarySemantic = new BinarySemanticHandler;\n// src/semantic/text.ts\nclass TextSemanticHandler {\n name = \"text\";\n async resolve(transport, location, context) {\n const result = await transport.get(location, context.params);\n if (result.metadata?.type === \"directory\") {\n const meta2 = {\n url: context.url,\n semantic: context.semantic,\n transport: context.transport,\n location: context.location,\n size: result.content.length,\n encoding: \"utf-8\",\n mimeType: \"application/json\",\n resolvedAt: context.timestamp.toISOString(),\n type: \"directory\"\n };\n return {\n type: \"text\",\n content: result.content.toString(\"utf-8\"),\n meta: meta2\n };\n }\n const text = result.content.toString(\"utf-8\");\n const meta = {\n url: context.url,\n semantic: context.semantic,\n transport: context.transport,\n location: context.location,\n size: result.metadata?.size ?? result.content.length,\n encoding: \"utf-8\",\n mimeType: \"text/plain\",\n resolvedAt: context.timestamp.toISOString(),\n type: \"file\"\n };\n return {\n type: \"text\",\n content: text,\n meta\n };\n }\n async deposit(transport, location, data, context) {\n const buffer = Buffer.from(data, \"utf-8\");\n try {\n await transport.set(location, buffer, context.params);\n } catch (error) {\n throw new SemanticError(`Failed to deposit text to \"${location}\": ${error.message}`, this.name, { cause: error });\n }\n }\n async exists(transport, location, _context) {\n return transport.exists(location);\n }\n async delete(transport, location, _context) {\n try {\n await transport.delete(location);\n } catch (error) {\n throw new SemanticError(`Failed to delete \"${location}\": ${error.message}`, this.name, { cause: error });\n }\n }\n}\nvar textSemantic = new TextSemanticHandler;\n// src/transport/file.ts\nimport { access, mkdir, readdir, readFile, rm, stat, writeFile } from \"node:fs/promises\";\nimport { dirname, join, resolve } from \"node:path\";\nclass FileTransportHandler {\n name = \"file\";\n resolvePath(location) {\n return resolve(process.cwd(), location);\n }\n async get(location, params) {\n const filePath = this.resolvePath(location);\n try {\n const stats = await stat(filePath);\n if (stats.isDirectory()) {\n return this.getDirectory(filePath, stats, params);\n } else {\n return this.getFile(filePath, stats);\n }\n } catch (error) {\n const err = error;\n throw new TransportError(`File get error: ${err.code} - ${filePath}`, this.name, {\n cause: err\n });\n }\n }\n async getFile(filePath, stats) {\n const content = await readFile(filePath);\n return {\n content,\n metadata: {\n type: \"file\",\n size: Number(stats.size),\n modifiedAt: stats.mtime\n }\n };\n }\n async getDirectory(dirPath, stats, params) {\n const recursive = params?.recursive === \"true\";\n const pattern = params?.pattern;\n let entries;\n if (recursive) {\n entries = await this.listRecursive(dirPath, dirPath);\n } else {\n entries = await readdir(dirPath);\n }\n if (pattern) {\n entries = this.filterByPattern(entries, pattern);\n }\n const content = Buffer.from(JSON.stringify(entries));\n return {\n content,\n metadata: {\n type: \"directory\",\n modifiedAt: stats.mtime\n }\n };\n }\n async listRecursive(basePath, currentPath) {\n const entries = await readdir(currentPath, { withFileTypes: true });\n const results = [];\n for (const entry of entries) {\n const fullPath = join(currentPath, entry.name);\n const relativePath = fullPath.substring(basePath.length + 1);\n if (entry.isDirectory()) {\n const subEntries = await this.listRecursive(basePath, fullPath);\n results.push(...subEntries);\n } else {\n results.push(relativePath);\n }\n }\n return results;\n }\n filterByPattern(entries, pattern) {\n const regexPattern = pattern.replace(/\\./g, \"\\\\.\").replace(/\\*/g, \".*\").replace(/\\?/g, \".\");\n const regex = new RegExp(`^${regexPattern}$`);\n return entries.filter((entry) => {\n const filename = entry.split(\"/\").pop() || entry;\n return regex.test(filename);\n });\n }\n async set(location, content, _params) {\n const filePath = this.resolvePath(location);\n try {\n await mkdir(dirname(filePath), { recursive: true });\n await writeFile(filePath, content);\n } catch (error) {\n const err = error;\n throw new TransportError(`File set error: ${err.code} - ${filePath}`, this.name, {\n cause: err\n });\n }\n }\n async exists(location) {\n const filePath = this.resolvePath(location);\n try {\n await access(filePath);\n return true;\n } catch {\n return false;\n }\n }\n async delete(location) {\n const filePath = this.resolvePath(location);\n try {\n await rm(filePath, { recursive: true });\n } catch (error) {\n const err = error;\n if (err.code === \"ENOENT\") {\n return;\n }\n throw new TransportError(`File delete error: ${err.code} - ${filePath}`, this.name, {\n cause: err\n });\n }\n }\n async list(location, options) {\n const dirPath = this.resolvePath(location);\n try {\n let entries;\n if (options?.recursive) {\n entries = await this.listRecursive(dirPath, dirPath);\n } else {\n entries = await readdir(dirPath);\n }\n if (options?.pattern) {\n entries = this.filterByPattern(entries, options.pattern);\n }\n return entries;\n } catch (error) {\n const err = error;\n throw new TransportError(`File list error: ${err.code} - ${dirPath}`, this.name, {\n cause: err\n });\n }\n }\n async mkdir(location) {\n const dirPath = this.resolvePath(location);\n try {\n await mkdir(dirPath, { recursive: true });\n } catch (error) {\n const err = error;\n throw new TransportError(`File mkdir error: ${err.code} - ${dirPath}`, this.name, {\n cause: err\n });\n }\n }\n}\nvar fileTransport = new FileTransportHandler;\n// src/transport/http.ts\nclass HttpTransportHandler {\n name;\n protocol;\n constructor(protocol = \"https\") {\n this.protocol = protocol;\n this.name = protocol;\n }\n async get(location, params) {\n const url = this.buildUrl(location, params);\n try {\n const response = await fetch(url);\n if (!response.ok) {\n throw new TransportError(`HTTP ${response.status}: ${response.statusText} - ${url}`, this.name);\n }\n const arrayBuffer = await response.arrayBuffer();\n const content = Buffer.from(arrayBuffer);\n const contentType = response.headers.get(\"content-type\");\n const contentLength = response.headers.get(\"content-length\");\n const lastModified = response.headers.get(\"last-modified\");\n return {\n content,\n metadata: {\n type: \"file\",\n size: contentLength ? parseInt(contentLength, 10) : content.length,\n modifiedAt: lastModified ? new Date(lastModified) : undefined,\n contentType\n }\n };\n } catch (error) {\n if (error instanceof TransportError) {\n throw error;\n }\n throw new TransportError(`Network error: ${url}`, this.name, {\n cause: error\n });\n }\n }\n buildUrl(location, params) {\n const url = new URL(`${this.protocol}://${location}`);\n if (params) {\n for (const [key, value] of Object.entries(params)) {\n url.searchParams.set(key, value);\n }\n }\n return url.toString();\n }\n async set(_location, _content, _params) {\n throw new TransportError(\"HTTP transport is read-only, set not supported\", this.name);\n }\n async exists(location) {\n const url = `${this.protocol}://${location}`;\n try {\n const response = await fetch(url, { method: \"HEAD\" });\n return response.ok;\n } catch {\n return false;\n }\n }\n async delete(_location) {\n throw new TransportError(\"HTTP transport is read-only, delete not supported\", this.name);\n }\n}\nvar httpsTransport = new HttpTransportHandler(\"https\");\nvar httpTransport = new HttpTransportHandler(\"http\");\n// src/ARP.ts\nclass ARP {\n transports;\n semantics;\n constructor(config = {}) {\n this.transports = new Map;\n this.semantics = new Map;\n const defaultTransports = [fileTransport, httpTransport, httpsTransport];\n const defaultSemantics = [textSemantic, binarySemantic];\n for (const handler of defaultTransports) {\n this.transports.set(handler.name, handler);\n }\n for (const handler of defaultSemantics) {\n this.semantics.set(handler.name, handler);\n }\n if (config.transports) {\n for (const handler of config.transports) {\n this.transports.set(handler.name, handler);\n }\n }\n if (config.semantics) {\n for (const handler of config.semantics) {\n this.semantics.set(handler.name, handler);\n }\n }\n }\n registerTransport(handler) {\n this.transports.set(handler.name, handler);\n }\n registerSemantic(handler) {\n this.semantics.set(handler.name, handler);\n }\n getTransportHandler(name) {\n const handler = this.transports.get(name);\n if (!handler) {\n throw new TransportError(`Unsupported transport type: ${name}`, name);\n }\n return handler;\n }\n getSemanticHandler(name) {\n const handler = this.semantics.get(name);\n if (!handler) {\n throw new SemanticError(`Unsupported semantic type: ${name}`, name);\n }\n return handler;\n }\n parse(url) {\n if (!url.startsWith(\"arp:\")) {\n throw new ParseError(`Invalid ARP URL: must start with \"arp:\"`, url);\n }\n const content = url.substring(4);\n const separatorIndex = content.indexOf(\"://\");\n if (separatorIndex === -1) {\n throw new ParseError(`Invalid ARP URL: missing \"://\"`, url);\n }\n const typePart = content.substring(0, separatorIndex);\n const location = content.substring(separatorIndex + 3);\n const colonIndex = typePart.indexOf(\":\");\n if (colonIndex === -1) {\n throw new ParseError(`Invalid ARP URL: must have exactly 2 types (semantic:transport)`, url);\n }\n const semantic = typePart.substring(0, colonIndex);\n const transport = typePart.substring(colonIndex + 1);\n if (!semantic) {\n throw new ParseError(`Invalid ARP URL: semantic type cannot be empty`, url);\n }\n if (!transport) {\n throw new ParseError(`Invalid ARP URL: transport type cannot be empty`, url);\n }\n if (!location) {\n throw new ParseError(`Invalid ARP URL: location cannot be empty`, url);\n }\n this.getTransportHandler(transport);\n this.getSemanticHandler(semantic);\n return new ARL(semantic, transport, location, this);\n }\n}\nfunction createARP(config) {\n return new ARP(config);\n}\n\n// src/index.ts\nvar VERSION = \"2.15.0\";\nexport {\n textSemantic,\n httpsTransport,\n httpTransport,\n fileTransport,\n createARP,\n binarySemantic,\n VERSION,\n TransportError,\n TextSemanticHandler,\n SemanticError,\n ParseError,\n HttpTransportHandler,\n FileTransportHandler,\n BinarySemanticHandler,\n ARPError,\n ARP\n};\n\n//# debugId=DA0ABED843E95DD764756E2164756E21\n"
6
6
  ],
7
7
  "mappings": "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",
8
- "debugId": "599016E14854407A64756E2164756E21",
8
+ "debugId": "DAE75374296EF27C64756E2164756E21",
9
9
  "names": []
10
10
  }
package/dist/index.js CHANGED
@@ -66,9 +66,9 @@ import { readdir, readFile, stat } from "node:fs/promises";
66
66
  import { join, relative } from "node:path";
67
67
  import { readdir as readdir2, readFile as readFile2, stat as stat2 } from "node:fs/promises";
68
68
  import { join as join2, relative as relative2 } from "node:path";
69
+ import { createHash } from "node:crypto";
69
70
  import { lstat, mkdir, readdir as readdir3, readlink, rm, symlink } from "node:fs/promises";
70
71
  import { join as join3, resolve as resolvePath } from "node:path";
71
- import { createHash } from "node:crypto";
72
72
  import { readFile as readFile3 } from "node:fs/promises";
73
73
  import { isAbsolute, resolve } from "node:path";
74
74
  function writeString(view, offset, size, value) {
@@ -4686,7 +4686,7 @@ function define(input) {
4686
4686
  const rxd = Object.assign(Object.create(null), {
4687
4687
  name: validated.name,
4688
4688
  type: validated.type,
4689
- tag: validated.tag ?? validated.version ?? undefined,
4689
+ tag: validated.tag ?? undefined,
4690
4690
  registry: validated.registry,
4691
4691
  path: validated.path,
4692
4692
  description: validated.description,
@@ -4721,6 +4721,9 @@ function format(rxi) {
4721
4721
  if (rxi.tag && rxi.tag !== "latest") {
4722
4722
  result += `:${rxi.tag}`;
4723
4723
  }
4724
+ if (rxi.digest) {
4725
+ result += `@${rxi.digest}`;
4726
+ }
4724
4727
  return result;
4725
4728
  }
4726
4729
  function locate(rxm) {
@@ -4793,15 +4796,25 @@ function parse5(locator) {
4793
4796
  throw new LocatorError("Locator must be a non-empty string", locator);
4794
4797
  }
4795
4798
  validateLocatorSecurity(locator);
4796
- if (locator.includes("@")) {
4797
- throw new LocatorError("Invalid locator format. Use name:tag instead of name@version", locator);
4799
+ let digest;
4800
+ let locatorWithoutDigest = locator;
4801
+ const atIndex = locator.indexOf("@");
4802
+ if (atIndex !== -1) {
4803
+ if (atIndex === 0) {
4804
+ throw new LocatorError("Invalid locator format. Name is required before @", locator);
4805
+ }
4806
+ digest = locator.substring(atIndex + 1);
4807
+ locatorWithoutDigest = locator.substring(0, atIndex);
4808
+ if (!digest || digest.includes("@")) {
4809
+ throw new LocatorError("Invalid digest format after @", locator);
4810
+ }
4798
4811
  }
4799
- const lastSlashIndex = locator.lastIndexOf("/");
4812
+ const lastSlashIndex = locatorWithoutDigest.lastIndexOf("/");
4800
4813
  let beforeSlash = "";
4801
- let afterSlash = locator;
4814
+ let afterSlash = locatorWithoutDigest;
4802
4815
  if (lastSlashIndex !== -1) {
4803
- beforeSlash = locator.substring(0, lastSlashIndex);
4804
- afterSlash = locator.substring(lastSlashIndex + 1);
4816
+ beforeSlash = locatorWithoutDigest.substring(0, lastSlashIndex);
4817
+ afterSlash = locatorWithoutDigest.substring(lastSlashIndex + 1);
4805
4818
  }
4806
4819
  const colonIndex = afterSlash.lastIndexOf(":");
4807
4820
  let name;
@@ -4824,7 +4837,8 @@ function parse5(locator) {
4824
4837
  registry: undefined,
4825
4838
  path: undefined,
4826
4839
  name,
4827
- tag
4840
+ tag,
4841
+ digest
4828
4842
  };
4829
4843
  }
4830
4844
  const parts = beforeSlash.split("/");
@@ -4835,14 +4849,16 @@ function parse5(locator) {
4835
4849
  registry: registry2,
4836
4850
  path,
4837
4851
  name,
4838
- tag
4852
+ tag,
4853
+ digest
4839
4854
  };
4840
4855
  }
4841
4856
  return {
4842
4857
  registry: undefined,
4843
4858
  path: beforeSlash,
4844
4859
  name,
4845
- tag
4860
+ tag,
4861
+ digest
4846
4862
  };
4847
4863
  }
4848
4864
  function resource(rxm, rxa) {
@@ -4918,7 +4934,7 @@ class ResourceJsonDetector {
4918
4934
  return {
4919
4935
  type: json2.type,
4920
4936
  name: json2.name,
4921
- tag: json2.tag ?? json2.version ?? undefined,
4937
+ tag: json2.tag,
4922
4938
  description: json2.description,
4923
4939
  registry: json2.registry,
4924
4940
  path: json2.path,
@@ -5056,31 +5072,6 @@ class FolderSourceLoader {
5056
5072
  const files2 = await this.readFolderFiles(source);
5057
5073
  return { source, files: files2 };
5058
5074
  }
5059
- async isFresh(source, cachedAt) {
5060
- try {
5061
- const maxMtime = await this.getMaxMtime(source);
5062
- return maxMtime <= cachedAt;
5063
- } catch {
5064
- return false;
5065
- }
5066
- }
5067
- async getMaxMtime(folderPath) {
5068
- let max = new Date(0);
5069
- const entries = await readdir2(folderPath, { withFileTypes: true });
5070
- for (const entry of entries) {
5071
- const fullPath = join2(folderPath, entry.name);
5072
- if (entry.isFile()) {
5073
- const stats = await stat2(fullPath);
5074
- if (stats.mtime > max)
5075
- max = stats.mtime;
5076
- } else if (entry.isDirectory()) {
5077
- const subMax = await this.getMaxMtime(fullPath);
5078
- if (subMax > max)
5079
- max = subMax;
5080
- }
5081
- }
5082
- return max;
5083
- }
5084
5075
  async readFolderFiles(folderPath, basePath = folderPath) {
5085
5076
  const files2 = {};
5086
5077
  const entries = await readdir2(folderPath, { withFileTypes: true });
@@ -5200,17 +5191,6 @@ class SourceLoaderChain {
5200
5191
  }
5201
5192
  throw new ResourceXError(`Cannot load source: ${source}`);
5202
5193
  }
5203
- async isFresh(source, cachedAt) {
5204
- for (const loader of this.loaders) {
5205
- if (await loader.canLoad(source)) {
5206
- if (loader.isFresh) {
5207
- return loader.isFresh(source, cachedAt);
5208
- }
5209
- return false;
5210
- }
5211
- }
5212
- return false;
5213
- }
5214
5194
  }
5215
5195
  async function resolveSource(source, config2) {
5216
5196
  const loaderChain = config2?.loaderChain ?? SourceLoaderChain.create();
@@ -5292,6 +5272,19 @@ class RegistryMiddleware {
5292
5272
  function withRegistryValidation(registry2, trustedRegistry) {
5293
5273
  return new RegistryValidation(registry2, trustedRegistry);
5294
5274
  }
5275
+ function computeDigest(data) {
5276
+ const hash2 = createHash("sha256").update(data).digest("hex");
5277
+ return `sha256:${hash2}`;
5278
+ }
5279
+ function computeArchiveDigest(files2) {
5280
+ const entries = Object.keys(files2).sort().map((name) => `${name}:${files2[name]}`).join(`
5281
+ `);
5282
+ const hash2 = createHash("sha256").update(entries).digest("hex");
5283
+ return `sha256:${hash2}`;
5284
+ }
5285
+ function isValidDigest(digest) {
5286
+ return /^sha256:[a-f0-9]{64}$/.test(digest);
5287
+ }
5295
5288
 
5296
5289
  class CASRegistry {
5297
5290
  rxaStore;
@@ -5334,7 +5327,9 @@ class CASRegistry {
5334
5327
  keywords: storedRxm.keywords,
5335
5328
  repository: storedRxm.repository
5336
5329
  },
5337
- archive: {},
5330
+ archive: {
5331
+ digest: storedRxm.digest ?? computeArchiveDigest(storedRxm.files)
5332
+ },
5338
5333
  source: {}
5339
5334
  };
5340
5335
  const rxa = await archive(files2);
@@ -5344,9 +5339,10 @@ class CASRegistry {
5344
5339
  const files2 = await extract(rxr2.archive);
5345
5340
  const fileDigests = {};
5346
5341
  for (const [filename, content] of Object.entries(files2)) {
5347
- const digest = await this.rxaStore.put(content);
5348
- fileDigests[filename] = digest;
5342
+ const digest2 = await this.rxaStore.put(content);
5343
+ fileDigests[filename] = digest2;
5349
5344
  }
5345
+ const digest = computeArchiveDigest(fileDigests);
5350
5346
  const storedRxm = {
5351
5347
  registry: rxr2.manifest.definition.registry,
5352
5348
  path: rxr2.manifest.definition.path,
@@ -5358,12 +5354,18 @@ class CASRegistry {
5358
5354
  license: rxr2.manifest.definition.license,
5359
5355
  keywords: rxr2.manifest.definition.keywords,
5360
5356
  repository: rxr2.manifest.definition.repository,
5357
+ digest,
5361
5358
  files: fileDigests,
5362
5359
  createdAt: new Date,
5363
5360
  updatedAt: new Date
5364
5361
  };
5365
5362
  await this.rxmStore.put(storedRxm);
5366
5363
  await this.rxmStore.setLatest(rxr2.manifest.definition.name, rxr2.manifest.definition.tag, rxr2.manifest.definition.registry);
5364
+ return {
5365
+ definition: rxr2.manifest.definition,
5366
+ archive: { digest },
5367
+ source: rxr2.manifest.source
5368
+ };
5367
5369
  }
5368
5370
  async has(rxi) {
5369
5371
  const tag = await this.resolveTag(rxi.name, rxi.tag ?? "latest", rxi.registry);
@@ -5560,13 +5562,6 @@ class LinkedRegistry {
5560
5562
  }
5561
5563
  }
5562
5564
  }
5563
- function computeDigest(data) {
5564
- const hash2 = createHash("sha256").update(data).digest("hex");
5565
- return `sha256:${hash2}`;
5566
- }
5567
- function isValidDigest(digest) {
5568
- return /^sha256:[a-f0-9]{64}$/.test(digest);
5569
- }
5570
5565
 
5571
5566
  class MemoryRXAStore {
5572
5567
  blobs = new Map;
@@ -15500,7 +15495,6 @@ var init_dist = __esm(() => {
15500
15495
  name: exports_external.string().min(1).max(128),
15501
15496
  type: exports_external.string().min(1).max(64),
15502
15497
  tag: exports_external.string().max(64).optional(),
15503
- version: exports_external.string().max(64).optional(),
15504
15498
  registry: exports_external.string().max(256).optional(),
15505
15499
  path: exports_external.string().max(256).optional(),
15506
15500
  description: exports_external.string().max(1024).optional(),
@@ -31168,6 +31162,7 @@ function extractPreview(files2) {
31168
31162
  }
31169
31163
  return null;
31170
31164
  }
31165
+ var DEFAULT_REGISTRY = "https://registry.deepractice.dev";
31171
31166
  function normalizeRegistryUrl(url2) {
31172
31167
  try {
31173
31168
  const parsed = new URL(url2);
@@ -31193,7 +31188,6 @@ class DefaultResourceX {
31193
31188
  providerConfig;
31194
31189
  customDetectors;
31195
31190
  loaderChain;
31196
- sourceMap = new Map;
31197
31191
  constructor(config3) {
31198
31192
  this.provider = getProvider();
31199
31193
  this.providerConfig = { path: config3?.path };
@@ -31234,17 +31228,15 @@ class DefaultResourceX {
31234
31228
  path: rxr2.manifest.definition.path,
31235
31229
  name: rxr2.manifest.definition.name,
31236
31230
  type: rxr2.manifest.definition.type,
31237
- version: rxr2.manifest.definition.tag
31231
+ tag: rxr2.manifest.definition.tag
31238
31232
  });
31239
31233
  const newRxr = createResource(newManifest, rxr2.archive);
31240
31234
  await this.cas.put(newRxr);
31241
31235
  const res2 = this.toResource(newRxr);
31242
- this.sourceMap.set(path11, res2.locator);
31243
31236
  return res2;
31244
31237
  }
31245
31238
  await this.cas.put(rxr2);
31246
31239
  const res = this.toResource(rxr2);
31247
- this.sourceMap.set(path11, res.locator);
31248
31240
  return res;
31249
31241
  }
31250
31242
  async has(locator) {
@@ -31276,49 +31268,32 @@ class DefaultResourceX {
31276
31268
  return executable.execute(args2);
31277
31269
  }
31278
31270
  async ingest(locator, args2) {
31279
- const isSource = await this.canLoadSource(locator);
31271
+ const isSource = await this.loaderChain.canLoad(locator);
31280
31272
  if (isSource) {
31281
- const cached2 = await this.findCachedForSource(locator);
31282
- if (cached2) {
31283
- const isFresh = await this.loaderChain.isFresh(locator, cached2.updatedAt);
31284
- if (isFresh) {
31285
- return this.resolve(cached2.locator, args2);
31286
- }
31287
- }
31288
31273
  const resource2 = await this.add(locator);
31289
31274
  return this.resolve(resource2.locator, args2);
31290
31275
  }
31291
31276
  return this.resolve(locator, args2);
31292
31277
  }
31293
- async findCachedForSource(source) {
31294
- const locator = this.sourceMap.get(source);
31295
- if (!locator)
31296
- return null;
31297
- const rxi = parse5(locator);
31298
- const manifest2 = await this.cas.getStoredManifest(rxi);
31299
- if (!manifest2?.updatedAt)
31300
- return null;
31301
- return { locator, updatedAt: manifest2.updatedAt };
31302
- }
31303
- async canLoadSource(source) {
31304
- return this.loaderChain.canLoad(source);
31305
- }
31306
31278
  async prepareExecutable(locator) {
31307
31279
  const rxl = parse5(locator);
31308
31280
  let rxr2;
31309
31281
  try {
31310
31282
  rxr2 = await this.cas.get(rxl);
31311
- } catch (error48) {
31312
- if (!rxl.registry && this.registryUrl) {
31313
- const normalizedRegistry = normalizeRegistryUrl(this.registryUrl);
31314
- try {
31315
- rxr2 = await this.fetchFromRegistry(format(rxl), this.registryUrl, normalizedRegistry);
31283
+ if (rxl.registry) {
31284
+ const stale = await this.isRegistryCacheStale(rxl, rxr2);
31285
+ if (stale) {
31286
+ const protocol = rxl.registry.startsWith("localhost") ? "http" : "https";
31287
+ const registryUrl = `${protocol}://${rxl.registry}`;
31288
+ const locatorWithoutRegistry = format({ ...rxl, registry: undefined });
31289
+ rxr2 = await this.fetchFromRegistry(locatorWithoutRegistry, registryUrl, rxl.registry);
31316
31290
  await this.cas.put(rxr2);
31317
- } catch {
31318
- throw error48;
31319
31291
  }
31320
- } else if (rxl.registry) {
31321
- const registryUrl = `http://${rxl.registry}`;
31292
+ }
31293
+ } catch (error48) {
31294
+ if (rxl.registry) {
31295
+ const protocol = rxl.registry.startsWith("localhost") ? "http" : "https";
31296
+ const registryUrl = `${protocol}://${rxl.registry}`;
31322
31297
  const locatorWithoutRegistry = format({ ...rxl, registry: undefined });
31323
31298
  try {
31324
31299
  rxr2 = await this.fetchFromRegistry(locatorWithoutRegistry, registryUrl, rxl.registry);
@@ -31327,7 +31302,10 @@ class DefaultResourceX {
31327
31302
  throw error48;
31328
31303
  }
31329
31304
  } else {
31330
- throw error48;
31305
+ const pulled = await this.pullFromChain(format(rxl));
31306
+ if (!pulled)
31307
+ throw error48;
31308
+ rxr2 = pulled;
31331
31309
  }
31332
31310
  }
31333
31311
  const handler = this.typeHandler.getHandler(rxr2.manifest.definition.type);
@@ -31421,6 +31399,57 @@ class DefaultResourceX {
31421
31399
  throw new RegistryError(`Failed to publish: ${response.statusText}`);
31422
31400
  }
31423
31401
  }
31402
+ async pullFromChain(locator) {
31403
+ const entries = this.registries();
31404
+ const urls = entries.map((e) => e.url);
31405
+ const defaultUrl = DEFAULT_REGISTRY;
31406
+ const normalizedUrls = urls.map((u2) => normalizeRegistryUrl(u2));
31407
+ if (!normalizedUrls.includes(normalizeRegistryUrl(defaultUrl))) {
31408
+ urls.push(defaultUrl);
31409
+ }
31410
+ for (const url2 of urls) {
31411
+ const normalized = normalizeRegistryUrl(url2);
31412
+ try {
31413
+ const rxlWithRegistry = parse5(`${normalized}/${locator}`);
31414
+ const stored = await this.cas.getStoredManifest(rxlWithRegistry);
31415
+ if (stored?.digest) {
31416
+ const remoteDigest = await this.fetchRemoteDigest(locator, url2);
31417
+ if (remoteDigest && stored.digest === remoteDigest) {
31418
+ return this.cas.get(rxlWithRegistry);
31419
+ }
31420
+ }
31421
+ const rxr2 = await this.fetchFromRegistry(locator, url2, normalized);
31422
+ await this.cas.put(rxr2);
31423
+ return rxr2;
31424
+ } catch {}
31425
+ }
31426
+ return null;
31427
+ }
31428
+ async isRegistryCacheStale(rxl, rxr2) {
31429
+ const localDigest = rxr2.manifest.archive.digest;
31430
+ if (!localDigest)
31431
+ return true;
31432
+ try {
31433
+ const protocol = rxl.registry.startsWith("localhost") ? "http" : "https";
31434
+ const registryUrl = `${protocol}://${rxl.registry}`;
31435
+ const locatorWithoutRegistry = format({ ...rxl, registry: undefined });
31436
+ const remoteDigest = await this.fetchRemoteDigest(locatorWithoutRegistry, registryUrl);
31437
+ if (!remoteDigest)
31438
+ return true;
31439
+ return localDigest !== remoteDigest;
31440
+ } catch {
31441
+ return false;
31442
+ }
31443
+ }
31444
+ async fetchRemoteDigest(locator, registryUrl) {
31445
+ const baseUrl = registryUrl.replace(/\/$/, "");
31446
+ const manifestUrl = `${baseUrl}/api/v1/resource/${encodeURIComponent(locator)}`;
31447
+ const response = await fetch(manifestUrl);
31448
+ if (!response.ok)
31449
+ return;
31450
+ const data = await response.json();
31451
+ return data.digest;
31452
+ }
31424
31453
  async fetchFromRegistry(locator, registryUrl, normalizedRegistry) {
31425
31454
  const baseUrl = registryUrl.replace(/\/$/, "");
31426
31455
  const registry2 = normalizedRegistry ?? normalizeRegistryUrl(registryUrl);
@@ -31438,13 +31467,14 @@ class DefaultResourceX {
31438
31467
  wrap: wrap2,
31439
31468
  resource: createResource
31440
31469
  } = await Promise.resolve().then(() => (init_dist(), exports_dist));
31441
- const rxm = createManifest({
31470
+ const baseRxm = createManifest({
31442
31471
  registry: registry2,
31443
31472
  path: manifestData.path,
31444
31473
  name: manifestData.name,
31445
31474
  type: manifestData.type,
31446
31475
  tag: manifestData.tag
31447
31476
  });
31477
+ const rxm = manifestData.digest ? { ...baseRxm, archive: { ...baseRxm.archive, digest: manifestData.digest } } : baseRxm;
31448
31478
  const contentUrl = `${baseUrl}/api/v1/content/${encodeURIComponent(locator)}`;
31449
31479
  const contentResponse = await fetch(contentUrl);
31450
31480
  if (!contentResponse.ok) {
@@ -31466,7 +31496,7 @@ class DefaultResourceX {
31466
31496
  path: rxr.manifest.definition.path,
31467
31497
  name: rxr.manifest.definition.name,
31468
31498
  type: rxr.manifest.definition.type,
31469
- version: rxr.manifest.definition.tag
31499
+ tag: rxr.manifest.definition.tag
31470
31500
  },
31471
31501
  files
31472
31502
  };
@@ -31522,7 +31552,7 @@ function createResourceX2(config3) {
31522
31552
  }
31523
31553
 
31524
31554
  // src/index.ts
31525
- var VERSION = "2.14.1";
31555
+ var VERSION = "2.15.0";
31526
31556
  export {
31527
31557
  wrap,
31528
31558
  setProvider,
@@ -31550,4 +31580,4 @@ export {
31550
31580
  FolderSourceLoader
31551
31581
  };
31552
31582
 
31553
- //# debugId=FC3B15EA0B7D7EDA64756E2164756E21
31583
+ //# debugId=0E645F201FA16B4464756E2164756E21