mirror of
https://github.com/anyproto/anytype-heart.git
synced 2025-06-10 01:51:07 +09:00
GO-5143 Merge branch 'go-4932-type-dataview-widget' into go-5143-sync-rellinks-on-view-relations-update
This commit is contained in:
commit
bd6fbef0a8
69 changed files with 4906 additions and 2748 deletions
34
.github/scripts/is_runner_busy.sh
vendored
Executable file
34
.github/scripts/is_runner_busy.sh
vendored
Executable file
|
@ -0,0 +1,34 @@
|
|||
#!/bin/bash
|
||||
|
||||
# The script checks whether a runner with a specific label is busy
|
||||
|
||||
OWNER_REPO=$1
|
||||
CHECK_LABELS=$2
|
||||
|
||||
if [[ -z $OWNER_REPO ]]; then
|
||||
cat <<EOF 1>&2
|
||||
Usage: $0 OWNER/REPO CHECK_LABELS
|
||||
|
||||
example: $0 anyproto/test-concurrency "self-hosted ubuntu-latest"
|
||||
EOF
|
||||
exit 1
|
||||
fi
|
||||
|
||||
EXIT_CODE=0
|
||||
|
||||
# get current runners id
|
||||
# gh api repos/anyproto/test-concurrency/actions/runs --jq '.workflow_runs[] | select(.status!="completed") | {id, name, status, created_at, html_url}'
|
||||
for RUN_ID in $(gh api repos/${OWNER_REPO}/actions/runs --jq '.workflow_runs[] | select(.status!="completed") | .id'); do
|
||||
# get runner_name
|
||||
LABELS=$(gh api repos/${OWNER_REPO}/actions/runs/${RUN_ID}/jobs --jq '[.jobs[].labels[]] | unique | .[]')
|
||||
for CHECK_LABEL in $CHECK_LABELS; do
|
||||
if echo "$LABELS" | grep -q "$CHECK_LABEL"; then
|
||||
echo "A run='$RUN_ID' is executing on a runner with LABEL='$CHECK_LABEL' in the repository='$OWNER_REPO'" 1>&2
|
||||
EXIT_CODE=$(( EXIT_CODE + 1 ))
|
||||
else
|
||||
continue
|
||||
fi
|
||||
done
|
||||
done
|
||||
|
||||
exit $EXIT_CODE
|
4
.github/workflows/build.yml
vendored
4
.github/workflows/build.yml
vendored
|
@ -22,7 +22,11 @@ permissions:
|
|||
|
||||
|
||||
jobs:
|
||||
wait_for_perftest:
|
||||
uses: ./.github/workflows/reusable_wait_for_perftest.yml
|
||||
|
||||
build:
|
||||
needs: wait_for_perftest
|
||||
runs-on: ${{ github.event_name == 'push' && 'mac-mini-org-heart' || (github.event.inputs.run-on-runner || 'mac-mini-org-heart') }}
|
||||
steps:
|
||||
- name: validate agent
|
||||
|
|
4
.github/workflows/nightly.yml
vendored
4
.github/workflows/nightly.yml
vendored
|
@ -29,7 +29,11 @@ permissions:
|
|||
contents: 'write'
|
||||
|
||||
jobs:
|
||||
wait_for_perftest:
|
||||
uses: ./.github/workflows/reusable_wait_for_perftest.yml
|
||||
|
||||
build:
|
||||
needs: wait_for_perftest
|
||||
runs-on: ${{ github.event.inputs.run-on-runner }}
|
||||
steps:
|
||||
- name: Install Go
|
||||
|
|
4
.github/workflows/perftests-grafana.yml
vendored
4
.github/workflows/perftests-grafana.yml
vendored
|
@ -26,7 +26,11 @@ permissions:
|
|||
|
||||
|
||||
jobs:
|
||||
wait_for_self_hosted_mac_mini:
|
||||
uses: ./.github/workflows/reusable_wait_for_self_hosted_mac_mini.yml
|
||||
|
||||
perftests-grafana:
|
||||
needs: wait_for_self_hosted_mac_mini
|
||||
runs-on: ${{ github.event.inputs.run-on-runner || 'mac-mini-org-heart' }}
|
||||
steps:
|
||||
- name: Install Go
|
||||
|
|
4
.github/workflows/perftests.yml
vendored
4
.github/workflows/perftests.yml
vendored
|
@ -31,7 +31,11 @@ permissions:
|
|||
|
||||
|
||||
jobs:
|
||||
wait_for_self_hosted_mac_mini:
|
||||
uses: ./.github/workflows/reusable_wait_for_self_hosted_mac_mini.yml
|
||||
|
||||
perftests-macos:
|
||||
needs: wait_for_self_hosted_mac_mini
|
||||
timeout-minutes: 60
|
||||
runs-on: 'mac-mini-org-heart'
|
||||
steps:
|
||||
|
|
22
.github/workflows/reusable_wait_for_perftest.yml
vendored
Normal file
22
.github/workflows/reusable_wait_for_perftest.yml
vendored
Normal file
|
@ -0,0 +1,22 @@
|
|||
name: Reusable Workflow wait for perftests to finish
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
|
||||
jobs:
|
||||
wait_for_perftest:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Wait for perftests to finish
|
||||
run: |
|
||||
while true; do
|
||||
RUNNING=$(gh run list --repo $GITHUB_REPOSITORY --workflow perftests.yml --workflow perftests-grafana.yml --status in_progress --json status --jq 'length')
|
||||
if [[ "$RUNNING" -eq 0 ]]; then
|
||||
echo "perftests is finished, proceeding with build."
|
||||
break
|
||||
fi
|
||||
echo "perftests is still running. Waiting 10 seconds..."
|
||||
sleep 10
|
||||
done
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
26
.github/workflows/reusable_wait_for_self_hosted_mac_mini.yml
vendored
Normal file
26
.github/workflows/reusable_wait_for_self_hosted_mac_mini.yml
vendored
Normal file
|
@ -0,0 +1,26 @@
|
|||
name: Reusable Workflow wait for self-hosted mac mini is free
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
|
||||
jobs:
|
||||
wait_for_self_hosted_mac_mini:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Wait for self-hosted runners to be free
|
||||
run: |
|
||||
while true; do
|
||||
if .github/scripts/is_runner_busy.sh $GITHUB_REPOSITORY mac-mini-org-heart; then
|
||||
echo "self-hosted runner 'mac-mini-org-heart' is free"
|
||||
break
|
||||
else
|
||||
echo "self-hosted runner 'mac-mini-org-heart' is busy. waiting 10 seconds..."
|
||||
sleep 10
|
||||
continue
|
||||
fi
|
||||
done
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
4
.github/workflows/test.yml
vendored
4
.github/workflows/test.yml
vendored
|
@ -16,7 +16,11 @@ permissions:
|
|||
pull-requests: write
|
||||
|
||||
jobs:
|
||||
wait_for_perftest:
|
||||
uses: ./.github/workflows/reusable_wait_for_perftest.yml
|
||||
|
||||
unit-test:
|
||||
needs: wait_for_perftest
|
||||
runs-on: ${{ vars.RUNNER_TEST }}
|
||||
env:
|
||||
GOPRIVATE: github.com/anyproto
|
||||
|
|
|
@ -25,18 +25,18 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
|
|||
func init() { proto.RegisterFile("pb/protos/service/service.proto", fileDescriptor_93a29dc403579097) }
|
||||
|
||||
var fileDescriptor_93a29dc403579097 = []byte{
|
||||
// 5514 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x9d, 0x5f, 0x6f, 0x24, 0x49,
|
||||
0x52, 0xc0, 0xb7, 0x5f, 0x58, 0xa8, 0xe3, 0x16, 0xe8, 0x85, 0x65, 0x6f, 0xb9, 0x9b, 0x99, 0x9d,
|
||||
0x9d, 0xb1, 0x3d, 0x63, 0xbb, 0x3d, 0x3b, 0xb3, 0xff, 0xb8, 0x43, 0x82, 0x1e, 0x7b, 0xec, 0xf5,
|
||||
0x9d, 0xed, 0x35, 0xee, 0xf6, 0x8c, 0xb4, 0x12, 0x12, 0xe5, 0xaa, 0x74, 0xbb, 0x70, 0x75, 0x65,
|
||||
0x5d, 0x55, 0x76, 0x7b, 0xfa, 0x10, 0x08, 0x04, 0x02, 0x81, 0x40, 0x9c, 0xf8, 0x27, 0x78, 0x42,
|
||||
0x42, 0x7c, 0x00, 0x3e, 0x06, 0x8f, 0xf7, 0xc8, 0x23, 0xda, 0xfd, 0x0a, 0x7c, 0x00, 0x54, 0xf9,
|
||||
0x3f, 0xa3, 0x32, 0xb2, 0xca, 0xcb, 0xd3, 0x8c, 0x1c, 0xbf, 0x88, 0xc8, 0xac, 0x8c, 0xcc, 0x8c,
|
||||
0xcc, 0xca, 0xca, 0x8e, 0xee, 0x96, 0x17, 0x3b, 0x65, 0x45, 0x19, 0xad, 0x77, 0x6a, 0x52, 0x2d,
|
||||
// 5536 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x9d, 0x4f, 0x6f, 0x24, 0x49,
|
||||
0x56, 0xc0, 0xa7, 0x2e, 0x0c, 0xe4, 0xb2, 0x03, 0xd4, 0xc0, 0x30, 0x3b, 0xec, 0x76, 0xf7, 0xf4,
|
||||
0x74, 0xdb, 0xee, 0xb6, 0x5d, 0xee, 0xe9, 0x9e, 0x7f, 0xec, 0x22, 0x41, 0xb5, 0xdd, 0xf6, 0x78,
|
||||
0xd7, 0xf6, 0x18, 0x57, 0xb9, 0x5b, 0x1a, 0x09, 0x89, 0x74, 0x66, 0xb8, 0x9c, 0x38, 0x2b, 0x23,
|
||||
0x37, 0x33, 0xaa, 0xdc, 0xb5, 0x08, 0x04, 0x02, 0x81, 0x40, 0x20, 0x56, 0xfc, 0x13, 0x9c, 0x90,
|
||||
0xf8, 0x04, 0x1c, 0xf8, 0x10, 0x1c, 0xf7, 0xc8, 0x11, 0xcd, 0x7c, 0x06, 0xee, 0x28, 0xe3, 0x7f,
|
||||
0xbc, 0x8c, 0x17, 0x99, 0x1e, 0x4e, 0xdd, 0xf2, 0xfb, 0xbd, 0xf7, 0x22, 0x32, 0x5e, 0x44, 0xbc,
|
||||
0x88, 0x8c, 0x8c, 0x8a, 0xee, 0x96, 0x17, 0x3b, 0x65, 0x45, 0x19, 0xad, 0x77, 0x6a, 0x52, 0x2d,
|
||||
0xb3, 0x84, 0xa8, 0x7f, 0x47, 0xfc, 0xcf, 0xc3, 0x37, 0xe3, 0x62, 0xc5, 0x56, 0x25, 0x79, 0xef,
|
||||
0x5d, 0x43, 0x26, 0x74, 0x3e, 0x8f, 0x8b, 0xb4, 0x16, 0xc8, 0x7b, 0xef, 0x18, 0x09, 0x59, 0x92,
|
||||
0x82, 0xc9, 0xbf, 0x3f, 0xfd, 0x8f, 0xff, 0x1d, 0x44, 0x6f, 0xed, 0xe6, 0x19, 0x29, 0xd8, 0xae,
|
||||
0x82, 0xc9, 0xbf, 0x3f, 0xfd, 0xcf, 0xff, 0x1d, 0x44, 0x6f, 0xed, 0xe6, 0x19, 0x29, 0xd8, 0xae,
|
||||
0xd4, 0x18, 0x7e, 0x19, 0x7d, 0x7b, 0x5c, 0x96, 0x07, 0x84, 0xbd, 0x24, 0x55, 0x9d, 0xd1, 0x62,
|
||||
0xf8, 0xc1, 0x48, 0x3a, 0x18, 0x9d, 0x95, 0xc9, 0x68, 0x5c, 0x96, 0x23, 0x23, 0x1c, 0x9d, 0x91,
|
||||
0x1f, 0x2f, 0x48, 0xcd, 0xde, 0x7b, 0x10, 0x86, 0xea, 0x92, 0x16, 0x35, 0x19, 0x5e, 0x46, 0xbf,
|
||||
|
@ -179,7 +179,7 @@ var fileDescriptor_93a29dc403579097 = []byte{
|
|||
0xb4, 0xf4, 0xfa, 0x47, 0xd1, 0xbb, 0x6d, 0xaf, 0x72, 0x22, 0xda, 0xe9, 0x34, 0x05, 0xe6, 0xa2,
|
||||
0x27, 0xfd, 0x15, 0xa4, 0xfb, 0x7f, 0xd1, 0xfb, 0xd2, 0xc2, 0x7f, 0x42, 0xe7, 0x73, 0x52, 0xa4,
|
||||
0x24, 0x55, 0x1a, 0x75, 0xb3, 0x7e, 0xfa, 0x0c, 0xb7, 0xab, 0x15, 0x46, 0xb6, 0x86, 0x2e, 0xd1,
|
||||
0x6f, 0x7e, 0x03, 0x4d, 0x59, 0xb4, 0xff, 0x1c, 0x44, 0x8f, 0xbc, 0x45, 0x53, 0x81, 0xeb, 0x14,
|
||||
0x6f, 0x7e, 0x03, 0x4d, 0x59, 0xb4, 0xff, 0x18, 0x44, 0x8f, 0xbc, 0x45, 0x53, 0x81, 0xeb, 0x14,
|
||||
0xf1, 0x77, 0xfa, 0x38, 0xf2, 0x69, 0xea, 0xa2, 0x8e, 0xff, 0x1f, 0x16, 0x64, 0x91, 0xff, 0x75,
|
||||
0x10, 0xdd, 0x37, 0x8a, 0x4d, 0x78, 0xef, 0xd2, 0xe2, 0x32, 0xcf, 0x12, 0xc6, 0xdf, 0xc8, 0x4a,
|
||||
0x15, 0xfc, 0x71, 0x62, 0x1a, 0xdd, 0x8f, 0x33, 0xa0, 0x69, 0x16, 0xaf, 0x9f, 0x67, 0x35, 0xa3,
|
||||
|
@ -365,12 +365,13 @@ var fileDescriptor_93a29dc403579097 = []byte{
|
|||
0xf5, 0x24, 0xe0, 0x65, 0x53, 0x5c, 0xd9, 0x12, 0x23, 0xdf, 0xbd, 0x79, 0x30, 0xb3, 0x4e, 0x00,
|
||||
0x1e, 0x9e, 0xaf, 0x0e, 0x53, 0xb8, 0x4e, 0x80, 0xfa, 0x9c, 0x41, 0xd6, 0x09, 0x18, 0xeb, 0x36,
|
||||
0x9d, 0xde, 0xf7, 0x3a, 0x8a, 0x6b, 0x53, 0x39, 0x4f, 0xd3, 0x79, 0xc1, 0x50, 0xd3, 0x61, 0x0a,
|
||||
0xee, 0x23, 0xb5, 0xb7, 0xd6, 0x3c, 0x8f, 0xd4, 0xb7, 0xaf, 0xb6, 0xd6, 0x85, 0x99, 0x71, 0x49,
|
||||
0xaf, 0x27, 0xf9, 0x91, 0x25, 0xff, 0x6f, 0x35, 0x08, 0x21, 0x32, 0x2e, 0xb5, 0x20, 0x61, 0xfb,
|
||||
0xf9, 0xfb, 0xff, 0xf5, 0xd5, 0x9d, 0xc1, 0xcf, 0xbe, 0xba, 0x33, 0xf8, 0x9f, 0xaf, 0xee, 0x0c,
|
||||
0x7e, 0xfa, 0xf5, 0x9d, 0x37, 0x7e, 0xf6, 0xf5, 0x9d, 0x37, 0xfe, 0xfb, 0xeb, 0x3b, 0x6f, 0x7c,
|
||||
0xf9, 0xa6, 0xfc, 0x2d, 0xea, 0x8b, 0x9f, 0xe3, 0xbf, 0x28, 0xfd, 0xec, 0xff, 0x02, 0x00, 0x00,
|
||||
0xff, 0xff, 0xc9, 0x60, 0xbd, 0x6d, 0xaf, 0x7a, 0x00, 0x00,
|
||||
0xee, 0x23, 0xb5, 0xb7, 0xd6, 0x3c, 0x8f, 0xd4, 0xb7, 0xaf, 0xb6, 0xd6, 0x85, 0x59, 0x89, 0x8f,
|
||||
0x53, 0xc5, 0x29, 0x95, 0xc5, 0x90, 0xdf, 0x35, 0xd6, 0x20, 0xf1, 0x71, 0x8b, 0xdd, 0xa2, 0x91,
|
||||
0xc4, 0xa7, 0x5b, 0xcb, 0x8c, 0x93, 0x7a, 0x7d, 0xcb, 0x8f, 0x50, 0xf9, 0x7f, 0x3b, 0x42, 0x08,
|
||||
0x91, 0x71, 0xb2, 0x05, 0x09, 0xdb, 0xcf, 0xdf, 0xff, 0xaf, 0xaf, 0xee, 0x0c, 0x7e, 0xf6, 0xd5,
|
||||
0x9d, 0xc1, 0xff, 0x7c, 0x75, 0x67, 0xf0, 0xd3, 0xaf, 0xef, 0xbc, 0xf1, 0xb3, 0xaf, 0xef, 0xbc,
|
||||
0xf1, 0xdf, 0x5f, 0xdf, 0x79, 0xe3, 0xcb, 0x37, 0xe5, 0x6f, 0x63, 0x5f, 0xfc, 0x1c, 0xff, 0x85,
|
||||
0xeb, 0x67, 0xff, 0x17, 0x00, 0x00, 0xff, 0xff, 0xfd, 0x94, 0x61, 0xee, 0x3f, 0x7b, 0x00, 0x00,
|
||||
}
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
|
@ -723,6 +724,7 @@ type ClientCommandsHandler interface {
|
|||
ChatGetMessagesByIds(context.Context, *pb.RpcChatGetMessagesByIdsRequest) *pb.RpcChatGetMessagesByIdsResponse
|
||||
ChatSubscribeLastMessages(context.Context, *pb.RpcChatSubscribeLastMessagesRequest) *pb.RpcChatSubscribeLastMessagesResponse
|
||||
ChatUnsubscribe(context.Context, *pb.RpcChatUnsubscribeRequest) *pb.RpcChatUnsubscribeResponse
|
||||
ChatSubscribeToMessagePreviews(context.Context, *pb.RpcChatSubscribeToMessagePreviewsRequest) *pb.RpcChatSubscribeToMessagePreviewsResponse
|
||||
ObjectChatAdd(context.Context, *pb.RpcObjectChatAddRequest) *pb.RpcObjectChatAddResponse
|
||||
}
|
||||
|
||||
|
@ -6310,6 +6312,26 @@ func ChatUnsubscribe(b []byte) (resp []byte) {
|
|||
return resp
|
||||
}
|
||||
|
||||
func ChatSubscribeToMessagePreviews(b []byte) (resp []byte) {
|
||||
defer func() {
|
||||
if PanicHandler != nil {
|
||||
if r := recover(); r != nil {
|
||||
resp, _ = (&pb.RpcChatSubscribeToMessagePreviewsResponse{Error: &pb.RpcChatSubscribeToMessagePreviewsResponseError{Code: pb.RpcChatSubscribeToMessagePreviewsResponseError_UNKNOWN_ERROR, Description: "panic recovered"}}).Marshal()
|
||||
PanicHandler(r)
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
in := new(pb.RpcChatSubscribeToMessagePreviewsRequest)
|
||||
if err := in.Unmarshal(b); err != nil {
|
||||
resp, _ = (&pb.RpcChatSubscribeToMessagePreviewsResponse{Error: &pb.RpcChatSubscribeToMessagePreviewsResponseError{Code: pb.RpcChatSubscribeToMessagePreviewsResponseError_BAD_INPUT, Description: err.Error()}}).Marshal()
|
||||
return resp
|
||||
}
|
||||
|
||||
resp, _ = clientCommandsHandler.ChatSubscribeToMessagePreviews(context.Background(), in).Marshal()
|
||||
return resp
|
||||
}
|
||||
|
||||
func ObjectChatAdd(b []byte) (resp []byte) {
|
||||
defer func() {
|
||||
if PanicHandler != nil {
|
||||
|
@ -6894,6 +6916,8 @@ func CommandAsync(cmd string, data []byte, callback func(data []byte)) {
|
|||
cd = ChatSubscribeLastMessages(data)
|
||||
case "ChatUnsubscribe":
|
||||
cd = ChatUnsubscribe(data)
|
||||
case "ChatSubscribeToMessagePreviews":
|
||||
cd = ChatSubscribeToMessagePreviews(data)
|
||||
case "ObjectChatAdd":
|
||||
cd = ObjectChatAdd(data)
|
||||
default:
|
||||
|
@ -10824,6 +10848,20 @@ func (h *ClientCommandsHandlerProxy) ChatUnsubscribe(ctx context.Context, req *p
|
|||
call, _ := actualCall(ctx, req)
|
||||
return call.(*pb.RpcChatUnsubscribeResponse)
|
||||
}
|
||||
func (h *ClientCommandsHandlerProxy) ChatSubscribeToMessagePreviews(ctx context.Context, req *pb.RpcChatSubscribeToMessagePreviewsRequest) *pb.RpcChatSubscribeToMessagePreviewsResponse {
|
||||
actualCall := func(ctx context.Context, req any) (any, error) {
|
||||
return h.client.ChatSubscribeToMessagePreviews(ctx, req.(*pb.RpcChatSubscribeToMessagePreviewsRequest)), nil
|
||||
}
|
||||
for _, interceptor := range h.interceptors {
|
||||
toCall := actualCall
|
||||
currentInterceptor := interceptor
|
||||
actualCall = func(ctx context.Context, req any) (any, error) {
|
||||
return currentInterceptor(ctx, req, "ChatSubscribeToMessagePreviews", toCall)
|
||||
}
|
||||
}
|
||||
call, _ := actualCall(ctx, req)
|
||||
return call.(*pb.RpcChatSubscribeToMessagePreviewsResponse)
|
||||
}
|
||||
func (h *ClientCommandsHandlerProxy) ObjectChatAdd(ctx context.Context, req *pb.RpcObjectChatAddRequest) *pb.RpcObjectChatAddResponse {
|
||||
actualCall := func(ctx context.Context, req any) (any, error) {
|
||||
return h.client.ObjectChatAdd(ctx, req.(*pb.RpcObjectChatAddRequest)), nil
|
||||
|
|
|
@ -53,6 +53,7 @@ func main() {
|
|||
if err != nil {
|
||||
log.Fatal("can't import the tree:", err)
|
||||
}
|
||||
defer res.Store.Close()
|
||||
objectTree, err := res.CreateReadableTree(*fromRoot, "")
|
||||
if err != nil {
|
||||
log.Fatal("can't create readable tree:", err)
|
||||
|
|
|
@ -47,17 +47,21 @@ type (
|
|||
}
|
||||
|
||||
useCaseInfo struct {
|
||||
objects map[string]objectInfo
|
||||
relations map[string]domain.RelationKey
|
||||
types map[string]domain.TypeKey
|
||||
templates map[string]string
|
||||
options map[string]domain.RelationKey
|
||||
files []string
|
||||
objects map[string]objectInfo
|
||||
relations map[string]domain.RelationKey
|
||||
types map[string]domain.TypeKey
|
||||
templates map[string]string
|
||||
options map[string]domain.RelationKey
|
||||
fileObjects []string
|
||||
|
||||
// big data
|
||||
files map[string][]byte
|
||||
snapshots map[string]*pb.SnapshotWithType
|
||||
profile []byte
|
||||
|
||||
customTypesAndRelations map[string]customInfo
|
||||
|
||||
useCase string
|
||||
profileFileFound bool
|
||||
useCase string
|
||||
}
|
||||
|
||||
cliFlags struct {
|
||||
|
@ -68,12 +72,14 @@ type (
|
|||
}
|
||||
)
|
||||
|
||||
func (i customInfo) GetFormat() model.RelationFormat {
|
||||
return i.relationFormat
|
||||
}
|
||||
|
||||
func (f cliFlags) isUpdateNeeded() bool {
|
||||
return f.analytics || f.creator || f.removeRelations || f.exclude || f.rules != ""
|
||||
}
|
||||
|
||||
const anytypeProfileFilename = addr.AnytypeProfileId + ".pb"
|
||||
|
||||
var (
|
||||
errIncorrectFileFound = fmt.Errorf("incorrect protobuf file was found")
|
||||
errValidationFailed = fmt.Errorf("validation failed")
|
||||
|
@ -111,7 +117,7 @@ func run() error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !info.profileFileFound {
|
||||
if info.profile == nil {
|
||||
fmt.Println("profile file does not present in archive")
|
||||
}
|
||||
|
||||
|
@ -129,7 +135,7 @@ func run() error {
|
|||
defer writer.Close()
|
||||
}
|
||||
|
||||
err = processFiles(r.File, writer, info, flags, updateNeeded)
|
||||
err = processFiles(info, writer, flags)
|
||||
|
||||
if flags.list {
|
||||
listObjects(info)
|
||||
|
@ -199,17 +205,13 @@ func collectUseCaseInfo(files []*zip.File, fileName string) (info *useCaseInfo,
|
|||
types: make(map[string]domain.TypeKey, len(files)-1),
|
||||
templates: make(map[string]string),
|
||||
options: make(map[string]domain.RelationKey),
|
||||
files: make([]string, 0),
|
||||
files: make(map[string][]byte),
|
||||
snapshots: make(map[string]*pb.SnapshotWithType, len(files)),
|
||||
fileObjects: make([]string, 0),
|
||||
customTypesAndRelations: make(map[string]customInfo),
|
||||
profileFileFound: false,
|
||||
}
|
||||
for _, f := range files {
|
||||
if f.Name == constant.ProfileFile {
|
||||
info.profileFileFound = true
|
||||
continue
|
||||
}
|
||||
|
||||
if (strings.HasPrefix(f.Name, export.Files) && !strings.HasPrefix(f.Name, export.FilesObjects)) || f.FileInfo().IsDir() {
|
||||
if f.FileInfo().IsDir() {
|
||||
continue
|
||||
}
|
||||
|
||||
|
@ -218,7 +220,17 @@ func collectUseCaseInfo(files []*zip.File, fileName string) (info *useCaseInfo,
|
|||
return nil, err
|
||||
}
|
||||
|
||||
snapshot, _, err := extractSnapshotAndType(data, f.Name)
|
||||
if isPlainFile(f.Name) {
|
||||
info.files[f.Name] = data
|
||||
continue
|
||||
}
|
||||
|
||||
if f.Name == constant.ProfileFile {
|
||||
info.profile = data
|
||||
continue
|
||||
}
|
||||
|
||||
snapshot, err := extractSnapshotAndType(data, f.Name)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to extract snapshot from file %s: %w", f.Name, err)
|
||||
}
|
||||
|
@ -232,6 +244,8 @@ func collectUseCaseInfo(files []*zip.File, fileName string) (info *useCaseInfo,
|
|||
SbType: smartblock.SmartBlockType(snapshot.SbType),
|
||||
}
|
||||
|
||||
info.snapshots[f.Name] = snapshot
|
||||
|
||||
switch snapshot.SbType {
|
||||
case model.SmartBlockType_STRelation:
|
||||
uk := pbtypes.GetString(snapshot.Snapshot.Data.Details, bundle.RelationKeyUniqueKey.String())
|
||||
|
@ -268,7 +282,7 @@ func collectUseCaseInfo(files []*zip.File, fileName string) (info *useCaseInfo,
|
|||
case model.SmartBlockType_STRelationOption:
|
||||
info.options[id] = domain.RelationKey(pbtypes.GetString(snapshot.Snapshot.Data.Details, bundle.RelationKeyRelationKey.String()))
|
||||
case model.SmartBlockType_FileObject:
|
||||
info.files = append(info.files, id)
|
||||
info.fileObjects = append(info.fileObjects, id)
|
||||
}
|
||||
}
|
||||
return
|
||||
|
@ -287,46 +301,47 @@ func readData(f *zip.File) ([]byte, error) {
|
|||
return data, nil
|
||||
}
|
||||
|
||||
func processFiles(files []*zip.File, zw *zip.Writer, info *useCaseInfo, flags *cliFlags, writeNewFile bool) error {
|
||||
var incorrectFileFound bool
|
||||
for _, f := range files {
|
||||
if f.Name == anytypeProfileFilename {
|
||||
fmt.Println(anytypeProfileFilename, "is excluded")
|
||||
continue
|
||||
}
|
||||
data, err := readData(f)
|
||||
func processFiles(info *useCaseInfo, zw *zip.Writer, flags *cliFlags) error {
|
||||
var (
|
||||
incorrectFileFound bool
|
||||
writeNewFile = flags.isUpdateNeeded()
|
||||
)
|
||||
|
||||
if info.profile != nil {
|
||||
data, err := processProfile(info, flags.spaceDashboardId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var newData []byte
|
||||
if f.FileInfo().IsDir() {
|
||||
newData = data
|
||||
} else {
|
||||
newData, err = processRawData(data, f.Name, info, flags)
|
||||
if err != nil {
|
||||
if !(flags.exclude && errors.Is(err, errValidationFailed)) {
|
||||
// just do not include object that failed validation
|
||||
incorrectFileFound = true
|
||||
}
|
||||
continue
|
||||
if writeNewFile {
|
||||
if err = saveDataToZip(zw, constant.ProfileFile, data); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if writeNewFile {
|
||||
for name, data := range info.files {
|
||||
if err := saveDataToZip(zw, name, data); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for name, sn := range info.snapshots {
|
||||
newData, err := processSnapshot(sn, info, flags)
|
||||
if err != nil {
|
||||
if !(flags.exclude && errors.Is(err, errValidationFailed)) {
|
||||
// just do not include object that failed validation
|
||||
incorrectFileFound = true
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
if newData == nil || !writeNewFile {
|
||||
continue
|
||||
}
|
||||
newFileName := f.Name
|
||||
if strings.HasSuffix(newFileName, ".pb.json") {
|
||||
// output of usecase validator is always an archive with protobufs
|
||||
newFileName = strings.TrimSuffix(newFileName, ".json")
|
||||
}
|
||||
nf, err := zw.Create(newFileName)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create new file %s: %w", newFileName, err)
|
||||
}
|
||||
if _, err = io.Copy(nf, bytes.NewReader(newData)); err != nil {
|
||||
return fmt.Errorf("failed to copy snapshot to new file %s: %w", newFileName, err)
|
||||
if err = saveDataToZip(zw, name, newData); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -336,38 +351,40 @@ func processFiles(files []*zip.File, zw *zip.Writer, info *useCaseInfo, flags *c
|
|||
return nil
|
||||
}
|
||||
|
||||
func processRawData(data []byte, name string, info *useCaseInfo, flags *cliFlags) ([]byte, error) {
|
||||
if name == constant.ProfileFile {
|
||||
return processProfile(data, info, flags.spaceDashboardId)
|
||||
func saveDataToZip(zw *zip.Writer, fileName string, data []byte) error {
|
||||
if strings.HasSuffix(fileName, ".pb.json") {
|
||||
// output of usecase validator is always an archive with protobufs
|
||||
fileName = strings.TrimSuffix(fileName, ".json")
|
||||
}
|
||||
|
||||
if strings.HasPrefix(name, "files") {
|
||||
return data, nil
|
||||
}
|
||||
|
||||
snapshot, isOldAccount, err := extractSnapshotAndType(data, name)
|
||||
nf, err := zw.Create(fileName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return fmt.Errorf("failed to create new file %s: %w", fileName, err)
|
||||
}
|
||||
if _, err = io.Copy(nf, bytes.NewReader(data)); err != nil {
|
||||
return fmt.Errorf("failed to copy snapshot to new file %s: %w", fileName, err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func processSnapshot(s *pb.SnapshotWithType, info *useCaseInfo, flags *cliFlags) ([]byte, error) {
|
||||
if flags.analytics {
|
||||
insertAnalyticsData(snapshot.Snapshot, info)
|
||||
insertAnalyticsData(s.Snapshot, info)
|
||||
}
|
||||
|
||||
if flags.removeRelations {
|
||||
removeAccountRelatedDetails(snapshot.Snapshot)
|
||||
removeAccountRelatedDetails(s.Snapshot)
|
||||
}
|
||||
|
||||
if flags.creator {
|
||||
insertCreatorInfo(snapshot.Snapshot)
|
||||
insertCreatorInfo(s.Snapshot)
|
||||
}
|
||||
|
||||
if flags.rules != "" {
|
||||
processRules(snapshot.Snapshot)
|
||||
processRules(s.Snapshot)
|
||||
}
|
||||
|
||||
if flags.validate {
|
||||
if err = validate(snapshot, info); err != nil {
|
||||
if err := validate(s, info); err != nil {
|
||||
if errors.Is(err, errSkipObject) {
|
||||
// some validators register errors mentioning that object can be excluded
|
||||
return nil, nil
|
||||
|
@ -378,51 +395,49 @@ func processRawData(data []byte, name string, info *useCaseInfo, flags *cliFlags
|
|||
}
|
||||
|
||||
if flags.collectCustomUsageInfo {
|
||||
collectCustomObjectsUsageInfo(snapshot, info)
|
||||
collectCustomObjectsUsageInfo(s, info)
|
||||
}
|
||||
|
||||
if isOldAccount {
|
||||
return snapshot.Snapshot.Marshal()
|
||||
if s.SbType == model.SmartBlockType_AccountOld {
|
||||
return s.Snapshot.Marshal()
|
||||
}
|
||||
|
||||
return snapshot.Marshal()
|
||||
return s.Marshal()
|
||||
}
|
||||
|
||||
func extractSnapshotAndType(data []byte, name string) (s *pb.SnapshotWithType, isOldAccount bool, err error) {
|
||||
func extractSnapshotAndType(data []byte, name string) (s *pb.SnapshotWithType, err error) {
|
||||
s = &pb.SnapshotWithType{}
|
||||
if strings.HasSuffix(name, ".json") {
|
||||
if err = jsonpb.UnmarshalString(string(data), s); err != nil {
|
||||
return nil, false, fmt.Errorf("cannot unmarshal snapshot from file %s: %w", name, err)
|
||||
return nil, fmt.Errorf("cannot unmarshal snapshot from file %s: %w", name, err)
|
||||
}
|
||||
if s.SbType == model.SmartBlockType_AccountOld {
|
||||
cs := &pb.ChangeSnapshot{}
|
||||
isOldAccount = true
|
||||
if err = jsonpb.UnmarshalString(string(data), cs); err != nil {
|
||||
return nil, false, fmt.Errorf("cannot unmarshal snapshot from file %s: %w", name, err)
|
||||
return nil, fmt.Errorf("cannot unmarshal snapshot from file %s: %w", name, err)
|
||||
}
|
||||
s = &pb.SnapshotWithType{
|
||||
Snapshot: cs,
|
||||
SbType: model.SmartBlockType_Page,
|
||||
SbType: model.SmartBlockType_AccountOld,
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if err = s.Unmarshal(data); err != nil {
|
||||
return nil, false, fmt.Errorf("cannot unmarshal snapshot from file %s: %w", name, err)
|
||||
return nil, fmt.Errorf("cannot unmarshal snapshot from file %s: %w", name, err)
|
||||
}
|
||||
if s.SbType == model.SmartBlockType_AccountOld {
|
||||
cs := &pb.ChangeSnapshot{}
|
||||
isOldAccount = true
|
||||
if err = cs.Unmarshal(data); err != nil {
|
||||
return nil, false, fmt.Errorf("cannot unmarshal snapshot from file %s: %w", name, err)
|
||||
return nil, fmt.Errorf("cannot unmarshal snapshot from file %s: %w", name, err)
|
||||
}
|
||||
s = &pb.SnapshotWithType{
|
||||
Snapshot: cs,
|
||||
SbType: model.SmartBlockType_Page,
|
||||
SbType: model.SmartBlockType_AccountOld,
|
||||
}
|
||||
}
|
||||
return s, isOldAccount, nil
|
||||
return s, nil
|
||||
}
|
||||
|
||||
func validate(snapshot *pb.SnapshotWithType, info *useCaseInfo) (err error) {
|
||||
|
@ -478,7 +493,8 @@ func removeAccountRelatedDetails(s *pb.ChangeSnapshot) {
|
|||
bundle.RelationKeyAddedDate.String(),
|
||||
bundle.RelationKeySyncDate.String(),
|
||||
bundle.RelationKeySyncError.String(),
|
||||
bundle.RelationKeySyncStatus.String():
|
||||
bundle.RelationKeySyncStatus.String(),
|
||||
bundle.RelationKeyChatId.String():
|
||||
|
||||
delete(s.Data.Details.Fields, key)
|
||||
}
|
||||
|
@ -490,9 +506,9 @@ func insertCreatorInfo(s *pb.ChangeSnapshot) {
|
|||
s.Data.Details.Fields[bundle.RelationKeyLastModifiedBy.String()] = pbtypes.String(addr.AnytypeProfileId)
|
||||
}
|
||||
|
||||
func processProfile(data []byte, info *useCaseInfo, spaceDashboardId string) ([]byte, error) {
|
||||
func processProfile(info *useCaseInfo, spaceDashboardId string) ([]byte, error) {
|
||||
profile := &pb.Profile{}
|
||||
if err := profile.Unmarshal(data); err != nil {
|
||||
if err := profile.Unmarshal(info.profile); err != nil {
|
||||
e := fmt.Errorf("cannot unmarshal profile: %w", err)
|
||||
fmt.Println(e)
|
||||
return nil, e
|
||||
|
@ -564,8 +580,12 @@ func listObjects(info *useCaseInfo) {
|
|||
|
||||
fmt.Println("\n- File Objects:")
|
||||
fmt.Println("Id: " + strings.Repeat(" ", 31) + "Name")
|
||||
for _, id := range info.files {
|
||||
for _, id := range info.fileObjects {
|
||||
obj := info.objects[id]
|
||||
fmt.Printf("%s:\t%32s\n", id[len(id)-4:], obj.Name)
|
||||
}
|
||||
}
|
||||
|
||||
func isPlainFile(name string) bool {
|
||||
return strings.HasPrefix(name, export.Files) && !strings.HasPrefix(name, export.FilesObjects)
|
||||
}
|
||||
|
|
|
@ -4,11 +4,10 @@ package main
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"slices"
|
||||
"strings"
|
||||
|
||||
"github.com/hashicorp/go-multierror"
|
||||
"github.com/ipfs/go-cid"
|
||||
"github.com/samber/lo"
|
||||
|
||||
"github.com/anyproto/anytype-heart/core/block/editor/widget"
|
||||
"github.com/anyproto/anytype-heart/core/block/simple"
|
||||
|
@ -32,7 +31,6 @@ type keyWithIndex struct {
|
|||
}
|
||||
|
||||
var validators = []validator{
|
||||
validateRelationLinks,
|
||||
validateRelationBlocks,
|
||||
validateDetails,
|
||||
validateObjectTypes,
|
||||
|
@ -41,26 +39,6 @@ var validators = []validator{
|
|||
validateRelationOption,
|
||||
}
|
||||
|
||||
func validateRelationLinks(s *pb.SnapshotWithType, info *useCaseInfo) (err error) {
|
||||
id := pbtypes.GetString(s.Snapshot.Data.Details, bundle.RelationKeyId.String())
|
||||
linksToDelete := make([]keyWithIndex, 0)
|
||||
for i, rel := range s.Snapshot.Data.RelationLinks {
|
||||
if bundle.HasRelation(domain.RelationKey(rel.Key)) {
|
||||
continue
|
||||
}
|
||||
if _, found := info.customTypesAndRelations[rel.Key]; found {
|
||||
continue
|
||||
}
|
||||
linksToDelete = append([]keyWithIndex{{key: rel.Key, index: i}}, linksToDelete...)
|
||||
|
||||
}
|
||||
for _, link := range linksToDelete {
|
||||
fmt.Println("WARNING: object", id, "contains link to unknown relation:", link.key, ", so it was deleted from snapshot")
|
||||
s.Snapshot.Data.RelationLinks = append(s.Snapshot.Data.RelationLinks[:link.index], s.Snapshot.Data.RelationLinks[link.index+1:]...)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func validateRelationBlocks(s *pb.SnapshotWithType, info *useCaseInfo) (err error) {
|
||||
id := pbtypes.GetString(s.Snapshot.Data.Details, bundle.RelationKeyId.String())
|
||||
var relKeys []string
|
||||
|
@ -105,16 +83,10 @@ func validateDetails(s *pb.SnapshotWithType, info *useCaseInfo) (err error) {
|
|||
)
|
||||
rel, e = bundle.GetRelation(domain.RelationKey(k))
|
||||
if e != nil {
|
||||
rel = getRelationLinkByKey(s.Snapshot.Data.RelationLinks, k)
|
||||
if rel == nil {
|
||||
if relation, errFound := bundle.GetRelation(domain.RelationKey(k)); errFound == nil {
|
||||
s.Snapshot.Data.RelationLinks = append(s.Snapshot.Data.RelationLinks, &model.RelationLink{
|
||||
Key: k,
|
||||
Format: relation.Format,
|
||||
})
|
||||
continue
|
||||
}
|
||||
err = multierror.Append(err, fmt.Errorf("relation '%s' exists in details of object '%s', but not in relation links", k, id))
|
||||
var found bool
|
||||
rel, found = info.customTypesAndRelations[k]
|
||||
if !found {
|
||||
err = multierror.Append(err, fmt.Errorf("relation '%s' exists in details of object '%s', but not in the archive", k, id))
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
@ -122,7 +94,12 @@ func validateDetails(s *pb.SnapshotWithType, info *useCaseInfo) (err error) {
|
|||
continue
|
||||
}
|
||||
|
||||
values := pbtypes.GetStringListValue(v)
|
||||
var (
|
||||
values = pbtypes.GetStringListValue(v)
|
||||
isUpdateNeeded bool
|
||||
newValues = make([]string, 0, len(values))
|
||||
)
|
||||
|
||||
for _, val := range values {
|
||||
if bundle.HasRelation(domain.RelationKey(strings.TrimPrefix(val, addr.RelationKeyToIdPrefix))) ||
|
||||
bundle.HasObjectTypeByKey(domain.TypeKey(strings.TrimPrefix(val, addr.ObjectTypeKeyToIdPrefix))) || val == addr.AnytypeProfileId {
|
||||
|
@ -135,15 +112,31 @@ func validateDetails(s *pb.SnapshotWithType, info *useCaseInfo) (err error) {
|
|||
}
|
||||
}
|
||||
|
||||
if k == bundle.RelationKeySpaceDashboardId.String() && val == "lastOpened" {
|
||||
continue
|
||||
}
|
||||
|
||||
_, found := info.objects[val]
|
||||
if !found {
|
||||
if isBrokenTemplate(k, val) {
|
||||
fmt.Println("WARNING: object", id, "is a template with no target type included in the archive, so it will be skipped")
|
||||
return errSkipObject
|
||||
}
|
||||
if isRecommendedRelationsKey(k) {
|
||||
// we can exclude recommended relations that are not found, because the majority of types are not imported
|
||||
fmt.Println("WARNING: type", id, "contains relation", val, "that is not included in the archive, so this relation will be excluded from the list")
|
||||
isUpdateNeeded = true
|
||||
continue
|
||||
}
|
||||
err = multierror.Append(err, fmt.Errorf("failed to find target id for detail '%s: %s' of object %s", k, val, id))
|
||||
} else {
|
||||
newValues = append(newValues, val)
|
||||
}
|
||||
}
|
||||
|
||||
if isUpdateNeeded {
|
||||
s.Snapshot.Data.Details.Fields[k] = pbtypes.StringList(newValues)
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
@ -162,14 +155,22 @@ func validateObjectTypes(s *pb.SnapshotWithType, info *useCaseInfo) (err error)
|
|||
}
|
||||
|
||||
func validateBlockLinks(s *pb.SnapshotWithType, info *useCaseInfo) (err error) {
|
||||
id := pbtypes.GetString(s.Snapshot.Data.Details, bundle.RelationKeyId.String())
|
||||
var (
|
||||
id = pbtypes.GetString(s.Snapshot.Data.Details, bundle.RelationKeyId.String())
|
||||
widgetLinkBlocksToDelete []string
|
||||
)
|
||||
|
||||
for _, b := range s.Snapshot.Data.Blocks {
|
||||
switch a := simple.New(b).(type) {
|
||||
case link.Block:
|
||||
target := a.Model().GetLink().TargetBlockId
|
||||
_, found := info.objects[target]
|
||||
if !found {
|
||||
if s.SbType == model.SmartBlockType_Widget && isDefaultWidget(target) {
|
||||
if s.SbType == model.SmartBlockType_Widget {
|
||||
if isDefaultWidget(target) {
|
||||
continue
|
||||
}
|
||||
widgetLinkBlocksToDelete = append(widgetLinkBlocksToDelete, b.Id)
|
||||
continue
|
||||
}
|
||||
err = multierror.Append(err, fmt.Errorf("failed to find target id for link '%s' in block '%s' of object '%s'",
|
||||
|
@ -206,39 +207,10 @@ func validateBlockLinks(s *pb.SnapshotWithType, info *useCaseInfo) (err error) {
|
|||
}
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
if err == nil && len(widgetLinkBlocksToDelete) > 0 {
|
||||
err = removeWidgetBlocks(s, id, widgetLinkBlocksToDelete)
|
||||
}
|
||||
|
||||
func validateFileKeys(s *pb.SnapshotWithType, _ *useCaseInfo) (err error) {
|
||||
id := pbtypes.GetString(s.Snapshot.Data.Details, bundle.RelationKeyId.String())
|
||||
for _, r := range s.Snapshot.Data.RelationLinks {
|
||||
if r.Format == model.RelationFormat_file || r.Key == bundle.RelationKeyCoverId.String() {
|
||||
for _, hash := range pbtypes.GetStringList(s.Snapshot.GetData().GetDetails(), r.Key) {
|
||||
if r.Format != model.RelationFormat_file {
|
||||
_, err := cid.Parse(hash)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
}
|
||||
if !snapshotHasKeyForHash(s, hash) {
|
||||
err = multierror.Append(err, fmt.Errorf("object '%s' has file detail '%s' has hash '%s' which keys are not in the snapshot", id, r.Key, hash))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for _, b := range s.Snapshot.Data.Blocks {
|
||||
if v, ok := simple.New(b).(simple.FileHashes); ok {
|
||||
hashes := v.FillFileHashes([]string{})
|
||||
if len(hashes) == 0 {
|
||||
continue
|
||||
}
|
||||
for _, hash := range hashes {
|
||||
if !snapshotHasKeyForHash(s, hash) {
|
||||
err = multierror.Append(err, fmt.Errorf("file block '%s' of object '%s' has hash '%s' which keys are not in the snapshot", b.Id, id, hash))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -299,8 +271,14 @@ func snapshotHasKeyForHash(s *pb.SnapshotWithType, hash string) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
// these relations will be overwritten on import
|
||||
func isLinkRelation(k string) bool {
|
||||
return k == bundle.RelationKeyLinks.String() || k == bundle.RelationKeySourceObject.String() || k == bundle.RelationKeyBacklinks.String()
|
||||
return slices.Contains([]string{
|
||||
bundle.RelationKeyLinks.String(),
|
||||
bundle.RelationKeySourceObject.String(),
|
||||
bundle.RelationKeyBacklinks.String(),
|
||||
bundle.RelationKeyMentions.String(),
|
||||
}, k)
|
||||
}
|
||||
|
||||
func canRelationContainObjectValues(format model.RelationFormat) bool {
|
||||
|
@ -316,10 +294,11 @@ func canRelationContainObjectValues(format model.RelationFormat) bool {
|
|||
}
|
||||
|
||||
func isDefaultWidget(target string) bool {
|
||||
return lo.Contains([]string{
|
||||
return slices.Contains([]string{
|
||||
widget.DefaultWidgetFavorite,
|
||||
widget.DefaultWidgetSet,
|
||||
widget.DefaultWidgetRecent,
|
||||
widget.DefaultWidgetRecentOpen,
|
||||
widget.DefaultWidgetCollection,
|
||||
}, target)
|
||||
}
|
||||
|
@ -327,3 +306,56 @@ func isDefaultWidget(target string) bool {
|
|||
func isBrokenTemplate(key, value string) bool {
|
||||
return key == bundle.RelationKeyTargetObjectType.String() && value == addr.MissingObject
|
||||
}
|
||||
|
||||
func isRecommendedRelationsKey(key string) bool {
|
||||
return slices.Contains([]string{
|
||||
bundle.RelationKeyRecommendedRelations.String(),
|
||||
bundle.RelationKeyRecommendedFeaturedRelations.String(),
|
||||
bundle.RelationKeyRecommendedHiddenRelations.String(),
|
||||
bundle.RelationKeyRecommendedFileRelations.String(),
|
||||
}, key)
|
||||
}
|
||||
|
||||
// removeWidgetBlocks removes link blocks and widget blocks from Widget object.
|
||||
// For each link block we should remove parent widget block and remove its id from root's children.
|
||||
// Widget object blocks structure:
|
||||
//
|
||||
// root
|
||||
// |--- widget1
|
||||
// | |--- link1
|
||||
// |
|
||||
// |--- widget2
|
||||
// |--- link2
|
||||
func removeWidgetBlocks(s *pb.SnapshotWithType, rootId string, linkBlockIds []string) error {
|
||||
widgetBlockIds := make([]string, 0, len(linkBlockIds))
|
||||
var rootBlock *model.Block
|
||||
|
||||
for _, b := range s.Snapshot.Data.Blocks {
|
||||
if b.Id == rootId {
|
||||
rootBlock = b
|
||||
continue
|
||||
}
|
||||
// widget block has only one child - link block
|
||||
if len(b.ChildrenIds) != 1 {
|
||||
continue
|
||||
}
|
||||
if slices.Contains(linkBlockIds, b.ChildrenIds[0]) {
|
||||
widgetBlockIds = append(widgetBlockIds, b.Id)
|
||||
}
|
||||
}
|
||||
|
||||
if rootBlock == nil {
|
||||
return fmt.Errorf("root block not found")
|
||||
}
|
||||
|
||||
rootBlock.ChildrenIds = slices.DeleteFunc(rootBlock.ChildrenIds, func(id string) bool {
|
||||
return slices.Contains(widgetBlockIds, id)
|
||||
})
|
||||
|
||||
blocksToDelete := slices.Concat(widgetBlockIds, linkBlockIds)
|
||||
s.Snapshot.Data.Blocks = slices.DeleteFunc(s.Snapshot.Data.Blocks, func(b *model.Block) bool {
|
||||
return slices.Contains(blocksToDelete, b.Id)
|
||||
})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
153
cmd/usecasevalidator/validators_test.go
Normal file
153
cmd/usecasevalidator/validators_test.go
Normal file
|
@ -0,0 +1,153 @@
|
|||
//go:build !nogrpcserver && !_test
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/gogo/protobuf/types"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/anyproto/anytype-heart/pb"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/bundle"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/localstore/addr"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/pb/model"
|
||||
"github.com/anyproto/anytype-heart/util/pbtypes"
|
||||
)
|
||||
|
||||
func TestValidateDetails(t *testing.T) {
|
||||
t.Run("snapshot is valid", func(t *testing.T) {
|
||||
// given
|
||||
s := &pb.SnapshotWithType{Snapshot: &pb.ChangeSnapshot{Data: &model.SmartBlockSnapshotBase{
|
||||
Details: &types.Struct{Fields: map[string]*types.Value{
|
||||
bundle.RelationKeyName.String(): pbtypes.String("snap shot"),
|
||||
bundle.RelationKeyType.String(): pbtypes.String(bundle.TypeKeyTask.URL()),
|
||||
bundle.RelationKeyAssignee.String(): pbtypes.String("kirill"),
|
||||
bundle.RelationKeyTasks.String(): pbtypes.StringList([]string{"task1", "task2"}),
|
||||
bundle.RelationKeyFeaturedRelations.String(): pbtypes.StringList([]string{
|
||||
bundle.RelationKeyType.URL(), "rel-customTag",
|
||||
}),
|
||||
}},
|
||||
}}}
|
||||
info := &useCaseInfo{
|
||||
objects: map[string]objectInfo{
|
||||
bundle.TypeKeyTask.URL(): {},
|
||||
"kirill": {},
|
||||
"task1": {},
|
||||
"task2": {},
|
||||
},
|
||||
customTypesAndRelations: map[string]customInfo{
|
||||
"rel-customTag": {},
|
||||
},
|
||||
}
|
||||
|
||||
// when
|
||||
err := validateDetails(s, info)
|
||||
|
||||
// then
|
||||
assert.NoError(t, err)
|
||||
})
|
||||
|
||||
t.Run("some object is missing", func(t *testing.T) {
|
||||
// given
|
||||
s := &pb.SnapshotWithType{Snapshot: &pb.ChangeSnapshot{Data: &model.SmartBlockSnapshotBase{
|
||||
Details: &types.Struct{Fields: map[string]*types.Value{
|
||||
bundle.RelationKeyAssignee.String(): pbtypes.String("kirill"),
|
||||
}},
|
||||
}}}
|
||||
info := &useCaseInfo{}
|
||||
|
||||
// when
|
||||
err := validateDetails(s, info)
|
||||
|
||||
// then
|
||||
assert.Error(t, err)
|
||||
})
|
||||
|
||||
t.Run("broken template", func(t *testing.T) {
|
||||
// given
|
||||
s := &pb.SnapshotWithType{Snapshot: &pb.ChangeSnapshot{Data: &model.SmartBlockSnapshotBase{
|
||||
Details: &types.Struct{Fields: map[string]*types.Value{
|
||||
bundle.RelationKeyTargetObjectType.String(): pbtypes.String(addr.MissingObject),
|
||||
}},
|
||||
}}}
|
||||
info := &useCaseInfo{}
|
||||
|
||||
// when
|
||||
err := validateDetails(s, info)
|
||||
|
||||
// then
|
||||
assert.Error(t, err)
|
||||
assert.ErrorIs(t, errSkipObject, err)
|
||||
})
|
||||
|
||||
t.Run("exclude missing recommendedRelations", func(t *testing.T) {
|
||||
// given
|
||||
s := &pb.SnapshotWithType{Snapshot: &pb.ChangeSnapshot{Data: &model.SmartBlockSnapshotBase{
|
||||
Details: &types.Struct{Fields: map[string]*types.Value{
|
||||
bundle.RelationKeyRecommendedRelations.String(): pbtypes.StringList([]string{
|
||||
bundle.RelationKeyCreator.BundledURL(),
|
||||
bundle.RelationKeyCreatedDate.BundledURL(),
|
||||
}),
|
||||
bundle.RelationKeyRecommendedFeaturedRelations.String(): pbtypes.StringList([]string{
|
||||
bundle.RelationKeyType.BundledURL(),
|
||||
bundle.RelationKeyTag.BundledURL(),
|
||||
}),
|
||||
}},
|
||||
}}}
|
||||
info := &useCaseInfo{
|
||||
objects: map[string]objectInfo{
|
||||
bundle.RelationKeyCreator.BundledURL(): {},
|
||||
bundle.RelationKeyTag.BundledURL(): {},
|
||||
},
|
||||
}
|
||||
|
||||
// when
|
||||
err := validateDetails(s, info)
|
||||
|
||||
// then
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, []string{bundle.RelationKeyCreator.BundledURL()}, pbtypes.GetStringList(s.Snapshot.Data.Details, bundle.RelationKeyRecommendedRelations.String()))
|
||||
assert.Equal(t, []string{bundle.RelationKeyTag.BundledURL()}, pbtypes.GetStringList(s.Snapshot.Data.Details, bundle.RelationKeyRecommendedFeaturedRelations.String()))
|
||||
})
|
||||
}
|
||||
|
||||
func TestRemoveWidgetBlock(t *testing.T) {
|
||||
rootId := "root"
|
||||
t.Run("blocks were removed", func(t *testing.T) {
|
||||
// given
|
||||
s := &pb.SnapshotWithType{Snapshot: &pb.ChangeSnapshot{Data: &model.SmartBlockSnapshotBase{
|
||||
Blocks: []*model.Block{
|
||||
{Id: rootId, ChildrenIds: []string{"w1", "w2", "w3"}},
|
||||
{Id: "w1", ChildrenIds: []string{"l1"}},
|
||||
{Id: "w2", ChildrenIds: []string{"l2"}},
|
||||
{Id: "w3", ChildrenIds: []string{"l3"}},
|
||||
{Id: "l1"}, {Id: "l2"}, {Id: "l3"},
|
||||
},
|
||||
}}}
|
||||
|
||||
// when
|
||||
err := removeWidgetBlocks(s, rootId, []string{"l2", "l3"})
|
||||
|
||||
// then
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, s.Snapshot.Data.Blocks, 3)
|
||||
assert.Equal(t, []string{"w1"}, s.Snapshot.Data.Blocks[0].ChildrenIds)
|
||||
})
|
||||
|
||||
t.Run("no root found", func(t *testing.T) {
|
||||
// given
|
||||
s := &pb.SnapshotWithType{Snapshot: &pb.ChangeSnapshot{Data: &model.SmartBlockSnapshotBase{
|
||||
Blocks: []*model.Block{
|
||||
{Id: "wrong root id", ChildrenIds: []string{"w1"}},
|
||||
{Id: "w1", ChildrenIds: []string{"l1"}}, {Id: "l1"},
|
||||
},
|
||||
}}}
|
||||
|
||||
// when
|
||||
err := removeWidgetBlocks(s, rootId, []string{"l1"})
|
||||
|
||||
// then
|
||||
assert.Error(t, err)
|
||||
})
|
||||
}
|
|
@ -150,6 +150,7 @@ func (s *service) GetInfo(ctx context.Context) (*model.AccountInfo, error) {
|
|||
AnalyticsId: analyticsId,
|
||||
NetworkId: s.getNetworkId(),
|
||||
TechSpaceId: s.spaceService.TechSpaceId(),
|
||||
EthereumAddress: s.wallet.GetAccountEthAddress().Hex(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
|
|
@ -222,6 +222,9 @@ func Bootstrap(a *app.App, components ...app.Component) {
|
|||
Register(backlinks.New()).
|
||||
Register(filestore.New()).
|
||||
// Services
|
||||
Register(collection.New()).
|
||||
Register(subscription.New()).
|
||||
Register(crossspacesub.New()).
|
||||
Register(nodeconfsource.New()).
|
||||
Register(nodeconfstore.New()).
|
||||
Register(nodeconf.New()).
|
||||
|
@ -294,9 +297,6 @@ func Bootstrap(a *app.App, components ...app.Component) {
|
|||
Register(unsplash.New()).
|
||||
Register(restriction.New()).
|
||||
Register(debug.New()).
|
||||
Register(collection.New()).
|
||||
Register(subscription.New()).
|
||||
Register(crossspacesub.New()).
|
||||
Register(syncsubscriptions.New()).
|
||||
Register(builtinobjects.New()).
|
||||
Register(bookmark.New()).
|
||||
|
|
|
@ -2,17 +2,32 @@ package chats
|
|||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
"github.com/anyproto/any-sync/app"
|
||||
"github.com/cheggaaa/mb/v3"
|
||||
"go.uber.org/zap"
|
||||
|
||||
"github.com/anyproto/anytype-heart/core/block/cache"
|
||||
"github.com/anyproto/anytype-heart/core/block/editor/chatobject"
|
||||
"github.com/anyproto/anytype-heart/core/domain"
|
||||
"github.com/anyproto/anytype-heart/core/event"
|
||||
"github.com/anyproto/anytype-heart/core/session"
|
||||
subscriptionservice "github.com/anyproto/anytype-heart/core/subscription"
|
||||
"github.com/anyproto/anytype-heart/core/subscription/crossspacesub"
|
||||
"github.com/anyproto/anytype-heart/pb"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/bundle"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/database"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/logging"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/pb/model"
|
||||
)
|
||||
|
||||
const CName = "core.block.chats"
|
||||
|
||||
var log = logging.Logger(CName).Desugar()
|
||||
|
||||
type Service interface {
|
||||
AddMessage(ctx context.Context, sessionCtx session.Context, chatObjectId string, message *model.ChatMessage) (string, error)
|
||||
EditMessage(ctx context.Context, chatObjectId string, messageId string, newMessage *model.ChatMessage) error
|
||||
|
@ -20,16 +35,27 @@ type Service interface {
|
|||
DeleteMessage(ctx context.Context, chatObjectId string, messageId string) error
|
||||
GetMessages(ctx context.Context, chatObjectId string, req chatobject.GetMessagesRequest) ([]*model.ChatMessage, error)
|
||||
GetMessagesByIds(ctx context.Context, chatObjectId string, messageIds []string) ([]*model.ChatMessage, error)
|
||||
SubscribeLastMessages(ctx context.Context, chatObjectId string, limit int) ([]*model.ChatMessage, int, error)
|
||||
Unsubscribe(chatObjectId string) error
|
||||
SubscribeLastMessages(ctx context.Context, chatObjectId string, limit int, subId string) ([]*model.ChatMessage, int, error)
|
||||
Unsubscribe(chatObjectId string, subId string) error
|
||||
|
||||
app.Component
|
||||
SubscribeToMessagePreviews(ctx context.Context) (string, error)
|
||||
|
||||
app.ComponentRunnable
|
||||
}
|
||||
|
||||
var _ Service = (*service)(nil)
|
||||
|
||||
type service struct {
|
||||
objectGetter cache.ObjectGetter
|
||||
objectGetter cache.ObjectGetter
|
||||
crossSpaceSubService crossspacesub.Service
|
||||
|
||||
componentCtx context.Context
|
||||
componentCtxCancel context.CancelFunc
|
||||
|
||||
eventSender event.Sender
|
||||
|
||||
lock sync.Mutex
|
||||
chatObjectsSubQueue *mb.MB[*pb.EventMessage]
|
||||
}
|
||||
|
||||
func New() Service {
|
||||
|
@ -42,10 +68,113 @@ func (s *service) Name() string {
|
|||
|
||||
func (s *service) Init(a *app.App) error {
|
||||
s.objectGetter = app.MustComponent[cache.ObjectGetter](a)
|
||||
s.crossSpaceSubService = app.MustComponent[crossspacesub.Service](a)
|
||||
s.eventSender = app.MustComponent[event.Sender](a)
|
||||
s.componentCtx, s.componentCtxCancel = context.WithCancel(context.Background())
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
const (
|
||||
allChatsSubscriptionId = "allChatObjects"
|
||||
)
|
||||
|
||||
func (s *service) SubscribeToMessagePreviews(ctx context.Context) (string, error) {
|
||||
s.lock.Lock()
|
||||
if s.chatObjectsSubQueue != nil {
|
||||
s.lock.Unlock()
|
||||
return chatobject.LastMessageSubscriptionId, nil
|
||||
}
|
||||
s.chatObjectsSubQueue = mb.New[*pb.EventMessage](0)
|
||||
s.lock.Unlock()
|
||||
|
||||
resp, err := s.crossSpaceSubService.Subscribe(subscriptionservice.SubscribeRequest{
|
||||
SubId: allChatsSubscriptionId,
|
||||
InternalQueue: s.chatObjectsSubQueue,
|
||||
Keys: []string{bundle.RelationKeyId.String()},
|
||||
NoDepSubscription: true,
|
||||
Filters: []database.FilterRequest{
|
||||
{
|
||||
RelationKey: bundle.RelationKeyLayout,
|
||||
Condition: model.BlockContentDataviewFilter_Equal,
|
||||
Value: domain.Int64(model.ObjectType_chatDerived),
|
||||
},
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("cross-space sub: %w", err)
|
||||
}
|
||||
for _, rec := range resp.Records {
|
||||
err := s.onChatAdded(rec.GetString(bundle.RelationKeyId))
|
||||
if err != nil {
|
||||
log.Error("init lastMessage subscription", zap.Error(err))
|
||||
}
|
||||
}
|
||||
go s.monitorChats()
|
||||
|
||||
return chatobject.LastMessageSubscriptionId, nil
|
||||
}
|
||||
|
||||
func (s *service) Run(ctx context.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *service) monitorChats() {
|
||||
matcher := subscriptionservice.EventMatcher{
|
||||
OnAdd: func(add *pb.EventObjectSubscriptionAdd) {
|
||||
err := s.onChatAdded(add.Id)
|
||||
if err != nil {
|
||||
log.Error("init last message subscription", zap.Error(err))
|
||||
}
|
||||
},
|
||||
OnRemove: func(remove *pb.EventObjectSubscriptionRemove) {
|
||||
err := s.Unsubscribe(remove.Id, chatobject.LastMessageSubscriptionId)
|
||||
if err != nil && !errors.Is(err, domain.ErrObjectNotFound) {
|
||||
log.Error("unsubscribe from the last message", zap.Error(err))
|
||||
}
|
||||
},
|
||||
}
|
||||
for {
|
||||
msg, err := s.chatObjectsSubQueue.WaitOne(s.componentCtx)
|
||||
if errors.Is(err, mb.ErrClosed) {
|
||||
return
|
||||
}
|
||||
if err != nil {
|
||||
log.Error("wait message", zap.Error(err))
|
||||
return
|
||||
}
|
||||
matcher.Match(msg)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *service) onChatAdded(chatObjectId string) error {
|
||||
return cache.Do(s.objectGetter, chatObjectId, func(sb chatobject.StoreObject) error {
|
||||
var err error
|
||||
_, _, err = sb.SubscribeLastMessages(s.componentCtx, chatobject.LastMessageSubscriptionId, 1, true)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func (s *service) Close(ctx context.Context) error {
|
||||
var err error
|
||||
s.lock.Lock()
|
||||
defer s.lock.Unlock()
|
||||
|
||||
if s.chatObjectsSubQueue != nil {
|
||||
err = s.chatObjectsSubQueue.Close()
|
||||
}
|
||||
|
||||
s.componentCtxCancel()
|
||||
|
||||
err = errors.Join(err,
|
||||
s.crossSpaceSubService.Unsubscribe(allChatsSubscriptionId),
|
||||
)
|
||||
return err
|
||||
}
|
||||
|
||||
func (s *service) AddMessage(ctx context.Context, sessionCtx session.Context, chatObjectId string, message *model.ChatMessage) (string, error) {
|
||||
var messageId string
|
||||
err := cache.Do(s.objectGetter, chatObjectId, func(sb chatobject.StoreObject) error {
|
||||
|
@ -100,14 +229,14 @@ func (s *service) GetMessagesByIds(ctx context.Context, chatObjectId string, mes
|
|||
return res, err
|
||||
}
|
||||
|
||||
func (s *service) SubscribeLastMessages(ctx context.Context, chatObjectId string, limit int) ([]*model.ChatMessage, int, error) {
|
||||
func (s *service) SubscribeLastMessages(ctx context.Context, chatObjectId string, limit int, subId string) ([]*model.ChatMessage, int, error) {
|
||||
var (
|
||||
msgs []*model.ChatMessage
|
||||
numBefore int
|
||||
)
|
||||
err := cache.Do(s.objectGetter, chatObjectId, func(sb chatobject.StoreObject) error {
|
||||
var err error
|
||||
msgs, numBefore, err = sb.SubscribeLastMessages(ctx, limit)
|
||||
msgs, numBefore, err = sb.SubscribeLastMessages(ctx, subId, limit, false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -116,8 +245,8 @@ func (s *service) SubscribeLastMessages(ctx context.Context, chatObjectId string
|
|||
return msgs, numBefore, err
|
||||
}
|
||||
|
||||
func (s *service) Unsubscribe(chatObjectId string) error {
|
||||
func (s *service) Unsubscribe(chatObjectId string, subId string) error {
|
||||
return cache.Do(s.objectGetter, chatObjectId, func(sb chatobject.StoreObject) error {
|
||||
return sb.Unsubscribe()
|
||||
return sb.Unsubscribe(subId)
|
||||
})
|
||||
}
|
||||
|
|
|
@ -43,7 +43,7 @@ func (d ChatHandler) BeforeCreate(ctx context.Context, ch storestate.ChangeOp) (
|
|||
|
||||
model := msg.toModel()
|
||||
model.OrderId = ch.Change.Order
|
||||
d.subscription.add(model)
|
||||
d.subscription.add(ch.Change.PrevOrderId, model)
|
||||
|
||||
return
|
||||
}
|
||||
|
|
|
@ -19,6 +19,8 @@ import (
|
|||
"github.com/anyproto/anytype-heart/core/event"
|
||||
"github.com/anyproto/anytype-heart/core/session"
|
||||
"github.com/anyproto/anytype-heart/pb"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore/spaceindex"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/logging"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/pb/model"
|
||||
)
|
||||
|
||||
|
@ -28,6 +30,8 @@ const (
|
|||
ascOrder = "_o.id"
|
||||
)
|
||||
|
||||
var log = logging.Logger("core.block.editor.chatobject").Desugar()
|
||||
|
||||
type StoreObject interface {
|
||||
smartblock.SmartBlock
|
||||
anystoredebug.AnystoreDebug
|
||||
|
@ -38,9 +42,9 @@ type StoreObject interface {
|
|||
EditMessage(ctx context.Context, messageId string, newMessage *model.ChatMessage) error
|
||||
ToggleMessageReaction(ctx context.Context, messageId string, emoji string) error
|
||||
DeleteMessage(ctx context.Context, messageId string) error
|
||||
SubscribeLastMessages(ctx context.Context, limit int) ([]*model.ChatMessage, int, error)
|
||||
SubscribeLastMessages(ctx context.Context, subId string, limit int, asyncInit bool) ([]*model.ChatMessage, int, error)
|
||||
MarkSeenHeads(heads []string)
|
||||
Unsubscribe() error
|
||||
Unsubscribe(subId string) error
|
||||
}
|
||||
|
||||
type GetMessagesRequest struct {
|
||||
|
@ -64,11 +68,12 @@ type storeObject struct {
|
|||
eventSender event.Sender
|
||||
subscription *subscription
|
||||
crdtDb anystore.DB
|
||||
spaceIndex spaceindex.Store
|
||||
|
||||
arenaPool *anyenc.ArenaPool
|
||||
}
|
||||
|
||||
func New(sb smartblock.SmartBlock, accountService AccountService, eventSender event.Sender, crdtDb anystore.DB) StoreObject {
|
||||
func New(sb smartblock.SmartBlock, accountService AccountService, eventSender event.Sender, crdtDb anystore.DB, spaceIndex spaceindex.Store) StoreObject {
|
||||
return &storeObject{
|
||||
SmartBlock: sb,
|
||||
locker: sb.(smartblock.Locker),
|
||||
|
@ -76,6 +81,7 @@ func New(sb smartblock.SmartBlock, accountService AccountService, eventSender ev
|
|||
arenaPool: &anyenc.ArenaPool{},
|
||||
eventSender: eventSender,
|
||||
crdtDb: crdtDb,
|
||||
spaceIndex: spaceIndex,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -84,7 +90,7 @@ func (s *storeObject) Init(ctx *smartblock.InitContext) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
s.subscription = newSubscription(s.SpaceID(), s.Id(), s.eventSender)
|
||||
s.subscription = newSubscription(s.SpaceID(), s.Id(), s.eventSender, s.spaceIndex)
|
||||
|
||||
stateStore, err := storestate.New(ctx.Ctx, s.Id(), s.crdtDb, ChatHandler{
|
||||
subscription: s.subscription,
|
||||
|
@ -312,13 +318,20 @@ func (s *storeObject) hasMyReaction(ctx context.Context, arena *anyenc.Arena, me
|
|||
return false, nil
|
||||
}
|
||||
|
||||
func (s *storeObject) SubscribeLastMessages(ctx context.Context, limit int) ([]*model.ChatMessage, int, error) {
|
||||
func (s *storeObject) SubscribeLastMessages(ctx context.Context, subId string, limit int, asyncInit bool) ([]*model.ChatMessage, int, error) {
|
||||
coll, err := s.store.Collection(ctx, collectionName)
|
||||
if err != nil {
|
||||
return nil, 0, fmt.Errorf("get collection: %w", err)
|
||||
}
|
||||
|
||||
txn, err := s.store.NewTx(ctx)
|
||||
if err != nil {
|
||||
return nil, 0, fmt.Errorf("init read transaction: %w", err)
|
||||
}
|
||||
defer txn.Commit()
|
||||
|
||||
query := coll.Find(nil).Sort(descOrder).Limit(uint(limit))
|
||||
messages, err := s.queryMessages(ctx, query)
|
||||
messages, err := s.queryMessages(txn.Context(), query)
|
||||
if err != nil {
|
||||
return nil, 0, fmt.Errorf("query messages: %w", err)
|
||||
}
|
||||
|
@ -327,13 +340,29 @@ func (s *storeObject) SubscribeLastMessages(ctx context.Context, limit int) ([]*
|
|||
return messages[i].OrderId < messages[j].OrderId
|
||||
})
|
||||
|
||||
s.subscription.enable()
|
||||
s.subscription.subscribe(subId)
|
||||
if asyncInit {
|
||||
var previousOrderId string
|
||||
if len(messages) > 0 {
|
||||
previousOrderId, err = txn.GetPrevOrderId(messages[0].OrderId)
|
||||
if err != nil {
|
||||
return nil, 0, fmt.Errorf("get previous order id: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
return messages, 0, nil
|
||||
for _, message := range messages {
|
||||
s.subscription.add(previousOrderId, message)
|
||||
previousOrderId = message.OrderId
|
||||
}
|
||||
s.subscription.flush()
|
||||
return nil, 0, nil
|
||||
} else {
|
||||
return messages, 0, nil
|
||||
}
|
||||
}
|
||||
|
||||
func (s *storeObject) Unsubscribe() error {
|
||||
s.subscription.close()
|
||||
func (s *storeObject) Unsubscribe(subId string) error {
|
||||
s.subscription.unsubscribe(subId)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -341,7 +370,7 @@ func (s *storeObject) TryClose(objectTTL time.Duration) (res bool, err error) {
|
|||
if !s.locker.TryLock() {
|
||||
return false, nil
|
||||
}
|
||||
isActive := s.subscription.enabled
|
||||
isActive := s.subscription.isActive()
|
||||
s.Unlock()
|
||||
|
||||
if isActive {
|
||||
|
|
|
@ -21,6 +21,7 @@ import (
|
|||
"github.com/anyproto/anytype-heart/core/event/mock_event"
|
||||
"github.com/anyproto/anytype-heart/core/session"
|
||||
"github.com/anyproto/anytype-heart/pb"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore/spaceindex"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/pb/model"
|
||||
)
|
||||
|
||||
|
@ -58,7 +59,9 @@ func newFixture(t *testing.T) *fixture {
|
|||
|
||||
sb := smarttest.New("chatId1")
|
||||
|
||||
object := New(sb, accountService, eventSender, db)
|
||||
spaceIndex := spaceindex.NewStoreFixture(t)
|
||||
|
||||
object := New(sb, accountService, eventSender, db, spaceIndex)
|
||||
|
||||
fx := &fixture{
|
||||
storeObject: object.(*storeObject),
|
||||
|
|
|
@ -2,13 +2,22 @@ package chatobject
|
|||
|
||||
import (
|
||||
"slices"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/golang-lru/v2/expirable"
|
||||
"go.uber.org/zap"
|
||||
|
||||
"github.com/anyproto/anytype-heart/core/domain"
|
||||
"github.com/anyproto/anytype-heart/core/event"
|
||||
"github.com/anyproto/anytype-heart/core/session"
|
||||
"github.com/anyproto/anytype-heart/pb"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore/spaceindex"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/pb/model"
|
||||
"github.com/anyproto/anytype-heart/util/slice"
|
||||
)
|
||||
|
||||
const LastMessageSubscriptionId = "lastMessage"
|
||||
|
||||
type subscription struct {
|
||||
spaceId string
|
||||
chatId string
|
||||
|
@ -18,23 +27,39 @@ type subscription struct {
|
|||
|
||||
eventsBuffer []*pb.EventMessage
|
||||
|
||||
enabled bool
|
||||
spaceIndex spaceindex.Store
|
||||
|
||||
identityCache *expirable.LRU[string, *domain.Details]
|
||||
|
||||
ids []string
|
||||
}
|
||||
|
||||
func newSubscription(spaceId string, chatId string, eventSender event.Sender) *subscription {
|
||||
func newSubscription(spaceId string, chatId string, eventSender event.Sender, spaceIndex spaceindex.Store) *subscription {
|
||||
return &subscription{
|
||||
spaceId: spaceId,
|
||||
chatId: chatId,
|
||||
eventSender: eventSender,
|
||||
spaceId: spaceId,
|
||||
chatId: chatId,
|
||||
eventSender: eventSender,
|
||||
spaceIndex: spaceIndex,
|
||||
identityCache: expirable.NewLRU[string, *domain.Details](50, nil, time.Minute),
|
||||
}
|
||||
}
|
||||
|
||||
func (s *subscription) enable() {
|
||||
s.enabled = true
|
||||
func (s *subscription) subscribe(subId string) {
|
||||
if !slices.Contains(s.ids, subId) {
|
||||
s.ids = append(s.ids, subId)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *subscription) close() {
|
||||
s.enabled = false
|
||||
func (s *subscription) unsubscribe(subId string) {
|
||||
s.ids = slice.Remove(s.ids, subId)
|
||||
}
|
||||
|
||||
func (s *subscription) isActive() bool {
|
||||
return len(s.ids) > 0
|
||||
}
|
||||
|
||||
func (s *subscription) withDeps() bool {
|
||||
return slices.Equal(s.ids, []string{LastMessageSubscriptionId})
|
||||
}
|
||||
|
||||
// setSessionContext sets the session context for the current operation
|
||||
|
@ -59,20 +84,54 @@ func (s *subscription) flush() {
|
|||
s.sessionContext.SetMessages(s.chatId, slices.Clone(s.eventsBuffer))
|
||||
s.eventSender.BroadcastToOtherSessions(s.sessionContext.ID(), ev)
|
||||
s.sessionContext = nil
|
||||
} else if s.enabled {
|
||||
} else if s.isActive() {
|
||||
s.eventSender.Broadcast(ev)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *subscription) add(message *model.ChatMessage) {
|
||||
func (s *subscription) getIdentityDetails(identity string) (*domain.Details, error) {
|
||||
cached, ok := s.identityCache.Get(identity)
|
||||
if ok {
|
||||
return cached, nil
|
||||
}
|
||||
details, err := s.spaceIndex.GetDetails(domain.NewParticipantId(s.spaceId, identity))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
s.identityCache.Add(identity, details)
|
||||
return details, nil
|
||||
}
|
||||
|
||||
func (s *subscription) add(prevOrderId string, message *model.ChatMessage) {
|
||||
if !s.canSend() {
|
||||
return
|
||||
}
|
||||
ev := &pb.EventChatAdd{
|
||||
Id: message.Id,
|
||||
Message: message,
|
||||
OrderId: message.OrderId,
|
||||
Id: message.Id,
|
||||
Message: message,
|
||||
OrderId: message.OrderId,
|
||||
AfterOrderId: prevOrderId,
|
||||
SubIds: slices.Clone(s.ids),
|
||||
}
|
||||
|
||||
if s.withDeps() {
|
||||
identityDetails, err := s.getIdentityDetails(message.Creator)
|
||||
if err != nil {
|
||||
log.Error("get identity details", zap.Error(err))
|
||||
} else {
|
||||
ev.Dependencies = append(ev.Dependencies, identityDetails.ToProto())
|
||||
}
|
||||
|
||||
for _, attachment := range message.Attachments {
|
||||
attachmentDetails, err := s.spaceIndex.GetDetails(attachment.Target)
|
||||
if err != nil {
|
||||
log.Error("get attachment details", zap.Error(err))
|
||||
} else {
|
||||
ev.Dependencies = append(ev.Dependencies, attachmentDetails.ToProto())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
s.eventsBuffer = append(s.eventsBuffer, event.NewMessage(s.spaceId, &pb.EventMessageValueOfChatAdd{
|
||||
ChatAdd: ev,
|
||||
}))
|
||||
|
@ -80,7 +139,8 @@ func (s *subscription) add(message *model.ChatMessage) {
|
|||
|
||||
func (s *subscription) delete(messageId string) {
|
||||
ev := &pb.EventChatDelete{
|
||||
Id: messageId,
|
||||
Id: messageId,
|
||||
SubIds: slices.Clone(s.ids),
|
||||
}
|
||||
s.eventsBuffer = append(s.eventsBuffer, event.NewMessage(s.spaceId, &pb.EventMessageValueOfChatDelete{
|
||||
ChatDelete: ev,
|
||||
|
@ -94,6 +154,7 @@ func (s *subscription) updateFull(message *model.ChatMessage) {
|
|||
ev := &pb.EventChatUpdate{
|
||||
Id: message.Id,
|
||||
Message: message,
|
||||
SubIds: slices.Clone(s.ids),
|
||||
}
|
||||
s.eventsBuffer = append(s.eventsBuffer, event.NewMessage(s.spaceId, &pb.EventMessageValueOfChatUpdate{
|
||||
ChatUpdate: ev,
|
||||
|
@ -107,6 +168,7 @@ func (s *subscription) updateReactions(message *model.ChatMessage) {
|
|||
ev := &pb.EventChatUpdateReactions{
|
||||
Id: message.Id,
|
||||
Reactions: message.Reactions,
|
||||
SubIds: slices.Clone(s.ids),
|
||||
}
|
||||
s.eventsBuffer = append(s.eventsBuffer, event.NewMessage(s.spaceId, &pb.EventMessageValueOfChatUpdateReactions{
|
||||
ChatUpdateReactions: ev,
|
||||
|
@ -117,7 +179,7 @@ func (s *subscription) canSend() bool {
|
|||
if s.sessionContext != nil {
|
||||
return true
|
||||
}
|
||||
if !s.enabled {
|
||||
if !s.isActive() {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
|
|
|
@ -21,7 +21,7 @@ func TestSubscription(t *testing.T) {
|
|||
assert.NotEmpty(t, messageId)
|
||||
}
|
||||
|
||||
messages, _, err := fx.SubscribeLastMessages(ctx, 5)
|
||||
messages, _, err := fx.SubscribeLastMessages(ctx, "subId", 5, false)
|
||||
require.NoError(t, err)
|
||||
wantTexts := []string{"text 6", "text 7", "text 8", "text 9", "text 10"}
|
||||
for i, msg := range messages {
|
||||
|
|
|
@ -170,7 +170,7 @@ func (f *ObjectFactory) produceSmartblock(space smartblock.Space) (smartblock.Sm
|
|||
}
|
||||
|
||||
func (f *ObjectFactory) New(space smartblock.Space, sbType coresb.SmartBlockType) (smartblock.SmartBlock, error) {
|
||||
sb, store := f.produceSmartblock(space)
|
||||
sb, spaceIndex := f.produceSmartblock(space)
|
||||
switch sbType {
|
||||
case coresb.SmartBlockTypePage,
|
||||
coresb.SmartBlockTypeDate,
|
||||
|
@ -183,9 +183,9 @@ func (f *ObjectFactory) New(space smartblock.Space, sbType coresb.SmartBlockType
|
|||
case coresb.SmartBlockTypeObjectType:
|
||||
return f.newObjectType(space.Id(), sb), nil
|
||||
case coresb.SmartBlockTypeArchive:
|
||||
return NewArchive(sb, store), nil
|
||||
return NewArchive(sb, spaceIndex), nil
|
||||
case coresb.SmartBlockTypeHome:
|
||||
return NewDashboard(sb, store, f.layoutConverter), nil
|
||||
return NewDashboard(sb, spaceIndex, f.layoutConverter), nil
|
||||
case coresb.SmartBlockTypeProfilePage,
|
||||
coresb.SmartBlockTypeAnytypeProfile:
|
||||
return f.newProfile(space.Id(), sb), nil
|
||||
|
@ -195,25 +195,25 @@ func (f *ObjectFactory) New(space smartblock.Space, sbType coresb.SmartBlockType
|
|||
coresb.SmartBlockTypeBundledTemplate:
|
||||
return f.newTemplate(space.Id(), sb), nil
|
||||
case coresb.SmartBlockTypeWorkspace:
|
||||
return f.newWorkspace(sb, store), nil
|
||||
return f.newWorkspace(sb, spaceIndex), nil
|
||||
case coresb.SmartBlockTypeSpaceView:
|
||||
return f.newSpaceView(sb), nil
|
||||
case coresb.SmartBlockTypeMissingObject:
|
||||
return NewMissingObject(sb), nil
|
||||
case coresb.SmartBlockTypeWidget:
|
||||
return NewWidgetObject(sb, store, f.layoutConverter), nil
|
||||
return NewWidgetObject(sb, spaceIndex, f.layoutConverter), nil
|
||||
case coresb.SmartBlockTypeNotificationObject:
|
||||
return NewNotificationObject(sb), nil
|
||||
case coresb.SmartBlockTypeSubObject:
|
||||
return nil, fmt.Errorf("subobject not supported via factory")
|
||||
case coresb.SmartBlockTypeParticipant:
|
||||
return f.newParticipant(space.Id(), sb, store), nil
|
||||
return f.newParticipant(space.Id(), sb, spaceIndex), nil
|
||||
case coresb.SmartBlockTypeDevicesObject:
|
||||
return NewDevicesObject(sb, f.deviceService), nil
|
||||
case coresb.SmartBlockTypeChatDerivedObject:
|
||||
return chatobject.New(sb, f.accountService, f.eventSender, f.objectStore.GetCrdtDb(space.Id())), nil
|
||||
return chatobject.New(sb, f.accountService, f.eventSender, f.objectStore.GetCrdtDb(space.Id()), spaceIndex), nil
|
||||
case coresb.SmartBlockTypeAccountObject:
|
||||
return accountobject.New(sb, f.accountService.Keys(), store, f.layoutConverter, f.fileObjectService, f.objectStore.GetCrdtDb(space.Id()), f.config), nil
|
||||
return accountobject.New(sb, f.accountService.Keys(), spaceIndex, f.layoutConverter, f.fileObjectService, f.objectStore.GetCrdtDb(space.Id()), f.config), nil
|
||||
default:
|
||||
return nil, fmt.Errorf("unexpected smartblock type: %v", sbType)
|
||||
}
|
||||
|
|
|
@ -105,6 +105,7 @@ func (ot *ObjectType) CreationStateMigration(ctx *smartblock.InitContext) migrat
|
|||
template.WithTitle,
|
||||
template.WithLayout(model.ObjectType_objectType),
|
||||
}
|
||||
templates = append(templates, ot.dataviewTemplates()...)
|
||||
|
||||
template.InitTemplate(s, templates...)
|
||||
},
|
||||
|
@ -121,6 +122,12 @@ func (ot *ObjectType) StateMigrations() migration.Migrations {
|
|||
Version: 3,
|
||||
Proc: ot.featuredRelationsMigration,
|
||||
},
|
||||
{
|
||||
Version: 4,
|
||||
Proc: func(s *state.State) {
|
||||
template.InitTemplate(s, ot.dataviewTemplates()...)
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -133,7 +140,12 @@ func (ot *ObjectType) featuredRelationsMigration(s *state.State) {
|
|||
return
|
||||
}
|
||||
|
||||
featuredRelationKeys := relationutils.DefaultFeaturedRelationKeys()
|
||||
var typeKey domain.TypeKey
|
||||
if uk, err := domain.UnmarshalUniqueKey(s.Details().GetString(bundle.RelationKeyUniqueKey)); err == nil {
|
||||
typeKey = domain.TypeKey(uk.InternalKey())
|
||||
}
|
||||
|
||||
featuredRelationKeys := relationutils.DefaultFeaturedRelationKeys(typeKey)
|
||||
featuredRelationIds := make([]string, 0, len(featuredRelationKeys))
|
||||
for _, key := range featuredRelationKeys {
|
||||
id, err := ot.Space().DeriveObjectID(context.Background(), domain.MustUniqueKey(coresb.SmartBlockTypeRelation, key.String()))
|
||||
|
@ -384,6 +396,30 @@ func (ot *ObjectType) queryObjectsAndTemplates() ([]database.Record, error) {
|
|||
return append(records, templates...), nil
|
||||
}
|
||||
|
||||
func (ot *ObjectType) dataviewTemplates() []template.StateTransformer {
|
||||
details := ot.Details()
|
||||
name := details.GetString(bundle.RelationKeyName)
|
||||
key := details.GetString(bundle.RelationKeyUniqueKey)
|
||||
|
||||
dvContent := template.MakeDataviewContent(false, &model.ObjectType{
|
||||
Url: ot.Id(),
|
||||
Name: name,
|
||||
// todo: add RelationLinks, because they are not indexed at this moment :(
|
||||
Key: key,
|
||||
}, []*model.RelationLink{
|
||||
{
|
||||
Key: bundle.RelationKeyName.String(),
|
||||
Format: model.RelationFormat_longtext,
|
||||
},
|
||||
}, objectTypeAllViewId)
|
||||
|
||||
dvContent.Dataview.TargetObjectId = ot.Id()
|
||||
return []template.StateTransformer{
|
||||
template.WithDataviewID(state.DataviewBlockID, dvContent, false),
|
||||
template.WithForcedDetail(bundle.RelationKeySetOf, domain.StringList([]string{ot.Id()})),
|
||||
}
|
||||
}
|
||||
|
||||
type layoutRelationsChanges struct {
|
||||
relationsToRemove []domain.RelationKey
|
||||
isLayoutFound bool
|
||||
|
|
|
@ -231,12 +231,6 @@ func (p *Page) CreationStateMigration(ctx *smartblock.InitContext) migration.Mig
|
|||
template.WithTitle,
|
||||
template.WithLayout(layout),
|
||||
)
|
||||
case model.ObjectType_objectType:
|
||||
templates = append(templates,
|
||||
template.WithTitle,
|
||||
template.WithLayout(layout),
|
||||
)
|
||||
templates = append(templates, p.getObjectTypeTemplates()...)
|
||||
case model.ObjectType_chat:
|
||||
templates = append(templates,
|
||||
template.WithTitle,
|
||||
|
@ -268,48 +262,5 @@ func (p *Page) CreationStateMigration(ctx *smartblock.InitContext) migration.Mig
|
|||
}
|
||||
|
||||
func (p *Page) StateMigrations() migration.Migrations {
|
||||
migrations := []migration.Migration{
|
||||
{
|
||||
Version: 2,
|
||||
Proc: func(s *state.State) {},
|
||||
},
|
||||
}
|
||||
|
||||
// migration 3 is skipped
|
||||
// migration 4 is applied only for ObjectType
|
||||
if p.ObjectTypeKey() == bundle.TypeKeyObjectType {
|
||||
migrations = append(migrations,
|
||||
migration.Migration{
|
||||
Version: 4,
|
||||
Proc: func(s *state.State) {
|
||||
template.InitTemplate(s, p.getObjectTypeTemplates()...)
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
return migration.MakeMigrations(migrations)
|
||||
}
|
||||
|
||||
func (p *Page) getObjectTypeTemplates() []template.StateTransformer {
|
||||
details := p.Details()
|
||||
name := details.GetString(bundle.RelationKeyName)
|
||||
key := details.GetString(bundle.RelationKeyUniqueKey)
|
||||
|
||||
dvContent := template.MakeDataviewContent(false, &model.ObjectType{
|
||||
Url: p.Id(),
|
||||
Name: name,
|
||||
// todo: add RelationLinks, because they are not indexed at this moment :(
|
||||
Key: key,
|
||||
}, []*model.RelationLink{
|
||||
{
|
||||
Key: bundle.RelationKeyName.String(),
|
||||
Format: model.RelationFormat_longtext,
|
||||
},
|
||||
}, objectTypeAllViewId)
|
||||
|
||||
dvContent.Dataview.TargetObjectId = p.Id()
|
||||
return []template.StateTransformer{
|
||||
template.WithDataviewID(state.DataviewBlockID, dvContent, false),
|
||||
template.WithForcedDetail(bundle.RelationKeySetOf, domain.StringList([]string{p.Id()})),
|
||||
}
|
||||
return migration.Migrations{Migrations: []migration.Migration{}}
|
||||
}
|
||||
|
|
|
@ -76,19 +76,21 @@ func New(ctx context.Context, id string, db anystore.DB, handlers ...Handler) (s
|
|||
}
|
||||
|
||||
type ChangeSet struct {
|
||||
Id string
|
||||
Order string
|
||||
Creator string
|
||||
Changes []*pb.StoreChangeContent
|
||||
Timestamp int64
|
||||
Id string
|
||||
PrevOrderId string
|
||||
Order string
|
||||
Creator string
|
||||
Changes []*pb.StoreChangeContent
|
||||
Timestamp int64
|
||||
}
|
||||
|
||||
type Change struct {
|
||||
Id string
|
||||
Order string
|
||||
Creator string
|
||||
Change *pb.StoreChangeContent
|
||||
Timestamp int64
|
||||
Id string
|
||||
PrevOrderId string
|
||||
Order string
|
||||
Creator string
|
||||
Change *pb.StoreChangeContent
|
||||
Timestamp int64
|
||||
}
|
||||
|
||||
type StoreState struct {
|
||||
|
@ -134,11 +136,12 @@ func (ss *StoreState) Collection(ctx context.Context, name string) (anystore.Col
|
|||
func (ss *StoreState) applyChangeSet(ctx context.Context, set ChangeSet) (err error) {
|
||||
for _, ch := range set.Changes {
|
||||
applyErr := ss.applyChange(ctx, Change{
|
||||
Id: set.Id,
|
||||
Order: set.Order,
|
||||
Change: ch,
|
||||
Creator: set.Creator,
|
||||
Timestamp: set.Timestamp,
|
||||
Id: set.Id,
|
||||
PrevOrderId: set.PrevOrderId,
|
||||
Order: set.Order,
|
||||
Change: ch,
|
||||
Creator: set.Creator,
|
||||
Timestamp: set.Timestamp,
|
||||
})
|
||||
if applyErr == nil || errors.Is(applyErr, ErrIgnore) {
|
||||
continue
|
||||
|
|
|
@ -49,6 +49,28 @@ func TestStoreStateTx_GetOrder(t *testing.T) {
|
|||
})
|
||||
}
|
||||
|
||||
func TestStoreStateTx_GetPrevOrderId(t *testing.T) {
|
||||
fx := newFixture(t, "test", DefaultHandler{Name: "tcoll"})
|
||||
tx, err := fx.NewTx(ctx)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = tx.SetOrder("ch1", "1")
|
||||
require.NoError(t, err)
|
||||
err = tx.SetOrder("ch2", "2")
|
||||
require.NoError(t, err)
|
||||
|
||||
prev, err := tx.GetPrevOrderId("1")
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, "", prev)
|
||||
|
||||
prev, err = tx.GetPrevOrderId("2")
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, "1", prev)
|
||||
|
||||
err = tx.Commit()
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestStoreStateTx_ApplyChangeSet(t *testing.T) {
|
||||
t.Run("create", func(t *testing.T) {
|
||||
fx := newFixture(t, "objId", DefaultHandler{Name: "testColl"})
|
||||
|
|
|
@ -3,10 +3,12 @@ package storestate
|
|||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
anystore "github.com/anyproto/any-store"
|
||||
"github.com/anyproto/any-store/anyenc"
|
||||
"github.com/anyproto/any-store/query"
|
||||
)
|
||||
|
||||
const maxOrderId = "_max"
|
||||
|
@ -20,6 +22,10 @@ type StoreStateTx struct {
|
|||
maxOrderChanged bool
|
||||
}
|
||||
|
||||
func (stx *StoreStateTx) Context() context.Context {
|
||||
return stx.ctx
|
||||
}
|
||||
|
||||
func (stx *StoreStateTx) init() (err error) {
|
||||
stx.maxOrder, err = stx.GetOrder(maxOrderId)
|
||||
if err != nil && !errors.Is(err, ErrOrderNotFound) {
|
||||
|
@ -28,6 +34,26 @@ func (stx *StoreStateTx) init() (err error) {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (stx *StoreStateTx) GetPrevOrderId(orderId string) (string, error) {
|
||||
iter, err := stx.state.collChangeOrders.Find(query.Key{
|
||||
Path: []string{"o"},
|
||||
Filter: query.NewComp(query.CompOpLt, orderId),
|
||||
}).Sort("-o").Limit(1).Iter(stx.ctx)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("open iterator: %w", err)
|
||||
}
|
||||
defer iter.Close()
|
||||
|
||||
if !iter.Next() {
|
||||
return "", iter.Err()
|
||||
}
|
||||
doc, err := iter.Doc()
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("get prev order id: %w", err)
|
||||
}
|
||||
return string(doc.Value().GetStringBytes("o")), nil
|
||||
}
|
||||
|
||||
func (stx *StoreStateTx) GetOrder(changeId string) (orderId string, err error) {
|
||||
doc, err := stx.state.collChangeOrders.FindId(stx.ctx, changeId)
|
||||
if err != nil {
|
||||
|
|
|
@ -92,7 +92,7 @@ func TestMakeDataviewContent(t *testing.T) {
|
|||
},
|
||||
} {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
block := MakeDataviewContent(tc.isCollection, tc.ot, tc.relLinks)
|
||||
block := MakeDataviewContent(tc.isCollection, tc.ot, tc.relLinks, "")
|
||||
assertDataviewBlock(t, block, tc.isCollection, tc.expectedRelations, tc.isVisible)
|
||||
})
|
||||
}
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
package editor
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"golang.org/x/exp/slices"
|
||||
|
||||
"github.com/anyproto/anytype-heart/core/block/editor/basic"
|
||||
"github.com/anyproto/anytype-heart/core/block/editor/converter"
|
||||
"github.com/anyproto/anytype-heart/core/block/editor/smartblock"
|
||||
|
@ -8,6 +12,7 @@ import (
|
|||
"github.com/anyproto/anytype-heart/core/block/editor/template"
|
||||
"github.com/anyproto/anytype-heart/core/block/editor/widget"
|
||||
"github.com/anyproto/anytype-heart/core/block/migration"
|
||||
"github.com/anyproto/anytype-heart/core/block/simple"
|
||||
"github.com/anyproto/anytype-heart/core/domain"
|
||||
"github.com/anyproto/anytype-heart/core/session"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/bundle"
|
||||
|
@ -49,7 +54,7 @@ func (w *WidgetObject) Init(ctx *smartblock.InitContext) (err error) {
|
|||
|
||||
func (w *WidgetObject) CreationStateMigration(ctx *smartblock.InitContext) migration.Migration {
|
||||
return migration.Migration{
|
||||
Version: 1,
|
||||
Version: 2,
|
||||
Proc: func(st *state.State) {
|
||||
template.InitTemplate(st,
|
||||
template.WithEmpty,
|
||||
|
@ -61,8 +66,54 @@ func (w *WidgetObject) CreationStateMigration(ctx *smartblock.InitContext) migra
|
|||
}
|
||||
}
|
||||
|
||||
func replaceWidgetTarget(st *state.State, targetFrom string, targetTo string, viewId string, layout model.BlockContentWidgetLayout) {
|
||||
st.Iterate(func(b simple.Block) (isContinue bool) {
|
||||
if wc, ok := b.Model().Content.(*model.BlockContentOfWidget); ok {
|
||||
// get child
|
||||
if len(b.Model().GetChildrenIds()) > 0 {
|
||||
child := st.Get(b.Model().GetChildrenIds()[0])
|
||||
childBlock := st.Get(child.Model().Id)
|
||||
if linkBlock, ok := childBlock.Model().Content.(*model.BlockContentOfLink); ok {
|
||||
if linkBlock.Link.TargetBlockId == targetFrom {
|
||||
targets := st.Details().Get(bundle.RelationKeyAutoWidgetTargets).StringList()
|
||||
if slices.Contains(targets, targetTo) {
|
||||
return false
|
||||
}
|
||||
targets = append(targets, targetTo)
|
||||
st.SetDetail(bundle.RelationKeyAutoWidgetTargets, domain.StringList(targets))
|
||||
|
||||
linkBlock.Link.TargetBlockId = targetTo
|
||||
wc.Widget.ViewId = viewId
|
||||
wc.Widget.Layout = layout
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
})
|
||||
}
|
||||
func (w *WidgetObject) StateMigrations() migration.Migrations {
|
||||
return migration.MakeMigrations(nil)
|
||||
return migration.MakeMigrations([]migration.Migration{
|
||||
{
|
||||
Version: 2,
|
||||
Proc: func(s *state.State) {
|
||||
spc := w.Space()
|
||||
setTypeId, err := spc.GetTypeIdByKey(context.Background(), bundle.TypeKeySet)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
collectionTypeId, err := spc.GetTypeIdByKey(context.Background(), bundle.TypeKeyCollection)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
replaceWidgetTarget(s, "collection", collectionTypeId, "all", model.BlockContentWidget_View)
|
||||
replaceWidgetTarget(s, "set", setTypeId, "all", model.BlockContentWidget_View)
|
||||
|
||||
},
|
||||
},
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
func (w *WidgetObject) Unlink(ctx session.Context, ids ...string) (err error) {
|
||||
|
|
|
@ -734,7 +734,7 @@ func (e *exportContext) getRelationsFromStore(relations []string) ([]database.Re
|
|||
|
||||
func (e *exportContext) addRelation(relation database.Record) {
|
||||
relationKey := domain.RelationKey(relation.Details.GetString(bundle.RelationKeyRelationKey))
|
||||
if relationKey != "" && !bundle.HasRelation(relationKey) {
|
||||
if relationKey != "" {
|
||||
id := relation.Details.GetString(bundle.RelationKeyId)
|
||||
e.docs[id] = &Doc{Details: relation.Details, isLink: e.isLinkProcess}
|
||||
}
|
||||
|
|
|
@ -1690,7 +1690,7 @@ func Test_docsForExport(t *testing.T) {
|
|||
|
||||
// then
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, 3, len(expCtx.docs))
|
||||
assert.Equal(t, 4, len(expCtx.docs))
|
||||
})
|
||||
t.Run("objects without file", func(t *testing.T) {
|
||||
// given
|
||||
|
|
|
@ -146,7 +146,7 @@ func TestIconSyncer_Sync(t *testing.T) {
|
|||
Url: "http://url.com",
|
||||
},
|
||||
ObjectOrigin: objectorigin.Import(model.Import_Pb),
|
||||
}).Return("newFileObjectId", nil, nil)
|
||||
}).Return("newFileObjectId", model.BlockContentFile_Image, nil, nil)
|
||||
|
||||
syncer := NewIconSyncer(fileUploader, service)
|
||||
|
||||
|
@ -191,7 +191,7 @@ func TestIconSyncer_Sync(t *testing.T) {
|
|||
Url: "http://url.com",
|
||||
},
|
||||
ObjectOrigin: objectorigin.Import(model.Import_Pb),
|
||||
}).Return("", nil, fmt.Errorf("failed to upload"))
|
||||
}).Return("", model.BlockContentFile_Image, nil, fmt.Errorf("failed to upload"))
|
||||
|
||||
syncer := NewIconSyncer(fileUploader, service)
|
||||
|
||||
|
|
|
@ -11,6 +11,8 @@ import (
|
|||
|
||||
mock "github.com/stretchr/testify/mock"
|
||||
|
||||
model "github.com/anyproto/anytype-heart/pkg/lib/pb/model"
|
||||
|
||||
session "github.com/anyproto/anytype-heart/core/session"
|
||||
|
||||
smartblock "github.com/anyproto/anytype-heart/core/block/editor/smartblock"
|
||||
|
@ -207,7 +209,7 @@ func (_c *MockBlockService_UploadBlockFile_Call) RunAndReturn(run func(session.C
|
|||
}
|
||||
|
||||
// UploadFile provides a mock function with given fields: ctx, spaceId, req
|
||||
func (_m *MockBlockService) UploadFile(ctx context.Context, spaceId string, req block.FileUploadRequest) (string, *domain.Details, error) {
|
||||
func (_m *MockBlockService) UploadFile(ctx context.Context, spaceId string, req block.FileUploadRequest) (string, model.BlockContentFileType, *domain.Details, error) {
|
||||
ret := _m.Called(ctx, spaceId, req)
|
||||
|
||||
if len(ret) == 0 {
|
||||
|
@ -215,9 +217,10 @@ func (_m *MockBlockService) UploadFile(ctx context.Context, spaceId string, req
|
|||
}
|
||||
|
||||
var r0 string
|
||||
var r1 *domain.Details
|
||||
var r2 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, string, block.FileUploadRequest) (string, *domain.Details, error)); ok {
|
||||
var r1 model.BlockContentFileType
|
||||
var r2 *domain.Details
|
||||
var r3 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, string, block.FileUploadRequest) (string, model.BlockContentFileType, *domain.Details, error)); ok {
|
||||
return rf(ctx, spaceId, req)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(context.Context, string, block.FileUploadRequest) string); ok {
|
||||
|
@ -226,21 +229,27 @@ func (_m *MockBlockService) UploadFile(ctx context.Context, spaceId string, req
|
|||
r0 = ret.Get(0).(string)
|
||||
}
|
||||
|
||||
if rf, ok := ret.Get(1).(func(context.Context, string, block.FileUploadRequest) *domain.Details); ok {
|
||||
if rf, ok := ret.Get(1).(func(context.Context, string, block.FileUploadRequest) model.BlockContentFileType); ok {
|
||||
r1 = rf(ctx, spaceId, req)
|
||||
} else {
|
||||
if ret.Get(1) != nil {
|
||||
r1 = ret.Get(1).(*domain.Details)
|
||||
r1 = ret.Get(1).(model.BlockContentFileType)
|
||||
}
|
||||
|
||||
if rf, ok := ret.Get(2).(func(context.Context, string, block.FileUploadRequest) *domain.Details); ok {
|
||||
r2 = rf(ctx, spaceId, req)
|
||||
} else {
|
||||
if ret.Get(2) != nil {
|
||||
r2 = ret.Get(2).(*domain.Details)
|
||||
}
|
||||
}
|
||||
|
||||
if rf, ok := ret.Get(2).(func(context.Context, string, block.FileUploadRequest) error); ok {
|
||||
r2 = rf(ctx, spaceId, req)
|
||||
if rf, ok := ret.Get(3).(func(context.Context, string, block.FileUploadRequest) error); ok {
|
||||
r3 = rf(ctx, spaceId, req)
|
||||
} else {
|
||||
r2 = ret.Error(2)
|
||||
r3 = ret.Error(3)
|
||||
}
|
||||
|
||||
return r0, r1, r2
|
||||
return r0, r1, r2, r3
|
||||
}
|
||||
|
||||
// MockBlockService_UploadFile_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'UploadFile'
|
||||
|
@ -263,12 +272,12 @@ func (_c *MockBlockService_UploadFile_Call) Run(run func(ctx context.Context, sp
|
|||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockBlockService_UploadFile_Call) Return(objectId string, details *domain.Details, err error) *MockBlockService_UploadFile_Call {
|
||||
_c.Call.Return(objectId, details, err)
|
||||
func (_c *MockBlockService_UploadFile_Call) Return(objectId string, fileType model.BlockContentFileType, details *domain.Details, err error) *MockBlockService_UploadFile_Call {
|
||||
_c.Call.Return(objectId, fileType, details, err)
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockBlockService_UploadFile_Call) RunAndReturn(run func(context.Context, string, block.FileUploadRequest) (string, *domain.Details, error)) *MockBlockService_UploadFile_Call {
|
||||
func (_c *MockBlockService_UploadFile_Call) RunAndReturn(run func(context.Context, string, block.FileUploadRequest) (string, model.BlockContentFileType, *domain.Details, error)) *MockBlockService_UploadFile_Call {
|
||||
_c.Call.Return(run)
|
||||
return _c
|
||||
}
|
||||
|
|
|
@ -66,7 +66,7 @@ func TestFileRelationSyncer_Sync(t *testing.T) {
|
|||
Url: "http://url.com",
|
||||
},
|
||||
ObjectOrigin: objectorigin.Import(model.Import_Pb),
|
||||
}).Return("newFileObjectId", nil, nil)
|
||||
}).Return("newFileObjectId", model.BlockContentFile_File, nil, nil)
|
||||
syncer := NewFileRelationSyncer(fileUploader, nil)
|
||||
|
||||
// when
|
||||
|
@ -84,7 +84,7 @@ func TestFileRelationSyncer_Sync(t *testing.T) {
|
|||
LocalPath: "local path",
|
||||
},
|
||||
ObjectOrigin: objectorigin.Import(model.Import_Pb),
|
||||
}).Return("newFileObjectId", nil, nil)
|
||||
}).Return("newFileObjectId", model.BlockContentFile_File, nil, nil)
|
||||
syncer := NewFileRelationSyncer(fileUploader, nil)
|
||||
|
||||
// when
|
||||
|
|
|
@ -268,7 +268,7 @@ func (s *service) prepareDetailsForInstallingObject(
|
|||
|
||||
switch uk.SmartblockType() {
|
||||
case coresb.SmartBlockTypeBundledObjectType, coresb.SmartBlockTypeObjectType:
|
||||
relationKeys, isAlreadyFilled, err := relationutils.FillRecommendedRelations(ctx, spc, details)
|
||||
relationKeys, isAlreadyFilled, err := relationutils.FillRecommendedRelations(ctx, spc, details, domain.TypeKey(uk.InternalKey()))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("fill recommended relations: %w", err)
|
||||
}
|
||||
|
|
|
@ -30,7 +30,7 @@ func (s *service) createObjectType(ctx context.Context, space clientspace.Space,
|
|||
object.SetInt64(bundle.RelationKeyRecommendedLayout, int64(model.ObjectType_basic))
|
||||
}
|
||||
|
||||
keys, isAlreadyFilled, err := relationutils.FillRecommendedRelations(ctx, space, object)
|
||||
keys, isAlreadyFilled, err := relationutils.FillRecommendedRelations(ctx, space, object, domain.TypeKey(uniqueKey.InternalKey()))
|
||||
if err != nil {
|
||||
return "", nil, fmt.Errorf("fill recommended relations: %w", err)
|
||||
}
|
||||
|
|
|
@ -153,6 +153,7 @@ func (s *store) PushStoreChange(ctx context.Context, params PushStoreChangeParam
|
|||
if err != nil {
|
||||
return "", fmt.Errorf("marshal change: %w", err)
|
||||
}
|
||||
|
||||
addResult, err := s.ObjectTree.AddContentWithValidator(ctx, objecttree.SignableChangeContent{
|
||||
Data: data,
|
||||
Key: s.accountKeysService.Account().SignKey,
|
||||
|
@ -160,13 +161,17 @@ func (s *store) PushStoreChange(ctx context.Context, params PushStoreChangeParam
|
|||
DataType: dataType,
|
||||
Timestamp: params.Time.Unix(),
|
||||
}, func(change objecttree.StorageChange) error {
|
||||
// TODO: get order here
|
||||
prevOrder, err := tx.GetPrevOrderId(change.OrderId)
|
||||
if err != nil {
|
||||
return fmt.Errorf("get prev order id: %w", err)
|
||||
}
|
||||
err = tx.ApplyChangeSet(storestate.ChangeSet{
|
||||
Id: change.Id,
|
||||
Order: change.OrderId,
|
||||
Changes: params.Changes,
|
||||
Creator: s.accountService.AccountID(),
|
||||
Timestamp: params.Time.Unix(),
|
||||
Id: change.Id,
|
||||
PrevOrderId: prevOrder,
|
||||
Order: change.OrderId,
|
||||
Changes: params.Changes,
|
||||
Creator: s.accountService.AccountID(),
|
||||
Timestamp: params.Time.Unix(),
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("apply change set: %w", err)
|
||||
|
@ -202,8 +207,9 @@ func (s *store) update(ctx context.Context, tree objecttree.ObjectTree) error {
|
|||
return err
|
||||
}
|
||||
applier := &storeApply{
|
||||
tx: tx,
|
||||
ot: tree,
|
||||
tx: tx,
|
||||
ot: tree,
|
||||
needFetchPrevOrderId: true,
|
||||
}
|
||||
if err = applier.Apply(); err != nil {
|
||||
return errors.Join(tx.Rollback(), err)
|
||||
|
|
|
@ -16,31 +16,39 @@ type storeApply struct {
|
|||
ot objecttree.ObjectTree
|
||||
allIsNew bool
|
||||
|
||||
prevOrder string
|
||||
prevChange *objecttree.Change
|
||||
|
||||
nextCachedOrder string
|
||||
nextCacheChange map[string]struct{}
|
||||
needFetchPrevOrderId bool
|
||||
}
|
||||
|
||||
func (a *storeApply) Apply() (err error) {
|
||||
iterErr := a.ot.IterateRoot(UnmarshalStoreChange, func(change *objecttree.Change) bool {
|
||||
func (a *storeApply) Apply() error {
|
||||
var lastErr error
|
||||
|
||||
err := a.ot.IterateRoot(UnmarshalStoreChange, func(change *objecttree.Change) bool {
|
||||
// not a new change - remember and continue
|
||||
if !a.allIsNew && !change.IsNew {
|
||||
return true
|
||||
}
|
||||
if err = a.applyChange(change); err != nil {
|
||||
|
||||
var prevOrderId string
|
||||
if a.needFetchPrevOrderId {
|
||||
prevOrderId, lastErr = a.tx.GetPrevOrderId(change.OrderId)
|
||||
if lastErr != nil {
|
||||
log.With("error", lastErr).Error("get prev order")
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
lastErr = a.applyChange(prevOrderId, change)
|
||||
if lastErr != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
})
|
||||
if err == nil && iterErr != nil {
|
||||
return iterErr
|
||||
}
|
||||
return
|
||||
|
||||
return errors.Join(err, lastErr)
|
||||
}
|
||||
|
||||
func (a *storeApply) applyChange(change *objecttree.Change) (err error) {
|
||||
func (a *storeApply) applyChange(prevOrderId string, change *objecttree.Change) (err error) {
|
||||
storeChange, ok := change.Model.(*pb.StoreChange)
|
||||
if !ok {
|
||||
// if it is root
|
||||
|
@ -50,11 +58,12 @@ func (a *storeApply) applyChange(change *objecttree.Change) (err error) {
|
|||
return fmt.Errorf("unexpected change content type: %T", change.Model)
|
||||
}
|
||||
set := storestate.ChangeSet{
|
||||
Id: change.Id,
|
||||
Order: change.OrderId,
|
||||
Changes: storeChange.ChangeSet,
|
||||
Creator: change.Identity.Account(),
|
||||
Timestamp: change.Timestamp,
|
||||
Id: change.Id,
|
||||
PrevOrderId: prevOrderId,
|
||||
Order: change.OrderId,
|
||||
Changes: storeChange.ChangeSet,
|
||||
Creator: change.Identity.Account(),
|
||||
Timestamp: change.Timestamp,
|
||||
}
|
||||
err = a.tx.ApplyChangeSet(set)
|
||||
// Skip invalid changes
|
||||
|
|
|
@ -98,7 +98,7 @@ func (mw *Middleware) ChatGetMessagesByIds(cctx context.Context, req *pb.RpcChat
|
|||
func (mw *Middleware) ChatSubscribeLastMessages(cctx context.Context, req *pb.RpcChatSubscribeLastMessagesRequest) *pb.RpcChatSubscribeLastMessagesResponse {
|
||||
chatService := mustService[chats.Service](mw)
|
||||
|
||||
messages, numBefore, err := chatService.SubscribeLastMessages(cctx, req.ChatObjectId, int(req.Limit))
|
||||
messages, numBefore, err := chatService.SubscribeLastMessages(cctx, req.ChatObjectId, int(req.Limit), req.SubId)
|
||||
code := mapErrorCode[pb.RpcChatSubscribeLastMessagesResponseErrorCode](err)
|
||||
return &pb.RpcChatSubscribeLastMessagesResponse{
|
||||
Messages: messages,
|
||||
|
@ -113,7 +113,7 @@ func (mw *Middleware) ChatSubscribeLastMessages(cctx context.Context, req *pb.Rp
|
|||
func (mw *Middleware) ChatUnsubscribe(cctx context.Context, req *pb.RpcChatUnsubscribeRequest) *pb.RpcChatUnsubscribeResponse {
|
||||
chatService := mustService[chats.Service](mw)
|
||||
|
||||
err := chatService.Unsubscribe(req.ChatObjectId)
|
||||
err := chatService.Unsubscribe(req.ChatObjectId, req.SubId)
|
||||
code := mapErrorCode[pb.RpcChatUnsubscribeResponseErrorCode](err)
|
||||
return &pb.RpcChatUnsubscribeResponse{
|
||||
Error: &pb.RpcChatUnsubscribeResponseError{
|
||||
|
@ -122,3 +122,17 @@ func (mw *Middleware) ChatUnsubscribe(cctx context.Context, req *pb.RpcChatUnsub
|
|||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (mw *Middleware) ChatSubscribeToMessagePreviews(cctx context.Context, req *pb.RpcChatSubscribeToMessagePreviewsRequest) *pb.RpcChatSubscribeToMessagePreviewsResponse {
|
||||
chatService := mustService[chats.Service](mw)
|
||||
|
||||
subId, err := chatService.SubscribeToMessagePreviews(cctx)
|
||||
code := mapErrorCode[pb.RpcChatSubscribeToMessagePreviewsResponseErrorCode](err)
|
||||
return &pb.RpcChatSubscribeToMessagePreviewsResponse{
|
||||
SubId: subId,
|
||||
Error: &pb.RpcChatSubscribeToMessagePreviewsResponseError{
|
||||
Code: code,
|
||||
Description: getErrorDescription(err),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
@ -65,7 +65,7 @@ func ExportTree(ctx context.Context, params ExportParams) error {
|
|||
converter = params.Converter
|
||||
changes []*treechangeproto.RawTreeChangeWithId
|
||||
)
|
||||
err = writeTree.IterateRoot(
|
||||
err = params.Readable.IterateRoot(
|
||||
func(change *objecttree.Change, decrypted []byte) (any, error) {
|
||||
return converter.Unmarshall(change.DataType, decrypted)
|
||||
},
|
||||
|
|
|
@ -19,6 +19,7 @@ type ImportResult struct {
|
|||
List list.AclList
|
||||
Storage objecttree.Storage
|
||||
FolderPath string
|
||||
Store anystore.DB
|
||||
}
|
||||
|
||||
func (i ImportResult) CreateReadableTree(fullTree bool, beforeId string) (objecttree.ReadableObjectTree, error) {
|
||||
|
@ -48,11 +49,10 @@ func ImportStorage(ctx context.Context, path string) (res ImportResult, err erro
|
|||
if err = ziputil.UnzipFolder(path, targetDir); err != nil {
|
||||
return
|
||||
}
|
||||
anyStore, err := anystore.Open(ctx, targetDir, nil)
|
||||
anyStore, err := anystore.Open(ctx, filepath.Join(targetDir, "db"), nil)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
defer anyStore.Close()
|
||||
var (
|
||||
aclId string
|
||||
treeId string
|
||||
|
@ -92,5 +92,6 @@ func ImportStorage(ctx context.Context, path string) (res ImportResult, err erro
|
|||
List: acl,
|
||||
Storage: treeStorage,
|
||||
FolderPath: targetDir,
|
||||
Store: anyStore,
|
||||
}, nil
|
||||
}
|
||||
|
|
|
@ -43,10 +43,6 @@ func (e *treeExporter) Export(ctx context.Context, path string, tree objecttree.
|
|||
defer func() {
|
||||
_ = os.RemoveAll(exportDirPath)
|
||||
}()
|
||||
err = os.Mkdir(dbPath, 0755)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
anyStore, err := anystore.Open(ctx, dbPath, nil)
|
||||
if err != nil {
|
||||
return
|
||||
|
@ -76,8 +72,7 @@ func (e *treeExporter) Export(ctx context.Context, path string, tree objecttree.
|
|||
e.log.Printf("can't fetch localstore info: %v", err)
|
||||
} else {
|
||||
if len(data) > 0 {
|
||||
// TODO: [storage] fix details, take from main
|
||||
// data[0].Details = transform(data[0].Details, e.anonymized, anonymize.Struct)
|
||||
data[0].Details = transform(data[0].Details, e.anonymized, anonymize.Details)
|
||||
data[0].Snippet = transform(data[0].Snippet, e.anonymized, anonymize.Text)
|
||||
for i, r := range data[0].Relations {
|
||||
data[0].Relations[i] = transform(r, e.anonymized, anonymize.Relation)
|
||||
|
|
|
@ -11,7 +11,6 @@ import (
|
|||
"io/ioutil"
|
||||
"net/http"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
@ -546,8 +545,7 @@ func (u *uploader) detectType(buf *fileReader) model.BlockContentFileType {
|
|||
log.With("error", err).Error("detect MIME")
|
||||
return model.BlockContentFile_File
|
||||
}
|
||||
mediaType, _ := path.Split(mime.String())
|
||||
return file.DetectTypeByMIME(u.name, mediaType)
|
||||
return file.DetectTypeByMIME(u.name, mime.String())
|
||||
}
|
||||
|
||||
type FileComponent interface {
|
||||
|
|
|
@ -438,9 +438,10 @@ func (i *indexer) reindexIDs(ctx context.Context, space smartblock.Space, reinde
|
|||
func (i *indexer) reindexOutdatedObjects(ctx context.Context, space clientspace.Space) (toReindex, success int, err error) {
|
||||
store := i.store.SpaceIndex(space.Id())
|
||||
var entries []headstorage.HeadsEntry
|
||||
|
||||
err = space.Storage().HeadStorage().IterateEntries(ctx, headstorage.IterOpts{}, func(entry headstorage.HeadsEntry) (bool, error) {
|
||||
// skipping Acl
|
||||
if entry.CommonSnapshot != "" {
|
||||
if entry.CommonSnapshot != "" && entry.Id != space.Storage().StateStorage().SettingsId() {
|
||||
entries = append(entries, entry)
|
||||
}
|
||||
return true, nil
|
||||
|
|
|
@ -13,6 +13,7 @@ var allObjectsRelationsWhiteList = []string{
|
|||
bundle.RelationKeySpaceId.String(),
|
||||
bundle.RelationKeyId.String(),
|
||||
bundle.RelationKeyLayout.String(),
|
||||
bundle.RelationKeyResolvedLayout.String(),
|
||||
bundle.RelationKeyIsArchived.String(),
|
||||
bundle.RelationKeyIsDeleted.String(),
|
||||
bundle.RelationKeyName.String(),
|
||||
|
@ -39,6 +40,15 @@ var derivedObjectsWhiteList = append(slices.Clone(allObjectsRelationsWhiteList),
|
|||
var relationsWhiteList = append(slices.Clone(derivedObjectsWhiteList), bundle.RelationKeyRelationFormat.String())
|
||||
|
||||
var relationOptionWhiteList = append(slices.Clone(derivedObjectsWhiteList), bundle.RelationKeyRelationOptionColor.String())
|
||||
var objectWhiteList = append(slices.Clone(derivedObjectsWhiteList),
|
||||
bundle.RelationKeyRecommendedRelations.String(),
|
||||
bundle.RelationKeyRecommendedFeaturedRelations.String(),
|
||||
bundle.RelationKeyRecommendedLayout.String(),
|
||||
bundle.RelationKeyLayoutWidth.String(),
|
||||
bundle.RelationKeyLayoutAlign.String(),
|
||||
bundle.RelationKeyIconName.String(),
|
||||
bundle.RelationKeyIconOption.String(),
|
||||
)
|
||||
|
||||
var fileRelationsWhiteList = append(
|
||||
slices.Clone(documentRelationsWhiteList),
|
||||
|
@ -60,7 +70,7 @@ var publishingRelationsWhiteList = map[model.ObjectTypeLayout][]string{
|
|||
model.ObjectType_todo: todoRelationsWhiteList,
|
||||
model.ObjectType_set: documentRelationsWhiteList,
|
||||
model.ObjectType_collection: documentRelationsWhiteList,
|
||||
model.ObjectType_objectType: derivedObjectsWhiteList,
|
||||
model.ObjectType_objectType: objectWhiteList,
|
||||
model.ObjectType_relation: relationsWhiteList,
|
||||
model.ObjectType_file: fileRelationsWhiteList,
|
||||
model.ObjectType_pdf: fileRelationsWhiteList,
|
||||
|
|
|
@ -25,6 +25,13 @@ var (
|
|||
bundle.RelationKeyBacklinks,
|
||||
}
|
||||
|
||||
defaultSetFeaturedRelationKeys = []domain.RelationKey{
|
||||
bundle.RelationKeyType,
|
||||
bundle.RelationKeySetOf,
|
||||
bundle.RelationKeyTag,
|
||||
bundle.RelationKeyBacklinks,
|
||||
}
|
||||
|
||||
defaultRecommendedRelationKeys = []domain.RelationKey{
|
||||
bundle.RelationKeyCreatedDate,
|
||||
bundle.RelationKeyCreator,
|
||||
|
@ -36,10 +43,6 @@ var (
|
|||
bundle.RelationKeyLastModifiedBy,
|
||||
bundle.RelationKeyLastOpenedDate,
|
||||
bundle.RelationKeyAddedDate,
|
||||
bundle.RelationKeySource,
|
||||
bundle.RelationKeySourceObject,
|
||||
bundle.RelationKeyImportType,
|
||||
bundle.RelationKeyOrigin,
|
||||
}
|
||||
|
||||
fileSpecificRelationKeysMap = map[domain.RelationKey]struct{}{
|
||||
|
@ -64,14 +67,19 @@ var (
|
|||
errRecommendedRelationsAlreadyFilled = fmt.Errorf("recommended featured relations are already filled")
|
||||
)
|
||||
|
||||
func DefaultFeaturedRelationKeys() []domain.RelationKey {
|
||||
func DefaultFeaturedRelationKeys(typeKey domain.TypeKey) []domain.RelationKey {
|
||||
if typeKey == bundle.TypeKeySet {
|
||||
return defaultSetFeaturedRelationKeys
|
||||
}
|
||||
return defaultFeaturedRelationKeys
|
||||
}
|
||||
|
||||
// FillRecommendedRelations fills recommendedRelations, recommendedFeaturedRelations, recommendedFileRelations
|
||||
// and recommendedHiddenRelations based on object's details.
|
||||
// If these relations are already filled with correct ids, isAlreadyFilled = true is returned
|
||||
func FillRecommendedRelations(ctx context.Context, deriver ObjectIDDeriver, details *domain.Details) (keys []domain.RelationKey, isAlreadyFilled bool, err error) {
|
||||
func FillRecommendedRelations(
|
||||
ctx context.Context, deriver ObjectIDDeriver, details *domain.Details, typeKey domain.TypeKey,
|
||||
) (keys []domain.RelationKey, isAlreadyFilled bool, err error) {
|
||||
keys, err = getRelationKeysFromDetails(details)
|
||||
if err != nil {
|
||||
if errors.Is(err, errRecommendedRelationsAlreadyFilled) {
|
||||
|
@ -99,11 +107,13 @@ func FillRecommendedRelations(ctx context.Context, deriver ObjectIDDeriver, deta
|
|||
keys = other
|
||||
}
|
||||
|
||||
featuredRelationKeys := DefaultFeaturedRelationKeys(typeKey)
|
||||
|
||||
// we should include default system recommended relations and
|
||||
// exclude default recommended featured relations and default hidden relations
|
||||
keys = lo.Uniq(append(keys, defaultRecommendedRelationKeys...))
|
||||
keys = slices.DeleteFunc(keys, func(key domain.RelationKey) bool {
|
||||
return slices.Contains(append(defaultHiddenRelationKeys, defaultFeaturedRelationKeys...), key)
|
||||
return slices.Contains(append(defaultHiddenRelationKeys, featuredRelationKeys...), key)
|
||||
})
|
||||
|
||||
relationIds, err := prepareRelationIds(ctx, deriver, keys)
|
||||
|
@ -112,7 +122,7 @@ func FillRecommendedRelations(ctx context.Context, deriver ObjectIDDeriver, deta
|
|||
}
|
||||
details.SetStringList(bundle.RelationKeyRecommendedRelations, relationIds)
|
||||
|
||||
featuredRelationIds, err := prepareRelationIds(ctx, deriver, defaultFeaturedRelationKeys)
|
||||
featuredRelationIds, err := prepareRelationIds(ctx, deriver, featuredRelationKeys)
|
||||
if err != nil {
|
||||
return nil, false, fmt.Errorf("prepare recommended featured relation ids: %w", err)
|
||||
}
|
||||
|
@ -124,7 +134,7 @@ func FillRecommendedRelations(ctx context.Context, deriver ObjectIDDeriver, deta
|
|||
}
|
||||
details.SetStringList(bundle.RelationKeyRecommendedHiddenRelations, hiddenRelationIds)
|
||||
|
||||
return slices.Concat(keys, fileRecommendedRelationKeys, defaultHiddenRelationKeys, defaultFeaturedRelationKeys), false, nil
|
||||
return slices.Concat(keys, fileRecommendedRelationKeys, defaultHiddenRelationKeys, featuredRelationKeys), false, nil
|
||||
}
|
||||
|
||||
func getRelationKeysFromDetails(details *domain.Details) ([]domain.RelationKey, error) {
|
||||
|
|
|
@ -70,7 +70,7 @@ func TestFillRecommendedRelations(t *testing.T) {
|
|||
})
|
||||
|
||||
// when
|
||||
keys, isAlreadyFilled, err := FillRecommendedRelations(nil, &mockDeriver{}, details)
|
||||
keys, isAlreadyFilled, err := FillRecommendedRelations(nil, &mockDeriver{}, details, bundle.TypeKeyNote)
|
||||
|
||||
// then
|
||||
assert.NoError(t, err)
|
||||
|
@ -78,7 +78,7 @@ func TestFillRecommendedRelations(t *testing.T) {
|
|||
assert.Equal(t, tc.expected, details.GetStringList(bundle.RelationKeyRecommendedRelations))
|
||||
assert.Equal(t, defaultRecFeatRelIds, details.GetStringList(bundle.RelationKeyRecommendedFeaturedRelations))
|
||||
assert.Equal(t, defaultRecHiddenRelIds, details.GetStringList(bundle.RelationKeyRecommendedHiddenRelations))
|
||||
assert.Len(t, keys, len(tc.expected)+3+8) // 3 featured and 8 hidden
|
||||
assert.Len(t, keys, len(tc.expected)+3+4) // 3 featured and 4 hidden
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -91,7 +91,7 @@ func TestFillRecommendedRelations(t *testing.T) {
|
|||
})
|
||||
|
||||
// when
|
||||
keys, isAlreadyFilled, err := FillRecommendedRelations(nil, &mockDeriver{}, details)
|
||||
keys, isAlreadyFilled, err := FillRecommendedRelations(nil, &mockDeriver{}, details, bundle.TypeKeyPage)
|
||||
|
||||
// then
|
||||
assert.NoError(t, err)
|
||||
|
@ -130,7 +130,7 @@ func TestFillRecommendedRelations(t *testing.T) {
|
|||
})
|
||||
|
||||
// when
|
||||
keys, isAlreadyFilled, err := FillRecommendedRelations(nil, &mockDeriver{}, details)
|
||||
keys, isAlreadyFilled, err := FillRecommendedRelations(nil, &mockDeriver{}, details, bundle.TypeKeyTask)
|
||||
|
||||
// then
|
||||
assert.NoError(t, err)
|
||||
|
@ -138,7 +138,7 @@ func TestFillRecommendedRelations(t *testing.T) {
|
|||
assert.Equal(t, tc.expected, details.GetStringList(bundle.RelationKeyRecommendedRelations))
|
||||
assert.Equal(t, defaultRecFeatRelIds, details.GetStringList(bundle.RelationKeyRecommendedFeaturedRelations))
|
||||
assert.Equal(t, defaultRecHiddenRelIds, details.GetStringList(bundle.RelationKeyRecommendedHiddenRelations))
|
||||
assert.Len(t, keys, len(tc.expected)+3+8) // 3 featured and 8 hidden
|
||||
assert.Len(t, keys, len(tc.expected)+3+4) // 3 featured and 4 hidden
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -146,7 +146,6 @@ func TestFillRecommendedRelations(t *testing.T) {
|
|||
// given
|
||||
details := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{
|
||||
bundle.RelationKeyRecommendedRelations: domain.StringList([]string{
|
||||
bundle.RelationKeyOrigin.BundledURL(),
|
||||
bundle.RelationKeyFileExt.BundledURL(),
|
||||
bundle.RelationKeyAddedDate.BundledURL(),
|
||||
bundle.RelationKeyCameraIso.BundledURL(),
|
||||
|
@ -156,7 +155,7 @@ func TestFillRecommendedRelations(t *testing.T) {
|
|||
})
|
||||
|
||||
// when
|
||||
keys, isAlreadyFilled, err := FillRecommendedRelations(nil, &mockDeriver{}, details)
|
||||
keys, isAlreadyFilled, err := FillRecommendedRelations(nil, &mockDeriver{}, details, bundle.TypeKeyProject)
|
||||
|
||||
// then
|
||||
assert.NoError(t, err)
|
||||
|
@ -169,7 +168,30 @@ func TestFillRecommendedRelations(t *testing.T) {
|
|||
bundle.RelationKeyCameraIso.URL(),
|
||||
bundle.RelationKeyAperture.URL(),
|
||||
}, details.GetStringList(bundle.RelationKeyRecommendedFileRelations))
|
||||
assert.Len(t, keys, 17)
|
||||
assert.Len(t, keys, 13)
|
||||
})
|
||||
|
||||
t.Run("recommendedRelations relations of Set", func(t *testing.T) {
|
||||
// given
|
||||
details := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{
|
||||
bundle.RelationKeyRecommendedRelations: domain.StringList([]string{
|
||||
bundle.RelationKeySetOf.BundledURL(),
|
||||
bundle.RelationKeyType.BundledURL(),
|
||||
bundle.RelationKeyTag.BundledURL(),
|
||||
bundle.RelationKeyCreatedDate.BundledURL(),
|
||||
}),
|
||||
})
|
||||
|
||||
// when
|
||||
keys, isAlreadyFilled, err := FillRecommendedRelations(nil, &mockDeriver{}, details, bundle.TypeKeySet)
|
||||
|
||||
// then
|
||||
assert.NoError(t, err)
|
||||
assert.False(t, isAlreadyFilled)
|
||||
assert.Equal(t, buildRelationIds(defaultRecommendedRelationKeys), details.GetStringList(bundle.RelationKeyRecommendedRelations))
|
||||
assert.Equal(t, buildRelationIds(defaultSetFeaturedRelationKeys), details.GetStringList(bundle.RelationKeyRecommendedFeaturedRelations))
|
||||
assert.Equal(t, defaultRecHiddenRelIds, details.GetStringList(bundle.RelationKeyRecommendedHiddenRelations))
|
||||
assert.Len(t, keys, 4+3+4) // 4 featured + 3 sidebar + 4 hidden
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -381,6 +381,9 @@ type EventMatcher struct {
|
|||
}
|
||||
|
||||
func (m EventMatcher) Match(msg *pb.EventMessage) {
|
||||
if msg == nil || msg.Value == nil {
|
||||
return
|
||||
}
|
||||
switch v := msg.Value.(type) {
|
||||
case *pb.EventMessageValueOfSubscriptionAdd:
|
||||
if m.OnAdd != nil {
|
||||
|
|
|
@ -64,7 +64,7 @@ func newCrossSpaceSubscription(subId string, request subscriptionservice.Subscri
|
|||
return s, aggregatedResp, nil
|
||||
}
|
||||
|
||||
func (s *crossSpaceSubscription) run() {
|
||||
func (s *crossSpaceSubscription) run(internalQueue *mb.MB[*pb.EventMessage]) {
|
||||
for {
|
||||
msgs, err := s.queue.Wait(s.ctx)
|
||||
if errors.Is(err, context.Canceled) {
|
||||
|
@ -75,11 +75,19 @@ func (s *crossSpaceSubscription) run() {
|
|||
}
|
||||
for _, msg := range msgs {
|
||||
s.patchEvent(msg)
|
||||
if internalQueue != nil {
|
||||
err = internalQueue.Add(s.ctx, msg)
|
||||
if err != nil {
|
||||
log.Error("add to internal queue", zap.Error(err), zap.String("subId", s.subId))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
s.eventSender.Broadcast(&pb.Event{
|
||||
Messages: msgs,
|
||||
})
|
||||
if internalQueue == nil {
|
||||
s.eventSender.Broadcast(&pb.Event{
|
||||
Messages: msgs,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -89,6 +89,9 @@ func (s *service) Subscribe(req subscriptionservice.SubscribeRequest) (*subscrip
|
|||
if len(req.Sorts) > 0 {
|
||||
return nil, fmt.Errorf("sorting is not supported")
|
||||
}
|
||||
if req.AsyncInit {
|
||||
return nil, fmt.Errorf("async init is not supported")
|
||||
}
|
||||
|
||||
s.lock.Lock()
|
||||
defer s.lock.Unlock()
|
||||
|
@ -97,7 +100,7 @@ func (s *service) Subscribe(req subscriptionservice.SubscribeRequest) (*subscrip
|
|||
return nil, fmt.Errorf("new cross space subscription: %w", err)
|
||||
}
|
||||
s.subscriptions[req.SubId] = spaceSub
|
||||
go spaceSub.run()
|
||||
go spaceSub.run(req.InternalQueue)
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
|
|
|
@ -172,6 +172,9 @@ func (s *service) Close(ctx context.Context) error {
|
|||
}
|
||||
|
||||
func (s *service) Search(req SubscribeRequest) (resp *SubscribeResponse, err error) {
|
||||
if req.SpaceId == "" {
|
||||
return nil, fmt.Errorf("spaceId should not be empty")
|
||||
}
|
||||
// todo: removed temp fix after we will have session-scoped subscriptions
|
||||
// this is to prevent multiple subscriptions with the same id in different spaces
|
||||
err = s.Unsubscribe(req.SubId)
|
||||
|
@ -186,6 +189,9 @@ func (s *service) Search(req SubscribeRequest) (resp *SubscribeResponse, err err
|
|||
}
|
||||
|
||||
func (s *service) SubscribeIdsReq(req pb.RpcObjectSubscribeIdsRequest) (resp *pb.RpcObjectSubscribeIdsResponse, err error) {
|
||||
if req.SpaceId == "" {
|
||||
return nil, fmt.Errorf("spaceId should not be empty")
|
||||
}
|
||||
// todo: removed temp fix after we will have session-scoped subscriptions
|
||||
// this is to prevent multiple subscriptions with the same id in different spaces
|
||||
err = s.Unsubscribe(req.SubId)
|
||||
|
|
|
@ -62,6 +62,7 @@ func TestService_Search(t *testing.T) {
|
|||
}
|
||||
|
||||
t.Run("dependencies", func(t *testing.T) {
|
||||
|
||||
fx := newFixture(t)
|
||||
defer fx.a.Close(context.Background())
|
||||
defer fx.ctrl.Finish()
|
||||
|
@ -83,7 +84,7 @@ func TestService_Search(t *testing.T) {
|
|||
require.NoError(t, err)
|
||||
|
||||
// Wait enough time to flush pending updates to subscriptions handler
|
||||
time.Sleep(batchTime + 3*time.Millisecond)
|
||||
time.Sleep(batchTime + 4*time.Millisecond)
|
||||
|
||||
spaceSub.onChange([]*entry{
|
||||
newEntry("1", domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{
|
||||
|
|
|
@ -564,6 +564,10 @@
|
|||
- [Rpc.Chat.SubscribeLastMessages.Request](#anytype-Rpc-Chat-SubscribeLastMessages-Request)
|
||||
- [Rpc.Chat.SubscribeLastMessages.Response](#anytype-Rpc-Chat-SubscribeLastMessages-Response)
|
||||
- [Rpc.Chat.SubscribeLastMessages.Response.Error](#anytype-Rpc-Chat-SubscribeLastMessages-Response-Error)
|
||||
- [Rpc.Chat.SubscribeToMessagePreviews](#anytype-Rpc-Chat-SubscribeToMessagePreviews)
|
||||
- [Rpc.Chat.SubscribeToMessagePreviews.Request](#anytype-Rpc-Chat-SubscribeToMessagePreviews-Request)
|
||||
- [Rpc.Chat.SubscribeToMessagePreviews.Response](#anytype-Rpc-Chat-SubscribeToMessagePreviews-Response)
|
||||
- [Rpc.Chat.SubscribeToMessagePreviews.Response.Error](#anytype-Rpc-Chat-SubscribeToMessagePreviews-Response-Error)
|
||||
- [Rpc.Chat.ToggleMessageReaction](#anytype-Rpc-Chat-ToggleMessageReaction)
|
||||
- [Rpc.Chat.ToggleMessageReaction.Request](#anytype-Rpc-Chat-ToggleMessageReaction-Request)
|
||||
- [Rpc.Chat.ToggleMessageReaction.Response](#anytype-Rpc-Chat-ToggleMessageReaction-Response)
|
||||
|
@ -1421,6 +1425,7 @@
|
|||
- [Rpc.Chat.GetMessages.Response.Error.Code](#anytype-Rpc-Chat-GetMessages-Response-Error-Code)
|
||||
- [Rpc.Chat.GetMessagesByIds.Response.Error.Code](#anytype-Rpc-Chat-GetMessagesByIds-Response-Error-Code)
|
||||
- [Rpc.Chat.SubscribeLastMessages.Response.Error.Code](#anytype-Rpc-Chat-SubscribeLastMessages-Response-Error-Code)
|
||||
- [Rpc.Chat.SubscribeToMessagePreviews.Response.Error.Code](#anytype-Rpc-Chat-SubscribeToMessagePreviews-Response-Error-Code)
|
||||
- [Rpc.Chat.ToggleMessageReaction.Response.Error.Code](#anytype-Rpc-Chat-ToggleMessageReaction-Response-Error-Code)
|
||||
- [Rpc.Chat.Unsubscribe.Response.Error.Code](#anytype-Rpc-Chat-Unsubscribe-Response-Error-Code)
|
||||
- [Rpc.Debug.AccountSelectTrace.Response.Error.Code](#anytype-Rpc-Debug-AccountSelectTrace-Response-Error-Code)
|
||||
|
@ -2303,6 +2308,7 @@
|
|||
| ChatGetMessagesByIds | [Rpc.Chat.GetMessagesByIds.Request](#anytype-Rpc-Chat-GetMessagesByIds-Request) | [Rpc.Chat.GetMessagesByIds.Response](#anytype-Rpc-Chat-GetMessagesByIds-Response) | |
|
||||
| ChatSubscribeLastMessages | [Rpc.Chat.SubscribeLastMessages.Request](#anytype-Rpc-Chat-SubscribeLastMessages-Request) | [Rpc.Chat.SubscribeLastMessages.Response](#anytype-Rpc-Chat-SubscribeLastMessages-Response) | |
|
||||
| ChatUnsubscribe | [Rpc.Chat.Unsubscribe.Request](#anytype-Rpc-Chat-Unsubscribe-Request) | [Rpc.Chat.Unsubscribe.Response](#anytype-Rpc-Chat-Unsubscribe-Response) | |
|
||||
| ChatSubscribeToMessagePreviews | [Rpc.Chat.SubscribeToMessagePreviews.Request](#anytype-Rpc-Chat-SubscribeToMessagePreviews-Request) | [Rpc.Chat.SubscribeToMessagePreviews.Response](#anytype-Rpc-Chat-SubscribeToMessagePreviews-Response) | |
|
||||
| ObjectChatAdd | [Rpc.Object.ChatAdd.Request](#anytype-Rpc-Object-ChatAdd-Request) | [Rpc.Object.ChatAdd.Response](#anytype-Rpc-Object-ChatAdd-Response) | |
|
||||
|
||||
|
||||
|
@ -10442,6 +10448,7 @@ Get marks list in the selected range in text block.
|
|||
| ----- | ---- | ----- | ----------- |
|
||||
| chatObjectId | [string](#string) | | Identifier for the chat |
|
||||
| limit | [int32](#int32) | | Number of max last messages to return and subscribe |
|
||||
| subId | [string](#string) | | |
|
||||
|
||||
|
||||
|
||||
|
@ -10481,6 +10488,58 @@ Get marks list in the selected range in text block.
|
|||
|
||||
|
||||
|
||||
<a name="anytype-Rpc-Chat-SubscribeToMessagePreviews"></a>
|
||||
|
||||
### Rpc.Chat.SubscribeToMessagePreviews
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<a name="anytype-Rpc-Chat-SubscribeToMessagePreviews-Request"></a>
|
||||
|
||||
### Rpc.Chat.SubscribeToMessagePreviews.Request
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<a name="anytype-Rpc-Chat-SubscribeToMessagePreviews-Response"></a>
|
||||
|
||||
### Rpc.Chat.SubscribeToMessagePreviews.Response
|
||||
|
||||
|
||||
|
||||
| Field | Type | Label | Description |
|
||||
| ----- | ---- | ----- | ----------- |
|
||||
| error | [Rpc.Chat.SubscribeToMessagePreviews.Response.Error](#anytype-Rpc-Chat-SubscribeToMessagePreviews-Response-Error) | | |
|
||||
| subId | [string](#string) | | |
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<a name="anytype-Rpc-Chat-SubscribeToMessagePreviews-Response-Error"></a>
|
||||
|
||||
### Rpc.Chat.SubscribeToMessagePreviews.Response.Error
|
||||
|
||||
|
||||
|
||||
| Field | Type | Label | Description |
|
||||
| ----- | ---- | ----- | ----------- |
|
||||
| code | [Rpc.Chat.SubscribeToMessagePreviews.Response.Error.Code](#anytype-Rpc-Chat-SubscribeToMessagePreviews-Response-Error-Code) | | |
|
||||
| description | [string](#string) | | |
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<a name="anytype-Rpc-Chat-ToggleMessageReaction"></a>
|
||||
|
||||
### Rpc.Chat.ToggleMessageReaction
|
||||
|
@ -10558,6 +10617,7 @@ Get marks list in the selected range in text block.
|
|||
| Field | Type | Label | Description |
|
||||
| ----- | ---- | ----- | ----------- |
|
||||
| chatObjectId | [string](#string) | | Identifier for the chat |
|
||||
| subId | [string](#string) | | |
|
||||
|
||||
|
||||
|
||||
|
@ -22758,6 +22818,19 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er
|
|||
|
||||
|
||||
|
||||
<a name="anytype-Rpc-Chat-SubscribeToMessagePreviews-Response-Error-Code"></a>
|
||||
|
||||
### Rpc.Chat.SubscribeToMessagePreviews.Response.Error.Code
|
||||
|
||||
|
||||
| Name | Number | Description |
|
||||
| ---- | ------ | ----------- |
|
||||
| NULL | 0 | |
|
||||
| UNKNOWN_ERROR | 1 | |
|
||||
| BAD_INPUT | 2 | ... |
|
||||
|
||||
|
||||
|
||||
<a name="anytype-Rpc-Chat-ToggleMessageReaction-Response-Error-Code"></a>
|
||||
|
||||
### Rpc.Chat.ToggleMessageReaction.Response.Error.Code
|
||||
|
@ -27527,7 +27600,10 @@ Precondition: user A opened a block
|
|||
| ----- | ---- | ----- | ----------- |
|
||||
| id | [string](#string) | | |
|
||||
| orderId | [string](#string) | | |
|
||||
| afterOrderId | [string](#string) | | |
|
||||
| message | [model.ChatMessage](#anytype-model-ChatMessage) | | |
|
||||
| subIds | [string](#string) | repeated | |
|
||||
| dependencies | [google.protobuf.Struct](#google-protobuf-Struct) | repeated | |
|
||||
|
||||
|
||||
|
||||
|
@ -27543,6 +27619,7 @@ Precondition: user A opened a block
|
|||
| Field | Type | Label | Description |
|
||||
| ----- | ---- | ----- | ----------- |
|
||||
| id | [string](#string) | | |
|
||||
| subIds | [string](#string) | repeated | |
|
||||
|
||||
|
||||
|
||||
|
@ -27559,6 +27636,7 @@ Precondition: user A opened a block
|
|||
| ----- | ---- | ----- | ----------- |
|
||||
| id | [string](#string) | | |
|
||||
| message | [model.ChatMessage](#anytype-model-ChatMessage) | | |
|
||||
| subIds | [string](#string) | repeated | |
|
||||
|
||||
|
||||
|
||||
|
@ -27575,6 +27653,7 @@ Precondition: user A opened a block
|
|||
| ----- | ---- | ----- | ----------- |
|
||||
| id | [string](#string) | | |
|
||||
| reactions | [model.ChatMessage.Reactions](#anytype-model-ChatMessage-Reactions) | | |
|
||||
| subIds | [string](#string) | repeated | |
|
||||
|
||||
|
||||
|
||||
|
@ -29012,6 +29091,7 @@ Contains basic information about a user account
|
|||
| timeZone | [string](#string) | | time zone from config |
|
||||
| analyticsId | [string](#string) | | |
|
||||
| networkId | [string](#string) | | network id to which anytype is connected |
|
||||
| ethereumAddress | [string](#string) | | we have Any PK AND Ethereum PK derived from one seed phrase |
|
||||
|
||||
|
||||
|
||||
|
|
46
go.mod
46
go.mod
|
@ -51,11 +51,11 @@ require (
|
|||
github.com/hbagdi/go-unsplash v0.0.0-20230414214043-474fc02c9119
|
||||
github.com/huandu/skiplist v1.2.1
|
||||
github.com/improbable-eng/grpc-web v0.15.0
|
||||
github.com/ipfs/boxo v0.28.0
|
||||
github.com/ipfs/boxo v0.29.0
|
||||
github.com/ipfs/go-block-format v0.2.0
|
||||
github.com/ipfs/go-cid v0.5.0
|
||||
github.com/ipfs/go-datastore v0.8.1
|
||||
github.com/ipfs/go-ds-flatfs v0.5.4
|
||||
github.com/ipfs/go-datastore v0.8.2
|
||||
github.com/ipfs/go-ds-flatfs v0.5.5
|
||||
github.com/ipfs/go-ipld-format v0.6.0
|
||||
github.com/ipfs/go-log v1.0.5
|
||||
github.com/joho/godotenv v1.5.1
|
||||
|
@ -81,7 +81,7 @@ require (
|
|||
github.com/otiai10/copy v1.14.1
|
||||
github.com/otiai10/opengraph/v2 v2.1.0
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/prometheus/client_golang v1.20.5
|
||||
github.com/prometheus/client_golang v1.21.1
|
||||
github.com/pseudomuto/protoc-gen-doc v1.5.1
|
||||
github.com/rwcarlsen/goexif v0.0.0-20190401172101-9e8deecbddbd
|
||||
github.com/samber/lo v1.49.1
|
||||
|
@ -104,13 +104,13 @@ require (
|
|||
go.uber.org/multierr v1.11.0
|
||||
go.uber.org/zap v1.27.0
|
||||
golang.org/x/exp v0.0.0-20250218142911-aa4b98e5adaa
|
||||
golang.org/x/image v0.24.0
|
||||
golang.org/x/image v0.25.0
|
||||
golang.org/x/mobile v0.0.0-20250218173827-cd096645fcd3
|
||||
golang.org/x/net v0.35.0
|
||||
golang.org/x/oauth2 v0.27.0
|
||||
golang.org/x/sys v0.30.0
|
||||
golang.org/x/text v0.22.0
|
||||
google.golang.org/grpc v1.70.0
|
||||
golang.org/x/net v0.37.0
|
||||
golang.org/x/oauth2 v0.28.0
|
||||
golang.org/x/sys v0.31.0
|
||||
golang.org/x/text v0.23.0
|
||||
google.golang.org/grpc v1.71.0
|
||||
gopkg.in/Graylog2/go-gelf.v2 v2.0.0-20180125164251-1832d8546a9f
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.2.1
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
|
@ -148,7 +148,7 @@ require (
|
|||
github.com/cloudwego/iasm v0.2.0 // indirect
|
||||
github.com/crackcomm/go-gitignore v0.0.0-20241020182519-7843d2ba8fdf // indirect
|
||||
github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c // indirect
|
||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 // indirect
|
||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 // indirect
|
||||
github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f // indirect
|
||||
github.com/dgraph-io/ristretto v0.1.1 // indirect
|
||||
github.com/disintegration/imaging v1.6.2 // indirect
|
||||
|
@ -157,7 +157,7 @@ require (
|
|||
github.com/dsoprea/go-photoshop-info-format v0.0.0-20200609050348-3db9b63b202c // indirect
|
||||
github.com/dsoprea/go-utility/v2 v2.0.0-20221003172846-a3e1774ef349 // indirect
|
||||
github.com/dustin/go-humanize v1.0.1 // indirect
|
||||
github.com/envoyproxy/protoc-gen-validate v1.1.0 // indirect
|
||||
github.com/envoyproxy/protoc-gen-validate v1.2.1 // indirect
|
||||
github.com/flopp/go-findfont v0.1.0 // indirect
|
||||
github.com/fogleman/gg v1.3.0 // indirect
|
||||
github.com/fsnotify/fsnotify v1.6.0 // indirect
|
||||
|
@ -205,17 +205,17 @@ require (
|
|||
github.com/ipfs/go-ipfs-util v0.0.3 // indirect
|
||||
github.com/ipfs/go-ipld-legacy v0.2.1 // indirect
|
||||
github.com/ipfs/go-log/v2 v2.5.1 // indirect
|
||||
github.com/ipfs/go-metrics-interface v0.0.1 // indirect
|
||||
github.com/ipfs/go-metrics-interface v0.3.0 // indirect
|
||||
github.com/ipld/go-codec-dagpb v1.6.0 // indirect
|
||||
github.com/ipld/go-ipld-prime v0.21.0 // indirect
|
||||
github.com/jbenet/go-temp-err-catcher v0.1.0 // indirect
|
||||
github.com/jinzhu/copier v0.3.5 // indirect
|
||||
github.com/josharian/intern v1.0.0 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.2.9 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.2.10 // indirect
|
||||
github.com/leodido/go-urn v1.4.0 // indirect
|
||||
github.com/libp2p/go-buffer-pool v0.1.0 // indirect
|
||||
github.com/libp2p/go-libp2p v0.40.0 // indirect
|
||||
github.com/libp2p/go-libp2p v0.41.0 // indirect
|
||||
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect
|
||||
github.com/mailru/easyjson v0.7.6 // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
|
@ -229,7 +229,7 @@ require (
|
|||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/multiformats/go-base36 v0.2.0 // indirect
|
||||
github.com/multiformats/go-multiaddr v0.14.0 // indirect
|
||||
github.com/multiformats/go-multiaddr v0.15.0 // indirect
|
||||
github.com/multiformats/go-multicodec v0.9.0 // indirect
|
||||
github.com/multiformats/go-multistream v0.6.0 // indirect
|
||||
github.com/multiformats/go-varint v0.0.7 // indirect
|
||||
|
@ -279,18 +279,18 @@ require (
|
|||
go.opentelemetry.io/otel/metric v1.34.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.34.0 // indirect
|
||||
golang.org/x/arch v0.8.0 // indirect
|
||||
golang.org/x/crypto v0.35.0 // indirect
|
||||
golang.org/x/crypto v0.36.0 // indirect
|
||||
golang.org/x/mod v0.23.0 // indirect
|
||||
golang.org/x/sync v0.11.0 // indirect
|
||||
golang.org/x/term v0.29.0 // indirect
|
||||
golang.org/x/sync v0.12.0 // indirect
|
||||
golang.org/x/term v0.30.0 // indirect
|
||||
golang.org/x/time v0.10.0 // indirect
|
||||
golang.org/x/tools v0.30.0 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20241202173237-19429a94021a // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20241202173237-19429a94021a // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250106144421-5f5ef82da422 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f // indirect
|
||||
google.golang.org/protobuf v1.36.5 // indirect
|
||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
lukechampine.com/blake3 v1.3.0 // indirect
|
||||
lukechampine.com/blake3 v1.4.0 // indirect
|
||||
modernc.org/libc v1.61.13 // indirect
|
||||
modernc.org/mathutil v1.7.1 // indirect
|
||||
modernc.org/memory v1.8.2 // indirect
|
||||
|
@ -312,7 +312,7 @@ replace gopkg.in/Graylog2/go-gelf.v2 => github.com/anyproto/go-gelf v0.0.0-20210
|
|||
|
||||
replace github.com/araddon/dateparse => github.com/mehanizm/dateparse v0.0.0-20210806203422-f82c8742c9f8 // use a fork to support dd.mm.yyyy date format
|
||||
|
||||
replace github.com/multiformats/go-multiaddr => github.com/anyproto/go-multiaddr v0.8.1-0.20221213144344-0b6b93adaec4
|
||||
replace github.com/multiformats/go-multiaddr => github.com/anyproto/go-multiaddr v0.8.1-0.20250307125826-51ba58e2ebc7
|
||||
|
||||
replace github.com/gogo/protobuf => github.com/anyproto/protobuf v1.3.3-0.20240201225420-6e325cf0ac38
|
||||
|
||||
|
|
113
go.sum
113
go.sum
|
@ -84,6 +84,8 @@ github.com/andybalholm/cascadia v1.3.3 h1:AG2YHrzJIm4BZ19iwJ/DAua6Btl3IwJX+VI4kk
|
|||
github.com/andybalholm/cascadia v1.3.3/go.mod h1:xNd9bqTn98Ln4DwST8/nG+H0yuB8Hmgu1YHNnWw0GeA=
|
||||
github.com/anyproto/any-store v0.1.8 h1:/bxUVq6sBTwYkmPL2g1xUAWNb3axF+zPhP2dvdEBH68=
|
||||
github.com/anyproto/any-store v0.1.8/go.mod h1:GpnVhcGm5aUQtOwCnKeTt4jsWgVXZ773WbQVLFdeCFo=
|
||||
github.com/anyproto/any-store v0.1.7 h1:E3DntI+JXo3h7v0WTUJWH+nm7G4MV0PNOXZ6SFzQ2OU=
|
||||
github.com/anyproto/any-store v0.1.7/go.mod h1:nbyRoJYOlvSWU1xDOrmgPP96UeoTf4eYZ9k+qqLK9k8=
|
||||
github.com/anyproto/any-sync v0.6.1 h1:Dasbp7qGQme8diGGpzaDQfSDs5o7PAK3E5rxHHrB/+4=
|
||||
github.com/anyproto/any-sync v0.6.1/go.mod h1:5js8TNBdqe75zwlr9XEQSVDtwhsvEU2qLeC2wTnT/Fo=
|
||||
github.com/anyproto/anytype-publish-server/publishclient v0.0.0-20250131145601-de288583ff2a h1:ZZM+0OUCQMWSLSflpkf0ZMVo3V76qEDDIXPpQOClNs0=
|
||||
|
@ -96,8 +98,8 @@ github.com/anyproto/go-gelf v0.0.0-20210418191311-774bd5b016e7 h1:SyEu5uxZ5nKHEJ
|
|||
github.com/anyproto/go-gelf v0.0.0-20210418191311-774bd5b016e7/go.mod h1:N7kTiXo+LLnV94mHMr7Veos3I1SZ/ELcbkG8sZvcAPI=
|
||||
github.com/anyproto/go-log/v2 v2.1.2-0.20220721095711-bcf09ff293b2 h1:X8xiwPlNiSQs1HKguhZyHYs4XFQLWsj566bFsRjN7hM=
|
||||
github.com/anyproto/go-log/v2 v2.1.2-0.20220721095711-bcf09ff293b2/go.mod h1:TMD+iYDL/QBjspKUN0Ypxpr2IMAz3uGUAsbCeClDQ+4=
|
||||
github.com/anyproto/go-multiaddr v0.8.1-0.20221213144344-0b6b93adaec4 h1:ZUvfKh0DCmmY1wjMtBPS3ggvCvQA0+spKFsAuSSeCsU=
|
||||
github.com/anyproto/go-multiaddr v0.8.1-0.20221213144344-0b6b93adaec4/go.mod h1:Fs50eBDWvZu+l3/9S6xAE7ZYj6yhxlvaVZjakWN7xRs=
|
||||
github.com/anyproto/go-multiaddr v0.8.1-0.20250307125826-51ba58e2ebc7 h1:SD0mX7Ds438ZP6J1g7qpXN4naRi/Naa0umTvlTba76c=
|
||||
github.com/anyproto/go-multiaddr v0.8.1-0.20250307125826-51ba58e2ebc7/go.mod h1:JSVUmXDjsVFiW7RjIFMP7+Ev+h1DTbiJgVeTV/tcmP0=
|
||||
github.com/anyproto/go-naturaldate/v2 v2.0.2-0.20230524105841-9829cfd13438 h1:flfZXdcXB2iVHrTZDwSMlJ7RCRS/ydiPw63xWr+waSU=
|
||||
github.com/anyproto/go-naturaldate/v2 v2.0.2-0.20230524105841-9829cfd13438/go.mod h1:cmdcU4pcVTftMlM89z+d8dLBJc02HtY5tI12yQucUxM=
|
||||
github.com/anyproto/go-slip10 v1.0.0 h1:uAEtSuudR3jJBOfkOXf3bErxVoxbuKwdoJN55M1i6IA=
|
||||
|
@ -229,11 +231,11 @@ github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c/go.mod h1:6Uh
|
|||
github.com/dchesterton/go-jpeg-image-structure/v2 v2.0.0-20240318203529-c3eea088bd38 h1:GDvo0S+xL3iMJYofhBVQVM6EuAcTCoEV1096iN1pedI=
|
||||
github.com/dchesterton/go-jpeg-image-structure/v2 v2.0.0-20240318203529-c3eea088bd38/go.mod h1:WaARaUjQuSuDCDFAiU/GwzfxMTJBulfEhqEA2Tx6B4Y=
|
||||
github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc=
|
||||
github.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5ilcvdfma9wOH6Y=
|
||||
github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo=
|
||||
github.com/decred/dcrd/crypto/blake256 v1.1.0 h1:zPMNGQCm0g4QTY27fOCorQW7EryeQ/U0x++OzVrdms8=
|
||||
github.com/decred/dcrd/crypto/blake256 v1.1.0/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo=
|
||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeCxkaw7y45JueMRL4DIyJDKs=
|
||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 h1:rpfIENRNNilwHwZeG5+P150SMrnNEcHYvcCuK6dPZSg=
|
||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0=
|
||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 h1:NMZiJj8QnKe1LgsbDayM4UoHwbvwDRwnI3hwNaAHRnc=
|
||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0/go.mod h1:ZXNYxsqcloTdSy/rNShjYzMhyjf0LaoftYK0p+A3h40=
|
||||
github.com/decred/dcrd/lru v1.0.0/go.mod h1:mxKOwFd7lFjN2GZYsiz/ecgqR6kkYAl+0pz0tEMk218=
|
||||
github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f h1:U5y3Y5UE0w7amNe7Z5G/twsBW0KEalRQXZzf8ufSh9I=
|
||||
github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f/go.mod h1:xH/i4TFMt8koVQZ6WFms69WAsDWr2XsYL3Hkl7jkoLE=
|
||||
|
@ -285,8 +287,8 @@ github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1m
|
|||
github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po=
|
||||
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/envoyproxy/protoc-gen-validate v1.1.0 h1:tntQDh69XqOCOZsDz0lVJQez/2L6Uu2PdjCQwWCJ3bM=
|
||||
github.com/envoyproxy/protoc-gen-validate v1.1.0/go.mod h1:sXRDRVmzEbkM7CVcM06s9shE/m23dg3wzjl0UWqJ2q4=
|
||||
github.com/envoyproxy/protoc-gen-validate v1.2.1 h1:DEo3O99U8j4hBFwbJfrz9VtgcDfUKS7KJ7spH3d86P8=
|
||||
github.com/envoyproxy/protoc-gen-validate v1.2.1/go.mod h1:d/C80l/jxXLdfEIhX1W2TmLfsJ31lvEjwamM4DxlWXU=
|
||||
github.com/ethereum/go-ethereum v1.13.15 h1:U7sSGYGo4SPjP6iNIifNoyIAiNjrmQkz6EwQG+/EZWo=
|
||||
github.com/ethereum/go-ethereum v1.13.15/go.mod h1:TN8ZiHrdJwSe8Cb6x+p0hs5CxhJZPbqB7hHkaUXcmIU=
|
||||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||
|
@ -543,6 +545,7 @@ github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09
|
|||
github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90=
|
||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/golang-lru v1.0.2 h1:dV3g9Z/unq5DpblPpw+Oqcv4dU/1omnb4Ok8iPY6p1c=
|
||||
github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k=
|
||||
github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM=
|
||||
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
|
||||
|
@ -581,20 +584,20 @@ github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLf
|
|||
github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo=
|
||||
github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs=
|
||||
github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0=
|
||||
github.com/ipfs/boxo v0.28.0 h1:io6nXqN8XMOstB7dQGG5GWnMk4WssoMvva9OADErZdI=
|
||||
github.com/ipfs/boxo v0.28.0/go.mod h1:eY9w3iTpmZGKzDfEYjm3oK8f+xjv8KJhhNXJwicmd3I=
|
||||
github.com/ipfs/boxo v0.29.0 h1:clzd7PglUcE+Ufq1KucS3aKID7pzGVaSgcdRsW395t4=
|
||||
github.com/ipfs/boxo v0.29.0/go.mod h1:c3R52nMlgMsN1tADffYcogKoVRsX1RJE1TMYSpJ4uVs=
|
||||
github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA=
|
||||
github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU=
|
||||
github.com/ipfs/go-block-format v0.2.0 h1:ZqrkxBA2ICbDRbK8KJs/u0O3dlp6gmAuuXUJNiW1Ycs=
|
||||
github.com/ipfs/go-block-format v0.2.0/go.mod h1:+jpL11nFx5A/SPpsoBn6Bzkra/zaArfSmsknbPMYgzM=
|
||||
github.com/ipfs/go-cid v0.5.0 h1:goEKKhaGm0ul11IHA7I6p1GmKz8kEYniqFopaB5Otwg=
|
||||
github.com/ipfs/go-cid v0.5.0/go.mod h1:0L7vmeNXpQpUS9vt+yEARkJ8rOg43DF3iPgn4GIN0mk=
|
||||
github.com/ipfs/go-datastore v0.8.1 h1:p4+tWJuopShJgB3kIK0MMvnH6CFPvi7g/S44f2/EHQA=
|
||||
github.com/ipfs/go-datastore v0.8.1/go.mod h1:W+pI1NsUsz3tcsAACMtfC+IZdnQTnC/7VfPoJBQuts0=
|
||||
github.com/ipfs/go-datastore v0.8.2 h1:Jy3wjqQR6sg/LhyY0NIePZC3Vux19nLtg7dx0TVqr6U=
|
||||
github.com/ipfs/go-datastore v0.8.2/go.mod h1:W+pI1NsUsz3tcsAACMtfC+IZdnQTnC/7VfPoJBQuts0=
|
||||
github.com/ipfs/go-detect-race v0.0.1 h1:qX/xay2W3E4Q1U7d9lNs1sU9nvguX0a7319XbyQ6cOk=
|
||||
github.com/ipfs/go-detect-race v0.0.1/go.mod h1:8BNT7shDZPo99Q74BpGMK+4D8Mn4j46UU0LZ723meps=
|
||||
github.com/ipfs/go-ds-flatfs v0.5.4 h1:rQjd6tiQZgMU8yNmS2iai4FI+JP7EoYLhsjxxAkA/sE=
|
||||
github.com/ipfs/go-ds-flatfs v0.5.4/go.mod h1:sskCDxKNQT3GMVz7QpBc2DK4qalYHZ12y2iCGp4ZZbU=
|
||||
github.com/ipfs/go-ds-flatfs v0.5.5 h1:lkx5C99pFBMI7T1sYF7y3v7xIYekNVNMp/95Gm9Y3tY=
|
||||
github.com/ipfs/go-ds-flatfs v0.5.5/go.mod h1:bM7+m7KFUyv5dp3RBKTr3+OHgZ6h8ydCQkO7tjeO9Z4=
|
||||
github.com/ipfs/go-ipfs-delay v0.0.1 h1:r/UXYyRcddO6thwOnhiznIAiSvxMECGgtv35Xs1IeRQ=
|
||||
github.com/ipfs/go-ipfs-delay v0.0.1/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw=
|
||||
github.com/ipfs/go-ipfs-pq v0.0.3 h1:YpoHVJB+jzK15mr/xsWC574tyDLkezVrDNeaalQBsTE=
|
||||
|
@ -607,12 +610,12 @@ github.com/ipfs/go-ipld-legacy v0.2.1 h1:mDFtrBpmU7b//LzLSypVrXsD8QxkEWxu5qVxN99
|
|||
github.com/ipfs/go-ipld-legacy v0.2.1/go.mod h1:782MOUghNzMO2DER0FlBR94mllfdCJCkTtDtPM51otM=
|
||||
github.com/ipfs/go-log v1.0.5 h1:2dOuUCB1Z7uoczMWgAyDck5JLb72zHzrMnGnCNNbvY8=
|
||||
github.com/ipfs/go-log v1.0.5/go.mod h1:j0b8ZoR+7+R99LD9jZ6+AJsrzkPbSXbZfGakb5JPtIo=
|
||||
github.com/ipfs/go-metrics-interface v0.0.1 h1:j+cpbjYvu4R8zbleSs36gvB7jR+wsL2fGD6n0jO4kdg=
|
||||
github.com/ipfs/go-metrics-interface v0.0.1/go.mod h1:6s6euYU4zowdslK0GKHmqaIZ3j/b/tL7HTWtJ4VPgWY=
|
||||
github.com/ipfs/go-metrics-interface v0.3.0 h1:YwG7/Cy4R94mYDUuwsBfeziJCVm9pBMJ6q/JR9V40TU=
|
||||
github.com/ipfs/go-metrics-interface v0.3.0/go.mod h1:OxxQjZDGocXVdyTPocns6cOLwHieqej/jos7H4POwoY=
|
||||
github.com/ipfs/go-peertaskqueue v0.8.2 h1:PaHFRaVFdxQk1Qo3OKiHPYjmmusQy7gKQUaL8JDszAU=
|
||||
github.com/ipfs/go-peertaskqueue v0.8.2/go.mod h1:L6QPvou0346c2qPJNiJa6BvOibxDfaiPlqHInmzg0FA=
|
||||
github.com/ipfs/go-test v0.0.4 h1:DKT66T6GBB6PsDFLoO56QZPrOmzJkqU1FZH5C9ySkew=
|
||||
github.com/ipfs/go-test v0.0.4/go.mod h1:qhIM1EluEfElKKM6fnWxGn822/z9knUGM1+I/OAQNKI=
|
||||
github.com/ipfs/go-test v0.2.1 h1:/D/a8xZ2JzkYqcVcV/7HYlCnc7bv/pKHQiX5TdClkPE=
|
||||
github.com/ipfs/go-test v0.2.1/go.mod h1:dzu+KB9cmWjuJnXFDYJwC25T3j1GcN57byN+ixmK39M=
|
||||
github.com/ipld/go-codec-dagpb v1.6.0 h1:9nYazfyu9B1p3NAgfVdpRco3Fs2nFC72DqVsMj6rOcc=
|
||||
github.com/ipld/go-codec-dagpb v1.6.0/go.mod h1:ANzFhfP2uMJxRBr8CE+WQWs5UsNa0pYtmKZ+agnUw9s=
|
||||
github.com/ipld/go-ipld-prime v0.21.0 h1:n4JmcpOlPDIxBcY037SVfpd1G+Sj1nKZah0m6QH9C2E=
|
||||
|
@ -662,8 +665,8 @@ github.com/klauspost/compress v1.11.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYs
|
|||
github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=
|
||||
github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=
|
||||
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
||||
github.com/klauspost/cpuid/v2 v2.2.9 h1:66ze0taIn2H33fBvCkXuv9BmCwDfafmiIVpKV9kKGuY=
|
||||
github.com/klauspost/cpuid/v2 v2.2.9/go.mod h1:rqkxqrZ1EhYM9G+hXH7YdowN5R5RGN6NK4QwQ3WMXF8=
|
||||
github.com/klauspost/cpuid/v2 v2.2.10 h1:tBs3QSyvjDyFTq3uoc/9xFpCuOsJQFNPiAhYdw2skhE=
|
||||
github.com/klauspost/cpuid/v2 v2.2.10/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0=
|
||||
github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
|
@ -689,8 +692,8 @@ github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6
|
|||
github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QTWy5HSiZacSbPg=
|
||||
github.com/libp2p/go-flow-metrics v0.2.0 h1:EIZzjmeOE6c8Dav0sNv35vhZxATIXWZg6j/C08XmmDw=
|
||||
github.com/libp2p/go-flow-metrics v0.2.0/go.mod h1:st3qqfu8+pMfh+9Mzqb2GTiwrAGjIPszEjZmtksN8Jc=
|
||||
github.com/libp2p/go-libp2p v0.40.0 h1:1LOMO3gigxeXFs50HGEc1U79OINewUQB7o4gTKGPC3U=
|
||||
github.com/libp2p/go-libp2p v0.40.0/go.mod h1:hOzj2EAIYsXpVpBnyA1pRHzpUJGF9nbWiDLjgasnbF0=
|
||||
github.com/libp2p/go-libp2p v0.41.0 h1:JRaD39dqf/tBBGapJ0T38N73vOaDCsWgcx3mE6HgXWk=
|
||||
github.com/libp2p/go-libp2p v0.41.0/go.mod h1:Be8QYqC4JW6Xq8buukNeoZJjyT1XUDcGoIooCHm1ye4=
|
||||
github.com/libp2p/go-libp2p-asn-util v0.4.1 h1:xqL7++IKD9TBFMgnLPZR6/6iYhawHKHl950SO9L6n94=
|
||||
github.com/libp2p/go-libp2p-asn-util v0.4.1/go.mod h1:d/NI6XZ9qxw67b4e+NgpQexCIiFYJjErASrYW4PFDN8=
|
||||
github.com/libp2p/go-libp2p-record v0.3.1 h1:cly48Xi5GjNw5Wq+7gmjfBiG9HCzQVkiZOUZ8kUl+Fg=
|
||||
|
@ -699,8 +702,6 @@ github.com/libp2p/go-libp2p-testing v0.12.0 h1:EPvBb4kKMWO29qP4mZGyhVzUyR25dvfUI
|
|||
github.com/libp2p/go-libp2p-testing v0.12.0/go.mod h1:KcGDRXyN7sQCllucn1cOOS+Dmm7ujhfEyXQL5lvkcPg=
|
||||
github.com/libp2p/go-msgio v0.3.0 h1:mf3Z8B1xcFN314sWX+2vOTShIE0Mmn2TXn3YCUQGNj0=
|
||||
github.com/libp2p/go-msgio v0.3.0/go.mod h1:nyRM819GmVaF9LX3l03RMh10QdOroF++NBbxAb0mmDM=
|
||||
github.com/libp2p/go-nat v0.2.0 h1:Tyz+bUFAYqGyJ/ppPPymMGbIgNRH+WqC5QrT5fKrrGk=
|
||||
github.com/libp2p/go-nat v0.2.0/go.mod h1:3MJr+GRpRkyT65EpVPBstXLvOlAPzUVlG6Pwg9ohLJk=
|
||||
github.com/libp2p/go-netroute v0.2.2 h1:Dejd8cQ47Qx2kRABg6lPwknU7+nBnFRpko45/fFPuZ8=
|
||||
github.com/libp2p/go-netroute v0.2.2/go.mod h1:Rntq6jUAH0l9Gg17w5bFGhcC9a+vk4KNXs6s7IljKYE=
|
||||
github.com/libp2p/go-yamux/v5 v5.0.0 h1:2djUh96d3Jiac/JpGkKs4TO49YhsfLopAoryfPmf+Po=
|
||||
|
@ -883,8 +884,8 @@ github.com/pion/rtcp v1.2.15 h1:LZQi2JbdipLOj4eBjK4wlVoQWfrZbh3Q6eHtWtJBZBo=
|
|||
github.com/pion/rtcp v1.2.15/go.mod h1:jlGuAjHMEXwMUHK78RgX0UmEJFV4zUKOFHR7OP+D3D0=
|
||||
github.com/pion/rtp v1.8.11 h1:17xjnY5WO5hgO6SD3/NTIUPvSFw/PbLsIJyz1r1yNIk=
|
||||
github.com/pion/rtp v1.8.11/go.mod h1:8uMBJj32Pa1wwx8Fuv/AsFhn8jsgw+3rUC2PfoBZ8p4=
|
||||
github.com/pion/sctp v1.8.35 h1:qwtKvNK1Wc5tHMIYgTDJhfZk7vATGVHhXbUDfHbYwzA=
|
||||
github.com/pion/sctp v1.8.35/go.mod h1:EcXP8zCYVTRy3W9xtOF7wJm1L1aXfKRQzaM33SjQlzg=
|
||||
github.com/pion/sctp v1.8.36 h1:owNudmnz1xmhfYje5L/FCav3V9wpPRePHle3Zi+P+M0=
|
||||
github.com/pion/sctp v1.8.36/go.mod h1:cNiLdchXra8fHQwmIoqw0MbLLMs+f7uQ+dGMG2gWebE=
|
||||
github.com/pion/sdp/v3 v3.0.10 h1:6MChLE/1xYB+CjumMw+gZ9ufp2DPApuVSnDT8t5MIgA=
|
||||
github.com/pion/sdp/v3 v3.0.10/go.mod h1:88GMahN5xnScv1hIMTqLdu/cOcUkj6a9ytbncwMCq2E=
|
||||
github.com/pion/srtp/v3 v3.0.4 h1:2Z6vDVxzrX3UHEgrUyIGM4rRouoC7v+NiF1IHtp9B5M=
|
||||
|
@ -899,8 +900,8 @@ github.com/pion/transport/v3 v3.0.7 h1:iRbMH05BzSNwhILHoBoAPxoB9xQgOaJk+591KC9P1
|
|||
github.com/pion/transport/v3 v3.0.7/go.mod h1:YleKiTZ4vqNxVwh77Z0zytYi7rXHl7j6uPLGhhz9rwo=
|
||||
github.com/pion/turn/v4 v4.0.0 h1:qxplo3Rxa9Yg1xXDxxH8xaqcyGUtbHYw4QSCvmFWvhM=
|
||||
github.com/pion/turn/v4 v4.0.0/go.mod h1:MuPDkm15nYSklKpN8vWJ9W2M0PlyQZqYt1McGuxG7mA=
|
||||
github.com/pion/webrtc/v4 v4.0.9 h1:PyOYMRKJgfy0dzPcYtFD/4oW9zaw3Ze3oZzzbj2LV9E=
|
||||
github.com/pion/webrtc/v4 v4.0.9/go.mod h1:ViHLVaNpiuvaH8pdiuQxuA9awuE6KVzAXx3vVWilOck=
|
||||
github.com/pion/webrtc/v4 v4.0.10 h1:Hq/JLjhqLxi+NmCtE8lnRPDr8H4LcNvwg8OxVcdv56Q=
|
||||
github.com/pion/webrtc/v4 v4.0.10/go.mod h1:ViHLVaNpiuvaH8pdiuQxuA9awuE6KVzAXx3vVWilOck=
|
||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
|
@ -919,8 +920,8 @@ github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod
|
|||
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
|
||||
github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og=
|
||||
github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
|
||||
github.com/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+bR9r+8l63Y=
|
||||
github.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE=
|
||||
github.com/prometheus/client_golang v1.21.1 h1:DOvXXTqVzvkIewV/CDPFdejpMCGeMcbGCQ8YOmu+Ibk=
|
||||
github.com/prometheus/client_golang v1.21.1/go.mod h1:U9NM32ykUErtVBxdvD3zfi+EuFkkaBvMb09mIfe0Zgg=
|
||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
|
@ -1137,10 +1138,10 @@ go.opentelemetry.io/otel v1.34.0 h1:zRLXxLCgL1WyKsPVrgbSdMN4c0FMkDAskSTQP+0hdUY=
|
|||
go.opentelemetry.io/otel v1.34.0/go.mod h1:OWFPOQ+h4G8xpyjgqo4SxJYdDQ/qmRH+wivy7zzx9oI=
|
||||
go.opentelemetry.io/otel/metric v1.34.0 h1:+eTR3U0MyfWjRDhmFMxe2SsW64QrZ84AOhvqS7Y+PoQ=
|
||||
go.opentelemetry.io/otel/metric v1.34.0/go.mod h1:CEDrp0fy2D0MvkXE+dPV7cMi8tWZwX3dmaIhwPOaqHE=
|
||||
go.opentelemetry.io/otel/sdk v1.32.0 h1:RNxepc9vK59A8XsgZQouW8ue8Gkb4jpWtJm9ge5lEG4=
|
||||
go.opentelemetry.io/otel/sdk v1.32.0/go.mod h1:LqgegDBjKMmb2GC6/PrTnteJG39I8/vJCAP9LlJXEjU=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.32.0 h1:rZvFnvmvawYb0alrYkjraqJq0Z4ZUJAiyYCU9snn1CU=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.32.0/go.mod h1:PWeZlq0zt9YkYAp3gjKZ0eicRYvOh1Gd+X99x6GHpCQ=
|
||||
go.opentelemetry.io/otel/sdk v1.34.0 h1:95zS4k/2GOy069d321O8jWgYsW3MzVV+KuSPKp7Wr1A=
|
||||
go.opentelemetry.io/otel/sdk v1.34.0/go.mod h1:0e/pNiaMAqaykJGKbi+tSjWfNNHMTxoC9qANsCzbyxU=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.34.0 h1:5CeK9ujjbFVL5c1PhLuStg1wxA7vQv7ce1EK0Gyvahk=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.34.0/go.mod h1:jQ/r8Ze28zRKoNRdkjCZxfs6YvBTG1+YIqyFVFYec5w=
|
||||
go.opentelemetry.io/otel/trace v1.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC8mh/k=
|
||||
go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE=
|
||||
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
|
@ -1190,8 +1191,8 @@ golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliY
|
|||
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
|
||||
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
|
||||
golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
|
||||
golang.org/x/crypto v0.35.0 h1:b15kiHdrGCHrP6LvwaQ3c03kgNhhiMgvlhxHQhmg2Xs=
|
||||
golang.org/x/crypto v0.35.0/go.mod h1:dy7dXNW32cAb/6/PRuTNsix8T+vJAqvuIy5Bli/x0YQ=
|
||||
golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34=
|
||||
golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc=
|
||||
golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
|
@ -1212,8 +1213,8 @@ golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86h
|
|||
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
||||
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/image v0.24.0 h1:AN7zRgVsbvmTfNyqIbbOraYL8mSwcKncEj8ofjgzcMQ=
|
||||
golang.org/x/image v0.24.0/go.mod h1:4b/ITuLfqYq1hqZcjofwctIhi7sZh2WaCjvsBNjjya8=
|
||||
golang.org/x/image v0.25.0 h1:Y6uW6rH1y5y/LK1J8BPWZtr6yZ7hrsy6hFrXjgsc2fQ=
|
||||
golang.org/x/image v0.25.0/go.mod h1:tCAmOEGthTtkalusGp1g3xa2gke8J6c2N565dTyl9Rs=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
|
@ -1307,8 +1308,8 @@ golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
|
|||
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
|
||||
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
|
||||
golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4=
|
||||
golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8=
|
||||
golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk=
|
||||
golang.org/x/net v0.37.0 h1:1zLorHbz+LYj7MQlSf1+2tPIIgibq2eL5xkrGk6f+2c=
|
||||
golang.org/x/net v0.37.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
|
@ -1318,8 +1319,8 @@ golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ
|
|||
golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.27.0 h1:da9Vo7/tDv5RH/7nZDz1eMGS/q1Vv1N/7FCrBhI9I3M=
|
||||
golang.org/x/oauth2 v0.27.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8=
|
||||
golang.org/x/oauth2 v0.28.0 h1:CrgCKl8PPAVtLnU3c+EDw6x11699EWlsDeWNWKdIOkc=
|
||||
golang.org/x/oauth2 v0.28.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
|
@ -1337,8 +1338,8 @@ golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
|
|||
golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w=
|
||||
golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw=
|
||||
golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
|
||||
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
|
@ -1424,8 +1425,8 @@ golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|||
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc=
|
||||
golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik=
|
||||
golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||
golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
|
@ -1436,8 +1437,8 @@ golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU=
|
|||
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
|
||||
golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY=
|
||||
golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM=
|
||||
golang.org/x/term v0.29.0 h1:L6pJp37ocefwRRtYPKSWOWzOtWSxVajvz2ldH/xi3iU=
|
||||
golang.org/x/term v0.29.0/go.mod h1:6bl4lRlvVuDgSf3179VpIxBF0o10JUpXWOnI7nErv7s=
|
||||
golang.org/x/term v0.30.0 h1:PQ39fJZ+mfadBm0y5WlL4vlM7Sx1Hgf13sMIY2+QS9Y=
|
||||
golang.org/x/term v0.30.0/go.mod h1:NYYFdzHoI5wRh/h5tDMdMqCqPJZEuNqVR5xJLd/n67g=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
|
@ -1453,8 +1454,8 @@ golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
|||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
|
||||
golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM=
|
||||
golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY=
|
||||
golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY=
|
||||
golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4=
|
||||
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
|
@ -1601,8 +1602,8 @@ google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6D
|
|||
google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20210126160654-44e461bb6506/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20241202173237-19429a94021a h1:OAiGFfOiA0v9MRYsSidp3ubZaBnteRUyn3xB2ZQ5G/E=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20241202173237-19429a94021a/go.mod h1:jehYqy3+AhJU9ve55aNOaSml7wUXjF9x6z2LcCfpAhY=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250106144421-5f5ef82da422 h1:GVIKPyP/kLIyVOgOnTwFOrvQaQUzOzGMCxgFUOEmm24=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250106144421-5f5ef82da422/go.mod h1:b6h1vNKhxaSoEI+5jc3PJUCustfli/mRab7295pY7rw=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20241021214115-324edc3d5d38 h1:zciRKQ4kBpFgpfC5QQCVtnnNAcLIqweL7plyZRQHVpI=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20241021214115-324edc3d5d38/go.mod h1:GX3210XPVPUjJbTUbvwI8f2IpZDMZuPJWDzDuebbviI=
|
||||
google.golang.org/grpc v1.12.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
|
||||
|
@ -1628,8 +1629,8 @@ google.golang.org/grpc v1.32.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM
|
|||
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
|
||||
google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8=
|
||||
google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
|
||||
google.golang.org/grpc v1.70.0 h1:pWFv03aZoHzlRKHWicjsZytKAiYCtNS0dHbXnIdq7jQ=
|
||||
google.golang.org/grpc v1.70.0/go.mod h1:ofIJqVKDXx/JiXrwr2IG4/zwdH9txy3IlF40RmcJSQw=
|
||||
google.golang.org/grpc v1.71.0 h1:kF77BGdPTQ4/JZWMlb9VpJ5pa25aqvVqogsxNHHdeBg=
|
||||
google.golang.org/grpc v1.71.0/go.mod h1:H0GRtasmQOh9LkFoCPDu3ZrwUtD1YGE+b2vYBYd/8Ec=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||
|
@ -1683,8 +1684,8 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh
|
|||
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
||||
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||
lukechampine.com/blake3 v1.3.0 h1:sJ3XhFINmHSrYCgl958hscfIa3bw8x4DqMP3u1YvoYE=
|
||||
lukechampine.com/blake3 v1.3.0/go.mod h1:0OFRp7fBtAylGVCO40o87sbupkyIGgbpv1+M1k1LM6k=
|
||||
lukechampine.com/blake3 v1.4.0 h1:xDbKOZCVbnZsfzM6mHSYcGRHZ3YrLDzqz8XnV4uaD5w=
|
||||
lukechampine.com/blake3 v1.4.0/go.mod h1:MQJNQCTnR+kwOP/JEZSxj3MaQjp80FOFSNMMHXcSeX0=
|
||||
modernc.org/cc/v4 v4.24.4 h1:TFkx1s6dCkQpd6dKurBNmpo+G8Zl4Sq/ztJ+2+DEsh0=
|
||||
modernc.org/cc/v4 v4.24.4/go.mod h1:uVtb5OGqUKpoLWhqwNQo/8LwvoiEBLvZXIQ/SmO6mL0=
|
||||
modernc.org/ccgo/v4 v4.23.16 h1:Z2N+kk38b7SfySC1ZkpGLN2vthNJP1+ZzGZIlH7uBxo=
|
||||
|
|
3347
pb/commands.pb.go
3347
pb/commands.pb.go
File diff suppressed because it is too large
Load diff
1123
pb/events.pb.go
1123
pb/events.pb.go
File diff suppressed because it is too large
Load diff
|
@ -7952,6 +7952,7 @@ message Rpc {
|
|||
message Request {
|
||||
string chatObjectId = 1; // Identifier for the chat
|
||||
int32 limit = 2; // Number of max last messages to return and subscribe
|
||||
string subId = 3;
|
||||
}
|
||||
|
||||
message Response {
|
||||
|
@ -7976,6 +7977,7 @@ message Rpc {
|
|||
message Unsubscribe {
|
||||
message Request {
|
||||
string chatObjectId = 1; // Identifier for the chat
|
||||
string subId = 2;
|
||||
}
|
||||
message Response {
|
||||
Error error = 1;
|
||||
|
@ -7993,6 +7995,27 @@ message Rpc {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
message SubscribeToMessagePreviews {
|
||||
message Request {}
|
||||
|
||||
message Response {
|
||||
Error error = 1;
|
||||
string subId = 2;
|
||||
|
||||
message Error {
|
||||
Code code = 1;
|
||||
string description = 2;
|
||||
|
||||
enum Code {
|
||||
NULL = 0;
|
||||
UNKNOWN_ERROR = 1;
|
||||
BAD_INPUT = 2;
|
||||
// ...
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -124,18 +124,24 @@ message Event {
|
|||
message Add {
|
||||
string id = 1;
|
||||
string orderId = 2;
|
||||
string afterOrderId = 6;
|
||||
model.ChatMessage message = 3;
|
||||
repeated string subIds = 4;
|
||||
repeated google.protobuf.Struct dependencies = 5;
|
||||
}
|
||||
message Delete {
|
||||
string id = 1;
|
||||
repeated string subIds = 2;
|
||||
}
|
||||
message Update {
|
||||
string id = 1;
|
||||
model.ChatMessage message = 2;
|
||||
repeated string subIds = 3;
|
||||
}
|
||||
message UpdateReactions {
|
||||
string id = 1;
|
||||
model.ChatMessage.Reactions reactions = 2;
|
||||
repeated string subIds = 3;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -394,5 +394,6 @@ service ClientCommands {
|
|||
rpc ChatGetMessagesByIds (anytype.Rpc.Chat.GetMessagesByIds.Request) returns (anytype.Rpc.Chat.GetMessagesByIds.Response);
|
||||
rpc ChatSubscribeLastMessages (anytype.Rpc.Chat.SubscribeLastMessages.Request) returns (anytype.Rpc.Chat.SubscribeLastMessages.Response);
|
||||
rpc ChatUnsubscribe (anytype.Rpc.Chat.Unsubscribe.Request) returns (anytype.Rpc.Chat.Unsubscribe.Response);
|
||||
rpc ChatSubscribeToMessagePreviews (anytype.Rpc.Chat.SubscribeToMessagePreviews.Request) returns (anytype.Rpc.Chat.SubscribeToMessagePreviews.Response);
|
||||
rpc ObjectChatAdd (anytype.Rpc.Object.ChatAdd.Request) returns (anytype.Rpc.Object.ChatAdd.Response);
|
||||
}
|
||||
|
|
|
@ -5659,6 +5659,55 @@ func (_c *MockClientCommandsServer_ChatSubscribeLastMessages_Call) RunAndReturn(
|
|||
return _c
|
||||
}
|
||||
|
||||
// ChatSubscribeToMessagePreviews provides a mock function with given fields: _a0, _a1
|
||||
func (_m *MockClientCommandsServer) ChatSubscribeToMessagePreviews(_a0 context.Context, _a1 *pb.RpcChatSubscribeToMessagePreviewsRequest) *pb.RpcChatSubscribeToMessagePreviewsResponse {
|
||||
ret := _m.Called(_a0, _a1)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for ChatSubscribeToMessagePreviews")
|
||||
}
|
||||
|
||||
var r0 *pb.RpcChatSubscribeToMessagePreviewsResponse
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *pb.RpcChatSubscribeToMessagePreviewsRequest) *pb.RpcChatSubscribeToMessagePreviewsResponse); ok {
|
||||
r0 = rf(_a0, _a1)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*pb.RpcChatSubscribeToMessagePreviewsResponse)
|
||||
}
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// MockClientCommandsServer_ChatSubscribeToMessagePreviews_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ChatSubscribeToMessagePreviews'
|
||||
type MockClientCommandsServer_ChatSubscribeToMessagePreviews_Call struct {
|
||||
*mock.Call
|
||||
}
|
||||
|
||||
// ChatSubscribeToMessagePreviews is a helper method to define mock.On call
|
||||
// - _a0 context.Context
|
||||
// - _a1 *pb.RpcChatSubscribeToMessagePreviewsRequest
|
||||
func (_e *MockClientCommandsServer_Expecter) ChatSubscribeToMessagePreviews(_a0 interface{}, _a1 interface{}) *MockClientCommandsServer_ChatSubscribeToMessagePreviews_Call {
|
||||
return &MockClientCommandsServer_ChatSubscribeToMessagePreviews_Call{Call: _e.mock.On("ChatSubscribeToMessagePreviews", _a0, _a1)}
|
||||
}
|
||||
|
||||
func (_c *MockClientCommandsServer_ChatSubscribeToMessagePreviews_Call) Run(run func(_a0 context.Context, _a1 *pb.RpcChatSubscribeToMessagePreviewsRequest)) *MockClientCommandsServer_ChatSubscribeToMessagePreviews_Call {
|
||||
_c.Call.Run(func(args mock.Arguments) {
|
||||
run(args[0].(context.Context), args[1].(*pb.RpcChatSubscribeToMessagePreviewsRequest))
|
||||
})
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockClientCommandsServer_ChatSubscribeToMessagePreviews_Call) Return(_a0 *pb.RpcChatSubscribeToMessagePreviewsResponse) *MockClientCommandsServer_ChatSubscribeToMessagePreviews_Call {
|
||||
_c.Call.Return(_a0)
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockClientCommandsServer_ChatSubscribeToMessagePreviews_Call) RunAndReturn(run func(context.Context, *pb.RpcChatSubscribeToMessagePreviewsRequest) *pb.RpcChatSubscribeToMessagePreviewsResponse) *MockClientCommandsServer_ChatSubscribeToMessagePreviews_Call {
|
||||
_c.Call.Return(run)
|
||||
return _c
|
||||
}
|
||||
|
||||
// ChatToggleMessageReaction provides a mock function with given fields: _a0, _a1
|
||||
func (_m *MockClientCommandsServer) ChatToggleMessageReaction(_a0 context.Context, _a1 *pb.RpcChatToggleMessageReactionRequest) *pb.RpcChatToggleMessageReactionResponse {
|
||||
ret := _m.Called(_a0, _a1)
|
||||
|
|
|
@ -26,18 +26,18 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
|
|||
func init() { proto.RegisterFile("pb/protos/service/service.proto", fileDescriptor_93a29dc403579097) }
|
||||
|
||||
var fileDescriptor_93a29dc403579097 = []byte{
|
||||
// 5514 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x9d, 0x5f, 0x6f, 0x24, 0x49,
|
||||
0x52, 0xc0, 0xb7, 0x5f, 0x58, 0xa8, 0xe3, 0x16, 0xe8, 0x85, 0x65, 0x6f, 0xb9, 0x9b, 0x99, 0x9d,
|
||||
0x9d, 0xb1, 0x3d, 0x63, 0xbb, 0x3d, 0x3b, 0xb3, 0xff, 0xb8, 0x43, 0x82, 0x1e, 0x7b, 0xec, 0xf5,
|
||||
0x9d, 0xed, 0x35, 0xee, 0xf6, 0x8c, 0xb4, 0x12, 0x12, 0xe5, 0xaa, 0x74, 0xbb, 0x70, 0x75, 0x65,
|
||||
0x5d, 0x55, 0x76, 0x7b, 0xfa, 0x10, 0x08, 0x04, 0x02, 0x81, 0x40, 0x9c, 0xf8, 0x27, 0x78, 0x42,
|
||||
0x42, 0x7c, 0x00, 0x3e, 0x06, 0x8f, 0xf7, 0xc8, 0x23, 0xda, 0xfd, 0x0a, 0x7c, 0x00, 0x54, 0xf9,
|
||||
0x3f, 0xa3, 0x32, 0xb2, 0xca, 0xcb, 0xd3, 0x8c, 0x1c, 0xbf, 0x88, 0xc8, 0xac, 0x8c, 0xcc, 0x8c,
|
||||
0xcc, 0xca, 0xca, 0x8e, 0xee, 0x96, 0x17, 0x3b, 0x65, 0x45, 0x19, 0xad, 0x77, 0x6a, 0x52, 0x2d,
|
||||
// 5536 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x9d, 0x4f, 0x6f, 0x24, 0x49,
|
||||
0x56, 0xc0, 0xa7, 0x2e, 0x0c, 0xe4, 0xb2, 0x03, 0xd4, 0xc0, 0x30, 0x3b, 0xec, 0x76, 0xf7, 0xf4,
|
||||
0x74, 0xdb, 0xee, 0xb6, 0x5d, 0xee, 0xe9, 0x9e, 0x7f, 0xec, 0x22, 0x41, 0xb5, 0xdd, 0xf6, 0x78,
|
||||
0xd7, 0xf6, 0x18, 0x57, 0xb9, 0x5b, 0x1a, 0x09, 0x89, 0x74, 0x66, 0xb8, 0x9c, 0x38, 0x2b, 0x23,
|
||||
0x37, 0x33, 0xaa, 0xdc, 0xb5, 0x08, 0x04, 0x02, 0x81, 0x40, 0x20, 0x56, 0xfc, 0x13, 0x9c, 0x90,
|
||||
0xf8, 0x04, 0x1c, 0xf8, 0x10, 0x1c, 0xf7, 0xc8, 0x11, 0xcd, 0x7c, 0x06, 0xee, 0x28, 0xe3, 0x7f,
|
||||
0xbc, 0x8c, 0x17, 0x99, 0x1e, 0x4e, 0xdd, 0xf2, 0xfb, 0xbd, 0xf7, 0x22, 0x32, 0x5e, 0x44, 0xbc,
|
||||
0x88, 0x8c, 0x8c, 0x8a, 0xee, 0x96, 0x17, 0x3b, 0x65, 0x45, 0x19, 0xad, 0x77, 0x6a, 0x52, 0x2d,
|
||||
0xb3, 0x84, 0xa8, 0x7f, 0x47, 0xfc, 0xcf, 0xc3, 0x37, 0xe3, 0x62, 0xc5, 0x56, 0x25, 0x79, 0xef,
|
||||
0x5d, 0x43, 0x26, 0x74, 0x3e, 0x8f, 0x8b, 0xb4, 0x16, 0xc8, 0x7b, 0xef, 0x18, 0x09, 0x59, 0x92,
|
||||
0x82, 0xc9, 0xbf, 0x3f, 0xfd, 0x8f, 0xff, 0x1d, 0x44, 0x6f, 0xed, 0xe6, 0x19, 0x29, 0xd8, 0xae,
|
||||
0x82, 0xc9, 0xbf, 0x3f, 0xfd, 0xcf, 0xff, 0x1d, 0x44, 0x6f, 0xed, 0xe6, 0x19, 0x29, 0xd8, 0xae,
|
||||
0xd4, 0x18, 0x7e, 0x19, 0x7d, 0x7b, 0x5c, 0x96, 0x07, 0x84, 0xbd, 0x24, 0x55, 0x9d, 0xd1, 0x62,
|
||||
0xf8, 0xc1, 0x48, 0x3a, 0x18, 0x9d, 0x95, 0xc9, 0x68, 0x5c, 0x96, 0x23, 0x23, 0x1c, 0x9d, 0x91,
|
||||
0x1f, 0x2f, 0x48, 0xcd, 0xde, 0x7b, 0x10, 0x86, 0xea, 0x92, 0x16, 0x35, 0x19, 0x5e, 0x46, 0xbf,
|
||||
|
@ -180,7 +180,7 @@ var fileDescriptor_93a29dc403579097 = []byte{
|
|||
0xb4, 0xf4, 0xfa, 0x47, 0xd1, 0xbb, 0x6d, 0xaf, 0x72, 0x22, 0xda, 0xe9, 0x34, 0x05, 0xe6, 0xa2,
|
||||
0x27, 0xfd, 0x15, 0xa4, 0xfb, 0x7f, 0xd1, 0xfb, 0xd2, 0xc2, 0x7f, 0x42, 0xe7, 0x73, 0x52, 0xa4,
|
||||
0x24, 0x55, 0x1a, 0x75, 0xb3, 0x7e, 0xfa, 0x0c, 0xb7, 0xab, 0x15, 0x46, 0xb6, 0x86, 0x2e, 0xd1,
|
||||
0x6f, 0x7e, 0x03, 0x4d, 0x59, 0xb4, 0xff, 0x1c, 0x44, 0x8f, 0xbc, 0x45, 0x53, 0x81, 0xeb, 0x14,
|
||||
0x6f, 0x7e, 0x03, 0x4d, 0x59, 0xb4, 0xff, 0x18, 0x44, 0x8f, 0xbc, 0x45, 0x53, 0x81, 0xeb, 0x14,
|
||||
0xf1, 0x77, 0xfa, 0x38, 0xf2, 0x69, 0xea, 0xa2, 0x8e, 0xff, 0x1f, 0x16, 0x64, 0x91, 0xff, 0x75,
|
||||
0x10, 0xdd, 0x37, 0x8a, 0x4d, 0x78, 0xef, 0xd2, 0xe2, 0x32, 0xcf, 0x12, 0xc6, 0xdf, 0xc8, 0x4a,
|
||||
0x15, 0xfc, 0x71, 0x62, 0x1a, 0xdd, 0x8f, 0x33, 0xa0, 0x69, 0x16, 0xaf, 0x9f, 0x67, 0x35, 0xa3,
|
||||
|
@ -366,12 +366,13 @@ var fileDescriptor_93a29dc403579097 = []byte{
|
|||
0xf5, 0x24, 0xe0, 0x65, 0x53, 0x5c, 0xd9, 0x12, 0x23, 0xdf, 0xbd, 0x79, 0x30, 0xb3, 0x4e, 0x00,
|
||||
0x1e, 0x9e, 0xaf, 0x0e, 0x53, 0xb8, 0x4e, 0x80, 0xfa, 0x9c, 0x41, 0xd6, 0x09, 0x18, 0xeb, 0x36,
|
||||
0x9d, 0xde, 0xf7, 0x3a, 0x8a, 0x6b, 0x53, 0x39, 0x4f, 0xd3, 0x79, 0xc1, 0x50, 0xd3, 0x61, 0x0a,
|
||||
0xee, 0x23, 0xb5, 0xb7, 0xd6, 0x3c, 0x8f, 0xd4, 0xb7, 0xaf, 0xb6, 0xd6, 0x85, 0x99, 0x71, 0x49,
|
||||
0xaf, 0x27, 0xf9, 0x91, 0x25, 0xff, 0x6f, 0x35, 0x08, 0x21, 0x32, 0x2e, 0xb5, 0x20, 0x61, 0xfb,
|
||||
0xf9, 0xfb, 0xff, 0xf5, 0xd5, 0x9d, 0xc1, 0xcf, 0xbe, 0xba, 0x33, 0xf8, 0x9f, 0xaf, 0xee, 0x0c,
|
||||
0x7e, 0xfa, 0xf5, 0x9d, 0x37, 0x7e, 0xf6, 0xf5, 0x9d, 0x37, 0xfe, 0xfb, 0xeb, 0x3b, 0x6f, 0x7c,
|
||||
0xf9, 0xa6, 0xfc, 0x2d, 0xea, 0x8b, 0x9f, 0xe3, 0xbf, 0x28, 0xfd, 0xec, 0xff, 0x02, 0x00, 0x00,
|
||||
0xff, 0xff, 0xc9, 0x60, 0xbd, 0x6d, 0xaf, 0x7a, 0x00, 0x00,
|
||||
0xee, 0x23, 0xb5, 0xb7, 0xd6, 0x3c, 0x8f, 0xd4, 0xb7, 0xaf, 0xb6, 0xd6, 0x85, 0x59, 0x89, 0x8f,
|
||||
0x53, 0xc5, 0x29, 0x95, 0xc5, 0x90, 0xdf, 0x35, 0xd6, 0x20, 0xf1, 0x71, 0x8b, 0xdd, 0xa2, 0x91,
|
||||
0xc4, 0xa7, 0x5b, 0xcb, 0x8c, 0x93, 0x7a, 0x7d, 0xcb, 0x8f, 0x50, 0xf9, 0x7f, 0x3b, 0x42, 0x08,
|
||||
0x91, 0x71, 0xb2, 0x05, 0x09, 0xdb, 0xcf, 0xdf, 0xff, 0xaf, 0xaf, 0xee, 0x0c, 0x7e, 0xf6, 0xd5,
|
||||
0x9d, 0xc1, 0xff, 0x7c, 0x75, 0x67, 0xf0, 0xd3, 0xaf, 0xef, 0xbc, 0xf1, 0xb3, 0xaf, 0xef, 0xbc,
|
||||
0xf1, 0xdf, 0x5f, 0xdf, 0x79, 0xe3, 0xcb, 0x37, 0xe5, 0x6f, 0x63, 0x5f, 0xfc, 0x1c, 0xff, 0x85,
|
||||
0xeb, 0x67, 0xff, 0x17, 0x00, 0x00, 0xff, 0xff, 0xfd, 0x94, 0x61, 0xee, 0x3f, 0x7b, 0x00, 0x00,
|
||||
}
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
|
@ -729,6 +730,7 @@ type ClientCommandsClient interface {
|
|||
ChatGetMessagesByIds(ctx context.Context, in *pb.RpcChatGetMessagesByIdsRequest, opts ...grpc.CallOption) (*pb.RpcChatGetMessagesByIdsResponse, error)
|
||||
ChatSubscribeLastMessages(ctx context.Context, in *pb.RpcChatSubscribeLastMessagesRequest, opts ...grpc.CallOption) (*pb.RpcChatSubscribeLastMessagesResponse, error)
|
||||
ChatUnsubscribe(ctx context.Context, in *pb.RpcChatUnsubscribeRequest, opts ...grpc.CallOption) (*pb.RpcChatUnsubscribeResponse, error)
|
||||
ChatSubscribeToMessagePreviews(ctx context.Context, in *pb.RpcChatSubscribeToMessagePreviewsRequest, opts ...grpc.CallOption) (*pb.RpcChatSubscribeToMessagePreviewsResponse, error)
|
||||
ObjectChatAdd(ctx context.Context, in *pb.RpcObjectChatAddRequest, opts ...grpc.CallOption) (*pb.RpcObjectChatAddResponse, error)
|
||||
}
|
||||
|
||||
|
@ -3283,6 +3285,15 @@ func (c *clientCommandsClient) ChatUnsubscribe(ctx context.Context, in *pb.RpcCh
|
|||
return out, nil
|
||||
}
|
||||
|
||||
func (c *clientCommandsClient) ChatSubscribeToMessagePreviews(ctx context.Context, in *pb.RpcChatSubscribeToMessagePreviewsRequest, opts ...grpc.CallOption) (*pb.RpcChatSubscribeToMessagePreviewsResponse, error) {
|
||||
out := new(pb.RpcChatSubscribeToMessagePreviewsResponse)
|
||||
err := c.cc.Invoke(ctx, "/anytype.ClientCommands/ChatSubscribeToMessagePreviews", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *clientCommandsClient) ObjectChatAdd(ctx context.Context, in *pb.RpcObjectChatAddRequest, opts ...grpc.CallOption) (*pb.RpcObjectChatAddResponse, error) {
|
||||
out := new(pb.RpcObjectChatAddResponse)
|
||||
err := c.cc.Invoke(ctx, "/anytype.ClientCommands/ObjectChatAdd", in, out, opts...)
|
||||
|
@ -3637,6 +3648,7 @@ type ClientCommandsServer interface {
|
|||
ChatGetMessagesByIds(context.Context, *pb.RpcChatGetMessagesByIdsRequest) *pb.RpcChatGetMessagesByIdsResponse
|
||||
ChatSubscribeLastMessages(context.Context, *pb.RpcChatSubscribeLastMessagesRequest) *pb.RpcChatSubscribeLastMessagesResponse
|
||||
ChatUnsubscribe(context.Context, *pb.RpcChatUnsubscribeRequest) *pb.RpcChatUnsubscribeResponse
|
||||
ChatSubscribeToMessagePreviews(context.Context, *pb.RpcChatSubscribeToMessagePreviewsRequest) *pb.RpcChatSubscribeToMessagePreviewsResponse
|
||||
ObjectChatAdd(context.Context, *pb.RpcObjectChatAddRequest) *pb.RpcObjectChatAddResponse
|
||||
}
|
||||
|
||||
|
@ -4484,6 +4496,9 @@ func (*UnimplementedClientCommandsServer) ChatSubscribeLastMessages(ctx context.
|
|||
func (*UnimplementedClientCommandsServer) ChatUnsubscribe(ctx context.Context, req *pb.RpcChatUnsubscribeRequest) *pb.RpcChatUnsubscribeResponse {
|
||||
return nil
|
||||
}
|
||||
func (*UnimplementedClientCommandsServer) ChatSubscribeToMessagePreviews(ctx context.Context, req *pb.RpcChatSubscribeToMessagePreviewsRequest) *pb.RpcChatSubscribeToMessagePreviewsResponse {
|
||||
return nil
|
||||
}
|
||||
func (*UnimplementedClientCommandsServer) ObjectChatAdd(ctx context.Context, req *pb.RpcObjectChatAddRequest) *pb.RpcObjectChatAddResponse {
|
||||
return nil
|
||||
}
|
||||
|
@ -9536,6 +9551,24 @@ func _ClientCommands_ChatUnsubscribe_Handler(srv interface{}, ctx context.Contex
|
|||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _ClientCommands_ChatSubscribeToMessagePreviews_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(pb.RpcChatSubscribeToMessagePreviewsRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(ClientCommandsServer).ChatSubscribeToMessagePreviews(ctx, in), nil
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/anytype.ClientCommands/ChatSubscribeToMessagePreviews",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(ClientCommandsServer).ChatSubscribeToMessagePreviews(ctx, req.(*pb.RpcChatSubscribeToMessagePreviewsRequest)), nil
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _ClientCommands_ObjectChatAdd_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(pb.RpcObjectChatAddRequest)
|
||||
if err := dec(in); err != nil {
|
||||
|
@ -10674,6 +10707,10 @@ var _ClientCommands_serviceDesc = grpc.ServiceDesc{
|
|||
MethodName: "ChatUnsubscribe",
|
||||
Handler: _ClientCommands_ChatUnsubscribe_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "ChatSubscribeToMessagePreviews",
|
||||
Handler: _ClientCommands_ChatSubscribeToMessagePreviews_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "ObjectChatAdd",
|
||||
Handler: _ClientCommands_ObjectChatAdd_Handler,
|
||||
|
|
|
@ -9,7 +9,7 @@ import (
|
|||
"github.com/anyproto/anytype-heart/pkg/lib/pb/model"
|
||||
)
|
||||
|
||||
const TypeChecksum = "c4f1cd92b533a4b5f533c01185049b8c7c170401c2f0bf09d6d888cad6a61669"
|
||||
const TypeChecksum = "0d2b4f839dd21d6e7abce40021cda9dbc2ed6caef0cff7bbff21c7c5b815b716"
|
||||
const (
|
||||
TypePrefix = "_ot"
|
||||
)
|
||||
|
@ -356,10 +356,10 @@ var (
|
|||
IconColor: 6,
|
||||
IconName: "search",
|
||||
Layout: model.ObjectType_set,
|
||||
Name: "Set",
|
||||
Name: "Query",
|
||||
Readonly: true,
|
||||
RelationLinks: []*model.RelationLink{MustGetRelationLink(RelationKeyTag), MustGetRelationLink(RelationKeySetOf)},
|
||||
Revision: 1,
|
||||
Revision: 2,
|
||||
Types: []model.SmartBlockType{model.SmartBlockType_Page},
|
||||
Url: TypePrefix + "set",
|
||||
},
|
||||
|
|
|
@ -304,7 +304,7 @@
|
|||
},
|
||||
{
|
||||
"id": "set",
|
||||
"name": "Set",
|
||||
"name": "Query",
|
||||
"types": [
|
||||
"Page"
|
||||
],
|
||||
|
@ -317,7 +317,7 @@
|
|||
"setOf"
|
||||
],
|
||||
"description": "Query all objects in your space based on types and relations",
|
||||
"revision": 1
|
||||
"revision": 2
|
||||
},
|
||||
{
|
||||
"id": "collection",
|
||||
|
|
|
@ -50,6 +50,10 @@ func OpenDatabaseWithLockCheck(ctx context.Context, path string, config *anystor
|
|||
return nil, lockCloseNoop, err
|
||||
}
|
||||
store, err = anystore.Open(ctx, path, config)
|
||||
if err != nil {
|
||||
l.Errorf("failed to open anystore again, %s", err)
|
||||
return nil, lockCloseNoop, err
|
||||
}
|
||||
} else {
|
||||
l.Errorf("failed to open anystore, non-recoverable error")
|
||||
// some other error
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -672,6 +672,7 @@ message Account {
|
|||
string timeZone = 104; // time zone from config
|
||||
string analyticsId = 105;
|
||||
string networkId = 106; // network id to which anytype is connected
|
||||
string ethereumAddress = 107; // we have Any PK AND Ethereum PK derived from one seed phrase
|
||||
}
|
||||
|
||||
message Auth {
|
||||
|
|
|
@ -98,7 +98,7 @@ func reviseObject(ctx context.Context, log logger.CtxLogger, space dependencies.
|
|||
details := buildDiffDetails(bundleObject, localObject, isSystem)
|
||||
|
||||
if isSystem {
|
||||
recRelsDetails, err := checkRecommendedRelations(ctx, space, bundleObject, localObject)
|
||||
recRelsDetails, err := checkRecommendedRelations(ctx, space, bundleObject, localObject, uk)
|
||||
if err != nil {
|
||||
log.Error("failed to check recommended relations", zap.Error(err))
|
||||
}
|
||||
|
@ -225,7 +225,7 @@ func checkRelationFormatObjectTypes(
|
|||
}
|
||||
|
||||
func checkRecommendedRelations(
|
||||
ctx context.Context, space dependencies.SpaceWithCtx, origin, current *domain.Details,
|
||||
ctx context.Context, space dependencies.SpaceWithCtx, origin, current *domain.Details, uk domain.UniqueKey,
|
||||
) (newValues []*domain.Detail, err error) {
|
||||
details := origin.CopyOnlyKeys(
|
||||
bundle.RelationKeyRecommendedRelations,
|
||||
|
@ -233,7 +233,7 @@ func checkRecommendedRelations(
|
|||
bundle.RelationKeyUniqueKey,
|
||||
)
|
||||
|
||||
_, filled, err := relationutils.FillRecommendedRelations(ctx, space, details)
|
||||
_, filled, err := relationutils.FillRecommendedRelations(ctx, space, details, domain.TypeKey(uk.InternalKey()))
|
||||
if filled {
|
||||
return nil, nil
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ import (
|
|||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"slices"
|
||||
"strconv"
|
||||
"sync"
|
||||
"time"
|
||||
|
@ -32,6 +33,7 @@ import (
|
|||
"github.com/anyproto/anytype-heart/pb"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/bundle"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/core"
|
||||
coresb "github.com/anyproto/anytype-heart/pkg/lib/core/smartblock"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/database"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/logging"
|
||||
|
@ -77,19 +79,6 @@ var (
|
|||
pb.RpcObjectImportUseCaseRequest_GET_STARTED: getStartedZip,
|
||||
pb.RpcObjectImportUseCaseRequest_EMPTY: emptyZip,
|
||||
}
|
||||
|
||||
// TODO: GO-2009 Now we need to create widgets by hands, widget import is not implemented yet
|
||||
widgetParams = map[pb.RpcObjectImportUseCaseRequestUseCase][]widgetParameters{
|
||||
pb.RpcObjectImportUseCaseRequest_EMPTY: {
|
||||
{model.BlockContentWidget_Link, "bafyreic75ulgm2yz426hjwdjkzqw3kafniknki7qkhufqgrspmxzdppixa", "", true},
|
||||
},
|
||||
pb.RpcObjectImportUseCaseRequest_GET_STARTED: {
|
||||
{model.BlockContentWidget_Link, "bafyreiccjf5vbijsmr55ypsnnzltmcvl4n63g73twwxqnfkn5usoq2iqyi", "", true},
|
||||
{model.BlockContentWidget_View, "bafyreigigitlypzxjf2trrguj7ict7y6xu2r3qi6hc5eycp47pz66ghlpy", "all", true},
|
||||
{model.BlockContentWidget_View, "bafyreihruv47l2cm3fh5rl7gou2s3re2dtd6iofjahogp7nockgsaomg5m", "all", true},
|
||||
{model.BlockContentWidget_CompactList, widget.DefaultWidgetRecentOpen, "", false},
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
type BuiltinObjects interface {
|
||||
|
@ -374,39 +363,43 @@ func (b *builtinObjects) createWidgets(ctx session.Context, spaceId string, useC
|
|||
}
|
||||
|
||||
widgetObjectID := spc.DerivedIDs().Widgets
|
||||
typeId, err := spc.GetTypeIdByKey(context.Background(), bundle.TypeKeyPage)
|
||||
if err != nil {
|
||||
log.Errorf("failed to get type id: %w", err)
|
||||
return
|
||||
}
|
||||
|
||||
// todo: rewrite to use CreateTypeWidgetIfMissing in block.Service
|
||||
if err = cache.DoStateCtx(b.objectGetter, ctx, widgetObjectID, func(s *state.State, w widget.Widget) error {
|
||||
for _, param := range widgetParams[useCase] {
|
||||
objectID := param.objectID
|
||||
if param.isObjectIDChanged {
|
||||
objectID, err = b.getNewObjectID(spc.Id(), objectID)
|
||||
if err != nil {
|
||||
log.Errorf("Skipping creation of widget block as failed to get new object id using old one '%s': %v", objectID, err)
|
||||
continue
|
||||
}
|
||||
}
|
||||
request := &pb.RpcBlockCreateWidgetRequest{
|
||||
ContextId: widgetObjectID,
|
||||
Position: model.Block_Bottom,
|
||||
WidgetLayout: param.layout,
|
||||
Block: &model.Block{
|
||||
Content: &model.BlockContentOfLink{
|
||||
Link: &model.BlockContentLink{
|
||||
TargetBlockId: objectID,
|
||||
Style: model.BlockContentLink_Page,
|
||||
IconSize: model.BlockContentLink_SizeNone,
|
||||
CardStyle: model.BlockContentLink_Inline,
|
||||
Description: model.BlockContentLink_None,
|
||||
},
|
||||
targets := s.Details().Get(bundle.RelationKeyAutoWidgetTargets).StringList()
|
||||
if slices.Contains(targets, typeId) {
|
||||
return nil
|
||||
}
|
||||
targets = append(targets, typeId)
|
||||
s.Details().Set(bundle.RelationKeyAutoWidgetTargets, domain.StringList(targets))
|
||||
|
||||
objectID, e := spc.DeriveObjectID(nil, domain.MustUniqueKey(coresb.SmartBlockTypeObjectType, bundle.TypeKeyPage.String()))
|
||||
if e != nil {
|
||||
return fmt.Errorf("failed to derive page type object id: %w", err)
|
||||
}
|
||||
request := &pb.RpcBlockCreateWidgetRequest{
|
||||
ContextId: widgetObjectID,
|
||||
Position: model.Block_Bottom,
|
||||
WidgetLayout: model.BlockContentWidget_View,
|
||||
Block: &model.Block{
|
||||
Content: &model.BlockContentOfLink{
|
||||
Link: &model.BlockContentLink{
|
||||
TargetBlockId: objectID,
|
||||
Style: model.BlockContentLink_Page,
|
||||
IconSize: model.BlockContentLink_SizeNone,
|
||||
CardStyle: model.BlockContentLink_Inline,
|
||||
Description: model.BlockContentLink_None,
|
||||
},
|
||||
},
|
||||
}
|
||||
if param.viewID != "" {
|
||||
request.ViewId = param.viewID
|
||||
}
|
||||
if _, err = w.CreateBlock(s, request); err != nil {
|
||||
log.Errorf("Failed to make Widget blocks: %v", err)
|
||||
}
|
||||
},
|
||||
}
|
||||
if _, e = w.CreateBlock(s, request); err != nil {
|
||||
return fmt.Errorf("failed to make Widget block: %v", e)
|
||||
}
|
||||
return nil
|
||||
}); err != nil {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue