mirror of
https://github.com/tiddly-gittly/TidGi-Desktop.git
synced 2025-12-06 02:30:47 -08:00
feat: initialize an app level db for storing workflow state
This commit is contained in:
parent
94c23a597b
commit
e2f6e00f8f
14 changed files with 408 additions and 42 deletions
2
.nvmrc
2
.nvmrc
|
|
@ -1 +1 @@
|
|||
v16
|
||||
v18
|
||||
|
|
|
|||
|
|
@ -101,6 +101,7 @@
|
|||
"strip-ansi": "^7.1.0",
|
||||
"threads": "1.7.0",
|
||||
"type-fest": "3.13.0",
|
||||
"typeorm": "^0.3.17",
|
||||
"typescript-styled-is": "^2.1.0",
|
||||
"v8-compile-cache-lib": "^3.0.1",
|
||||
"winston": "3.10.0",
|
||||
|
|
|
|||
163
pnpm-lock.yaml
generated
163
pnpm-lock.yaml
generated
|
|
@ -229,6 +229,9 @@ dependencies:
|
|||
type-fest:
|
||||
specifier: 3.13.0
|
||||
version: 3.13.0
|
||||
typeorm:
|
||||
specifier: ^0.3.17
|
||||
version: 0.3.17(better-sqlite3@8.5.1)(ts-node@10.9.1)
|
||||
typescript-styled-is:
|
||||
specifier: ^2.1.0
|
||||
version: 2.1.0(react-dom@18.2.0)(react@18.2.0)(styled-components@6.0.7)
|
||||
|
|
@ -1931,7 +1934,6 @@ packages:
|
|||
engines: {node: '>=12'}
|
||||
dependencies:
|
||||
'@jridgewell/trace-mapping': 0.3.9
|
||||
dev: true
|
||||
|
||||
/@cucumber/ci-environment@9.2.0:
|
||||
resolution: {integrity: sha512-jLzRtVwdtNt+uAmTwvXwW9iGYLEOJFpDSmnx/dgoMGKXUWRx1UHT86Q696CLdgXO8kyTwsgJY0c6n5SW9VitAA==}
|
||||
|
|
@ -3385,7 +3387,6 @@ packages:
|
|||
/@jridgewell/resolve-uri@3.1.1:
|
||||
resolution: {integrity: sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==}
|
||||
engines: {node: '>=6.0.0'}
|
||||
dev: true
|
||||
|
||||
/@jridgewell/set-array@1.1.2:
|
||||
resolution: {integrity: sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==}
|
||||
|
|
@ -3415,7 +3416,6 @@ packages:
|
|||
dependencies:
|
||||
'@jridgewell/resolve-uri': 3.1.1
|
||||
'@jridgewell/sourcemap-codec': 1.4.15
|
||||
dev: true
|
||||
|
||||
/@leichtgewicht/ip-codec@2.0.4:
|
||||
resolution: {integrity: sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==}
|
||||
|
|
@ -3970,6 +3970,10 @@ packages:
|
|||
resolution: {integrity: sha512-aywhxHNb6l7COooF3m439eT/6QN8E/RSl5IVboSKthMHcp0GlZYMSoS7546rqDLmFRxTD8f1tu/NIS9vtDwYAg==}
|
||||
dev: true
|
||||
|
||||
/@sqltools/formatter@1.2.5:
|
||||
resolution: {integrity: sha512-Uy0+khmZqUrUGm5dmMqVlnvufZRSK0FbYzVgp0UMstm+F5+W2/jnEEQyc9vo1ZR/E5ZI/B1WjjoTqBqwJL6Krw==}
|
||||
dev: false
|
||||
|
||||
/@szmarczak/http-timer@4.0.6:
|
||||
resolution: {integrity: sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==}
|
||||
engines: {node: '>=10'}
|
||||
|
|
@ -3999,19 +4003,15 @@ packages:
|
|||
|
||||
/@tsconfig/node10@1.0.9:
|
||||
resolution: {integrity: sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==}
|
||||
dev: true
|
||||
|
||||
/@tsconfig/node12@1.0.11:
|
||||
resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==}
|
||||
dev: true
|
||||
|
||||
/@tsconfig/node14@1.0.3:
|
||||
resolution: {integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==}
|
||||
dev: true
|
||||
|
||||
/@tsconfig/node16@1.0.4:
|
||||
resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==}
|
||||
dev: true
|
||||
|
||||
/@types/better-sqlite3@7.6.4:
|
||||
resolution: {integrity: sha512-dzrRZCYPXIXfSR1/surNbJ/grU3scTaygS0OMzjlGf71i9sc2fGyHPXXiXmEvNIoE0cGwsanEFMVJxPXmco9Eg==}
|
||||
|
|
@ -4851,7 +4851,6 @@ packages:
|
|||
/acorn-walk@8.2.0:
|
||||
resolution: {integrity: sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==}
|
||||
engines: {node: '>=0.4.0'}
|
||||
dev: true
|
||||
|
||||
/acorn@8.9.0:
|
||||
resolution: {integrity: sha512-jaVNAFBHNLXspO543WnNNPZFRtavh3skAkITqD0/2aeMkKZTN+254PyhwxFYrk3vQ1xfY+2wbesJMs/JC8/PwQ==}
|
||||
|
|
@ -4988,7 +4987,6 @@ packages:
|
|||
|
||||
/any-promise@1.3.0:
|
||||
resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==}
|
||||
dev: true
|
||||
|
||||
/anymatch@3.1.3:
|
||||
resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==}
|
||||
|
|
@ -5004,6 +5002,11 @@ packages:
|
|||
execa: 5.1.1
|
||||
dev: false
|
||||
|
||||
/app-root-path@3.1.0:
|
||||
resolution: {integrity: sha512-biN3PwB2gUtjaYy/isrU3aNWI5w+fAfvHkSvCKeQGxhmYpwKFUxudR3Yya+KqVRHBmEDYh+/lTozYCFbmzX4nA==}
|
||||
engines: {node: '>= 6.0.0'}
|
||||
dev: false
|
||||
|
||||
/aproba@1.2.0:
|
||||
resolution: {integrity: sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==}
|
||||
dev: false
|
||||
|
|
@ -5029,7 +5032,6 @@ packages:
|
|||
|
||||
/arg@4.1.3:
|
||||
resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==}
|
||||
dev: true
|
||||
|
||||
/argparse@1.0.10:
|
||||
resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==}
|
||||
|
|
@ -5397,7 +5399,6 @@ packages:
|
|||
resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==}
|
||||
dependencies:
|
||||
balanced-match: 1.0.2
|
||||
dev: true
|
||||
|
||||
/braces@3.0.2:
|
||||
resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==}
|
||||
|
|
@ -5511,7 +5512,6 @@ packages:
|
|||
dependencies:
|
||||
base64-js: 1.5.1
|
||||
ieee754: 1.2.1
|
||||
dev: true
|
||||
|
||||
/bufferutil@4.0.7:
|
||||
resolution: {integrity: sha512-kukuqc39WOHtdxtw4UScxF/WVnMFVSQVKhtx3AjZJzhd0RGZZldcrfSEbVsWWe6KNH253574cq5F+wpv0G9pJw==}
|
||||
|
|
@ -5655,7 +5655,6 @@ packages:
|
|||
dependencies:
|
||||
ansi-styles: 4.3.0
|
||||
supports-color: 7.2.0
|
||||
dev: true
|
||||
|
||||
/chalk@5.3.0:
|
||||
resolution: {integrity: sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==}
|
||||
|
|
@ -5776,6 +5775,19 @@ packages:
|
|||
restore-cursor: 3.1.0
|
||||
dev: true
|
||||
|
||||
/cli-highlight@2.1.11:
|
||||
resolution: {integrity: sha512-9KDcoEVwyUXrjcJNvHD0NFc/hiwe/WPVYIleQh2O1N2Zro5gWJZ/K+3DGn8w8P/F6FxOgzyC5bxDyHIgCSPhGg==}
|
||||
engines: {node: '>=8.0.0', npm: '>=5.0.0'}
|
||||
hasBin: true
|
||||
dependencies:
|
||||
chalk: 4.1.2
|
||||
highlight.js: 10.7.3
|
||||
mz: 2.7.0
|
||||
parse5: 5.1.1
|
||||
parse5-htmlparser2-tree-adapter: 6.0.1
|
||||
yargs: 16.2.0
|
||||
dev: false
|
||||
|
||||
/cli-spinners@2.9.0:
|
||||
resolution: {integrity: sha512-4/aL9X3Wh0yiMQlE+eeRhWP6vclO3QRtw1JHKIT0FFUs5FjpFmESqtMvYZ0+lbzBw900b95mS0hohy+qn2VK/g==}
|
||||
engines: {node: '>=6'}
|
||||
|
|
@ -5813,8 +5825,6 @@ packages:
|
|||
string-width: 4.2.3
|
||||
strip-ansi: 6.0.1
|
||||
wrap-ansi: 7.0.0
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/cliui@8.0.1:
|
||||
resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==}
|
||||
|
|
@ -6144,7 +6154,6 @@ packages:
|
|||
|
||||
/create-require@1.1.1:
|
||||
resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==}
|
||||
dev: true
|
||||
|
||||
/cross-env@7.0.3:
|
||||
resolution: {integrity: sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==}
|
||||
|
|
@ -6325,7 +6334,6 @@ packages:
|
|||
engines: {node: '>=0.11'}
|
||||
dependencies:
|
||||
'@babel/runtime': 7.22.6
|
||||
dev: true
|
||||
|
||||
/debug@2.6.9:
|
||||
resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==}
|
||||
|
|
@ -6520,7 +6528,6 @@ packages:
|
|||
/diff@4.0.2:
|
||||
resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==}
|
||||
engines: {node: '>=0.3.1'}
|
||||
dev: true
|
||||
|
||||
/diffie-hellman@5.0.3:
|
||||
resolution: {integrity: sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==}
|
||||
|
|
@ -6646,6 +6653,11 @@ packages:
|
|||
tslib: 2.6.0
|
||||
dev: true
|
||||
|
||||
/dotenv@16.3.1:
|
||||
resolution: {integrity: sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==}
|
||||
engines: {node: '>=12'}
|
||||
dev: false
|
||||
|
||||
/dprint@0.37.1:
|
||||
resolution: {integrity: sha512-MVKIVOvk5FSiZQFFZlLv1KiB4zZXAirlZ/m8vtyKu2PTFnkD5d6jVv4aNHvd7M6f1ToganNZ/CqhSwpgadn8Ug==}
|
||||
hasBin: true
|
||||
|
|
@ -8528,7 +8540,6 @@ packages:
|
|||
inherits: 2.0.4
|
||||
minimatch: 5.1.6
|
||||
once: 1.4.0
|
||||
dev: true
|
||||
|
||||
/global-agent@3.0.0:
|
||||
resolution: {integrity: sha512-PT6XReJ+D07JvGoxQMkT6qji/jVNfX/h364XHZOWeRzy64sSFr+xJ5OX7LI3b4MPQzdL4H8Y8M0xzPpsVMwA8Q==}
|
||||
|
|
@ -8760,6 +8771,10 @@ packages:
|
|||
hasBin: true
|
||||
dev: true
|
||||
|
||||
/highlight.js@10.7.3:
|
||||
resolution: {integrity: sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==}
|
||||
dev: false
|
||||
|
||||
/hmac-drbg@1.0.1:
|
||||
resolution: {integrity: sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=}
|
||||
dependencies:
|
||||
|
|
@ -10052,7 +10067,6 @@ packages:
|
|||
|
||||
/make-error@1.3.6:
|
||||
resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==}
|
||||
dev: true
|
||||
|
||||
/make-fetch-happen@11.1.1:
|
||||
resolution: {integrity: sha512-rLWS7GCSTcEujjVBs2YqG7Y4643u8ucvCJeSRqiLYhesrDuzeuFIk37xREzAsfQaqzl8b9rNCE4m6J8tvX4Q8w==}
|
||||
|
|
@ -10263,7 +10277,6 @@ packages:
|
|||
engines: {node: '>=10'}
|
||||
dependencies:
|
||||
brace-expansion: 2.0.1
|
||||
dev: true
|
||||
|
||||
/minimatch@9.0.2:
|
||||
resolution: {integrity: sha512-PZOT9g5v2ojiTL7r1xF6plNHLtOeTpSlDI007As2NlA2aYBMfVom17yqa6QzhmDP8QOhn7LjHTg7DFCVSSa6yg==}
|
||||
|
|
@ -10373,7 +10386,6 @@ packages:
|
|||
resolution: {integrity: sha512-+hEnITedc8LAtIP9u3HJDFIdcLV2vXP33sqLLIzkv1Db1zO/1OxbvYf0Y1OC/S/Qo5dxHXepofhmxL02PsKe+A==}
|
||||
engines: {node: '>=10'}
|
||||
hasBin: true
|
||||
dev: true
|
||||
|
||||
/moment@2.29.4:
|
||||
resolution: {integrity: sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==}
|
||||
|
|
@ -10407,7 +10419,6 @@ packages:
|
|||
any-promise: 1.3.0
|
||||
object-assign: 4.1.1
|
||||
thenify-all: 1.6.0
|
||||
dev: true
|
||||
|
||||
/nanoclone@0.2.1:
|
||||
resolution: {integrity: sha512-wynEP02LmIbLpcYw8uBKpcfF6dmg2vcpKqxeH5UcoKEYdExslsdUA4ugFauuaeYdTB76ez6gJW8XAZ6CgkXYxA==}
|
||||
|
|
@ -11307,6 +11318,12 @@ packages:
|
|||
engines: {node: '>=0.10.0'}
|
||||
dev: true
|
||||
|
||||
/parse5-htmlparser2-tree-adapter@6.0.1:
|
||||
resolution: {integrity: sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==}
|
||||
dependencies:
|
||||
parse5: 6.0.1
|
||||
dev: false
|
||||
|
||||
/parse5-htmlparser2-tree-adapter@7.0.0:
|
||||
resolution: {integrity: sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g==}
|
||||
dependencies:
|
||||
|
|
@ -11314,6 +11331,14 @@ packages:
|
|||
parse5: 7.1.2
|
||||
dev: true
|
||||
|
||||
/parse5@5.1.1:
|
||||
resolution: {integrity: sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==}
|
||||
dev: false
|
||||
|
||||
/parse5@6.0.1:
|
||||
resolution: {integrity: sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==}
|
||||
dev: false
|
||||
|
||||
/parse5@7.1.2:
|
||||
resolution: {integrity: sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==}
|
||||
dependencies:
|
||||
|
|
@ -12087,7 +12112,7 @@ packages:
|
|||
dev: true
|
||||
|
||||
/require-directory@2.1.1:
|
||||
resolution: {integrity: sha1-jGStX9MNqxyXbiNE/+f3kqam30I=}
|
||||
resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
/require-from-string@2.0.2:
|
||||
|
|
@ -13088,7 +13113,6 @@ packages:
|
|||
engines: {node: '>=8'}
|
||||
dependencies:
|
||||
has-flag: 4.0.0
|
||||
dev: true
|
||||
|
||||
/supports-color@8.1.1:
|
||||
resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==}
|
||||
|
|
@ -13224,13 +13248,11 @@ packages:
|
|||
engines: {node: '>=0.8'}
|
||||
dependencies:
|
||||
thenify: 3.3.1
|
||||
dev: true
|
||||
|
||||
/thenify@3.3.1:
|
||||
resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==}
|
||||
dependencies:
|
||||
any-promise: 1.3.0
|
||||
dev: true
|
||||
|
||||
/threads-plugin@1.4.0(@babel/types@7.22.5)(webpack@5.88.1):
|
||||
resolution: {integrity: sha512-lQENPueZLsD+6Cvxvj/QaQyUskwnFZO+2ZGDMnPIvtytSeywWvYzete8paZ9L+5IR4v8jnSYNZPlIQrEhSK1EA==}
|
||||
|
|
@ -13414,7 +13436,6 @@ packages:
|
|||
typescript: 5.1.6
|
||||
v8-compile-cache-lib: 3.0.1
|
||||
yn: 3.1.1
|
||||
dev: true
|
||||
|
||||
/tslib@1.14.1:
|
||||
resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==}
|
||||
|
|
@ -13538,6 +13559,85 @@ packages:
|
|||
is-typedarray: 1.0.0
|
||||
dev: false
|
||||
|
||||
/typeorm@0.3.17(better-sqlite3@8.5.1)(ts-node@10.9.1):
|
||||
resolution: {integrity: sha512-UDjUEwIQalO9tWw9O2A4GU+sT3oyoUXheHJy4ft+RFdnRdQctdQ34L9SqE2p7LdwzafHx1maxT+bqXON+Qnmig==}
|
||||
engines: {node: '>= 12.9.0'}
|
||||
hasBin: true
|
||||
peerDependencies:
|
||||
'@google-cloud/spanner': ^5.18.0
|
||||
'@sap/hana-client': ^2.12.25
|
||||
better-sqlite3: ^7.1.2 || ^8.0.0
|
||||
hdb-pool: ^0.1.6
|
||||
ioredis: ^5.0.4
|
||||
mongodb: ^5.2.0
|
||||
mssql: ^9.1.1
|
||||
mysql2: ^2.2.5 || ^3.0.1
|
||||
oracledb: ^5.1.0
|
||||
pg: ^8.5.1
|
||||
pg-native: ^3.0.0
|
||||
pg-query-stream: ^4.0.0
|
||||
redis: ^3.1.1 || ^4.0.0
|
||||
sql.js: ^1.4.0
|
||||
sqlite3: ^5.0.3
|
||||
ts-node: ^10.7.0
|
||||
typeorm-aurora-data-api-driver: ^2.0.0
|
||||
peerDependenciesMeta:
|
||||
'@google-cloud/spanner':
|
||||
optional: true
|
||||
'@sap/hana-client':
|
||||
optional: true
|
||||
better-sqlite3:
|
||||
optional: true
|
||||
hdb-pool:
|
||||
optional: true
|
||||
ioredis:
|
||||
optional: true
|
||||
mongodb:
|
||||
optional: true
|
||||
mssql:
|
||||
optional: true
|
||||
mysql2:
|
||||
optional: true
|
||||
oracledb:
|
||||
optional: true
|
||||
pg:
|
||||
optional: true
|
||||
pg-native:
|
||||
optional: true
|
||||
pg-query-stream:
|
||||
optional: true
|
||||
redis:
|
||||
optional: true
|
||||
sql.js:
|
||||
optional: true
|
||||
sqlite3:
|
||||
optional: true
|
||||
ts-node:
|
||||
optional: true
|
||||
typeorm-aurora-data-api-driver:
|
||||
optional: true
|
||||
dependencies:
|
||||
'@sqltools/formatter': 1.2.5
|
||||
app-root-path: 3.1.0
|
||||
better-sqlite3: 8.5.1
|
||||
buffer: 6.0.3
|
||||
chalk: 4.1.2
|
||||
cli-highlight: 2.1.11
|
||||
date-fns: 2.30.0
|
||||
debug: 4.3.4(supports-color@8.1.1)
|
||||
dotenv: 16.3.1
|
||||
glob: 8.1.0
|
||||
mkdirp: 2.1.6
|
||||
reflect-metadata: 0.1.13
|
||||
sha.js: 2.4.11
|
||||
ts-node: 10.9.1(@types/node@20.5.1)(typescript@5.1.6)
|
||||
tslib: 2.6.0
|
||||
uuid: 9.0.0
|
||||
yargs: 17.7.2
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: false
|
||||
|
||||
/typescript-plugin-styled-components@3.0.0(typescript@5.1.6):
|
||||
resolution: {integrity: sha512-QWlhTl6NqsFxtJyxn7pJjm3RhgzXSByUftZ3AoQClrMMpa4yAaHuJKTN1gFpH3Ti+Rwm56fNUfG9pXSBU+WW3A==}
|
||||
peerDependencies:
|
||||
|
|
@ -13564,7 +13664,6 @@ packages:
|
|||
resolution: {integrity: sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA==}
|
||||
engines: {node: '>=14.17'}
|
||||
hasBin: true
|
||||
dev: true
|
||||
|
||||
/typesync@0.11.1:
|
||||
resolution: {integrity: sha512-sMoD2oBqrmUZPX1jAmRd75N07qPG8gTSocfJSfe09otfuoVx4rFNcOreOriUW+hp6Fh01dBuh42yD2NCgZD2dA==}
|
||||
|
|
@ -13759,7 +13858,6 @@ packages:
|
|||
/uuid@9.0.0:
|
||||
resolution: {integrity: sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==}
|
||||
hasBin: true
|
||||
dev: true
|
||||
|
||||
/v8-compile-cache-lib@3.0.1:
|
||||
resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==}
|
||||
|
|
@ -14346,8 +14444,6 @@ packages:
|
|||
resolution: {integrity: sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==}
|
||||
engines: {node: '>=10'}
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/yargs-parser@21.1.1:
|
||||
resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==}
|
||||
|
|
@ -14388,8 +14484,6 @@ packages:
|
|||
string-width: 4.2.3
|
||||
y18n: 5.0.8
|
||||
yargs-parser: 20.2.9
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/yargs@17.7.2:
|
||||
resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==}
|
||||
|
|
@ -14421,7 +14515,6 @@ packages:
|
|||
/yn@3.1.1:
|
||||
resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==}
|
||||
engines: {node: '>=6'}
|
||||
dev: true
|
||||
|
||||
/yocto-queue@0.1.0:
|
||||
resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
|
||||
|
|
|
|||
|
|
@ -147,6 +147,10 @@ export enum MetaDataChannel {
|
|||
name = 'MetaDataChannel',
|
||||
}
|
||||
|
||||
export enum WorkflowChannel {
|
||||
name = 'WorkflowChannel',
|
||||
}
|
||||
|
||||
export type Channels =
|
||||
| MainChannel
|
||||
| AuthenticationChannel
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ import { bindServiceAndProxy } from '@services/libs/bindServiceAndProxy';
|
|||
import serviceIdentifier from '@services/serviceIdentifier';
|
||||
import { WindowNames } from '@services/windows/WindowProperties';
|
||||
|
||||
import { IDatabaseService } from '@services/database/interface';
|
||||
import { reportErrorToGithubWithTemplates } from '@services/native/reportError';
|
||||
import type { IUpdaterService } from '@services/updater/interface';
|
||||
import { IWikiService } from '@services/wiki/interface';
|
||||
|
|
@ -58,6 +59,7 @@ const wikiGitWorkspaceService = container.get<IWikiGitWorkspaceService>(serviceI
|
|||
const wikiService = container.get<IWikiService>(serviceIdentifier.Wiki);
|
||||
const windowService = container.get<IWindowService>(serviceIdentifier.Window);
|
||||
const workspaceViewService = container.get<IWorkspaceViewService>(serviceIdentifier.WorkspaceView);
|
||||
const databaseService = container.get<IDatabaseService>(serviceIdentifier.Database);
|
||||
app.on('second-instance', () => {
|
||||
// Someone tried to run a second instance, we should focus our window.
|
||||
const mainWindow = windowService.get(WindowNames.main);
|
||||
|
|
@ -95,6 +97,7 @@ const commonInit = async (): Promise<void> => {
|
|||
preferenceService.get('attachToMenubar').then(async (attachToMenubar) => {
|
||||
attachToMenubar && await windowService.open(WindowNames.menuBar);
|
||||
}),
|
||||
databaseService.initializeForApp(),
|
||||
]);
|
||||
// perform wiki startup and git sync for each workspace
|
||||
await workspaceViewService.initializeAllWorkspaceView();
|
||||
|
|
|
|||
9
src/services/database/Readme.md
Normal file
9
src/services/database/Readme.md
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
# Database Service
|
||||
|
||||
We have workspace level db, work as cache for tiddlers, and change logs (to record deletion, for sync deletion with mobile clients).
|
||||
|
||||
And we have app level db, to store things for pages like workflow pages. They are also regarded as temporary cache, and user can toggle a switch to store something inside cache to a wiki.
|
||||
|
||||
## App level DB
|
||||
|
||||
`src/services/database/entity` and `src/services/database/migration` are for app level db.
|
||||
14
src/services/database/entity/User.ts
Normal file
14
src/services/database/entity/User.ts
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
import { Column, Entity, OneToMany, PrimaryGeneratedColumn } from 'typeorm';
|
||||
import { WorkflowNetwork } from './WorkflowNetwork';
|
||||
|
||||
@Entity()
|
||||
export class User {
|
||||
@PrimaryGeneratedColumn()
|
||||
id!: number;
|
||||
|
||||
@Column('text')
|
||||
username!: string;
|
||||
|
||||
@OneToMany(() => WorkflowNetwork, workflowNetwork => workflowNetwork.user)
|
||||
workflowNetworks!: WorkflowNetwork[];
|
||||
}
|
||||
26
src/services/database/entity/WorkflowNetwork.ts
Normal file
26
src/services/database/entity/WorkflowNetwork.ts
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
import { Column, Entity, ManyToOne, PrimaryGeneratedColumn } from 'typeorm';
|
||||
import { User } from './User';
|
||||
|
||||
export enum WorkflowRunningState {
|
||||
Idle = 'idle',
|
||||
Running = 'running',
|
||||
Stopped = 'stopped',
|
||||
}
|
||||
|
||||
@Entity()
|
||||
export class WorkflowNetwork {
|
||||
@PrimaryGeneratedColumn()
|
||||
id!: number;
|
||||
|
||||
@Column({
|
||||
type: 'varchar',
|
||||
default: WorkflowRunningState.Idle,
|
||||
})
|
||||
runningState!: WorkflowRunningState;
|
||||
|
||||
@Column('text') // use text for large JSON string
|
||||
serializedState!: string;
|
||||
|
||||
@ManyToOne(() => User, user => user.workflowNetworks)
|
||||
user!: User;
|
||||
}
|
||||
4
src/services/database/entity/index.ts
Normal file
4
src/services/database/entity/index.ts
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
import { User } from './User';
|
||||
import { WorkflowNetwork } from './WorkflowNetwork';
|
||||
|
||||
export const entities = [User, WorkflowNetwork];
|
||||
|
|
@ -11,6 +11,9 @@ import { lazyInject } from '@services/container';
|
|||
import { logger } from '@services/libs/log';
|
||||
import fs from 'fs-extra';
|
||||
import path from 'path';
|
||||
import { DataSource } from 'typeorm';
|
||||
import { entities } from './entity';
|
||||
import { migrations } from './migration';
|
||||
import { loadSqliteVss } from './sqlite-vss';
|
||||
|
||||
@injectable()
|
||||
|
|
@ -23,9 +26,9 @@ export class DatabaseService implements IDatabaseService {
|
|||
// private readonly dbWorker?: ModuleThread<GitWorker>;
|
||||
|
||||
async initializeForWorkspace(workspaceID: string): Promise<void> {
|
||||
const destinationFilePath = this.getDataBasePath(workspaceID);
|
||||
const destinationFilePath = this.getWorkspaceDataBasePath(workspaceID);
|
||||
// only create db file for this workspace's wiki if it doesn't exist
|
||||
if (await fs.exists(this.getDataBasePath(workspaceID))) {
|
||||
if (await fs.exists(this.getWorkspaceDataBasePath(workspaceID))) {
|
||||
logger.debug(`DatabaseService.initializeForWorkspace skip, there already has sqlite database for workspace ${workspaceID} in ${destinationFilePath}`);
|
||||
return;
|
||||
}
|
||||
|
|
@ -74,7 +77,130 @@ export class DatabaseService implements IDatabaseService {
|
|||
}
|
||||
}
|
||||
|
||||
getDataBasePath(workspaceID: string): string {
|
||||
async initializeForApp(): Promise<void> {
|
||||
const destinationFilePath = this.getAppDataBasePath();
|
||||
// only create db file for app if it doesn't exist
|
||||
if (await fs.exists(destinationFilePath)) {
|
||||
logger.debug(`DatabaseService.initializeForApp skip, there already has sqlite database for app in ${destinationFilePath}`);
|
||||
return;
|
||||
}
|
||||
await fs.ensureDir(CACHE_DATABASE_FOLDER);
|
||||
|
||||
try {
|
||||
logger.debug(`DatabaseService.initializeForApp create a sqlite database for app`, { SQLITE_BINARY_PATH });
|
||||
|
||||
// Initialize TypeORM Connection using DataSource
|
||||
const appDataSource = new DataSource({
|
||||
type: 'better-sqlite3',
|
||||
nativeBinding: SQLITE_BINARY_PATH,
|
||||
database: destinationFilePath,
|
||||
entities,
|
||||
synchronize: false,
|
||||
migrationsRun: true,
|
||||
logging: true,
|
||||
migrations,
|
||||
});
|
||||
|
||||
await appDataSource.initialize();
|
||||
await appDataSource.runMigrations();
|
||||
await appDataSource.destroy();
|
||||
logger.info(`DatabaseService.initializeForApp TypeORM connection initialized and migrations ran for app`);
|
||||
} catch (error) {
|
||||
logger.error(`DatabaseService.initializeForApp error when initializing TypeORM connection and running migrations for app: ${(error as Error).message}`);
|
||||
}
|
||||
}
|
||||
|
||||
private readonly dataSources = new Map<string, DataSource>();
|
||||
|
||||
async getAppDatabase(isRetry = false): Promise<DataSource> {
|
||||
const name = 'app-tidgi';
|
||||
if (!this.dataSources.has(name)) {
|
||||
try {
|
||||
const dataSource = new DataSource({
|
||||
type: 'sqlite',
|
||||
database: this.getAppDataBasePath(),
|
||||
entities,
|
||||
synchronize: false,
|
||||
migrationsRun: false,
|
||||
logging: true,
|
||||
migrations,
|
||||
});
|
||||
/**
|
||||
* Error `TypeError: Cannot read property 'transaction' of undefined` will show if run any query without initialize.
|
||||
*/
|
||||
await dataSource.initialize();
|
||||
|
||||
this.dataSources.set(name, dataSource);
|
||||
return dataSource;
|
||||
} catch (error) {
|
||||
console.error(`Failed to getDatabase ${name}: ${(error as Error).message} ${(error as Error).stack ?? ''}`);
|
||||
if (!isRetry) {
|
||||
try {
|
||||
await this.#fixAppDbLock();
|
||||
return await this.getAppDatabase(true);
|
||||
} catch (error) {
|
||||
console.error(`Failed to retry getDatabase ${name}: ${(error as Error).message} ${(error as Error).stack ?? ''}`);
|
||||
}
|
||||
}
|
||||
try {
|
||||
await this.dataSources.get(name)?.destroy();
|
||||
} catch (error) {
|
||||
console.error(`Failed to destroy in getDatabase ${name}: ${(error as Error).message} ${(error as Error).stack ?? ''}`);
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
return this.dataSources.get(name)!;
|
||||
}
|
||||
|
||||
async closeAppDatabase(drop?: boolean) {
|
||||
const name = 'app-tidgi';
|
||||
if (this.dataSources.has(name)) {
|
||||
try {
|
||||
const dataSource = this.dataSources.get(name)!;
|
||||
this.dataSources.delete(name);
|
||||
if (drop === true) {
|
||||
await dataSource.dropDatabase();
|
||||
// need to delete the file. May encounter SQLITE_BUSY error if not deleted.
|
||||
await fs.unlink(this.getAppDataBasePath());
|
||||
} else {
|
||||
await dataSource.destroy();
|
||||
console.log(`closeDatabase ${name}`);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(`Failed to closeDatabase ${name}: ${(error as Error).message} ${(error as Error).stack ?? ''}`);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fix SQLite busy by move the file.
|
||||
* @url https://stackoverflow.com/a/1226850
|
||||
*
|
||||
* Fixes this:
|
||||
*
|
||||
* ```error
|
||||
* [Error: Error getting skinny tiddlers list from SQLite: Call to function 'ExpoSQLite.exec' has been rejected.
|
||||
* → Caused by: android.database.sqlite.SQLiteDatabaseLockedException: database is locked (code 5 SQLITE_BUSY): , while compiling: PRAGMA journal_mode] Error: Error getting skinny tiddlers list from SQLite: Call to function 'ExpoSQLite.exec' has been rejected.
|
||||
* → Caused by: android.database.sqlite.SQLiteDatabaseLockedException: database is locked (code 5 SQLITE_BUSY): , while compiling: PRAGMA journal_mode
|
||||
* ```
|
||||
*/
|
||||
async #fixAppDbLock() {
|
||||
const oldSqlitePath = this.getAppDataBasePath();
|
||||
const temporarySqlitePath = `${oldSqlitePath}.temp`;
|
||||
await fs.copy(oldSqlitePath, temporarySqlitePath);
|
||||
await fs.unlink(oldSqlitePath);
|
||||
await fs.copy(temporarySqlitePath, oldSqlitePath);
|
||||
await fs.unlink(temporarySqlitePath);
|
||||
}
|
||||
|
||||
getWorkspaceDataBasePath(workspaceID: string): string {
|
||||
return path.resolve(CACHE_DATABASE_FOLDER, `${workspaceID}-sqlite3-cache.db`);
|
||||
}
|
||||
|
||||
getAppDataBasePath(): string {
|
||||
return path.resolve(CACHE_DATABASE_FOLDER, `app-tidgi-sqlite3-cache.db`);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,19 @@
|
|||
import { DatabaseChannel } from '@/constants/channels';
|
||||
import { ProxyPropertyType } from 'electron-ipc-cat/common';
|
||||
import { DataSource } from 'typeorm';
|
||||
|
||||
/**
|
||||
* Allow wiki or external app to save/search tiddlers cache from database like sqlite+sqlite-vss (vector storage)
|
||||
*/
|
||||
export interface IDatabaseService {
|
||||
getDataBasePath(workspaceID: string): string;
|
||||
closeAppDatabase(drop?: boolean): void;
|
||||
getAppDataBasePath(): string;
|
||||
/**
|
||||
* Get a database connection for the app db, which is a sqlite manages by TypeORM for all app level data
|
||||
*/
|
||||
getAppDatabase(isRetry?: boolean): Promise<DataSource>;
|
||||
getWorkspaceDataBasePath(workspaceID: string): string;
|
||||
initializeForApp(): Promise<void>;
|
||||
/**
|
||||
* Create a database file for a workspace, store it in the appData folder, and load it in a worker_thread to execute SQL. *
|
||||
* (not store `.db` file in the workspace wiki's folder, because this cache file shouldn't not by Database committed)
|
||||
|
|
@ -15,7 +23,9 @@ export interface IDatabaseService {
|
|||
export const DatabaseServiceIPCDescriptor = {
|
||||
channel: DatabaseChannel.name,
|
||||
properties: {
|
||||
initializeForWorkspace: ProxyPropertyType.Function,
|
||||
getAppDataBasePath: ProxyPropertyType.Function,
|
||||
getDataBasePath: ProxyPropertyType.Function,
|
||||
initializeForApp: ProxyPropertyType.Function,
|
||||
initializeForWorkspace: ProxyPropertyType.Function,
|
||||
},
|
||||
};
|
||||
|
|
|
|||
73
src/services/database/migration/1695276132349-init.ts
Normal file
73
src/services/database/migration/1695276132349-init.ts
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
import { MigrationInterface, QueryRunner, Table, TableForeignKey } from 'typeorm';
|
||||
|
||||
export class Init1695276132349 implements MigrationInterface {
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
// User table
|
||||
await queryRunner.createTable(
|
||||
new Table({
|
||||
name: 'user',
|
||||
columns: [
|
||||
{
|
||||
name: 'id',
|
||||
type: 'integer',
|
||||
isPrimary: true,
|
||||
isGenerated: true,
|
||||
generationStrategy: 'increment',
|
||||
},
|
||||
{
|
||||
name: 'username',
|
||||
type: 'varchar',
|
||||
},
|
||||
],
|
||||
}),
|
||||
true,
|
||||
);
|
||||
|
||||
// WorkflowNetwork table
|
||||
await queryRunner.createTable(
|
||||
new Table({
|
||||
name: 'workflowNetwork',
|
||||
columns: [
|
||||
{
|
||||
name: 'id',
|
||||
type: 'integer',
|
||||
isPrimary: true,
|
||||
isGenerated: true,
|
||||
generationStrategy: 'increment',
|
||||
},
|
||||
{
|
||||
name: 'runningState',
|
||||
type: 'varchar',
|
||||
// SQLite does not natively support the ENUM data type, and it seems like better-sqlite3 also does not support it. Error: Data type \"enum\" in \"WorkflowNetwork.runningState\" is not supported by \"better-sqlite3\" database.",
|
||||
// enum: ['idle', 'running', 'stopped'],
|
||||
default: "'idle'",
|
||||
},
|
||||
{
|
||||
name: 'serializedState',
|
||||
type: 'text',
|
||||
},
|
||||
{
|
||||
name: 'userId',
|
||||
type: 'integer',
|
||||
},
|
||||
],
|
||||
}),
|
||||
true,
|
||||
);
|
||||
|
||||
await queryRunner.createForeignKey(
|
||||
'workflowNetwork',
|
||||
new TableForeignKey({
|
||||
columnNames: ['userId'],
|
||||
referencedColumnNames: ['id'],
|
||||
referencedTableName: 'user',
|
||||
onDelete: 'CASCADE',
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.dropTable('workflowNetwork');
|
||||
await queryRunner.dropTable('user');
|
||||
}
|
||||
}
|
||||
3
src/services/database/migration/index.ts
Normal file
3
src/services/database/migration/index.ts
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
import { Init1695276132349 } from './1695276132349-init';
|
||||
|
||||
export const migrations = [Init1695276132349];
|
||||
|
|
@ -176,7 +176,7 @@ export class Wiki implements IWikiService {
|
|||
|
||||
logger.debug('startWiki calling initCacheDatabase in the main process', { function: 'wikiWorker.initCacheDatabase' });
|
||||
worker.initCacheDatabase({
|
||||
databaseFile: this.databaseService.getDataBasePath(workspaceID),
|
||||
databaseFile: this.databaseService.getWorkspaceDataBasePath(workspaceID),
|
||||
sqliteBinary: SQLITE_BINARY_PATH,
|
||||
packagePathBase: PACKAGE_PATH_BASE,
|
||||
}).subscribe(async (message) => {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue