experimental package manager for node.js

Related tags

Cryptography pacquet
Overview

pacquet

Experimental package manager for node.js written in rust.

Disclaimer: This is mostly a playground for me to learn Rust and understand how package managers work.

TODO

  • .npmrc support (for supported features readme.md)
  • CLI commands (for supported features readme.md)
  • Content addressable file store support
  • Shrink-file support in sync with pnpm-lock.yml
  • Workspace support
  • Full sync with pnpm error codes
  • Generate a node_modules/.bin folder
  • Add CLI report

Debugging

TRACE=pacquet_tarball just cli add fastify
Comments
  • Some feedback

    Some feedback

    Okay! So! Here I am!

    The very first thing I want to say is, this code was already really great. If you were a random beginner who asked me to look at their code, I would say "great job" and not offer any of this feedback unless they were looking to actively level up at Rust. And while we don't know each other well, I do know that you're an experienced systems programmer, and looking to level up your Rust.

    So I went a little extra. Sorry not sorry.

    Each of these commits tells a story, in order. I left detailed commit messages. Some code gets re-written multiple times, but each step should be instructive, so if you only look at the final diff, you won't learn everything. Please take what you want, and throw away what you don't. And I am happy to discuss anything about any of this in detail.

    This looks like a fun project!

    opened by steveklabnik 10
  • Run command improvements

    Run command improvements

    • [x] Should respect to ^ version pins while installing dependencies. For example, [email protected] and [email protected] should not be installed if both of them has the ^ version pin. (https://github.com/anonrig/pacquet/pull/10)
    • [x] Should not re-fetch same package multiple times. (https://github.com/anonrig/pacquet/pull/9/commits/fc0b3f40aa91f1efc3ba535f5e672b0195bd797a)
    • [x] Should update package.json and add package to dependencies.
    • [x] Add missing flags. Full list is available at https://pnpm.io/cli/add
    help wanted good first issue 
    opened by anonrig 9
  • refactor path handling for cross-platform compatibility

    refactor path handling for cross-platform compatibility

    This PR addresses the issue of inconsistent path handling across different operating systems in the get_all_folders function. The current implementation accepts both Unix and Windows path separators, leading to unpredictable behavior. The proposed solution aims to enhance cross-platform compatibility and improve code clarity

    opened by mertcanaltin 8
  • fix: store_dir envs should without $ symbols

    fix: store_dir envs should without $ symbols

    I think env should without $ symbols.

    $ just for us to use it with bash.For example

    echo $HOME
    

    In rust , we should use it with these code:

    let home = env::var('HOME')
    
    opened by southorange0929 6
  • feat: add initial install command support

    feat: add initial install command support

    Work in progress. Opening to receive feedback.

    I'm not really happy with the architecture of the whole project and how registry sits on top of everything. Any recommendations @steveklabnik?

    opened by anonrig 5
  • fix pacquet executer

    fix pacquet executer

    Until now pacquet just ran any script/shell commands by just directly passing the entire command to Command::new. As per the std, Command::new takes only the file/program name, and any additional args need to be provided via the arg or args method.

    Well now, i just touched it a little bit, to run sh -c and pass the actual command/script to it. This runs without any errors now, and sometimes scripts contain env vars too. For example

    {
      "scripts": {
        "test": "KEY=VALUE node index.js"
      }
    }
    

    Now it is passed as sh -c "KEY=ENV node index.js. This seems to be how the peeps do it in pnpm. (in pn)

    And also pass any sort of additional args provided in the run command to the script. For example,

    {
      "scripts": {
        "test": "echo Hello"
      }
    }
    

    Current running pacquet test and pacquet test World both just prints "Hello", but pnpm passes any additional args provided to the script too. So now it prints "Hello World" when done pacquet test World

    opened by Yakiyo 3
  • feat: add initial benchmark

    feat: add initial benchmark

    An initial pretty simplistic benchmark that uses verdaccio (to remove the overhead of http requests to npm registry).

    Benchmark 1: pacquet
      Time (mean ± σ):     364.6 ms ±  21.1 ms    [User: 44.0 ms, System: 173.1 ms]
      Range (min … max):   337.3 ms … 406.7 ms    10 runs
    
    Benchmark 2: pnpm
      Time (mean ± σ):     945.9 ms ±  43.4 ms    [User: 585.6 ms, System: 1491.7 ms]
      Range (min … max):   876.5 ms … 1003.7 ms    10 runs
    
    Benchmark 3: yarn
      Time (mean ± σ):     610.5 ms ±   7.5 ms    [User: 1250.2 ms, System: 181.2 ms]
      Range (min … max):   601.8 ms … 624.2 ms    10 runs
    
    Benchmark 4: bun
      Time (mean ± σ):      1.055 s ±  0.222 s    [User: 0.079 s, System: 0.306 s]
      Range (min … max):    0.733 s …  1.550 s    10 runs
    
    Summary
      pacquet ran
        1.67 ± 0.10 times faster than yarn
        2.59 ± 0.19 times faster than pnpm
        2.89 ± 0.63 times faster than bun
    
    opened by anonrig 3
  • chore(cargo): bump tempfile from 3.7.1 to 3.8.0

    chore(cargo): bump tempfile from 3.7.1 to 3.8.0

    Bumps tempfile from 3.7.1 to 3.8.0.

    Changelog

    Sourced from tempfile's changelog.

    3.8.0

    • Added with_prefix and with_prefix_in to TempDir and NamedTempFile to make it easier to create temporary files/directories with nice prefixes.
    • Misc cleanups.
    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot show <dependency name> ignore conditions will show all of the ignore conditions of the specified dependency
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    dependencies rust 
    opened by dependabot[bot] 1
  • chore(cargo): bump reflink-copy from 0.1.5 to 0.1.6

    chore(cargo): bump reflink-copy from 0.1.5 to 0.1.6

    Bumps reflink-copy from 0.1.5 to 0.1.6.

    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot show <dependency name> ignore conditions will show all of the ignore conditions of the specified dependency
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    dependencies rust 
    opened by dependabot[bot] 1
  • chore(cargo): bump thiserror from 1.0.44 to 1.0.47

    chore(cargo): bump thiserror from 1.0.44 to 1.0.47

    Bumps thiserror from 1.0.44 to 1.0.47.

    Release notes

    Sourced from thiserror's releases.

    1.0.47

    1.0.46

    • Add bootstrap workaround to allow rustc to depend on thiserror (#248, thanks @​RalfJung)

    1.0.45

    Commits
    • 0495eaa Release 1.0.47
    • 2d9425c Work around ridiculous rust-analyzer behavior
    • 5ada5d5 Release 1.0.46
    • f51271a Reword bootstrap comment
    • 1f02cdf Merge pull request #248 from RalfJung/bootstrap
    • fa63782 don't run build probes in rustc bootstrap
    • 2fd79cd Merge pull request #247 from dtolnay/errorprovide
    • 78e0ffe Pull in anyhow's new Error::provide support
    • 06f1895 Release 1.0.45
    • a11330f Merge pull request #246 from dtolnay/errorprovide
    • Additional commits viewable in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot show <dependency name> ignore conditions will show all of the ignore conditions of the specified dependency
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    dependencies rust 
    opened by dependabot[bot] 1
  • chore(cargo): bump clap from 4.3.21 to 4.3.23

    chore(cargo): bump clap from 4.3.21 to 4.3.23

    Bumps clap from 4.3.21 to 4.3.23.

    Release notes

    Sourced from clap's releases.

    v4.3.23

    [4.3.23] - 2023-08-18

    Fixes

    • Fixed UnknownArgumentValueParser to not error on flag's absence

    v4.3.22

    [4.3.22] - 2023-08-17

    Features

    • Add UnknownArgumentValueParser for injecting errors for improving the experience with errors
    Changelog

    Sourced from clap's changelog.

    [4.3.23] - 2023-08-18

    Fixes

    • Fixed UnknownArgumentValueParser to not error on flag's absence

    [4.3.22] - 2023-08-17

    Features

    • Add UnknownArgumentValueParser for injecting errors for improving the experience with errors
    Commits
    • b9df80c chore: Release
    • e46e12b docs: Update changelog
    • c992311 Merge pull request #5080 from epage/unknown
    • 56135f3 fix(builder): UnknownValueParser shouldn't error on flag absense
    • 6720240 feat(parser): Report source to value parsers
    • b55ebc9 test(parser): Show bad Unknown bug on flags
    • df337de chore: Release
    • fb8a12a docs: Update changelog
    • b87ca2f Merge pull request #5075 from epage/err
    • 9f65eb0 refactor(error): Give caller control over suggestion
    • Additional commits viewable in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot show <dependency name> ignore conditions will show all of the ignore conditions of the specified dependency
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    dependencies rust 
    opened by dependabot[bot] 1
  • feat: hashmap based caching

    feat: hashmap based caching

    Before this PR, pacquet install was installing packages by "generations": All direct dependencies are installed first, then dependencies of direct dependencies, then dependencies of dependencies of dependencies, and so on. This was not optimal, but it was done to avoid race condition where some packages would be fetched twice should they be invoked in the window of time where its duplicated has begun fetching but not yet saved to local disk.

    This PR aims to change this by using an in-memory hashmap cache to keep track of all fetched packages, then re-enable full parallelization.

    NOTE: This PR only affects pacquet install, pacquet add still uses the old algorithm.

    NOTE: New tests with multiple packages for pacquet install is required, but I am too tired right now.

    opened by KSXGitHub 4
  • Integrating pacquet to pnpm's existing codebase

    Integrating pacquet to pnpm's existing codebase

    Rewriting all pnpm functionalities from scratch in pacquet is a huge task, so I think we should integrate with pnpm. Let pacquet handle tasks sensitive to performance and correctness, and pnpm the rest. It is also important to test pacquet against pnpm's tests and real world use cases. This would hopefully allow us to eventually convert the codebase to Rust (if we want to) without creating too many regressions or changing too many existing quirks.

    How will we going to approach this? Should it be a separate process that communicate via IPC? Should it be a child process? Should it be a Node.js addon? Should it be a WASM library? Or should pacquet spawn pnpm as a child process instead?

    @anonrig @zkochan

    opened by KSXGitHub 5
  • feat: add http caching to reqwest

    feat: add http caching to reqwest

    before

    Benchmark 1: pacquet
      Time (mean ± σ):     799.0 ms ±  17.2 ms    [User: 141.8 ms, System: 818.4 ms]
      Range (min … max):   777.5 ms … 827.8 ms    10 runs
    

    after

    Benchmark 1: pacquet
      Time (mean ± σ):     656.5 ms ±  26.4 ms    [User: 152.1 ms, System: 811.8 ms]
      Range (min … max):   625.6 ms … 709.3 ms    10 runs
    
    opened by anonrig 5
  • [Feature Request] git diff friendly format of lockfile

    [Feature Request] git diff friendly format of lockfile

    The story of users

    1. yaml file is not friendly to git diff. Almost every time in git diff, each diff block will be confused by same content from different rows and different projects as shown in the images below. This kind of code diff is not easy to read.

    2. In a larger repository, there are usually many people working together, but their projects may be irrelevant. The lockfile conflict causes them to have to merge manually.

    image

    image

    the solution I think

    Inspired by Go's lockfile called "Go.sum", new format of lockfile stores the meta data of each packages in only one line.

    image

    The format I designed is like this.

    before

    image

    after

    // new-format.lock
    // Nodes
    [email protected] sha512-xxxxxxxxxx=  noDev
    [email protected] sha-xxxxxxxxxx= hasBin noDev
    [email protected] sha512-xxxxxxx= engines: {node: '>=0.10.0'} noDev
    
    // Edges
    [email protected] -> [email protected]
    [email protected] -> [email protected]
    

    Then, if I add a new version of loose-envify,code diff would become like this.

    // new-format.lock
    [email protected] sha512-xxxxxxxxxx=  noDev
    - [email protected] sha-xxxxxxxxxx= hasBin noDev
    + [email protected] sha-xxxxxxxxxx= hasBin noDev
    [email protected] sha512-xxxxxxx= engines: {node: '>=0.10.0'} noDev
    
    - [email protected] -> [email protected]
    - [email protected] -> [email protected]
    + [email protected] -> [email protected]
    + [email protected] -> [email protected]
    

    The reason why I open this issue is that I think the new package manager should have more opportunities to try experimental features

    enhancement 
    opened by SoonIter 0
  • Cache should not be racy

    Cache should not be racy

    So in #42, one issue that comes up multiple times is cache misses.

    Basically, Registrymanager::get_package is racy:

    1. look up package in cache, if it's there, return it
    2. if not, fetch the package
    3. insert package into cache

    This works but has the property of a "race condition." (but not a data race!!!) If we spin up two threads, and both are looking for the same package, and thread 1 goes "1, don't have it, go to step 2 and fetch" and then thread 2 starts and does the same, we've fetched the package twice. This manifests as a cache miss.

    The alternative is to cause 1 to block in some fashion. We want it to hold some sort of lock, so that if someone else wants something we're working on, we ask them to wait until it's ready. But there's not just one way to do this!

    The first way, and the way that's most obvious, is that you put a mutex around the whole thing. That way, if someone is downloading a new package, you wait until they're done. The issue there is that you'd end up blocking everyone when a package is being downloaded, which kind of defeats the purpose of downloading them in paralell, haha.

    So my next thought is that we need to do is change the data modelling from "package exists or not" to "package doesn't exist, package is being downloaded, package is complete in the cache." This more properly represents what's going on in the real world. But it's not actually the best way forward. Why? Well, what happens when we have a cache hit? We want to simply return the package. If we know that some other task is already downloading the package, what we actually want is to return. We have no more work to do! Sure it's not ready yet, but the other task will make sure it is.

    So, I think that's the task to fix this issue. I don't think it should be a super complex diff, but I'm not going to try and write a patch right this second.

    opened by steveklabnik 4
Releases(v0.1.3)
Owner
pnpm
Fast, disk space efficient package manager
pnpm
📦 An independent package manager that every hacker deserves.

An independent package manager for unix and linux?? Table of contents ?? Why Features Installation Hysp usages Hosting custom repo Packages Support Li

Nabeen Tiwaree 320 Dec 4, 2023
A node and runtime configuration for polkadot node.

MANTA NODE This repo is a fresh FRAME-based Substrate node, forked from substrate-developer-hub/substrate-node-templte ?? It links to pallet-manta-dap

Manta Network 14 Apr 25, 2021
Simple node and rust script to achieve an easy to use bridge between rust and node.js

Node-Rust Bridge Simple rust and node.js script to achieve a bridge between them. Only 1 bridge can be initialized per rust program. But node.js can h

Pure 5 Apr 30, 2023
Sample lightning node command-line app built on top of Ldk Node (similar to ldk-sample).

ldk-node-sample Sample lightning node command-line app built on top of Ldk Node (similar to ldk-sample ). Installation git clone https://github.com/op

optout 3 Nov 21, 2023
Manager for single node Rancher clusters

Bovine Manage single node Rancher clusters with a single binary, bovine. % bovine run Pulling [rancher/rancher:latest], this may take awhile... Ranche

Nick Gerace 51 Feb 17, 2022
Package used by the cosmos-rust-interface. Makes direct use of cosmos-rust.

Package used by the cosmos-rust-interface. Makes direct use of cosmos-rust (cosmos‑sdk‑proto, osmosis-proto, cosmrs).

Philipp 4 Dec 26, 2022
A package that has a collection of unspent p2wsh bitcoin transactions.

P2WSH-UTXO A package that has a collection of unspent p2wsh transactions. Useful to see what are potential unspent multisig transactions. Library Crea

Tony Giorgio 3 Oct 22, 2022
Tooling for the simple-package-paths Nix RFC

Implementation Index the tree for references. If .git exists, use ls-tree equivalent Check the validity of the pkgs/unit directory Should only contain

Nixpkgs Architecture Team 3 Jan 18, 2023
EXPERIMENTAL: Bitcoin Core Prometheus exporter based on User-Space, Statically Defined Tracing and eBPF.

bitcoind-observer An experimental Prometheus metric exporter for Bitcoin Core based on Userspace, Statically Defined Tracing and eBPF. This demo is ba

0xB10C 24 Nov 8, 2022
Experimental binary transparency for pacman with sigstore and rekor

pacman-bintrans This is an experimental implementation of binary transparency for pacman, the Arch Linux package manager. This project was originally

null 80 Dec 23, 2022
An experimental rust zksnarks compiler with embeeded bellman-bn128 prover

Za! An experimental port of the circom zk-SNARK compiler in Rust with embedded bellman-bn128 prover. I created it as a PoC port of the existing JavaSc

adria0.eth 39 Aug 26, 2022
Rust implementation of the Matter protocol. Status: Experimental

matter-rs: The Rust Implementation of Matter Build Building the library: $ cd matter $ cargo build Building the example: $ cd matter $ RUST_LOG="matt

Connectivity Standards Alliance 12 Jan 5, 2023
Write Extism plugins in JavaScript (Experimental)

Extism JavaScript PDK Note: This is very experimental. If you are interested in helping or following development, join the #js-pdk room in our discord

Extism 6 Jan 18, 2023
Avalanche primitive types in Rust (experimental)

AvalancheGo Compatibility Crate Version(s) AvalancheGo Version(s) Protocol Version v0.0.134-155 v1.9.2,v1.9.3 19 v0.0.156-176 v1.9.4 20 v0.0.177-200 v

Ava Labs 26 Feb 4, 2023
An experimental fork of a16z's Helios Ethereum client which can run its network traffic over the Nym mixnet

Helios (Nym mixnet fork) Helios is a fully trustless, efficient, and portable Ethereum light client written in Rust. This fork of Helios includes nasc

Nym 4 Mar 3, 2023
Briolette is an experimental framework for researching offline digital currency designs.

Briolette - experimental framework for offline-enabled digital currency Briolette is an experimental framework for researching offline digital currenc

Google 39 Apr 9, 2023
CosmOS - experimental operating system written in Rust.

CosmOS A simple operating system written in Rust. Table of Contents CosmOS Setup QEMU Run OS dev resources General Bootloader Setup Linux Arch pacman

COSMO PK Group 11 Oct 7, 2023
Polkadot Node Implementation

Polkadot Implementation of a https://polkadot.network node in Rust based on the Substrate framework. NOTE: In 2018, we split our implementation of "Po

Parity Technologies 6.5k Jan 6, 2023
⋰·⋰ Feeless is a Nano cryptocurrency node, wallet, tools, and Rust crate.

⋰·⋰ Feeless What is Feeless? Feeless is a Nano cryptocurrency node, wallet, tools, and Rust crate. This is not the official project for Nano, only an

null 127 Dec 5, 2022