Portable artifact entry trees and declared resource loading
///|
test {
let tree = @resources.EntryTree::directory(
[@resources.EntryPath::parse("messages/hello.txt").unwrap()],
_ => b"hello",
@resources.Location::parse("memory-directory").unwrap(),
)
let loaded = @resources.load_resources(tree, [
{
name: @resources.ResourceName::parse("greeting").unwrap(),
path: @resources.EntryPath::parse("messages/hello.txt").unwrap(),
},
])
assert_eq(loaded[0].name.to_string(), "greeting")
assert_eq(loaded[0].text(), "hello")
}| Value | Meaning |
|---|---|
| RepositoryId, ProviderId | Distinct configured repository and registered provider identifiers |
| ArtifactKey, ArtifactIdentity | Requested key and provider-resolved exact identity |
| RepositoryLocation | Provider-interpreted source address |
| EntryPath | Portable path inside a container |
| ResourceName | Consumer-facing logical name, independent of the physical path |
| Location | Source address with structured directory or archive entry relationships |
| Provenance | Physical location and typed acquisition history |
| ContentDigest | SHA-256 content identity, independent of repository keys |
mise exec -- moon run pkgs/artifact-resources/examples/local --target js| Code | Meaning |
|---|---|
| invalid-archive | Malformed or unsupported ZIP, tar or gzip data |
| integrity-failure | Content size, CRC or tar header checksum mismatch |
| unsafe-path | Unsafe physical path, logical name or local artifact key |
| missing-resource | A declared file is missing or is a directory |
| duplicate-entry | Repeated physical entry path |
| duplicate-resource | Repeated logical name |
| resource-limit | An entry, archive or total exceeds its limit |
| invalid-limits | A negative limit |
| invalid-utf8 | Text requested for non-UTF-8 bytes |
| local-io | Host filesystem acquisition failed |
| duplicate-provider, duplicate-repository | Repeated registration |
| unknown-provider, unknown-repository | Missing registration |
| invalid-resolution | A provider returned a different reference |
| missing-root, missing-selection | Missing subtree or selector matching no files |
| provider-failure | Provider-specific acquisition failure |
| Package | wasm | wasm-gc | JS | native |
|---|---|---|---|---|
| Entry trees, ZIP/tar/gzip readers, resources, provider registry | Yes | Yes | Yes | Yes |
| Local filesystem adapter | MoonBit filesystem host | MoonBit filesystem host | Node.js | Host OS |
| Backend / host | Archive reading | Default public acquisition |
|---|---|---|
| Native Linux, macOS | Yes | curl on trusted PATH |
| Native Windows | Yes | OS-installed curl |
| JS in Node.js 24+ | Yes | Host curl via Node child processes |
| Wasm / Wasm GC filesystem hosts | Yes | unsupported-transport |
| Browser JS | In-memory readers | Supply a host transport |
pub(all) struct Acquisition {
requested : HttpUrl
resolved : HttpUrl
digest : ContentDigest
} derive(Eq, Debug)impl Show for ArtifactIdentityimpl Show for ArtifactKeyimpl Show for Authorizationimpl Debug for Authorizationpub(all) struct CacheStore {
read : (CacheKey, Int) -> Bytes? raise ResourceError
publish : (CacheKey, Bytes) -> Unit raise ResourceError
}impl Show for ContentDigestfn EntryTree::select(self : EntryTree, selection : Selection) -> Array[Declaration] raise ResourceErrorfn EntryTree::tar(data : Bytes, origin : Location, limits? : Limits) -> EntryTree raise ResourceErrorfn EntryTree::tgz(data : Bytes, origin : Location, limits? : Limits) -> EntryTree raise ResourceErrorpub(all) struct GitHubArchive {
repository : GitHubRepository
reference : GitHubAssetRef
format : ArchiveFormat
expected_digest : ContentDigest?
} derive(Eq, Debug)fn GitHubArchive::open(self : GitHubArchive, transport : (HttpRequest, AcquisitionLimits) -> HttpResponse raise ResourceError, api? : HttpUrl, acquisition_limits? : AcquisitionLimits, limits? : Limits, cache? : VerifiedCache?, mode? : AcquisitionMode, credentials? : Credentials) -> EntryTree raise ResourceErrorpub(all) struct GitHubResolution {
repository : GitHubRepository
requested : GitHubAssetRef
release_id : GitHubReleaseId
asset_id : GitHubAssetId
download : HttpUrl
} derive(Eq, Debug)pub(all) struct HttpRequest {
url : HttpUrl
authorization : Authorization?
accept : HttpAccept
} derive(Eq, Debug)pub(all) struct Limits {
max_archive_bytes : Int
max_entries : Int
max_entry_bytes : Int
max_match_steps : Int
max_total_bytes : Int
max_expanded_bytes : Int
}pub(all) enum Location {
Source(RepositoryLocation)
FilesystemDirectory(CacheDirectory)
DirectoryEntry(Location, EntryPath, PathStyle)
ArchiveEntry(Location, EntryPath)
} derive(Eq, Debug)pub(all) struct MavenArchive {
repository : RepositoryUrl
coordinates : MavenCoordinates
checksum : MavenChecksum
expected_digest : ContentDigest?
} derive(Eq, Debug)fn MavenArchive::open(self : MavenArchive, transport : (HttpRequest, AcquisitionLimits) -> HttpResponse raise ResourceError, acquisition_limits? : AcquisitionLimits, limits? : Limits, cache? : VerifiedCache?, mode? : AcquisitionMode, credentials? : Credentials) -> EntryTree raise ResourceErrorpub(all) struct MavenCoordinates {
group : MavenGroupId
artifact : MavenArtifactId
version : MavenVersion
classifier : MavenClassifier?
} derive(Eq, Debug)pub(all) struct MavenResolution {
repository : RepositoryUrl
coordinates : MavenCoordinates
artifact : HttpUrl
verification : MavenVerification
} derive(Eq, Debug)pub(all) enum MavenVerification {
PinnedDigest(ContentDigest)
RepositoryChecksum(Acquisition, Checksum)
} derive(Eq, Debug)pub(all) struct NpmArchive {
registry : RepositoryUrl
reference : NpmPackageRef
expected_digest : ContentDigest?
} derive(Eq, Debug)fn NpmArchive::open(self : NpmArchive, transport : (HttpRequest, AcquisitionLimits) -> HttpResponse raise ResourceError, acquisition_limits? : AcquisitionLimits, limits? : Limits, cache? : VerifiedCache?, mode? : AcquisitionMode, credentials? : Credentials) -> EntryTree raise ResourceErrorfn NpmIntegrity::verify(self : NpmIntegrity, body : Bytes, at : Provenance) -> Unit raise ResourceErrorpub(all) struct NpmResolution {
registry : RepositoryUrl
reference : NpmPackageRef
metadata : Acquisition
tarball : HttpUrl
integrity : NpmIntegrity
} derive(Eq, Debug)impl Show for Provenancefn Provenance::github_requested(self : Provenance, repository : GitHubRepository, reference : GitHubAssetRef) -> Provenancefn Provenance::maven_requested(self : Provenance, repository : RepositoryUrl, coordinates : MavenCoordinates) -> Provenancefn Provenance::npm_requested(self : Provenance, registry : RepositoryUrl, reference : NpmPackageRef) -> Provenancefn Provenance::resolved(self : Provenance, reference : ArtifactRef, identity : ArtifactIdentity?) -> Provenancepub(all) enum ProvenanceOrigin {
Physical(Location)
ProviderRegistration(ProviderId)
RepositoryReference(RepositoryId)
} derive(Eq, Debug)pub(all) enum ProvenanceStep {
NpmRequestStep(RepositoryUrl, NpmPackageRef)
NpmStep(NpmResolution)
MavenRequestStep(RepositoryUrl, MavenCoordinates)
MavenStep(MavenResolution)
GitHubRequestStep(GitHubRepository, GitHubAssetRef)
GitHubStep(GitHubResolution)
AcquisitionStep(Acquisition)
ResolutionStep(Resolution)
ContainerStep(Location)
ProviderRegistrationStep(ProviderId)
RepositoryReferenceStep(RepositoryId)
} derive(Eq, Debug)impl Show for ProviderIdpub(all) struct PublicArchive {
url : HttpUrl
format : ArchiveFormat
expected_digest : ContentDigest?
} derive(Eq, Debug)fn PublicArchive::open(self : PublicArchive, transport : (HttpRequest, AcquisitionLimits) -> HttpResponse raise ResourceError, acquisition_limits? : AcquisitionLimits, limits? : Limits, cache? : VerifiedCache?, mode? : AcquisitionMode, verify? : (Bytes, Provenance) -> Unit raise ResourceError, credentials? : Credentials, accept? : HttpAccept) -> EntryTree raise ResourceErrorpub struct Registry {
// private fields
}fn Registry::add_repository(self : Registry, repository : Repository) -> Registry raise ResourceErrorfn Registry::register_provider(self : Registry, name : ProviderId, provider : (Repository, ArtifactRef) -> ResolvedArtifact raise ResourceError) -> Registry raise ResourceErrorfn Registry::resolve(self : Registry, reference : ArtifactRef) -> ResolvedArtifact raise ResourceErrorpub(all) struct Repository {
id : RepositoryId
provider : ProviderId
location : RepositoryLocation
} derive(Eq, Debug)impl Show for RepositoryIdpub(all) struct Resolution {
reference : ArtifactRef
identity : ArtifactIdentity?
} derive(Eq, Debug)pub(all) struct ResolvedArtifact {
reference : ArtifactRef
identity : ArtifactIdentity
tree : EntryTree
}pub struct Resource {
name : ResourceName
path : EntryPath
origin : Location
provenance : Provenance
bytes : Bytes
}pub(all) enum ResourceCode {
MissingPackageVersion
MissingArtifact
UnsupportedIntegrity
MissingRelease
AmbiguousAsset
RateLimited
OfflineMiss
CacheCorrupt
CacheIo
UnsupportedTransport
TransportFailure
AcquisitionTimeout
AuthenticationRequired
MissingAsset
HttpStatus
InvalidArchive
IntegrityFailure
UnsafePath
MissingResource
DuplicateEntry
DuplicateResource
ResourceLimit
InvalidLimits
InvalidUtf8
LocalIo
DuplicateProvider
DuplicateRepository
UnknownProvider
UnknownRepository
InvalidResolution
MissingSelection
MissingRoot
ProviderFailure
} derive(Eq, Debug)impl Show for ResourceCodepub(all) enum ResourceSelector {
Exact(EntryPath)
Named(EntryPath, ResourceName)
Matching(GlobPattern)
} derive(Eq, Debug)pub struct VerifiedCache {
// private fields
}fn acquire(requested : HttpUrl, transport : (HttpRequest, AcquisitionLimits) -> HttpResponse raise ResourceError, expected_digest? : ContentDigest?, limits? : AcquisitionLimits, cache? : VerifiedCache?, mode? : AcquisitionMode, verify? : (Bytes, Provenance) -> Unit raise ResourceError, credentials? : Credentials, accept? : HttpAccept) -> AcquiredBytes raise ResourceErrorfn load_resources(tree : EntryTree, declarations : Array[Declaration]) -> Array[Resource] raise ResourceErrorfn register_github(registry : Registry, transport : (HttpRequest, AcquisitionLimits) -> HttpResponse raise ResourceError, api? : HttpUrl, format? : ArchiveFormat, expected_digest? : ContentDigest?, acquisition_limits? : AcquisitionLimits, limits? : Limits, cache? : VerifiedCache?, mode? : AcquisitionMode, credentials? : Credentials) -> Registry raise ResourceErrorfn register_maven(registry : Registry, transport : (HttpRequest, AcquisitionLimits) -> HttpResponse raise ResourceError, checksum? : MavenChecksum, expected_digest? : ContentDigest?, acquisition_limits? : AcquisitionLimits, limits? : Limits, cache? : VerifiedCache?, mode? : AcquisitionMode, credentials? : Credentials) -> Registry raise ResourceErrorfn register_npm(registry : Registry, transport : (HttpRequest, AcquisitionLimits) -> HttpResponse raise ResourceError, expected_digest? : ContentDigest?, acquisition_limits? : AcquisitionLimits, limits? : Limits, cache? : VerifiedCache?, mode? : AcquisitionMode, credentials? : Credentials) -> Registry raise ResourceErrorfn register_public_http(registry : Registry, transport : (HttpRequest, AcquisitionLimits) -> HttpResponse raise ResourceError, format? : ArchiveFormat, expected_digest? : ContentDigest?, acquisition_limits? : AcquisitionLimits, limits? : Limits, cache? : VerifiedCache?, mode? : AcquisitionMode, credentials? : Credentials) -> Registry raise ResourceErrorfn valid_path(path : String) -> BoolInstall
Download zipPortable artifact entry trees and declared resource loading