mirror of
https://github.com/penpot/penpot.git
synced 2025-02-08 08:09:14 -05:00
Merge remote-tracking branch 'origin/staging' into develop
This commit is contained in:
commit
8b45ed9c0c
26 changed files with 312 additions and 195 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -15,6 +15,7 @@ node_modules
|
||||||
/backend/target/
|
/backend/target/
|
||||||
/backend/resources/public/media
|
/backend/resources/public/media
|
||||||
/backend/resources/public/assets
|
/backend/resources/public/assets
|
||||||
|
/backend/assets/
|
||||||
/backend/dist/
|
/backend/dist/
|
||||||
/backend/logs/
|
/backend/logs/
|
||||||
/backend/-
|
/backend/-
|
||||||
|
|
81
backend/scripts/build
Executable file
81
backend/scripts/build
Executable file
|
@ -0,0 +1,81 @@
|
||||||
|
#!/usr/bin/env bb
|
||||||
|
|
||||||
|
;; This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
;; License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
;;
|
||||||
|
;; This Source Code Form is "Incompatible With Secondary Licenses", as
|
||||||
|
;; defined by the Mozilla Public License, v. 2.0.
|
||||||
|
;;
|
||||||
|
;; Copyright (c) UXBOX Labs SL
|
||||||
|
|
||||||
|
(ns build
|
||||||
|
(:require
|
||||||
|
[clojure.string :as str]
|
||||||
|
[clojure.java.io :as io]
|
||||||
|
[clojure.pprint :refer [pprint]]
|
||||||
|
[babashka.fs :as fs]
|
||||||
|
[babashka.process :refer [$ check]]))
|
||||||
|
|
||||||
|
(defn split-cp
|
||||||
|
[data]
|
||||||
|
(str/split data #":"))
|
||||||
|
|
||||||
|
(def classpath
|
||||||
|
(->> ($ clojure -Spath)
|
||||||
|
(check)
|
||||||
|
(:out)
|
||||||
|
(slurp)
|
||||||
|
(split-cp)
|
||||||
|
(map str/trim)))
|
||||||
|
|
||||||
|
(def classpath-jars
|
||||||
|
(let [xfm (filter #(str/ends-with? % ".jar"))]
|
||||||
|
(into #{} xfm classpath)))
|
||||||
|
|
||||||
|
(def classpath-paths
|
||||||
|
(let [xfm (comp (remove #(str/ends-with? % ".jar"))
|
||||||
|
(filter #(.isDirectory (io/file %))))]
|
||||||
|
(into #{} xfm classpath)))
|
||||||
|
|
||||||
|
(def version
|
||||||
|
(or (first *command-line-args*) "%version%"))
|
||||||
|
|
||||||
|
;; Clean previous dist
|
||||||
|
(-> ($ rm -rf "./target/dist") check)
|
||||||
|
|
||||||
|
;; Create a new dist
|
||||||
|
(-> ($ mkdir -p "./target/dist/deps") check)
|
||||||
|
|
||||||
|
;; Copy all jar deps into dist
|
||||||
|
(run! (fn [item] (-> ($ cp ~item "./target/dist/deps/") check)) classpath-jars)
|
||||||
|
|
||||||
|
;; Create the application jar
|
||||||
|
(spit "./target/dist/version.txt" version)
|
||||||
|
(-> ($ jar cvf "./target/dist/deps/app.jar" -C ~(first classpath-paths) ".") check)
|
||||||
|
(-> ($ jar uvf "./target/dist/deps/app.jar" -C "./target/dist" "version.txt") check)
|
||||||
|
(run! (fn [item]
|
||||||
|
(-> ($ jar uvf "./target/dist/deps/app.jar" -C ~item ".") check))
|
||||||
|
(rest classpath-paths))
|
||||||
|
|
||||||
|
;; Copy logging configuration
|
||||||
|
(-> ($ cp "./resources/log4j2.xml" "./target/dist/") check)
|
||||||
|
|
||||||
|
;; Create classpath file
|
||||||
|
(let [jars (->> (into ["app.jar"] classpath-jars)
|
||||||
|
(map fs/file-name)
|
||||||
|
(map #(fs/path "deps" %))
|
||||||
|
(map str))]
|
||||||
|
(spit "./target/dist/classpath" (str/join ":" jars)))
|
||||||
|
|
||||||
|
;; Copy run script template
|
||||||
|
(-> ($ cp "./scripts/run.template.sh" "./target/dist/run.sh") check)
|
||||||
|
|
||||||
|
;; Copy run script template
|
||||||
|
(-> ($ cp "./scripts/manage.template.sh" "./target/dist/manage.sh") check)
|
||||||
|
|
||||||
|
;; Add exec permisions to scripts.
|
||||||
|
(-> ($ chmod +x "./target/dist/run.sh") check)
|
||||||
|
(-> ($ chmod +x "./target/dist/manage.sh") check)
|
||||||
|
|
||||||
|
nil
|
|
@ -1,75 +0,0 @@
|
||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
CLASSPATH=`(clojure -Spath)`
|
|
||||||
NEWCP="./main:./common"
|
|
||||||
|
|
||||||
rm -rf ./target/dist
|
|
||||||
mkdir -p ./target/dist/deps
|
|
||||||
|
|
||||||
for item in $(echo $CLASSPATH | tr ":" "\n"); do
|
|
||||||
if [ "${item: -4}" == ".jar" ]; then
|
|
||||||
cp $item ./target/dist/deps/;
|
|
||||||
BN="$(basename -- $item)"
|
|
||||||
NEWCP+=":./deps/$BN"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
cp ./resources/log4j2.xml ./target/dist/log4j2.xml
|
|
||||||
cp -r ./src ./target/dist/main
|
|
||||||
cp -r ./resources/emails ./target/dist/main/
|
|
||||||
cp -r ./resources/error-report.tmpl ./target/dist/main/
|
|
||||||
cp -r ../common ./target/dist/common
|
|
||||||
|
|
||||||
echo $NEWCP > ./target/dist/classpath;
|
|
||||||
|
|
||||||
tee -a ./target/dist/run.sh >> /dev/null <<EOF
|
|
||||||
#!/usr/bin/env bash
|
|
||||||
CP="$NEWCP"
|
|
||||||
|
|
||||||
set +e
|
|
||||||
JAVA_CMD=\$(type -p java)
|
|
||||||
|
|
||||||
set -e
|
|
||||||
if [[ ! -n "\$JAVA_CMD" ]]; then
|
|
||||||
if [[ -n "\$JAVA_HOME" ]] && [[ -x "\$JAVA_HOME/bin/java" ]]; then
|
|
||||||
JAVA_CMD="\$JAVA_HOME/bin/java"
|
|
||||||
else
|
|
||||||
>&2 echo "Couldn't find 'java'. Please set JAVA_HOME."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -f ./environ ]; then
|
|
||||||
source ./environ
|
|
||||||
fi
|
|
||||||
|
|
||||||
set -x
|
|
||||||
exec \$JAVA_CMD \$JVM_OPTS -classpath \$CP -Dlog4j2.configurationFile=./log4j2.xml "\$@" clojure.main -m app.main
|
|
||||||
EOF
|
|
||||||
|
|
||||||
tee -a ./target/dist/manage.sh >> /dev/null <<EOF
|
|
||||||
#!/usr/bin/env bash
|
|
||||||
CP="$NEWCP"
|
|
||||||
|
|
||||||
set +e
|
|
||||||
JAVA_CMD=\$(type -p java)
|
|
||||||
|
|
||||||
set -e
|
|
||||||
if [[ ! -n "\$JAVA_CMD" ]]; then
|
|
||||||
if [[ -n "\$JAVA_HOME" ]] && [[ -x "\$JAVA_HOME/bin/java" ]]; then
|
|
||||||
JAVA_CMD="\$JAVA_HOME/bin/java"
|
|
||||||
else
|
|
||||||
>&2 echo "Couldn't find 'java'. Please set JAVA_HOME."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -f ./environ ]; then
|
|
||||||
source ./environ
|
|
||||||
fi
|
|
||||||
|
|
||||||
exec \$JAVA_CMD \$JVM_OPTS -classpath \$CP -Dlog4j2.configurationFile=./log4j2.xml clojure.main -m app.cli.manage "\$@"
|
|
||||||
EOF
|
|
||||||
|
|
||||||
chmod +x ./target/dist/run.sh
|
|
||||||
chmod +x ./target/dist/manage.sh
|
|
|
@ -1,4 +0,0 @@
|
||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
clojure -Adev -m app.cli.collimp $@
|
|
||||||
|
|
19
backend/scripts/manage.template.sh
Normal file
19
backend/scripts/manage.template.sh
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set +e
|
||||||
|
JAVA_CMD=$(type -p java)
|
||||||
|
|
||||||
|
set -e
|
||||||
|
if [[ ! -n "$JAVA_CMD" ]]; then
|
||||||
|
if [[ -n "$JAVA_HOME" ]] && [[ -x "$JAVA_HOME/bin/java" ]]; then
|
||||||
|
JAVA_CMD="$JAVA_HOME/bin/java"
|
||||||
|
else
|
||||||
|
>&2 echo "Couldn't find 'java'. Please set JAVA_HOME."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -f ./environ ]; then
|
||||||
|
source ./environ
|
||||||
|
fi
|
||||||
|
|
||||||
|
exec $JAVA_CMD $JVM_OPTS -classpath $(cat classpath) -Dlog4j2.configurationFile=./log4j2.xml clojure.main -m app.cli.manage "\$@"
|
|
@ -1,16 +0,0 @@
|
||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
if [ "$#" -e 0 ]; then
|
|
||||||
echo "Expecting parameters: 1=path to backend; 2=destination directory"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
rm -rf $2 || exit 1;
|
|
||||||
|
|
||||||
rsync -avr \
|
|
||||||
--exclude="/test" \
|
|
||||||
--exclude="/resources/public/media" \
|
|
||||||
--exclude="/target" \
|
|
||||||
--exclude="/scripts" \
|
|
||||||
--exclude="/.*" \
|
|
||||||
$1 $2;
|
|
|
@ -1,2 +0,0 @@
|
||||||
#!/usr/bin/env bash
|
|
||||||
PGPASSWORD=$PENPOT_DATABASE_PASSWORD psql $PENPOT_DATABASE_URI -U $PENPOT_DATABASE_USERNAME
|
|
|
@ -1,4 +0,0 @@
|
||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
set -xe
|
|
||||||
clojure -Adev -m app.tests.main;
|
|
20
backend/scripts/run.template.sh
Normal file
20
backend/scripts/run.template.sh
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set +e
|
||||||
|
JAVA_CMD=$(type -p java)
|
||||||
|
|
||||||
|
set -e
|
||||||
|
if [[ ! -n "$JAVA_CMD" ]]; then
|
||||||
|
if [[ -n "$JAVA_HOME" ]] && [[ -x "$JAVA_HOME/bin/java" ]]; then
|
||||||
|
JAVA_CMD="$JAVA_HOME/bin/java"
|
||||||
|
else
|
||||||
|
>&2 echo "Couldn't find 'java'. Please set JAVA_HOME."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -f ./environ ]; then
|
||||||
|
source ./environ
|
||||||
|
fi
|
||||||
|
|
||||||
|
set -x
|
||||||
|
exec $JAVA_CMD $JVM_OPTS -classpath "$(cat classpath)" -Dlog4j2.configurationFile=./log4j2.xml "$@" clojure.main -m app.main
|
|
@ -1,2 +0,0 @@
|
||||||
#!/usr/bin/env bash
|
|
||||||
python -m smtpd -n -c DebuggingServer localhost:25
|
|
|
@ -1,2 +0,0 @@
|
||||||
#!/usr/bin/env sh
|
|
||||||
exec clojure -M:dev:tests "$@"
|
|
|
@ -16,6 +16,7 @@
|
||||||
[app.util.time :as dt]
|
[app.util.time :as dt]
|
||||||
[clojure.core :as c]
|
[clojure.core :as c]
|
||||||
[clojure.pprint :as pprint]
|
[clojure.pprint :as pprint]
|
||||||
|
[clojure.java.io :as io]
|
||||||
[clojure.spec.alpha :as s]
|
[clojure.spec.alpha :as s]
|
||||||
[cuerdas.core :as str]
|
[cuerdas.core :as str]
|
||||||
[environ.core :refer [env]]))
|
[environ.core :refer [env]]))
|
||||||
|
@ -50,7 +51,7 @@
|
||||||
|
|
||||||
:storage-backend :fs
|
:storage-backend :fs
|
||||||
|
|
||||||
:storage-fs-directory "resources/public/assets"
|
:storage-fs-directory "assets"
|
||||||
:storage-s3-region :eu-central-1
|
:storage-s3-region :eu-central-1
|
||||||
:storage-s3-bucket "penpot-devenv-assets-pre"
|
:storage-s3-bucket "penpot-devenv-assets-pre"
|
||||||
|
|
||||||
|
@ -246,14 +247,16 @@
|
||||||
{}
|
{}
|
||||||
env)))
|
env)))
|
||||||
|
|
||||||
|
|
||||||
(defn- read-config
|
(defn- read-config
|
||||||
[]
|
[]
|
||||||
(->> (read-env "penpot")
|
(->> (read-env "penpot")
|
||||||
(merge defaults)
|
(merge defaults)
|
||||||
(us/conform ::config)))
|
(us/conform ::config)))
|
||||||
|
|
||||||
(def version (v/parse "%version%"))
|
(def version (v/parse (or (some-> (io/resource "version.txt")
|
||||||
|
(slurp)
|
||||||
|
(str/trim))
|
||||||
|
"%version%")))
|
||||||
(def config (atom (read-config)))
|
(def config (atom (read-config)))
|
||||||
|
|
||||||
(def deletion-delay
|
(def deletion-delay
|
||||||
|
|
|
@ -6,7 +6,7 @@ ARG DEBIAN_FRONTEND=noninteractive
|
||||||
ENV NODE_VERSION=v14.16.0 \
|
ENV NODE_VERSION=v14.16.0 \
|
||||||
CLOJURE_VERSION=1.10.3.814 \
|
CLOJURE_VERSION=1.10.3.814 \
|
||||||
CLJKONDO_VERSION=2021.03.22 \
|
CLJKONDO_VERSION=2021.03.22 \
|
||||||
BABASHKA_VERSION=0.3.0 \
|
BABASHKA_VERSION=0.3.1 \
|
||||||
LANG=en_US.UTF-8 \
|
LANG=en_US.UTF-8 \
|
||||||
LC_ALL=en_US.UTF-8
|
LC_ALL=en_US.UTF-8
|
||||||
|
|
||||||
|
@ -151,6 +151,7 @@ EXPOSE 3449
|
||||||
EXPOSE 6060
|
EXPOSE 6060
|
||||||
EXPOSE 9090
|
EXPOSE 9090
|
||||||
|
|
||||||
|
COPY files/nginx.conf /etc/nginx/nginx.conf
|
||||||
COPY files/phantomjs-mock /usr/bin/phantomjs
|
COPY files/phantomjs-mock /usr/bin/phantomjs
|
||||||
|
|
||||||
COPY files/bashrc /root/.bashrc
|
COPY files/bashrc /root/.bashrc
|
||||||
|
|
|
@ -27,7 +27,6 @@ services:
|
||||||
volumes:
|
volumes:
|
||||||
- "user_data:/home/penpot/"
|
- "user_data:/home/penpot/"
|
||||||
- "${PWD}:/home/penpot/penpot"
|
- "${PWD}:/home/penpot/penpot"
|
||||||
- ./files/nginx.conf:/etc/nginx/nginx.conf
|
|
||||||
|
|
||||||
ports:
|
ports:
|
||||||
- 3447:3447
|
- 3447:3447
|
||||||
|
|
|
@ -91,7 +91,7 @@ http {
|
||||||
|
|
||||||
location /internal/assets {
|
location /internal/assets {
|
||||||
internal;
|
internal;
|
||||||
alias /home/penpot/penpot/backend/resources/public/assets;
|
alias /home/penpot/penpot/backend/assets;
|
||||||
add_header x-internal-redirect "$upstream_http_x_accel_redirect";
|
add_header x-internal-redirect "$upstream_http_x_accel_redirect";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,9 @@ tmux send-keys -t penpot 'npx shadow-cljs watch main' enter
|
||||||
tmux new-window -t penpot:2 -n 'exporter'
|
tmux new-window -t penpot:2 -n 'exporter'
|
||||||
tmux select-window -t penpot:2
|
tmux select-window -t penpot:2
|
||||||
tmux send-keys -t penpot 'cd penpot/exporter' enter C-l
|
tmux send-keys -t penpot 'cd penpot/exporter' enter C-l
|
||||||
|
tmux send-keys -t penpot 'rm -f target/app.js*' enter C-l
|
||||||
tmux send-keys -t penpot 'npx shadow-cljs watch main' enter
|
tmux send-keys -t penpot 'npx shadow-cljs watch main' enter
|
||||||
|
|
||||||
tmux split-window -v
|
tmux split-window -v
|
||||||
tmux send-keys -t penpot 'cd penpot/exporter' enter C-l
|
tmux send-keys -t penpot 'cd penpot/exporter' enter C-l
|
||||||
tmux send-keys -t penpot './scripts/wait-and-start.sh' enter
|
tmux send-keys -t penpot './scripts/wait-and-start.sh' enter
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
source ~/.bashrc
|
|
||||||
set -ex
|
set -ex
|
||||||
|
|
||||||
yarn install
|
yarn install
|
|
@ -1,16 +1,5 @@
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
set -e
|
bb -i '(babashka.wait/wait-for-port "localhost" 9630)';
|
||||||
|
bb -i '(babashka.wait/wait-for-path "target/app.js")';
|
||||||
wait_file() {
|
|
||||||
local file="$1"; shift
|
|
||||||
local wait_seconds="${1:-10}"; shift # 10 seconds as default timeout
|
|
||||||
|
|
||||||
until test $((wait_seconds--)) -eq 0 -o -f "$file" ; do sleep 1; done
|
|
||||||
|
|
||||||
((++wait_seconds))
|
|
||||||
}
|
|
||||||
|
|
||||||
wait_file "target/app.js" 120 && {
|
|
||||||
node target/app.js
|
node target/app.js
|
||||||
}
|
|
||||||
|
|
17
frontend/scripts/build
Executable file
17
frontend/scripts/build
Executable file
|
@ -0,0 +1,17 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
set -ex
|
||||||
|
|
||||||
|
CURRENT_VERSION=$1;
|
||||||
|
CURRENT_HASH=$(git rev-parse --short HEAD);
|
||||||
|
EXTRA_PARAMS=$SHADOWCLJS_EXTRA_PARAMS;
|
||||||
|
|
||||||
|
yarn install || exit 1;
|
||||||
|
npx gulp clean || exit 1;
|
||||||
|
npx shadow-cljs release main --config-merge "{:release-version \"${CURRENT_HASH}\"}" $EXTRA_PARAMS || exit 1
|
||||||
|
npx gulp build || exit 1;
|
||||||
|
npx gulp dist:clean || exit 1;
|
||||||
|
npx gulp dist:copy || exit 1;
|
||||||
|
|
||||||
|
sed -i -re "s/\%version\%/$CURRENT_VERSION/g" ./target/dist/index.html;
|
||||||
|
|
|
@ -1,8 +0,0 @@
|
||||||
#!/usr/bin/env bash
|
|
||||||
source ~/.bashrc
|
|
||||||
|
|
||||||
set -ex;
|
|
||||||
|
|
||||||
yarn install
|
|
||||||
clojure -Adev tools.clj build:tests
|
|
||||||
node ./target/tests/main
|
|
|
@ -1,21 +0,0 @@
|
||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
source ~/.bashrc
|
|
||||||
|
|
||||||
set -ex
|
|
||||||
|
|
||||||
if [ -z "${TAG}" ]; then
|
|
||||||
export TAG=$(git log -n 1 --pretty=format:%H -- ./);
|
|
||||||
fi
|
|
||||||
|
|
||||||
yarn install
|
|
||||||
|
|
||||||
export NODE_ENV=production;
|
|
||||||
|
|
||||||
# Clean the output directory
|
|
||||||
npx gulp clean || exit 1;
|
|
||||||
|
|
||||||
npx shadow-cljs release main --config-merge "{:release-version \"${TAG}\"}" $SHADOWCLJS_EXTRA_PARAMS
|
|
||||||
npx gulp build || exit 1;
|
|
||||||
npx gulp dist:clean || exit 1;
|
|
||||||
npx gulp dist:copy || exit 1;
|
|
|
@ -96,7 +96,8 @@
|
||||||
(mf/deps page-id)
|
(mf/deps page-id)
|
||||||
(fn [point]
|
(fn [point]
|
||||||
(let [rect (gsh/center->rect point 8 8)]
|
(let [rect (gsh/center->rect point 8 8)]
|
||||||
(uw/ask! {:cmd :selection/query
|
(uw/ask-buffered!
|
||||||
|
{:cmd :selection/query
|
||||||
:page-id page-id
|
:page-id page-id
|
||||||
:rect rect
|
:rect rect
|
||||||
:include-frames? true}))))
|
:include-frames? true}))))
|
||||||
|
|
|
@ -25,3 +25,7 @@
|
||||||
(defn ask!
|
(defn ask!
|
||||||
[message]
|
[message]
|
||||||
(uw/ask! instance message))
|
(uw/ask! instance message))
|
||||||
|
|
||||||
|
(defn ask-buffered!
|
||||||
|
[message]
|
||||||
|
(uw/ask-buffered! instance message))
|
||||||
|
|
|
@ -17,39 +17,58 @@
|
||||||
(declare handle-response)
|
(declare handle-response)
|
||||||
(defrecord Worker [instance stream])
|
(defrecord Worker [instance stream])
|
||||||
|
|
||||||
(defn ask!
|
(defn- send-message! [worker {sender-id :sender-id :as message}]
|
||||||
[w message]
|
(let [data (t/encode message)
|
||||||
(let [sender-id (uuid/next)
|
instance (:instance worker)]
|
||||||
data (t/encode {:payload message :sender-id sender-id})
|
|
||||||
instance (:instance w)]
|
|
||||||
(.postMessage instance data)
|
(.postMessage instance data)
|
||||||
(->> (:stream w)
|
(->> (:stream worker)
|
||||||
(rx/filter #(= (:reply-to %) sender-id))
|
(rx/filter #(= (:reply-to %) sender-id))
|
||||||
(rx/map handle-response)
|
(rx/take 1)
|
||||||
(rx/first))))
|
(rx/map handle-response))))
|
||||||
|
|
||||||
|
(defn ask!
|
||||||
|
[worker message]
|
||||||
|
(send-message!
|
||||||
|
worker
|
||||||
|
{:sender-id (uuid/next)
|
||||||
|
:payload message}))
|
||||||
|
|
||||||
|
(defn ask-buffered!
|
||||||
|
[worker message]
|
||||||
|
(send-message!
|
||||||
|
worker
|
||||||
|
{:sender-id (uuid/next)
|
||||||
|
:payload message
|
||||||
|
:buffer? true}))
|
||||||
|
|
||||||
(defn init
|
(defn init
|
||||||
"Return a initialized webworker instance."
|
"Return a initialized webworker instance."
|
||||||
[path on-error]
|
[path on-error]
|
||||||
(let [ins (js/Worker. path)
|
(let [instance (js/Worker. path)
|
||||||
bus (rx/subject)
|
bus (rx/subject)
|
||||||
wrk (Worker. ins bus)]
|
worker (Worker. instance bus)
|
||||||
(.addEventListener ins "message"
|
|
||||||
|
handle-message
|
||||||
(fn [event]
|
(fn [event]
|
||||||
(let [data (.-data event)
|
(let [data (.-data event)
|
||||||
data (t/decode data)]
|
data (t/decode data)]
|
||||||
(if (:error data)
|
(if (:error data)
|
||||||
(on-error (:error data))
|
(on-error (:error data))
|
||||||
(rx/push! bus data)))))
|
(rx/push! bus data))))
|
||||||
(.addEventListener ins "error"
|
|
||||||
(fn [error]
|
|
||||||
(on-error wrk (.-data error))))
|
|
||||||
|
|
||||||
wrk))
|
handle-error
|
||||||
|
(fn [error]
|
||||||
|
(on-error worker (.-data error)))]
|
||||||
|
|
||||||
|
(.addEventListener instance "message" handle-message)
|
||||||
|
(.addEventListener instance "error" handle-error)
|
||||||
|
|
||||||
|
worker))
|
||||||
|
|
||||||
(defn- handle-response
|
(defn- handle-response
|
||||||
[{:keys [payload error] :as response}]
|
[{:keys [payload error dropped] :as response}]
|
||||||
|
(when-not dropped
|
||||||
(if-let [{:keys [data message]} error]
|
(if-let [{:keys [data message]} error]
|
||||||
(throw (ex-info message data))
|
(throw (ex-info message data))
|
||||||
payload))
|
payload)))
|
||||||
|
|
||||||
|
|
|
@ -28,14 +28,23 @@
|
||||||
;; --- Messages Handling
|
;; --- Messages Handling
|
||||||
|
|
||||||
(s/def ::cmd keyword?)
|
(s/def ::cmd keyword?)
|
||||||
|
|
||||||
(s/def ::payload
|
(s/def ::payload
|
||||||
(s/keys :req-un [::cmd]))
|
(s/keys :req-un [::cmd]))
|
||||||
|
|
||||||
(s/def ::sender-id uuid?)
|
(s/def ::sender-id uuid?)
|
||||||
|
|
||||||
|
(s/def ::buffer? boolean?)
|
||||||
|
|
||||||
(s/def ::message
|
(s/def ::message
|
||||||
(s/keys :req-un [::payload ::sender-id]))
|
(s/keys
|
||||||
|
:req-opt [::buffer?]
|
||||||
|
:req-un [::payload ::sender-id]))
|
||||||
|
|
||||||
|
(def buffer (rx/subject))
|
||||||
|
|
||||||
(defn- handle-message
|
(defn- handle-message
|
||||||
|
"Process the message and returns to the client"
|
||||||
[{:keys [sender-id payload] :as message}]
|
[{:keys [sender-id payload] :as message}]
|
||||||
(us/assert ::message message)
|
(us/assert ::message message)
|
||||||
(try
|
(try
|
||||||
|
@ -68,20 +77,83 @@
|
||||||
:message (ex-message e)}}]
|
:message (ex-message e)}}]
|
||||||
(.postMessage js/self (t/encode message))))))
|
(.postMessage js/self (t/encode message))))))
|
||||||
|
|
||||||
|
(defn- drop-message
|
||||||
|
"Sends to the client a notifiction that its messages have been dropped"
|
||||||
|
[{:keys [sender-id payload] :as message}]
|
||||||
|
(us/assert ::message message)
|
||||||
|
(.postMessage js/self (t/encode {:reply-to sender-id
|
||||||
|
:dropped true})))
|
||||||
|
|
||||||
|
(defn subscribe-buffer-messages
|
||||||
|
"Creates a subscription to process the buffer messages"
|
||||||
|
[]
|
||||||
|
(let [empty [{} [] ::clear]]
|
||||||
|
(->> buffer
|
||||||
|
|
||||||
|
;; We want async processing to not block the main loop
|
||||||
|
(rx/observe-on :async)
|
||||||
|
|
||||||
|
;; This scan will store the last message per type in `messages`
|
||||||
|
;; when a previous message is dropped is stored in `dropped`
|
||||||
|
;; we also store the last message processed in order to detect
|
||||||
|
;; posible infinite loops
|
||||||
|
(rx/scan
|
||||||
|
(fn [[messages dropped last] message]
|
||||||
|
(let [cmd (get-in message [:payload :cmd])
|
||||||
|
|
||||||
|
;; The previous message is dropped
|
||||||
|
dropped
|
||||||
|
(cond-> dropped
|
||||||
|
(contains? messages cmd)
|
||||||
|
(conj (get messages cmd)))
|
||||||
|
|
||||||
|
;; This is the new "head" for its type
|
||||||
|
messages
|
||||||
|
(assoc messages cmd message)]
|
||||||
|
|
||||||
|
;; When a "clear" message is detected we empty the buffer
|
||||||
|
(if (= message ::clear)
|
||||||
|
empty
|
||||||
|
[messages dropped message])))
|
||||||
|
|
||||||
|
empty)
|
||||||
|
|
||||||
|
;; 1ms debounce, after 1ms without messages will process the buffer
|
||||||
|
(rx/debounce 1)
|
||||||
|
|
||||||
|
(rx/subs (fn [[messages dropped last]]
|
||||||
|
;; Send back the dropped messages replies
|
||||||
|
(doseq [msg dropped]
|
||||||
|
(drop-message msg))
|
||||||
|
|
||||||
|
;; Process the message
|
||||||
|
(doseq [msg (vals messages)]
|
||||||
|
(handle-message msg))
|
||||||
|
|
||||||
|
;; After process the buffer we send a clear
|
||||||
|
(when-not (= last ::clear)
|
||||||
|
(rx/push! buffer ::clear)))))))
|
||||||
|
|
||||||
|
(defonce process-message-sub (subscribe-buffer-messages))
|
||||||
|
|
||||||
(defn- on-message
|
(defn- on-message
|
||||||
[event]
|
[event]
|
||||||
(when (nil? (.-source event))
|
(when (nil? (.-source event))
|
||||||
(let [message (.-data event)
|
(let [message (.-data event)
|
||||||
message (t/decode message)]
|
message (t/decode message)]
|
||||||
(handle-message message))))
|
(if (:buffer? message)
|
||||||
|
(rx/push! buffer message)
|
||||||
|
(handle-message message)))))
|
||||||
|
|
||||||
(.addEventListener js/self "message" on-message)
|
(.addEventListener js/self "message" on-message)
|
||||||
|
|
||||||
(defn ^:dev/before-load stop []
|
(defn ^:dev/before-load stop []
|
||||||
|
(rx/-dispose process-message-sub)
|
||||||
(.removeEventListener js/self "message" on-message))
|
(.removeEventListener js/self "message" on-message))
|
||||||
|
|
||||||
(defn ^:dev/after-load start []
|
(defn ^:dev/after-load start []
|
||||||
[]
|
[]
|
||||||
|
(set! process-message-sub (subscribe-buffer-messages))
|
||||||
(.addEventListener js/self "message" on-message))
|
(.addEventListener js/self "message" on-message))
|
||||||
|
|
||||||
|
|
||||||
|
|
38
manage.sh
38
manage.sh
|
@ -71,6 +71,9 @@ function run-devenv {
|
||||||
}
|
}
|
||||||
|
|
||||||
function build {
|
function build {
|
||||||
|
echo ">> build start: $1"
|
||||||
|
local version=$(print-current-version);
|
||||||
|
|
||||||
pull-devenv-if-not-exists;
|
pull-devenv-if-not-exists;
|
||||||
docker volume create ${DEVENV_PNAME}_user_data;
|
docker volume create ${DEVENV_PNAME}_user_data;
|
||||||
docker run -t --rm \
|
docker run -t --rm \
|
||||||
|
@ -79,10 +82,28 @@ function build {
|
||||||
-e EXTERNAL_UID=$CURRENT_USER_ID \
|
-e EXTERNAL_UID=$CURRENT_USER_ID \
|
||||||
-e SHADOWCLJS_EXTRA_PARAMS=$SHADOWCLJS_EXTRA_PARAMS \
|
-e SHADOWCLJS_EXTRA_PARAMS=$SHADOWCLJS_EXTRA_PARAMS \
|
||||||
-w /home/penpot/penpot/$1 \
|
-w /home/penpot/penpot/$1 \
|
||||||
$DEVENV_IMGNAME:latest sudo -EH -u penpot ./scripts/build.sh
|
$DEVENV_IMGNAME:latest sudo -EH -u penpot ./scripts/build $version
|
||||||
|
|
||||||
|
echo ">> build end: $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
function put-license-file {
|
||||||
|
local target=$1;
|
||||||
|
tee -a $target/LICENSE >> /dev/null <<EOF
|
||||||
|
This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
|
||||||
|
This Source Code Form is "Incompatible With Secondary Licenses", as
|
||||||
|
defined by the Mozilla Public License, v. 2.0.
|
||||||
|
|
||||||
|
Copyright (c) UXBOX Labs SL
|
||||||
|
EOF
|
||||||
}
|
}
|
||||||
|
|
||||||
function build-app-bundle {
|
function build-app-bundle {
|
||||||
|
echo ">> bundle app start";
|
||||||
|
|
||||||
local version=$(print-current-version);
|
local version=$(print-current-version);
|
||||||
local bundle_dir="./bundle-app";
|
local bundle_dir="./bundle-app";
|
||||||
|
|
||||||
|
@ -91,25 +112,28 @@ function build-app-bundle {
|
||||||
|
|
||||||
rm -rf $bundle_dir
|
rm -rf $bundle_dir
|
||||||
mkdir -p $bundle_dir;
|
mkdir -p $bundle_dir;
|
||||||
cp -r ./frontend/target/dist $bundle_dir/frontend;
|
mv ./frontend/target/dist $bundle_dir/frontend;
|
||||||
cp -r ./backend/target/dist $bundle_dir/backend;
|
mv ./backend/target/dist $bundle_dir/backend;
|
||||||
|
|
||||||
echo $version > $bundle_dir/version.txt
|
echo $version > $bundle_dir/version.txt
|
||||||
|
put-license-file $bundle_dir;
|
||||||
sed -i -re "s/\%version\%/$version/g" $bundle_dir/frontend/index.html;
|
echo ">> bundle app end";
|
||||||
sed -i -re "s/\%version\%/$version/g" $bundle_dir/backend/main/app/config.clj;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function build-exporter-bundle {
|
function build-exporter-bundle {
|
||||||
|
echo ">> bundle exporter start";
|
||||||
local version=$(print-current-version);
|
local version=$(print-current-version);
|
||||||
local bundle_dir="./bundle-exporter";
|
local bundle_dir="./bundle-exporter";
|
||||||
|
|
||||||
build "exporter";
|
build "exporter";
|
||||||
|
|
||||||
rm -rf $bundle_dir;
|
rm -rf $bundle_dir;
|
||||||
cp -r ./exporter/target $bundle_dir;
|
mv ./exporter/target $bundle_dir;
|
||||||
|
|
||||||
echo $version > $bundle_dir/version.txt
|
echo $version > $bundle_dir/version.txt
|
||||||
|
put-license-file $bundle_dir;
|
||||||
|
|
||||||
|
echo ">> bundle exporter end";
|
||||||
}
|
}
|
||||||
|
|
||||||
function usage {
|
function usage {
|
||||||
|
|
Loading…
Add table
Reference in a new issue