internal Task SendOpAsync(IDocumentInternal doc, OpMessageType msgType, int seq, JToken op)
        {
            var msg = new JObject(
                new JProperty("a", "op"),
                new JProperty("c", doc.Collection),
                new JProperty("d", doc.Id),
                new JProperty("v", doc.Version < 0 ? null : (int?)doc.Version),
                new JProperty("src", _id),
                new JProperty("seq", seq));

            switch (msgType)
            {
            case OpMessageType.Op:
                msg["op"] = op.DeepClone();
                break;

            case OpMessageType.Create:
                msg["create"] = new JObject(
                    new JProperty("type", doc.Type.Uri.ToString()),
                    new JProperty("data", op.DeepClone()));
                break;

            case OpMessageType.Delete:
                msg["del"] = true;
                break;
            }
            return(_socket.SendTextAsync(msg.ToString()));
        }
        internal Task SendFetchAsync(IDocumentInternal doc)
        {
            var msg = new JObject(
                new JProperty("a", "f"),
                new JProperty("c", doc.Collection),
                new JProperty("d", doc.Id),
                new JProperty("v", doc.Version < 0 ? null : (int?)doc.Version));

            return(_socket.SendTextAsync(msg.ToString()));
        }