@aigne/afs-did-space implements DID-scoped persistent storage as an AFS provider. One principal DID maps to one DID Space. A service or blocklet occupies a path prefix inside that space; it does not receive a second parallel storage product.
Package surfaces
| Import / entry | Role |
|---|---|
@aigne/afs-did-space | Package root |
@aigne/afs-did-space/local | Node local provider (DIDSpace) — filesystem objects + SQLite metadata |
@aigne/afs-did-space/cloudflare | Cloudflare provider — D1 index + R2 objects |
@aigne/afs-did-space client / transports | Mount remote or static views as AFS modules |
Package description in source: AIGNE AFS provider for DID-scoped persistent storage with CID-based content deduplication.
Role prefixes under an instance
For an instance fragment, the local provider requires role system or user and builds a role-specific prefix under the principal's blocklet space:
{principalDid}/blocklets/{instance-did}/system/... # installer / instance-owned
{principalDid}/blocklets/{instance-did}/user/... # caller-owned for that principalgetInstanceSpace({ instanceDid, role }) rejects any other role string. Role content trees sit directly at the role root (no extra files/ wrapper). config/ is an internal sibling for provider configuration and is not part of the blocklet /instance view.
When you inspect with CLI, those prefixes appear as logical AFS paths:
/spaces/<user-did>/blocklets/<app-did>/system
/spaces/<user-did>/blocklets/<app-did>/userarc space path prints those fragments. See Inspect local spaces.
Minimal local mount sketch
import { DIDSpace } from "@aigne/afs-did-space/local";
const space = new DIDSpace({
rootPath: "~/.afs/spaces",
userDid: "did:abt:z1...",
});
const afs = await space.getInstanceSpace({
instanceDid: "did:abt:z1blocklet",
role: "system",
});
await afs.write("/hello.txt", { content: "hello" });This sketch shows the provider boundary. It is not a full deployment recipe. Prefer session views (/user, optional /space) inside a running blocklet rather than re-implementing mount selection in application UI code.
Transport capabilities are not equal
connectDIDSpace accepts transport kinds http, ws, and static-readonly. The client strips operations the transport does not support so AFS routing sees undefined methods instead of surprising remote failures.
| Transport | Default access mode | Stripped or unsupported ops (current client) |
|---|---|---|
ws | readwrite (unless overridden) | Full forward set when the transport implements it |
http | readwrite (unless overridden) | stat, search, exec, explain unsupported |
static-readonly | readonly | search, exec unsupported; write / delete stripped by access mode |
Do not treat “mounted in AFS” as a promise that every view can read, write, search, and execute. Write a Blocklet against the operations its chosen transport has actually exposed and tested.
Local and Cloudflare backends also share content-addressed objects (.objects/{cid}), tree indexes, and conformance suites. Backend choice does not by itself equalize transport capabilities.
What this page does not specify
- One physical backend as the only supported deployment.
- Public CDN, anonymous share-as-default, or “open the whole space on the internet” behavior.
- A complete remote import/export operational runbook (cloud subcommands exist on
arc space; they need environment-specific auth and are not re-run as part of this page). - Instance DID lifecycle or VC trust gates.
For session-visible paths over this storage, continue with Session data. For local CLI inspection, continue with Inspect local spaces.