subCollection<U> method

AtCollection<U> subCollection<U>({
  1. required CItem<T> parent,
  2. required String subName,
  3. required Duration defaultExpiration,
  4. U fromJson(
    1. Map<String, dynamic>
    )?,
  5. String? typeTag,
})

Returns an AtCollection of CItems scoped to parent — e.g. the comments on a specific blog post, or the replies on a specific comment.

final comments = posts.subCollection<Comment>(
  parent: post,
  subName: 'comments',
  defaultExpiration: const Duration(days: 30),
  fromJson: Comment.fromJson,
);
await comments.create(obj: Comment('great post'));

The returned collection is a plain AtCollection<U>; it supports every method of the parent class, including further nesting:

final replies = comments.subCollection<Reply>(
  parent: aComment,
  subName: 'replies',
  defaultExpiration: const Duration(days: 30),
  fromJson: Reply.fromJson,
);

Nesting depth is bounded by the Atsign Protocol's 255-char key limit. The composed namespace this call produces is <subName>.<parent.id>.<this.namespace>. The absolute worst-case on-wire key for any descendant is the cached-copy shape cached:<other-atsign>:<itemId>.<composedNs>@<self-atsign>; at 55 chars per atSign that's a fixed wrapper overhead of 118 chars (cached: 7 + <other> 55 + : 1 + @<self> 55), leaving 137 chars for <itemId>.<composedNs>. Reserving 8 chars for the SDK's auto-generated item id and 1 for the separator, composedNs is capped at 128 chars — applied independently of the actual self-atSign length so the same SDK builds round-trip-safe keys regardless of which atSign owns this client.

Throws ArgumentError when:

  • subName is empty;
  • subName contains a .;
  • subName is __rr (reserved for the built-in read-receipt sub-collection — use item.readBy / item.markReadByMe / AtCollection.readReceiptsFor instead);
  • parent.id contains a .;
  • the composed namespace would exceed 128 chars.

Parent-delete behaviour. When parent is deleted — locally, or via a remote-delete notification — the sub-collection automatically deletes this atSign's own items scoped to it. See cleanupOrphans for the cold-start / offline recovery equivalent.

Implementation

AtCollection<U> subCollection<U>({
  required CItem<T> parent,
  required String subName,
  required Duration defaultExpiration,
  U Function(Map<String, dynamic>)? fromJson,
  String? typeTag,
}) =>
    _subCollectionInternal<U>(
      parent: parent,
      subName: subName,
      defaultExpiration: defaultExpiration,
      fromJson: fromJson,
      typeTag: typeTag,
    );