mirror of
https://github.com/Dvorinka/excalidraw-full.git
synced 2026-06-03 22:02:57 +00:00
Initial prototype
This commit is contained in:
@@ -0,0 +1,2 @@
|
|||||||
|
dist/
|
||||||
|
excalidraw-backend
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
# This is an example .goreleaser.yml file with some sensible defaults.
|
||||||
|
# Make sure to check the documentation at https://goreleaser.com
|
||||||
|
|
||||||
|
# The lines below are called `modelines`. See `:help modeline`
|
||||||
|
# Feel free to remove those if you don't want/need to use them.
|
||||||
|
# yaml-language-server: $schema=https://goreleaser.com/static/schema.json
|
||||||
|
# vim: set ts=2 sw=2 tw=0 fo=cnqoj
|
||||||
|
|
||||||
|
version: 1
|
||||||
|
|
||||||
|
# before:
|
||||||
|
# hooks:
|
||||||
|
# # You may remove this if you don't use go modules.
|
||||||
|
# - go mod tidy
|
||||||
|
# # you may remove this if you don't need go generate
|
||||||
|
# - go generate ./...
|
||||||
|
|
||||||
|
builds:
|
||||||
|
- env:
|
||||||
|
- CGO_ENABLED=0
|
||||||
|
goos:
|
||||||
|
- linux
|
||||||
|
- windows
|
||||||
|
- darwin
|
||||||
|
|
||||||
|
archives:
|
||||||
|
- format: tar.gz
|
||||||
|
files: []
|
||||||
|
# this name template makes the OS and Arch compatible with the results of `uname`.
|
||||||
|
name_template: >-
|
||||||
|
{{ .ProjectName }}_
|
||||||
|
{{- title .Os }}_
|
||||||
|
{{- if eq .Arch "amd64" }}x86_64
|
||||||
|
{{- else if eq .Arch "386" }}i386
|
||||||
|
{{- else }}{{ .Arch }}{{ end }}
|
||||||
|
{{- if .Arm }}v{{ .Arm }}{{ end }}
|
||||||
|
# use zip for windows archives
|
||||||
|
format_overrides:
|
||||||
|
- goos: windows
|
||||||
|
format: zip
|
||||||
|
|
||||||
|
changelog:
|
||||||
|
sort: asc
|
||||||
|
filters:
|
||||||
|
exclude:
|
||||||
|
- "^docs:"
|
||||||
|
- "^test:"
|
||||||
|
|
||||||
|
release:
|
||||||
|
disable: true
|
||||||
|
skip_upload: true
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
# Exalidraw Backend
|
||||||
|
|
||||||
|
Frustrated on how difficult it is to setup excalidraw self-hosted but with data
|
||||||
|
storage and collaboration function this represents and attempt to run the
|
||||||
|
necessary function with a single binary implemented in go.
|
||||||
|
|
||||||
|
Apply the patch to the frontend and build excalidraw. Run Excalidraw frontend and
|
||||||
|
on the same host run
|
||||||
|
```bash
|
||||||
|
go run main.go
|
||||||
|
```
|
||||||
|
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
package core
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"context"
|
||||||
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
Document struct {
|
||||||
|
Data bytes.Buffer
|
||||||
|
}
|
||||||
|
|
||||||
|
DocumentStore interface {
|
||||||
|
FindID(ctx context.Context, id string) (*Document, error)
|
||||||
|
Create(ctx context.Context, document *Document) (string, error)
|
||||||
|
}
|
||||||
|
)
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
package memory
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"excalidraw-backend/core"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/oklog/ulid/v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
var savedDocuments = make(map[string]core.Document)
|
||||||
|
|
||||||
|
type documentStore struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewDocumentStore() core.DocumentStore {
|
||||||
|
return &documentStore{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *documentStore) FindID(ctx context.Context, id string) (*core.Document, error) {
|
||||||
|
if val, ok := savedDocuments[id]; ok {
|
||||||
|
return &val, nil
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("document with id %s not found", id)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *documentStore) Create(ctx context.Context, document *core.Document) (string, error) {
|
||||||
|
id := ulid.Make().String()
|
||||||
|
savedDocuments[id] = *document
|
||||||
|
return id, nil
|
||||||
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
diff --git a/.env.production b/.env.production
|
||||||
|
index 0c715854..422add5c 100644
|
||||||
|
--- a/.env.production
|
||||||
|
+++ b/.env.production
|
||||||
|
@@ -1,17 +1,25 @@
|
||||||
|
-VITE_APP_BACKEND_V2_GET_URL=https://json.excalidraw.com/api/v2/
|
||||||
|
-VITE_APP_BACKEND_V2_POST_URL=https://json.excalidraw.com/api/v2/post/
|
||||||
|
+# VITE_APP_BACKEND_V2_GET_URL=https://json.excalidraw.com/api/v2/
|
||||||
|
+# VITE_APP_BACKEND_V2_POST_URL=https://json.excalidraw.com/api/v2/post/
|
||||||
|
+VITE_APP_BACKEND_V2_GET_URL=http://localhost:3002/api/v2/
|
||||||
|
+VITE_APP_BACKEND_V2_POST_URL=http://localhost:3002/api/v2/post/
|
||||||
|
|
||||||
|
VITE_APP_LIBRARY_URL=https://libraries.excalidraw.com
|
||||||
|
-VITE_APP_LIBRARY_BACKEND=https://us-central1-excalidraw-room-persistence.cloudfunctions.net/libraries
|
||||||
|
+# VITE_APP_LIBRARY_BACKEND=https://us-central1-excalidraw-room-persistence.cloudfunctions.net/libraries
|
||||||
|
+VITE_APP_LIBRARY_BACKEND=http://localhost:3002/libraries
|
||||||
|
+# VITE_APP_PLUS_LP=https://plus.excalidraw.com
|
||||||
|
+VITE_APP_PLUS_LP=http://localhost:3002/plus/
|
||||||
|
+# VITE_APP_PLUS_APP=https://app.excalidraw.com
|
||||||
|
+VITE_APP_PLUS_APP=http://localhost:3002/app/
|
||||||
|
|
||||||
|
-VITE_APP_PLUS_LP=https://plus.excalidraw.com
|
||||||
|
-VITE_APP_PLUS_APP=https://app.excalidraw.com
|
||||||
|
-
|
||||||
|
-VITE_APP_AI_BACKEND=https://oss-ai.excalidraw.com
|
||||||
|
+# VITE_APP_AI_BACKEND=https://oss-ai.excalidraw.com
|
||||||
|
+VITE_APP_AI_BACKEND=http://localhost:3002/ai/
|
||||||
|
|
||||||
|
# socket server URL used for collaboration
|
||||||
|
-VITE_APP_WS_SERVER_URL=https://oss-collab.excalidraw.com
|
||||||
|
+VITE_APP_WS_SERVER_URL=http://localhost:3002
|
||||||
|
+# VITE_APP_WS_SERVER_URL=https://oss-collab.excalidraw.com
|
||||||
|
|
||||||
|
-VITE_APP_FIREBASE_CONFIG='{"apiKey":"AIzaSyAd15pYlMci_xIp9ko6wkEsDzAAA0Dn0RU","authDomain":"excalidraw-room-persistence.firebaseapp.com","databaseURL":"https://excalidraw-room-persistence.firebaseio.com","projectId":"excalidraw-room-persistence","storageBucket":"excalidraw-room-persistence.appspot.com","messagingSenderId":"654800341332","appId":"1:654800341332:web:4a692de832b55bd57ce0c1"}'
|
||||||
|
+# VITE_APP_FIREBASE_CONFIG='{"apiKey":"AIzaSyAd15pYlMci_xIp9ko6wkEsDzAAA0Dn0RU","authDomain":"excalidraw-room-persistence.firebaseapp.com","databaseURL":"https://excalidraw-room-persistence.firebaseio.com","projectId":"excalidraw-room-persistence","storageBucket":"excalidraw-room-persistence.appspot.com","messagingSenderId":"654800341332","appId":"1:654800341332:web:4a692de832b55bd57ce0c1"}'
|
||||||
|
+VITE_APP_FIREBASE_CONFIG='{"apiKey":"AIzaSyAd15pYlMci_xIp9ko6wkEsDzAAA0Dn0RU","authDomain":"","databaseURL":"","projectId":"excalidraw-room-persistence","storageBucket":"","messagingSenderId":"654800341332","appId":"1:654800341332:web:4a692de832b55bd57ce0c1"}'
|
||||||
|
|
||||||
|
-VITE_APP_DISABLE_TRACKING=
|
||||||
|
+# VITE_APP_DISABLE_TRACKING=
|
||||||
|
+VITE_APP_DISABLE_TRACKING=yes
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
module excalidraw-backend
|
||||||
|
|
||||||
|
go 1.21
|
||||||
|
|
||||||
|
toolchain go1.22.1
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/go-chi/chi/v5 v5.0.12
|
||||||
|
github.com/go-chi/cors v1.2.1
|
||||||
|
github.com/go-chi/render v1.0.3
|
||||||
|
github.com/oklog/ulid/v2 v2.1.0
|
||||||
|
github.com/zishang520/engine.io/v2 v2.0.6
|
||||||
|
github.com/zishang520/socket.io/v2 v2.0.5
|
||||||
|
)
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/ajg/form v1.5.1 // indirect
|
||||||
|
github.com/andybalholm/brotli v1.0.6 // indirect
|
||||||
|
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect
|
||||||
|
github.com/google/pprof v0.0.0-20230821062121-407c9e7a662f // indirect
|
||||||
|
github.com/gookit/color v1.5.4 // indirect
|
||||||
|
github.com/gorilla/websocket v1.5.0 // indirect
|
||||||
|
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
||||||
|
github.com/onsi/ginkgo/v2 v2.12.0 // indirect
|
||||||
|
github.com/quic-go/qpack v0.4.0 // indirect
|
||||||
|
github.com/quic-go/qtls-go1-20 v0.4.1 // indirect
|
||||||
|
github.com/quic-go/quic-go v0.40.1 // indirect
|
||||||
|
github.com/quic-go/webtransport-go v0.6.0 // indirect
|
||||||
|
github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect
|
||||||
|
github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
|
||||||
|
github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778 // indirect
|
||||||
|
github.com/zishang520/engine.io-go-parser v1.2.3 // indirect
|
||||||
|
github.com/zishang520/socket.io-go-parser/v2 v2.0.4 // indirect
|
||||||
|
go.uber.org/mock v0.3.0 // indirect
|
||||||
|
golang.org/x/crypto v0.17.0 // indirect
|
||||||
|
golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 // indirect
|
||||||
|
golang.org/x/mod v0.12.0 // indirect
|
||||||
|
golang.org/x/net v0.17.0 // indirect
|
||||||
|
golang.org/x/sys v0.15.0 // indirect
|
||||||
|
golang.org/x/text v0.14.0 // indirect
|
||||||
|
golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846 // indirect
|
||||||
|
)
|
||||||
@@ -0,0 +1,88 @@
|
|||||||
|
github.com/ajg/form v1.5.1 h1:t9c7v8JUKu/XxOGBU0yjNpaMloxGEJhUkqFRq0ibGeU=
|
||||||
|
github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY=
|
||||||
|
github.com/andybalholm/brotli v1.0.6 h1:Yf9fFpf49Zrxb9NlQaluyE92/+X7UVHlhMNJN2sxfOI=
|
||||||
|
github.com/andybalholm/brotli v1.0.6/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
|
||||||
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/francoispqt/gojay v1.2.13 h1:d2m3sFjloqoIUQU3TsHBgj6qg/BVGlTBeHDUmyJnXKk=
|
||||||
|
github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY=
|
||||||
|
github.com/go-chi/chi/v5 v5.0.12 h1:9euLV5sTrTNTRUU9POmDUvfxyj6LAABLUcEWO+JJb4s=
|
||||||
|
github.com/go-chi/chi/v5 v5.0.12/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
|
||||||
|
github.com/go-chi/cors v1.2.1 h1:xEC8UT3Rlp2QuWNEr4Fs/c2EAGVKBwy/1vHx3bppil4=
|
||||||
|
github.com/go-chi/cors v1.2.1/go.mod h1:sSbTewc+6wYHBBCW7ytsFSn836hqM7JxpglAy2Vzc58=
|
||||||
|
github.com/go-chi/render v1.0.3 h1:AsXqd2a1/INaIfUSKq3G5uA8weYx20FOsM7uSoCyyt4=
|
||||||
|
github.com/go-chi/render v1.0.3/go.mod h1:/gr3hVkmYR0YlEy3LxCuVRFzEu9Ruok+gFqbIofjao0=
|
||||||
|
github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ=
|
||||||
|
github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||||
|
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
|
||||||
|
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls=
|
||||||
|
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
|
||||||
|
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||||
|
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
||||||
|
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||||
|
github.com/google/pprof v0.0.0-20230821062121-407c9e7a662f h1:pDhu5sgp8yJlEF/g6osliIIpF9K4F5jvkULXa4daRDQ=
|
||||||
|
github.com/google/pprof v0.0.0-20230821062121-407c9e7a662f/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik=
|
||||||
|
github.com/gookit/color v1.5.4 h1:FZmqs7XOyGgCAxmWyPslpiok1k05wmY3SJTytgvYFs0=
|
||||||
|
github.com/gookit/color v1.5.4/go.mod h1:pZJOeOS8DM43rXbp4AZo1n9zCU2qjpcRko0b6/QJi9w=
|
||||||
|
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
|
||||||
|
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||||
|
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
|
||||||
|
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||||
|
github.com/oklog/ulid/v2 v2.1.0 h1:+9lhoxAP56we25tyYETBBY1YLA2SaoLvUFgrP2miPJU=
|
||||||
|
github.com/oklog/ulid/v2 v2.1.0/go.mod h1:rcEKHmBBKfef9DhnvX7y1HZBYxjXb0cP5ExxNsTT1QQ=
|
||||||
|
github.com/onsi/ginkgo/v2 v2.12.0 h1:UIVDowFPwpg6yMUpPjGkYvf06K3RAiJXUhCxEwQVHRI=
|
||||||
|
github.com/onsi/ginkgo/v2 v2.12.0/go.mod h1:ZNEzXISYlqpb8S36iN71ifqLi3vVD1rVJGvWRCJOUpQ=
|
||||||
|
github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI=
|
||||||
|
github.com/onsi/gomega v1.27.10/go.mod h1:RsS8tutOdbdgzbPtzzATp12yT7kM5I5aElG3evPbQ0M=
|
||||||
|
github.com/pborman/getopt v0.0.0-20170112200414-7148bc3a4c30/go.mod h1:85jBQOZwpVEaDAr341tbn15RS4fCAsIst0qp7i8ex1o=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
|
github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo=
|
||||||
|
github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A=
|
||||||
|
github.com/quic-go/qtls-go1-20 v0.4.1 h1:D33340mCNDAIKBqXuAvexTNMUByrYmFYVfKfDN5nfFs=
|
||||||
|
github.com/quic-go/qtls-go1-20 v0.4.1/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k=
|
||||||
|
github.com/quic-go/quic-go v0.40.1 h1:X3AGzUNFs0jVuO3esAGnTfvdgvL4fq655WaOi1snv1Q=
|
||||||
|
github.com/quic-go/quic-go v0.40.1/go.mod h1:PeN7kuVJ4xZbxSv/4OX6S1USOX8MJvydwpTx31vx60c=
|
||||||
|
github.com/quic-go/webtransport-go v0.6.0 h1:CvNsKqc4W2HljHJnoT+rMmbRJybShZ0YPFDD3NxaZLY=
|
||||||
|
github.com/quic-go/webtransport-go v0.6.0/go.mod h1:9KjU4AEBqEQidGHNDkZrb8CAa1abRaosM2yGOyiikEc=
|
||||||
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
|
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
|
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||||
|
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||||
|
github.com/vmihailenco/msgpack/v5 v5.4.1 h1:cQriyiUvjTwOHg8QZaPihLWeRAAVoCpE00IUPn0Bjt8=
|
||||||
|
github.com/vmihailenco/msgpack/v5 v5.4.1/go.mod h1:GaZTsDaehaPpQVyxrf5mtQlH+pc21PIudVV/E3rRQok=
|
||||||
|
github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g=
|
||||||
|
github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds=
|
||||||
|
github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778 h1:QldyIu/L63oPpyvQmHgvgickp1Yw510KJOqX7H24mg8=
|
||||||
|
github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778/go.mod h1:2MuV+tbUrU1zIOPMxZ5EncGwgmMJsa+9ucAQZXxsObs=
|
||||||
|
github.com/zishang520/engine.io-go-parser v1.2.3 h1:y++zdMKIFgyVvH60TEEHw8gdJkS/qy22wesdALoh+HA=
|
||||||
|
github.com/zishang520/engine.io-go-parser v1.2.3/go.mod h1:UrXBVZWQgyHDITYmhnxi2d+NpEWBN8dACboD4dXcx38=
|
||||||
|
github.com/zishang520/engine.io/v2 v2.0.6 h1:hXZRwSoZql7xgxbW4xupRjDDLUXcwo/pYSlWc6dNCAk=
|
||||||
|
github.com/zishang520/engine.io/v2 v2.0.6/go.mod h1:M908EfW1x3hf+GIONy5x9ZOeeYsPOwUImxyuTabtsYA=
|
||||||
|
github.com/zishang520/socket.io-go-parser/v2 v2.0.4 h1:PxzWPrTxueiKXFZJQduJ9sIIzsBbHMi9XO5nTLbIjS4=
|
||||||
|
github.com/zishang520/socket.io-go-parser/v2 v2.0.4/go.mod h1:fei4NeEGrSJK+uQPnuI4WVm8h+WLF/kVpDHVjeI+0bA=
|
||||||
|
github.com/zishang520/socket.io/v2 v2.0.5 h1:CImu9z6YKFif2mMX2b3y2OUhxxH8nz01PqP6+W6dXy4=
|
||||||
|
github.com/zishang520/socket.io/v2 v2.0.5/go.mod h1:r+spG2g+Q0lxhgTHevGl7/h4DzkKrO00i8AEF9vj2PQ=
|
||||||
|
go.uber.org/mock v0.3.0 h1:3mUxI1No2/60yUYax92Pt8eNOEecx2D3lcXZh2NEZJo=
|
||||||
|
go.uber.org/mock v0.3.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc=
|
||||||
|
golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k=
|
||||||
|
golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
|
||||||
|
golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 h1:m64FZMko/V45gv0bNmrNYoDEq8U5YUhetc9cBWKS1TQ=
|
||||||
|
golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63/go.mod h1:0v4NqG35kSWCMzLaMeX+IQrlSnVE/bqGSyC2cz/9Le8=
|
||||||
|
golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc=
|
||||||
|
golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||||
|
golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
|
||||||
|
golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
|
||||||
|
golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc=
|
||||||
|
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
|
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
|
||||||
|
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||||
|
golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846 h1:Vve/L0v7CXXuxUmaMGIEK/dEeq7uiqb5qBgQrZzIE7E=
|
||||||
|
golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846/go.mod h1:Sc0INKfu04TlqNoRA1hgpFZbhYXHPr4V5DzpSBTPqQM=
|
||||||
|
google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw=
|
||||||
|
google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||||
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
@@ -0,0 +1,192 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"excalidraw-backend/core"
|
||||||
|
"excalidraw-backend/documents/memory"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"os/signal"
|
||||||
|
"syscall"
|
||||||
|
|
||||||
|
"github.com/go-chi/chi/v5"
|
||||||
|
"github.com/go-chi/chi/v5/middleware"
|
||||||
|
"github.com/go-chi/cors"
|
||||||
|
"github.com/go-chi/render"
|
||||||
|
"github.com/oklog/ulid/v2"
|
||||||
|
"github.com/zishang520/engine.io/v2/types"
|
||||||
|
socketio "github.com/zishang520/socket.io/v2/socket"
|
||||||
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
DocumentCreateResponse struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
UserToFollow struct {
|
||||||
|
SocketId string
|
||||||
|
Username string
|
||||||
|
}
|
||||||
|
OnUserFollowedPayload struct {
|
||||||
|
UserToFollow UserToFollow
|
||||||
|
action string
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
opts := socketio.DefaultServerOptions()
|
||||||
|
opts.SetMaxHttpBufferSize(5000000)
|
||||||
|
opts.SetPath("/socket.io")
|
||||||
|
opts.SetAllowEIO3(true)
|
||||||
|
opts.SetCors(&types.Cors{
|
||||||
|
Origin: "*",
|
||||||
|
Credentials: true,
|
||||||
|
})
|
||||||
|
ioo := socketio.NewServer(nil, opts)
|
||||||
|
ioo.On("connection", func(clients ...any) {
|
||||||
|
socket := clients[0].(*socketio.Socket)
|
||||||
|
ioo.To(socketio.Room(socket.Id())).Emit("init-room")
|
||||||
|
me := socket.Id()
|
||||||
|
socket.On("join-room", func(datas ...any) {
|
||||||
|
room := socketio.Room(datas[0].(string))
|
||||||
|
fmt.Printf("Socket %v has joined %v\n", me, room)
|
||||||
|
socket.Join(room)
|
||||||
|
ioo.In(room).FetchSockets()(func(sockets []*socketio.RemoteSocket, _ error) {
|
||||||
|
|
||||||
|
if len(sockets) <= 1 {
|
||||||
|
ioo.To(socketio.Room(socket.Id())).Emit("first-in-room")
|
||||||
|
} else {
|
||||||
|
fmt.Printf("emit new user %v in room %v\n", me, room)
|
||||||
|
socket.Broadcast().To(room).Emit("new-user", me)
|
||||||
|
}
|
||||||
|
|
||||||
|
data := []socketio.SocketId{}
|
||||||
|
for _, osocket := range sockets {
|
||||||
|
data = append(data, osocket.Id())
|
||||||
|
}
|
||||||
|
fmt.Printf(" room %v has users %v\n", room, data)
|
||||||
|
|
||||||
|
ioo.In(room).Emit(
|
||||||
|
"room-user-change",
|
||||||
|
data,
|
||||||
|
)
|
||||||
|
|
||||||
|
})
|
||||||
|
})
|
||||||
|
socket.On("server-broadcast", func(datas ...any) {
|
||||||
|
roomID := datas[0].(string)
|
||||||
|
fmt.Printf(" user %v sends update to room %v\n", me, roomID)
|
||||||
|
socket.Broadcast().To(socketio.Room(roomID)).Emit("client-broadcast", datas[1], datas[2])
|
||||||
|
})
|
||||||
|
socket.On("server-volatile-broadcast", func(datas ...any) {
|
||||||
|
roomID := datas[0].(string)
|
||||||
|
fmt.Printf(" user %v sends volatile update to room %v\n", me, roomID)
|
||||||
|
socket.Volatile().Broadcast().To(socketio.Room(roomID)).Emit("client-broadcast", datas[1], datas[2])
|
||||||
|
})
|
||||||
|
|
||||||
|
socket.On("user-follow", func(datas ...any) {
|
||||||
|
// TODO()
|
||||||
|
|
||||||
|
})
|
||||||
|
socket.On("disconnecting", func(datas ...any) {
|
||||||
|
for _, oroom := range socket.Rooms().Keys() {
|
||||||
|
ioo.In(oroom).FetchSockets()(func(sockets []*socketio.RemoteSocket, _ error) {
|
||||||
|
otherClients := []socketio.SocketId{}
|
||||||
|
fmt.Printf("disconnecting %v from room %v", me, oroom)
|
||||||
|
for _, osocket := range sockets {
|
||||||
|
if osocket.Id() != me {
|
||||||
|
otherClients = append(otherClients, osocket.Id())
|
||||||
|
fmt.Println("other", osocket.Id())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(otherClients) > 0 {
|
||||||
|
ioo.In(oroom).Emit(
|
||||||
|
"room-user-change",
|
||||||
|
otherClients,
|
||||||
|
)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
socket.On("disconnect", func(datas ...any) {
|
||||||
|
socket.RemoveAllListeners("")
|
||||||
|
socket.Disconnect(true)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
r := chi.NewRouter()
|
||||||
|
r.Use(middleware.Logger)
|
||||||
|
|
||||||
|
r.Use(cors.Handler(cors.Options{
|
||||||
|
AllowedOrigins: []string{"https://*", "http://*"},
|
||||||
|
AllowedMethods: []string{"GET", "POST", "PUT", "DELETE", "OPTIONS"},
|
||||||
|
AllowedHeaders: []string{"Accept", "Authorization", "Content-Type", "Content-Length", "X-CSRF-Token", "Token", "session", "Origin", "Host", "Connection", "Accept-Encoding", "Accept-Language", "X-Requested-With"},
|
||||||
|
AllowCredentials: true,
|
||||||
|
MaxAge: 300, // Maximum value not ignored by any of major browsers
|
||||||
|
}))
|
||||||
|
|
||||||
|
documentStore := memory.NewDocumentStore()
|
||||||
|
|
||||||
|
r.Get("/", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
w.Write([]byte("you are all set"))
|
||||||
|
fmt.Println(ulid.Make())
|
||||||
|
render.Status(r, http.StatusOK)
|
||||||
|
})
|
||||||
|
|
||||||
|
r.Route("/api/v2", func(r chi.Router) {
|
||||||
|
r.Post("/post/", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
data := new(bytes.Buffer)
|
||||||
|
_, err := io.Copy(data, r.Body)
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, "Failed to copy", http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
id, err := documentStore.Create(r.Context(), &core.Document{Data: *data})
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, "Failed to save", http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
render.JSON(w, r, DocumentCreateResponse{ID: id})
|
||||||
|
render.Status(r, http.StatusOK)
|
||||||
|
})
|
||||||
|
r.Route("/{id}", func(r chi.Router) {
|
||||||
|
r.Get("/", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
id := chi.URLParam(r, "id")
|
||||||
|
document, err := documentStore.FindID(r.Context(), id)
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, "not found", http.StatusNotFound)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
w.Write(document.Data.Bytes())
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
r.Handle("/socket.io/", ioo.ServeHandler(nil))
|
||||||
|
go http.ListenAndServe(":3002", r)
|
||||||
|
|
||||||
|
exit := make(chan struct{})
|
||||||
|
SignalC := make(chan os.Signal)
|
||||||
|
|
||||||
|
signal.Notify(SignalC, os.Interrupt, syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT)
|
||||||
|
go func() {
|
||||||
|
for s := range SignalC {
|
||||||
|
switch s {
|
||||||
|
case os.Interrupt, syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT:
|
||||||
|
close(exit)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
<-exit
|
||||||
|
ioo.Close(nil)
|
||||||
|
os.Exit(0)
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user