Collections
A collection is a named content lane inside a publication. It groups related entries together and determines how their Walrus payload references are stored.
What is a collection?
Collections organize entries into predictable buckets for editorial workflows and API consumers. A publication holds collections in a VecMap<String, Collection> keyed by name. The choice of VecMap reflects the expectation that a publication will have only a small number of named collections.
public struct Collection has store { name: String, storage_mode: u8, // 0 = blob, 1 = quilt; immutable after creation next_entry_id: u64, // monotonic counter entries: Table<u64, Entry>, }
Storage modes
Every collection has a storage_mode set at creation that controls how entry revisions reference Walrus content.
Each entry revision references a standalone Walrus Blob object by its Sui object ID.
Each entry revision stores a 37-byte QuiltPatchId pointing to a patch within a shared Walrus Quilt blob.
Blob mode
In blob mode, every revision stores a BlobRef::Blob(ID), the Sui object ID of a standalone Walrus Blob. Each entry revision is fully independent: uploading new content creates a new blob, and the old blobs remain accessible by their IDs.
Best for:
- Articles, blog posts, documentation pages
- Media libraries (images, videos, audio)
- Any collection where entries change independently and frequently
- Situations where you want maximum operational simplicity
Quilt mode
In quilt mode, every revision stores a BlobRef::QuiltPatch(vector<u8>), a 37-byte identifier that locates a patch within a shared Walrus Quilt blob. This is more compact and efficient when updating small parts of a grouped content set.
┌──────────────────────────────┬─────────┬───────────────┬─────────────┐ │ quilt_blob_id (32 bytes) │ ver (1) │ start_idx (2) │ end_idx (2) │ └──────────────────────────────┴─────────┴───────────────┴─────────────┘ Walrus blob ID of the quilt version start index end index (this is the Walrus blob_id, (u16 LE) (u16 LE) not the Sui object ID)
The contract validates that every QuiltPatchId is exactly 37 bytes. Shorter or longer byte vectors are rejected with EInvalidQuiltPatchId.
Best for:
- Website navigation sections or config-like structured documents
- Compact content sets updated in place (e.g. featured banners, site metadata)
- Stable grouped content with targeted patch updates
Choosing a storage mode
| Scenario | Recommended mode |
|---|---|
| Growing blog / article feed | Blob (0) |
| Frequently updated individual documents | Blob (0) |
| Media / asset library | Blob (0) |
| Static site sections (header, footer, nav) | Quilt (1) |
| Config JSONs updated as a group | Quilt (1) |
| Small, bounded content sets | Quilt (1) |
storage_mode, it cannot be changed. All entries in the collection must use references that match the collection's storage mode. The contract enforces this on every write. Creating a collection
Collections are created through the publication module's create_collection function, which requires a valid PublisherCap.
A collection cannot exist outside of a publication; every collection is scoped to exactly one.
The --mode flag sets the storage mode (blob or quilt); defaults to blob if omitted.
morse collection create <name> [--mode <blob|quilt>]
The new collection is automatically selected as the active collection, so follow-up entry commands target it by default.
morse collection create articles --mode blob morse collection create site-pages --mode quilt
Created collection "articles". Selected as the active collection. (tx: AbCdEf...)
import { createCollection } from "@arcadiasystems/morse-sdk"; // See sdk-client-setup.html for adapter and config initialization // publicationId and publisherCapId come from createPublication(); see the Publications page const result = await createCollection(adapter, config, { publicationId: "0x1a2b...3c4d", publisherCapId: "0x7a8b...", name: "articles", storageMode: "blob", }); // result → { digest, gasUsedMist }
public fun create_collection( publication: &mut Publication, cap: &PublisherCap, name: String, storage_mode: u8, // 0 = blob, 1 = quilt ctx: &mut TxContext, )
Use SDK Setup → morseConfig() to get the package ID and registry ID, SDK Setup → Server setup to initialize the client, and Contract Cookbooks for complete PTB examples.
Collection names must be unique within a publication. Creating a collection with a name that already exists aborts with ECollectionAlreadyExists.
morse entry add command does not yet support populating them. To work with quilt-mode entries, use the SDK or construct PTBs directly. Blob mode is recommended for most use cases.To list collections in a publication, use the CLI: morse collection list.
See CLI Commands → Collection for the full syntax.
Deleting a collection
Collections can be deleted, but only when all entries have been removed first.
Pass -y before the subcommand to skip the prompt (e.g. morse -y collection delete <name>).
morse collection delete <name>
morse collection delete articles
import { deleteCollection } from "@arcadiasystems/morse-sdk"; await deleteCollection(adapter, config, { publicationId: "0x1a2b...3c4d", publisherCapId: "0x7a8b...", name: "articles", });
public fun delete_collection( publication: &mut Publication, cap: &PublisherCap, name: String, ctx: &mut TxContext, )
Entries must be removed first because the Table<u64, Entry> that holds them requires an explicit destroy_empty. Sui's type system does not allow dropping a non-empty table. Delete entries individually with delete_entry_from_collection before removing the collection.
Events
Collection lifecycle events are emitted by the publication module.
| Event | When emitted | Fields |
|---|---|---|
CollectionAdded |
Collection created in a publication | publication: ID, name: String |
CollectionRemoved |
Collection deleted from a publication | publication: ID, name: String |
Error codes
For more error codes, see: Publications, Entries, Access Control.
| Code | Constant | Meaning |
|---|---|---|
0 | ECollectionAlreadyExists | A collection with this name already exists in the publication (from publication module) |
0 | EEntryNotFound | No entry exists for the requested entry_id (from collection module) |
1 | EInvalidStorageMode | Storage mode must be 0 or 1 |
11 | EInvalidQuiltPatchId | Quilt patch ID must be exactly 37 bytes (from entry module) |