Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
e97fc1f
add deno lock
jeff-hykin Apr 19, 2025
bf93add
get working on macos
jeff-hykin Apr 20, 2025
ec682e4
name distinction pt1
jeff-hykin Apr 20, 2025
c4f385d
name distinction pt2
jeff-hykin Apr 20, 2025
94b2719
name distinction pt3
jeff-hykin Apr 20, 2025
837bd24
add example to bindContext
jeff-hykin Apr 20, 2025
953e334
patch directory test to get context.test.js passing
jeff-hykin Apr 20, 2025
05daf81
fix --preserve in test script
jeff-hykin Apr 20, 2025
e3e2791
fix some not-awaited directory tests
jeff-hykin Apr 20, 2025
cb8f75b
add missing specifier for buffer
jeff-hykin Apr 20, 2025
0effbc9
isolated tree works!
jeff-hykin Apr 20, 2025
0e582f6
add ergonomic interface for it
jeff-hykin Apr 20, 2025
9860d4c
Merge remote-tracking branch 'upstream/main'
jeff-hykin Jul 10, 2025
80e08e8
Merge branch 'main' into multi
jeff-hykin Jul 10, 2025
93433ba
create core approach to isolated context
jeff-hykin Jul 11, 2025
f35774b
make normalizePath use context
jeff-hykin Jul 11, 2025
12ff9bf
add flake to help with build issues
jeff-hykin Sep 4, 2025
046d336
allow visualizing circular dependencies
jeff-hykin Sep 4, 2025
2d03216
fix circular dependency
jeff-hykin Sep 4, 2025
67c1d3c
Merge remote-tracking branch 'upstream/main' into multi
jeff-hykin Sep 5, 2025
a35426a
merge fix; all tests passing except port
jeff-hykin Sep 5, 2025
35e686b
remove debugging
jeff-hykin Sep 5, 2025
5bae834
fix edgecase, all tests passing!
jeff-hykin Sep 5, 2025
773bc65
change feature name
jeff-hykin Sep 5, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,341 changes: 1,341 additions & 0 deletions deno.lock

Large diffs are not rendered by default.

167 changes: 167 additions & 0 deletions flake.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

125 changes: 125 additions & 0 deletions flake.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
{
description = "ZenFS";
inputs = {
libSource.url = "github:divnix/nixpkgs.lib";
flake-utils.url = "github:numtide/flake-utils";
nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.05";
home-manager.url = "github:nix-community/home-manager/release-25.05";
home-manager.inputs.nixpkgs.follows = "nixpkgs";
xome.url = "github:jeff-hykin/xome";
xome.inputs.nixpkgs.follows = "nixpkgs";
xome.inputs.home-manager.follows = "home-manager";
};
outputs = { self, flake-utils, nixpkgs, xome, ... }:
flake-utils.lib.eachSystem flake-utils.lib.defaultSystems (system:
let
pkgs = import nixpkgs {
inherit system;
overlays = [
];
config = {
allowUnfree = true;
allowInsecure = false;
permittedInsecurePackages = [
];
};
};
inputPackages = [
pkgs.nodejs
pkgs.esbuild
pkgs.graphviz
pkgs.nodePackages.typescript
pkgs.nodePackages.prettier
];
in
{
# this is how the package is built (as a dependency)
packages.default = pkgs.stdenv.mkDerivation {
name = "my-ts-app";
src = ./.;

buildInputs = inputPackages;

buildPhase = ''
export HOME=$(mktemp -d) # Needed by npm to avoid global install warnings
npm install
tsc
'';

installPhase = ''
mkdir -p $out
cp -r dist/* $out/
'';
};

# development environment for contributions
devShells = xome.simpleMakeHomeFor {
inherit pkgs;
pure = true;
homeModule = {
# for home-manager examples, see:
# https://deepwiki.com/nix-community/home-manager/5-configuration-examples
# all home-manager options:
# https://nix-community.github.io/home-manager/options.xhtml
home.homeDirectory = "/tmp/virtual_homes/zenfs";
home.stateVersion = "25.05";
home.packages = inputPackages ++ [
# vital stuff
pkgs.dash # provides "sh"
pkgs.coreutils-full

# optional stuff
pkgs.gnugrep
pkgs.findutils
pkgs.wget
pkgs.curl
pkgs.unixtools.locale
pkgs.unixtools.more
pkgs.unixtools.ps
pkgs.unixtools.getopt
pkgs.unixtools.ifconfig
pkgs.unixtools.hostname
pkgs.unixtools.ping
pkgs.unixtools.hexdump
pkgs.unixtools.killall
pkgs.unixtools.mount
pkgs.unixtools.sysctl
pkgs.unixtools.top
pkgs.unixtools.umount
pkgs.git
pkgs.htop
pkgs.ripgrep
];

programs = {
home-manager = {
enable = true;
};
zsh = {
enable = true;
enableCompletion = true;
autosuggestion.enable = true;
syntaxHighlighting.enable = true;
shellAliases.ll = "ls -la";
history.size = 100000;
# this is kinda like .zshrc
initContent = ''
# lots of things need "sh"
ln -s "$(which dash)" "$HOME/.local/bin/sh" 2>/dev/null

# this enables some impure stuff like sudo, comment it out to get FULL purity
# export PATH="$PATH:/usr/bin/"
echo
echo "NOTE: if you want to use sudo/git/vim/etc (anything impure) do: sys <that command>"
'';
};
starship = {
enable = true;
enableZshIntegration = true;
};
};
};
};
}
);
}
23 changes: 23 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,29 @@ const contents = fs.readFileSync('/test.txt', 'utf-8');
console.log(contents);
```

#### Mount Namespaces

If making middleware, and the downstream consumer isn't providing a file system, you can make an isolated file system. This prevents accidental conflict if multiple middlewares use ZenFS.

```js
import { configureIsolated, fs as globalThisFs } from '@zenfs/core';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So configureIsolated doesn't actually exist. Also, I'd like to avoiding creating yet another configure function.

Let's adopt a similar approach as Linux where creating a new context (e.g. with boundContext) can include a new set of mounts (no new function needed). Maybe we should also have a flag for sharing subtrees (see mount_namespaces(7).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops, yeah my readme edit is completely out of date. I'll add that to the cleaning list


// create a local fs
const {fs, path} = await configureIsolated({
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Normally the context examples use fs for the global and ctx or context for the conext's FS. Let's stay consistent.

pwd: '/home',
credentials: { uid: 1000, gid: 1000 },
mounts: {
'/': InMemory,
'/home': InMemory,
},
});

fs.writeFileSync('/home/test.txt', 'isolated');
globalThisFs.writeFileSync('/home/test.txt', 'global');
// still says "isolated"
console.log(fs.readFileSync('/home/test.txt', 'utf8'));
```

#### FS Promises

The FS promises API is exposed as `promises`.
Expand Down
Loading
Loading