-
Notifications
You must be signed in to change notification settings - Fork 4
Description
Overview
Not sure where juno datastore collections fit into the vision and I know the docs primarily mention the use case of user-generated assets, like in my example I use it for user profile avatars.
But what if we make it easier to use it for more, would you be open to this?
Juno has the hosting command for frontend assets and datastore collections, but what about poor neglected storage datastores? 😁
Motivation
I have been testing storing larger assets for a web game in different locations like
- Amazon S3
- StorJ
- ICP Assets Canister
- Juno Storage Collection
Cost & Feature Comparison
| Amazon S3 | StorJ | ICP Assets Canister | Juno Storage | |
|---|---|---|---|---|
| Monthly min | ~$0.50 | $4/mo flat | ~$0.50 (cycles) | ~$0.50 (cycles) |
| Storage (1 GB) | $0.023/GB | included in $4 | ~$5/GB/yr cycles | ~$5/GB/yr cycles |
| Egress | $0.09/GB | $7/TB | free (boundary nodes) | free (boundary nodes) |
| Upload | API/SDK | API/SDK | dfx CLI | ❌ no CLI support |
| Prune stale assets | manual/lifecycle rules | manual | manual | ❌ no CLI support |
| Decentralized | ❌ | ✅ | ✅ | ✅ |
| On-chain certified | ❌ | ❌ | ✅ | ✅ |
Result: Juno Storage Collections are the best fit for decentralized game assets — competitive on cost, on-chain certified, zero egress fees. The only missing piece is CLI tooling to deploy/prune/clear storage assets the same way juno hosting manages frontend assets.
Gap
There doesn't currently exist a way I can easily see to decoratively manage my game assets using juno.
Proposal
Would you be open to something like this?
juno storage --help
__ __ __ __ _ ____
__) || | || \| |/ \
\___/ \___/ |_|\__|\____/ CLI vTEST
Deploy and manage assets in your satellite storage collections.
Usage: juno storage <subcommand> [options]
Subcommands:
clear Remove assets from your satellite storage collections.
deploy Deploy files to your satellite storage collections.
prune Remove stale assets from your satellite storage collections that are no longer in your lo
cal source.You would define it something like this in your juno.config.mjs
import {defineConfig} from "@junobuild/config";
export default defineConfig(() => ({
satellite: {
ids: {
development: "your-satellite-id",
},
source: "build",
collections: {
storage: [
{collection: "audio", read: "public", write: "managed", memory: "heap"},
{collection: "images", read: "public", write: "managed", memory: "heap"},
],
},
// Map local directories to storage collections for `juno storage deploy`.
// Only collections listed here are affected by deploy/prune/clear.
deploy: [
{source: "storage/audio", collection: "audio"},
{source: "storage/images", collection: "images"},
],
},
}));And use it in a similar way to hosting;
# Upload files from storage/audio/ → "audio" collection, storage/images/ → "images"
juno storage deploy --mode development
# Remove remote assets no longer in local directories
juno storage prune --mode development
# Or, to delete all assets from configured collections
juno storage clear --mode developmentDesign Decisions
- Naming things is hard 😁
- Current prototype uses
deploy. - Could be
configas it gets managed viajuno configanyway? - Could be namespaced
storage.deploy - Could be
uploads - Could be
sync
- Current prototype uses
Issues
This doesn't solve the 40B instruction limit or having a single large asset, but splitting into multiple different storage collections has definitely helped keeping the certification tree smaller, reducing the per-upload storage costs.
My use case only involves HTTP access from boundary nodes, not streaming files in chunks.
Prototype
NOTE: Prototype PRs incoming for discussion...
- juno-js: feat(cli-tools): juno storage cmd juno-js#842
- juno-cli: feat(cli): juno storage cmd #496