ChatTextMutation.prepare constructor

ChatTextMutation.prepare({
  1. required List<ChatTextAppend> parts,
  2. required Map<ChatMessage, int> previousRetained,
  3. required ChatInputBudget inputBudget,
  4. ChatMessage? omissionTarget,
  5. ChatInputOmission? omission,
})

Implementation

factory ChatTextMutation.prepare({
  required List<ChatTextAppend> parts,
  required Map<ChatMessage, int> previousRetained,
  required ChatInputBudget inputBudget,
  ChatMessage? omissionTarget,
  ChatInputOmission? omission,
}) {
  final projections = HashMap<ChatMessage, _MessageMutation>.identity();
  _MessageMutation projectionFor(ChatMessage message) =>
      projections.putIfAbsent(message, () {
        final retained = previousRetained[message];
        if (retained == null) {
          throw StateError('Message is not owned by the active ledger');
        }
        return _MessageMutation(message, retained);
      });
  for (final part in parts) {
    if (part.acceptedUtf8Bytes < 0) throw ArgumentError('Negative text size');
    projectionFor(part.target).acceptedUtf8Bytes += part.acceptedUtf8Bytes;
  }
  if (omissionTarget != null && omission != null) {
    final p = projectionFor(omissionTarget);
    if (!p.omissions.any(
          (old) =>
              old.resource == omission.resource &&
              old.reason == omission.reason,
        ) &&
        p.omissions.length < inputBudget.maxCollectionItems) {
      p.omissions.add(omission);
    }
  }
  var totalDelta = 0;
  final next = HashMap<ChatMessage, int>.identity();
  for (final p in projections.values) {
    final retained = projectionEstimateChatMessageRetainedBytes(
      metadata: p.message.metadata,
      omissions: p.omissions,
      acceptedUtf8Bytes: p.acceptedUtf8Bytes,
      inputBudget: inputBudget,
    );
    final delta = retained - p.previousRetained;
    if (delta < 0) throw StateError('Append cannot shrink retained content');
    totalDelta = projectionCheckedRetainedAdd(totalDelta, delta);
    next[p.message] = retained;
  }
  return ChatTextMutation._(
    List.unmodifiable(parts),
    omissionTarget,
    omission,
    totalDelta,
    Map.unmodifiable(next),
    {for (final m in projections.keys) m: m.revision},
  );
}