mirror of
https://github.com/toeverything/AFFiNE.git
synced 2024-11-22 07:52:07 +03:00
feat(native): provide FSWatcher
This commit is contained in:
parent
ee1e50f391
commit
e54a5b6128
4
.gitignore
vendored
4
.gitignore
vendored
@ -66,3 +66,7 @@ i18n-generated.ts
|
||||
# Cache
|
||||
.eslintcache
|
||||
next-env.d.ts
|
||||
|
||||
# Rust
|
||||
target
|
||||
*.node
|
||||
|
9
.taplo.toml
Normal file
9
.taplo.toml
Normal file
@ -0,0 +1,9 @@
|
||||
exclude = ["node_modules/**/*.toml"]
|
||||
|
||||
[[rule]]
|
||||
keys = ["dependencies", "*-dependencies"]
|
||||
|
||||
[rule.formatting]
|
||||
align_entries = true
|
||||
indent_tables = true
|
||||
reorder_keys = true
|
1
.vscode/settings.json
vendored
1
.vscode/settings.json
vendored
@ -26,7 +26,6 @@
|
||||
"[toml]": {
|
||||
"editor.defaultFormatter": "tamasfe.even-better-toml"
|
||||
},
|
||||
"rust-analyzer.linkedProjects": ["packages/octobase-node/Cargo.toml"],
|
||||
"[typescriptreact]": {
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||
},
|
||||
|
756
Cargo.lock
generated
Normal file
756
Cargo.lock
generated
Normal file
@ -0,0 +1,756 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "affine_octobase"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"napi",
|
||||
"napi-build",
|
||||
"napi-derive",
|
||||
"notify",
|
||||
"parking_lot",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"tokio",
|
||||
"uuid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "67fc08ce920c31afb70f013dcce1bfc3a3195de6a228474e45e1f145b36f8d04"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.71"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8"
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "2.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "24a6904aef64d73cf10ab17ebace7befb918b82164785cb89907993be7f83813"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "convert_case"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ec182b0ca2f35d8fc196cf3404988fd8b8c739a4d270ff118a398feb0cbec1ca"
|
||||
dependencies = [
|
||||
"unicode-segmentation",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-channel"
|
||||
version = "0.5.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-utils"
|
||||
version = "0.8.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3c063cd8cc95f5c377ed0d4b49a4b21f632396ff690e8470c29b3359b346984b"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ctor"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dd4056f63fce3b82d852c3da92b08ea59959890813a7f4ce9c0ff85b10cf301b"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"syn 2.0.15",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "filetime"
|
||||
version = "0.2.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5cbc844cecaee9d4443931972e1289c8ff485cb4cc2767cb03ca139ed6885153"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"redox_syscall",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fsevent-sys"
|
||||
version = "4.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "76ee7a02da4d231650c7cea31349b889be2f45ddb3ef3032d2ec8185f6313fd2"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.2.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c85e1d9ab2eadba7e5040d4e09cbd6d072b76a557ad64e797c2cb9d4da21d7e4"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"wasi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.2.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "inotify"
|
||||
version = "0.9.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f8069d3ec154eb856955c1c0fbffefbf5f3c40a104ec912d4797314c1801abff"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"inotify-sys",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "inotify-sys"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e05c02b5e89bff3b946cedeca278abc628fe811e604f027c45a8aa3cf793d0eb"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6"
|
||||
|
||||
[[package]]
|
||||
name = "kqueue"
|
||||
version = "1.0.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2c8fc60ba15bf51257aa9807a48a61013db043fcf3a78cb0d916e8e396dcad98"
|
||||
dependencies = [
|
||||
"kqueue-sys",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "kqueue-sys"
|
||||
version = "1.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8367585489f01bc55dd27404dcf56b95e6da061a256a666ab23be9ba96a2e587"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.144"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2b00cc1c228a6782d0f076e7b232802e0c5689d41bb5df366f2a6b6621cfdfe1"
|
||||
|
||||
[[package]]
|
||||
name = "libloading"
|
||||
version = "0.7.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lock_api"
|
||||
version = "0.4.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"scopeguard",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
|
||||
|
||||
[[package]]
|
||||
name = "mio"
|
||||
version = "0.8.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5b9d9a46eff5b4ff64b45a9e316a6d1e0bc719ef429cbec4dc630684212bfdf9"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"log",
|
||||
"wasi",
|
||||
"windows-sys 0.45.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "napi"
|
||||
version = "2.12.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "49ac8112fe5998579b22e29903c7b277fc7f91c7860c0236f35792caf8156e18"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bitflags 2.2.1",
|
||||
"ctor",
|
||||
"napi-derive",
|
||||
"napi-sys",
|
||||
"once_cell",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "napi-build"
|
||||
version = "2.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "882a73d9ef23e8dc2ebbffb6a6ae2ef467c0f18ac10711e4cc59c5485d41df0e"
|
||||
|
||||
[[package]]
|
||||
name = "napi-derive"
|
||||
version = "2.12.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c47e0f395207c062e680a158f0624ec456c1dfb3c96a8cb888e0401506d50ae9"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"convert_case",
|
||||
"napi-derive-backend",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "napi-derive-backend"
|
||||
version = "1.0.51"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0a83afae5b4ba6f98ed6e33a52da343fdeb66474f1162a38cde5a3d46eb054e7"
|
||||
dependencies = [
|
||||
"convert_case",
|
||||
"once_cell",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"regex",
|
||||
"semver",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "napi-sys"
|
||||
version = "2.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "166b5ef52a3ab5575047a9fe8d4a030cdd0f63c96f071cd6907674453b07bae3"
|
||||
dependencies = [
|
||||
"libloading",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "notify"
|
||||
version = "5.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "58ea850aa68a06e48fdb069c0ec44d0d64c8dbffa49bf3b6f7f0a901fdea1ba9"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"crossbeam-channel",
|
||||
"filetime",
|
||||
"fsevent-sys",
|
||||
"inotify",
|
||||
"kqueue",
|
||||
"libc",
|
||||
"mio",
|
||||
"serde",
|
||||
"walkdir",
|
||||
"windows-sys 0.42.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num_cpus"
|
||||
version = "1.15.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b"
|
||||
dependencies = [
|
||||
"hermit-abi",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.17.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3"
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f"
|
||||
dependencies = [
|
||||
"lock_api",
|
||||
"parking_lot_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot_core"
|
||||
version = "0.9.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9069cbb9f99e3a5083476ccb29ceb1de18b9118cafa53e90c9551235de2b9521"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"redox_syscall",
|
||||
"smallvec",
|
||||
"windows-sys 0.45.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pin-project-lite"
|
||||
version = "0.2.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116"
|
||||
|
||||
[[package]]
|
||||
name = "ppv-lite86"
|
||||
version = "0.2.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.56"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2b63bdb0cd06f1f4dedf69b254734f9b45af66e4a031e42a7480257d9898b435"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f4f29d145265ec1c483c7c654450edde0bfe043d3938d6972630663356d9500"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.8.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"rand_chacha",
|
||||
"rand_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_chacha"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
|
||||
dependencies = [
|
||||
"ppv-lite86",
|
||||
"rand_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.6.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.2.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "af83e617f331cc6ae2da5443c602dfa5af81e517212d9d611a5b3ba1777b5370"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-syntax",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a5996294f19bd3aae0453a862ad728f60e6600695733dd5df01da90c54363a3c"
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041"
|
||||
|
||||
[[package]]
|
||||
name = "same-file"
|
||||
version = "1.0.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
|
||||
dependencies = [
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "scopeguard"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
|
||||
|
||||
[[package]]
|
||||
name = "semver"
|
||||
version = "1.0.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.162"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "71b2f6e1ab5c2b98c05f0f35b236b22e8df7ead6ffbf51d7808da7f8817e7ab6"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.162"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a2a0814352fd64b58489904a44ea8d90cb1a91dcb6b4f5ebabc32c8318e93cb6"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.15",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.96"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "057d394a50403bcac12672b2b18fb387ab6d289d957dab67dd201875391e52f1"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"ryu",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "smallvec"
|
||||
version = "1.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.109"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a34fcf3e8b60f57e6a14301a2e916d323af98b0ea63c599441eec8558660c822"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio"
|
||||
version = "1.28.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c3c786bf8134e5a3a166db9b29ab8f48134739014a3eca7bc6bfa95d673b136f"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num_cpus",
|
||||
"pin-project-lite",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-segmentation"
|
||||
version = "1.10.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36"
|
||||
|
||||
[[package]]
|
||||
name = "uuid"
|
||||
version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4dad5567ad0cf5b760e5665964bec1b47dfd077ba8a2544b513f3556d3d239a2"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
"rand",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "walkdir"
|
||||
version = "2.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "36df944cda56c7d8d8b7496af378e6b16de9284591917d307c9b4d313c44e698"
|
||||
dependencies = [
|
||||
"same-file",
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.11.0+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
||||
dependencies = [
|
||||
"winapi-i686-pc-windows-gnu",
|
||||
"winapi-x86_64-pc-windows-gnu",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-i686-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-util"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.42.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm 0.42.2",
|
||||
"windows_aarch64_msvc 0.42.2",
|
||||
"windows_i686_gnu 0.42.2",
|
||||
"windows_i686_msvc 0.42.2",
|
||||
"windows_x86_64_gnu 0.42.2",
|
||||
"windows_x86_64_gnullvm 0.42.2",
|
||||
"windows_x86_64_msvc 0.42.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.45.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0"
|
||||
dependencies = [
|
||||
"windows-targets 0.42.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.48.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
|
||||
dependencies = [
|
||||
"windows-targets 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.42.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm 0.42.2",
|
||||
"windows_aarch64_msvc 0.42.2",
|
||||
"windows_i686_gnu 0.42.2",
|
||||
"windows_i686_msvc 0.42.2",
|
||||
"windows_x86_64_gnu 0.42.2",
|
||||
"windows_x86_64_gnullvm 0.42.2",
|
||||
"windows_x86_64_msvc 0.42.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.48.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm 0.48.0",
|
||||
"windows_aarch64_msvc 0.48.0",
|
||||
"windows_i686_gnu 0.48.0",
|
||||
"windows_i686_msvc 0.48.0",
|
||||
"windows_x86_64_gnu 0.48.0",
|
||||
"windows_x86_64_gnullvm 0.48.0",
|
||||
"windows_x86_64_msvc 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.42.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.48.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.42.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.48.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.42.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.48.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.42.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.48.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.42.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.48.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.42.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.48.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.42.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.48.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a"
|
2
Cargo.toml
Normal file
2
Cargo.toml
Normal file
@ -0,0 +1,2 @@
|
||||
[workspace]
|
||||
members = ["./packages/native"]
|
@ -1,3 +1,3 @@
|
||||
# Please do not edit this file manually
|
||||
# It should be added in your version-control system (i.e. Git)
|
||||
provider = "postgresql"
|
||||
provider = "postgresql"
|
||||
|
@ -36,7 +36,10 @@
|
||||
},
|
||||
"lint-staged": {
|
||||
"*": "prettier --write --ignore-unknown --cache",
|
||||
"*.{ts,tsx,mjs,js,jsx}": "eslint --cache --fix"
|
||||
"*.{ts,tsx,mjs,js,jsx}": "eslint --cache --fix",
|
||||
"*.toml": [
|
||||
"taplo format"
|
||||
]
|
||||
},
|
||||
"devDependencies": {
|
||||
"@affine-test/kit": "workspace:*",
|
||||
@ -48,6 +51,7 @@
|
||||
"@magic-works/i18n-codegen": "^0.5.0",
|
||||
"@perfsee/sdk": "^1.6.0",
|
||||
"@playwright/test": "^1.33.0",
|
||||
"@taplo/cli": "^0.5.2",
|
||||
"@testing-library/react": "^14.0.0",
|
||||
"@types/eslint": "^8.37.0",
|
||||
"@types/node": "^18.16.7",
|
||||
|
198
packages/native/.gitignore
vendored
198
packages/native/.gitignore
vendored
@ -1,197 +1 @@
|
||||
# Created by https://www.toptal.com/developers/gitignore/api/node
|
||||
# Edit at https://www.toptal.com/developers/gitignore?templates=node
|
||||
|
||||
### Node ###
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
lerna-debug.log*
|
||||
|
||||
# Diagnostic reports (https://nodejs.org/api/report.html)
|
||||
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
|
||||
|
||||
# Runtime data
|
||||
pids
|
||||
*.pid
|
||||
*.seed
|
||||
*.pid.lock
|
||||
|
||||
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||
lib-cov
|
||||
|
||||
# Coverage directory used by tools like istanbul
|
||||
coverage
|
||||
*.lcov
|
||||
|
||||
# nyc test coverage
|
||||
.nyc_output
|
||||
|
||||
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
|
||||
.grunt
|
||||
|
||||
# Bower dependency directory (https://bower.io/)
|
||||
bower_components
|
||||
|
||||
# node-waf configuration
|
||||
.lock-wscript
|
||||
|
||||
# Compiled binary addons (https://nodejs.org/api/addons.html)
|
||||
build/Release
|
||||
|
||||
# Dependency directories
|
||||
node_modules/
|
||||
jspm_packages/
|
||||
|
||||
# TypeScript v1 declaration files
|
||||
typings/
|
||||
|
||||
# TypeScript cache
|
||||
*.tsbuildinfo
|
||||
|
||||
# Optional npm cache directory
|
||||
.npm
|
||||
|
||||
# Optional eslint cache
|
||||
.eslintcache
|
||||
|
||||
# Microbundle cache
|
||||
.rpt2_cache/
|
||||
.rts2_cache_cjs/
|
||||
.rts2_cache_es/
|
||||
.rts2_cache_umd/
|
||||
|
||||
# Optional REPL history
|
||||
.node_repl_history
|
||||
|
||||
# Output of 'npm pack'
|
||||
*.tgz
|
||||
|
||||
# Yarn Integrity file
|
||||
.yarn-integrity
|
||||
|
||||
# dotenv environment variables file
|
||||
.env
|
||||
.env.test
|
||||
|
||||
# parcel-bundler cache (https://parceljs.org/)
|
||||
.cache
|
||||
|
||||
# Next.js build output
|
||||
.next
|
||||
|
||||
# Nuxt.js build / generate output
|
||||
.nuxt
|
||||
dist
|
||||
|
||||
# Gatsby files
|
||||
.cache/
|
||||
# Comment in the public line in if your project uses Gatsby and not Next.js
|
||||
# https://nextjs.org/blog/next-9-1#public-directory-support
|
||||
# public
|
||||
|
||||
# vuepress build output
|
||||
.vuepress/dist
|
||||
|
||||
# Serverless directories
|
||||
.serverless/
|
||||
|
||||
# FuseBox cache
|
||||
.fusebox/
|
||||
|
||||
# DynamoDB Local files
|
||||
.dynamodb/
|
||||
|
||||
# TernJS port file
|
||||
.tern-port
|
||||
|
||||
# Stores VSCode versions used for testing VSCode extensions
|
||||
.vscode-test
|
||||
|
||||
# End of https://www.toptal.com/developers/gitignore/api/node
|
||||
|
||||
# Created by https://www.toptal.com/developers/gitignore/api/macos
|
||||
# Edit at https://www.toptal.com/developers/gitignore?templates=macos
|
||||
|
||||
### macOS ###
|
||||
# General
|
||||
.DS_Store
|
||||
.AppleDouble
|
||||
.LSOverride
|
||||
|
||||
# Icon must end with two
|
||||
Icon
|
||||
|
||||
|
||||
# Thumbnails
|
||||
._*
|
||||
|
||||
# Files that might appear in the root of a volume
|
||||
.DocumentRevisions-V100
|
||||
.fseventsd
|
||||
.Spotlight-V100
|
||||
.TemporaryItems
|
||||
.Trashes
|
||||
.VolumeIcon.icns
|
||||
.com.apple.timemachine.donotpresent
|
||||
|
||||
# Directories potentially created on remote AFP share
|
||||
.AppleDB
|
||||
.AppleDesktop
|
||||
Network Trash Folder
|
||||
Temporary Items
|
||||
.apdisk
|
||||
|
||||
### macOS Patch ###
|
||||
# iCloud generated files
|
||||
*.icloud
|
||||
|
||||
# End of https://www.toptal.com/developers/gitignore/api/macos
|
||||
|
||||
# Created by https://www.toptal.com/developers/gitignore/api/windows
|
||||
# Edit at https://www.toptal.com/developers/gitignore?templates=windows
|
||||
|
||||
### Windows ###
|
||||
# Windows thumbnail cache files
|
||||
Thumbs.db
|
||||
Thumbs.db:encryptable
|
||||
ehthumbs.db
|
||||
ehthumbs_vista.db
|
||||
|
||||
# Dump file
|
||||
*.stackdump
|
||||
|
||||
# Folder config file
|
||||
[Dd]esktop.ini
|
||||
|
||||
# Recycle Bin used on file shares
|
||||
$RECYCLE.BIN/
|
||||
|
||||
# Windows Installer files
|
||||
*.cab
|
||||
*.msi
|
||||
*.msix
|
||||
*.msm
|
||||
*.msp
|
||||
|
||||
# Windows shortcuts
|
||||
*.lnk
|
||||
|
||||
# End of https://www.toptal.com/developers/gitignore/api/windows
|
||||
|
||||
#Added by cargo
|
||||
|
||||
/target
|
||||
Cargo.lock
|
||||
|
||||
.pnp.*
|
||||
.yarn/*
|
||||
!.yarn/patches
|
||||
!.yarn/plugins
|
||||
!.yarn/releases
|
||||
!.yarn/sdks
|
||||
!.yarn/versions
|
||||
|
||||
*.node
|
||||
*.fixture
|
||||
|
@ -7,23 +7,25 @@ version = "0.0.0"
|
||||
crate-type = ["cdylib"]
|
||||
|
||||
[dependencies]
|
||||
anyhow = "1"
|
||||
# Default enable napi4 feature, see https://nodejs.org/api/n-api.html#node-api-version-matrix
|
||||
napi = { version = "2.11.1", default-features = false, features = ["napi4", "tokio_rt"] }
|
||||
napi-derive = "2.11.0"
|
||||
jwst = { git = "https://github.com/toeverything/OctoBase", rev = "b701935", package = "jwst" }
|
||||
jwst-storage = { git = "https://github.com/toeverything/OctoBase", rev = "b701935", package = "jwst-storage", features = [ "sqlite"] }
|
||||
cloud-database = { git = "https://github.com/toeverything/OctoBase", rev = "b701935", package = "cloud-database", features = [ "sqlite"] }
|
||||
jwst-rpc = { git = "https://github.com/toeverything/OctoBase", rev = "b701935", package = "jwst-rpc" }
|
||||
lib0 = "0.16.3"
|
||||
tokio = "1.24.2"
|
||||
yrs = "0.16.3"
|
||||
bytes = "1.3.0"
|
||||
futures = "^0.3.25"
|
||||
napi = { version = "2", default-features = false, features = [
|
||||
"napi4",
|
||||
"tokio_rt",
|
||||
"serde-json",
|
||||
"error_anyhow",
|
||||
] }
|
||||
napi-derive = "2"
|
||||
notify = { version = "5", features = ["serde"] }
|
||||
parking_lot = "0.12"
|
||||
serde = "1"
|
||||
serde_json = "1"
|
||||
tokio = "1"
|
||||
uuid = { version = "1", default-features = false, features = [
|
||||
"serde",
|
||||
"v4",
|
||||
"fast-rng",
|
||||
] }
|
||||
|
||||
[build-dependencies]
|
||||
napi-build = "2.0.1"
|
||||
|
||||
[patch.crates-io]
|
||||
rust-embed = { git = "https://github.com/pyrossh/rust-embed", rev = "7c0fc42" }
|
||||
lib0 = { git = "https://github.com/toeverything/y-crdt", rev = "a3f7263" }
|
||||
yrs = { git = "https://github.com/toeverything/y-crdt", rev = "a3f7263" }
|
||||
napi-build = "2"
|
||||
|
81
packages/native/__tests__/fs.spec.mts
Normal file
81
packages/native/__tests__/fs.spec.mts
Normal file
@ -0,0 +1,81 @@
|
||||
import assert, { doesNotThrow } from 'node:assert';
|
||||
import { promises as fs } from 'node:fs';
|
||||
import { join } from 'node:path';
|
||||
import { test } from 'node:test';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
|
||||
import { lastValueFrom, Subject } from 'rxjs';
|
||||
import { v4 } from 'uuid';
|
||||
|
||||
import type { FSWatcher } from '../index';
|
||||
import { watch } from '../index.js';
|
||||
|
||||
test('fs watch', { concurrency: false }, async t => {
|
||||
let watcher: FSWatcher;
|
||||
let fixture: string;
|
||||
t.beforeEach(async () => {
|
||||
const fixtureName = `fs-${v4()}.fixture`;
|
||||
fixture = join(fileURLToPath(import.meta.url), '..', fixtureName);
|
||||
await fs.writeFile(fixture, '\n');
|
||||
watcher = watch(fixture);
|
||||
});
|
||||
|
||||
t.afterEach(async () => {
|
||||
watcher.close();
|
||||
await fs.unlink(fixture).catch(() => false);
|
||||
});
|
||||
|
||||
await t.test('should watch without error', () => {
|
||||
doesNotThrow(() => {
|
||||
const subscription = watcher.subscribe(() => {});
|
||||
subscription.unsubscribe();
|
||||
});
|
||||
});
|
||||
|
||||
await t.test('should watch file change', () => {
|
||||
return (async () => {
|
||||
const defer = new Subject<void>();
|
||||
const subscription = watcher.subscribe(
|
||||
event => {
|
||||
assert.deepEqual(event.paths, [fixture]);
|
||||
subscription.unsubscribe();
|
||||
defer.next();
|
||||
defer.complete();
|
||||
},
|
||||
err => {
|
||||
subscription.unsubscribe();
|
||||
defer.error(err);
|
||||
}
|
||||
);
|
||||
await fs.appendFile(fixture, 'test');
|
||||
return lastValueFrom(defer.asObservable());
|
||||
})();
|
||||
});
|
||||
|
||||
await t.test('should watch file delete', () => {
|
||||
return (async () => {
|
||||
const defer = new Subject<void>();
|
||||
const subscription = watcher.subscribe(
|
||||
event => {
|
||||
if (event.type.remove) {
|
||||
assert.deepEqual(event.paths, [fixture]);
|
||||
assert.deepEqual(event.type, {
|
||||
remove: {
|
||||
kind: 'file',
|
||||
},
|
||||
});
|
||||
}
|
||||
subscription.unsubscribe();
|
||||
defer.next();
|
||||
defer.complete();
|
||||
},
|
||||
err => {
|
||||
subscription.unsubscribe();
|
||||
defer.error(err);
|
||||
}
|
||||
);
|
||||
await fs.unlink(fixture);
|
||||
return lastValueFrom(defer.asObservable());
|
||||
})();
|
||||
});
|
||||
});
|
@ -1,5 +1,6 @@
|
||||
extern crate napi_build;
|
||||
|
||||
fn main() {
|
||||
fn main() -> Result<(), std::io::Error> {
|
||||
napi_build::setup();
|
||||
Ok(())
|
||||
}
|
||||
|
50
packages/native/index.d.ts
vendored
50
packages/native/index.d.ts
vendored
@ -3,18 +3,42 @@
|
||||
|
||||
/* auto-generated by NAPI-RS */
|
||||
|
||||
export class Storage {
|
||||
constructor(path: string);
|
||||
error(): string | null;
|
||||
getBlob(workspaceId: string | undefined | null, id: string): Promise<Buffer>;
|
||||
connect(workspaceId: string, remote: string): Workspace | null;
|
||||
sync(workspaceId: string, remote: string): Workspace;
|
||||
export interface WatchOptions {
|
||||
recursive?: boolean;
|
||||
}
|
||||
export class Workspace {
|
||||
constructor(id: string);
|
||||
id(): string;
|
||||
clientId(): number;
|
||||
search(query: string): string;
|
||||
getSearchIndex(): Array<string>;
|
||||
setSearchIndex(fields: Array<string>): boolean;
|
||||
/** Watcher kind enumeration */
|
||||
export const enum WatcherKind {
|
||||
/** inotify backend (linux) */
|
||||
Inotify = 'Inotify',
|
||||
/** FS-Event backend (mac) */
|
||||
Fsevent = 'Fsevent',
|
||||
/** KQueue backend (bsd,optionally mac) */
|
||||
Kqueue = 'Kqueue',
|
||||
/** Polling based backend (fallback) */
|
||||
PollWatcher = 'PollWatcher',
|
||||
/** Windows backend */
|
||||
ReadDirectoryChangesWatcher = 'ReadDirectoryChangesWatcher',
|
||||
/** Fake watcher for testing */
|
||||
NullWatcher = 'NullWatcher',
|
||||
Unknown = 'Unknown',
|
||||
}
|
||||
export function watch(
|
||||
p: string,
|
||||
options?: WatchOptions | undefined | null
|
||||
): FSWatcher;
|
||||
export class Subscription {
|
||||
unsubscribe(): void;
|
||||
}
|
||||
export type FSWatcher = FsWatcher;
|
||||
export class FsWatcher {
|
||||
get kind(): WatcherKind;
|
||||
toString(): string;
|
||||
subscribe(
|
||||
callback: (value: any) => any,
|
||||
errorCallback?: (
|
||||
err: Error | null,
|
||||
value: undefined
|
||||
) => any | undefined | null
|
||||
): Subscription;
|
||||
close(): void;
|
||||
}
|
||||
|
@ -36,13 +36,13 @@ switch (platform) {
|
||||
switch (arch) {
|
||||
case 'arm64':
|
||||
localFileExisted = existsSync(
|
||||
join(__dirname, 'octobase.android-arm64.node')
|
||||
join(__dirname, 'affine.android-arm64.node')
|
||||
);
|
||||
try {
|
||||
if (localFileExisted) {
|
||||
nativeBinding = require('./octobase.android-arm64.node');
|
||||
nativeBinding = require('./affine.android-arm64.node');
|
||||
} else {
|
||||
nativeBinding = require('@affine/octobase-node-android-arm64');
|
||||
nativeBinding = require('@affine/native-android-arm64');
|
||||
}
|
||||
} catch (e) {
|
||||
loadError = e;
|
||||
@ -50,13 +50,13 @@ switch (platform) {
|
||||
break;
|
||||
case 'arm':
|
||||
localFileExisted = existsSync(
|
||||
join(__dirname, 'octobase.android-arm-eabi.node')
|
||||
join(__dirname, 'affine.android-arm-eabi.node')
|
||||
);
|
||||
try {
|
||||
if (localFileExisted) {
|
||||
nativeBinding = require('./octobase.android-arm-eabi.node');
|
||||
nativeBinding = require('./affine.android-arm-eabi.node');
|
||||
} else {
|
||||
nativeBinding = require('@affine/octobase-node-android-arm-eabi');
|
||||
nativeBinding = require('@affine/native-android-arm-eabi');
|
||||
}
|
||||
} catch (e) {
|
||||
loadError = e;
|
||||
@ -70,13 +70,13 @@ switch (platform) {
|
||||
switch (arch) {
|
||||
case 'x64':
|
||||
localFileExisted = existsSync(
|
||||
join(__dirname, 'octobase.win32-x64-msvc.node')
|
||||
join(__dirname, 'affine.win32-x64-msvc.node')
|
||||
);
|
||||
try {
|
||||
if (localFileExisted) {
|
||||
nativeBinding = require('./octobase.win32-x64-msvc.node');
|
||||
nativeBinding = require('./affine.win32-x64-msvc.node');
|
||||
} else {
|
||||
nativeBinding = require('@affine/octobase-node-win32-x64-msvc');
|
||||
nativeBinding = require('@affine/native-win32-x64-msvc');
|
||||
}
|
||||
} catch (e) {
|
||||
loadError = e;
|
||||
@ -84,13 +84,13 @@ switch (platform) {
|
||||
break;
|
||||
case 'ia32':
|
||||
localFileExisted = existsSync(
|
||||
join(__dirname, 'octobase.win32-ia32-msvc.node')
|
||||
join(__dirname, 'affine.win32-ia32-msvc.node')
|
||||
);
|
||||
try {
|
||||
if (localFileExisted) {
|
||||
nativeBinding = require('./octobase.win32-ia32-msvc.node');
|
||||
nativeBinding = require('./affine.win32-ia32-msvc.node');
|
||||
} else {
|
||||
nativeBinding = require('@affine/octobase-node-win32-ia32-msvc');
|
||||
nativeBinding = require('@affine/native-win32-ia32-msvc');
|
||||
}
|
||||
} catch (e) {
|
||||
loadError = e;
|
||||
@ -98,13 +98,13 @@ switch (platform) {
|
||||
break;
|
||||
case 'arm64':
|
||||
localFileExisted = existsSync(
|
||||
join(__dirname, 'octobase.win32-arm64-msvc.node')
|
||||
join(__dirname, 'affine.win32-arm64-msvc.node')
|
||||
);
|
||||
try {
|
||||
if (localFileExisted) {
|
||||
nativeBinding = require('./octobase.win32-arm64-msvc.node');
|
||||
nativeBinding = require('./affine.win32-arm64-msvc.node');
|
||||
} else {
|
||||
nativeBinding = require('@affine/octobase-node-win32-arm64-msvc');
|
||||
nativeBinding = require('@affine/native-win32-arm64-msvc');
|
||||
}
|
||||
} catch (e) {
|
||||
loadError = e;
|
||||
@ -116,26 +116,26 @@ switch (platform) {
|
||||
break;
|
||||
case 'darwin':
|
||||
localFileExisted = existsSync(
|
||||
join(__dirname, 'octobase.darwin-universal.node')
|
||||
join(__dirname, 'affine.darwin-universal.node')
|
||||
);
|
||||
try {
|
||||
if (localFileExisted) {
|
||||
nativeBinding = require('./octobase.darwin-universal.node');
|
||||
nativeBinding = require('./affine.darwin-universal.node');
|
||||
} else {
|
||||
nativeBinding = require('@affine/octobase-node-darwin-universal');
|
||||
nativeBinding = require('@affine/native-darwin-universal');
|
||||
}
|
||||
break;
|
||||
} catch {}
|
||||
switch (arch) {
|
||||
case 'x64':
|
||||
localFileExisted = existsSync(
|
||||
join(__dirname, 'octobase.darwin-x64.node')
|
||||
join(__dirname, 'affine.darwin-x64.node')
|
||||
);
|
||||
try {
|
||||
if (localFileExisted) {
|
||||
nativeBinding = require('./octobase.darwin-x64.node');
|
||||
nativeBinding = require('./affine.darwin-x64.node');
|
||||
} else {
|
||||
nativeBinding = require('@affine/octobase-node-darwin-x64');
|
||||
nativeBinding = require('@affine/native-darwin-x64');
|
||||
}
|
||||
} catch (e) {
|
||||
loadError = e;
|
||||
@ -143,13 +143,13 @@ switch (platform) {
|
||||
break;
|
||||
case 'arm64':
|
||||
localFileExisted = existsSync(
|
||||
join(__dirname, 'octobase.darwin-arm64.node')
|
||||
join(__dirname, 'affine.darwin-arm64.node')
|
||||
);
|
||||
try {
|
||||
if (localFileExisted) {
|
||||
nativeBinding = require('./octobase.darwin-arm64.node');
|
||||
nativeBinding = require('./affine.darwin-arm64.node');
|
||||
} else {
|
||||
nativeBinding = require('@affine/octobase-node-darwin-arm64');
|
||||
nativeBinding = require('@affine/native-darwin-arm64');
|
||||
}
|
||||
} catch (e) {
|
||||
loadError = e;
|
||||
@ -163,12 +163,12 @@ switch (platform) {
|
||||
if (arch !== 'x64') {
|
||||
throw new Error(`Unsupported architecture on FreeBSD: ${arch}`);
|
||||
}
|
||||
localFileExisted = existsSync(join(__dirname, 'octobase.freebsd-x64.node'));
|
||||
localFileExisted = existsSync(join(__dirname, 'affine.freebsd-x64.node'));
|
||||
try {
|
||||
if (localFileExisted) {
|
||||
nativeBinding = require('./octobase.freebsd-x64.node');
|
||||
nativeBinding = require('./affine.freebsd-x64.node');
|
||||
} else {
|
||||
nativeBinding = require('@affine/octobase-node-freebsd-x64');
|
||||
nativeBinding = require('@affine/native-freebsd-x64');
|
||||
}
|
||||
} catch (e) {
|
||||
loadError = e;
|
||||
@ -179,26 +179,26 @@ switch (platform) {
|
||||
case 'x64':
|
||||
if (isMusl()) {
|
||||
localFileExisted = existsSync(
|
||||
join(__dirname, 'octobase.linux-x64-musl.node')
|
||||
join(__dirname, 'affine.linux-x64-musl.node')
|
||||
);
|
||||
try {
|
||||
if (localFileExisted) {
|
||||
nativeBinding = require('./octobase.linux-x64-musl.node');
|
||||
nativeBinding = require('./affine.linux-x64-musl.node');
|
||||
} else {
|
||||
nativeBinding = require('@affine/octobase-node-linux-x64-musl');
|
||||
nativeBinding = require('@affine/native-linux-x64-musl');
|
||||
}
|
||||
} catch (e) {
|
||||
loadError = e;
|
||||
}
|
||||
} else {
|
||||
localFileExisted = existsSync(
|
||||
join(__dirname, 'octobase.linux-x64-gnu.node')
|
||||
join(__dirname, 'affine.linux-x64-gnu.node')
|
||||
);
|
||||
try {
|
||||
if (localFileExisted) {
|
||||
nativeBinding = require('./octobase.linux-x64-gnu.node');
|
||||
nativeBinding = require('./affine.linux-x64-gnu.node');
|
||||
} else {
|
||||
nativeBinding = require('@affine/octobase-node-linux-x64-gnu');
|
||||
nativeBinding = require('@affine/native-linux-x64-gnu');
|
||||
}
|
||||
} catch (e) {
|
||||
loadError = e;
|
||||
@ -208,26 +208,26 @@ switch (platform) {
|
||||
case 'arm64':
|
||||
if (isMusl()) {
|
||||
localFileExisted = existsSync(
|
||||
join(__dirname, 'octobase.linux-arm64-musl.node')
|
||||
join(__dirname, 'affine.linux-arm64-musl.node')
|
||||
);
|
||||
try {
|
||||
if (localFileExisted) {
|
||||
nativeBinding = require('./octobase.linux-arm64-musl.node');
|
||||
nativeBinding = require('./affine.linux-arm64-musl.node');
|
||||
} else {
|
||||
nativeBinding = require('@affine/octobase-node-linux-arm64-musl');
|
||||
nativeBinding = require('@affine/native-linux-arm64-musl');
|
||||
}
|
||||
} catch (e) {
|
||||
loadError = e;
|
||||
}
|
||||
} else {
|
||||
localFileExisted = existsSync(
|
||||
join(__dirname, 'octobase.linux-arm64-gnu.node')
|
||||
join(__dirname, 'affine.linux-arm64-gnu.node')
|
||||
);
|
||||
try {
|
||||
if (localFileExisted) {
|
||||
nativeBinding = require('./octobase.linux-arm64-gnu.node');
|
||||
nativeBinding = require('./affine.linux-arm64-gnu.node');
|
||||
} else {
|
||||
nativeBinding = require('@affine/octobase-node-linux-arm64-gnu');
|
||||
nativeBinding = require('@affine/native-linux-arm64-gnu');
|
||||
}
|
||||
} catch (e) {
|
||||
loadError = e;
|
||||
@ -236,13 +236,13 @@ switch (platform) {
|
||||
break;
|
||||
case 'arm':
|
||||
localFileExisted = existsSync(
|
||||
join(__dirname, 'octobase.linux-arm-gnueabihf.node')
|
||||
join(__dirname, 'affine.linux-arm-gnueabihf.node')
|
||||
);
|
||||
try {
|
||||
if (localFileExisted) {
|
||||
nativeBinding = require('./octobase.linux-arm-gnueabihf.node');
|
||||
nativeBinding = require('./affine.linux-arm-gnueabihf.node');
|
||||
} else {
|
||||
nativeBinding = require('@affine/octobase-node-linux-arm-gnueabihf');
|
||||
nativeBinding = require('@affine/native-linux-arm-gnueabihf');
|
||||
}
|
||||
} catch (e) {
|
||||
loadError = e;
|
||||
@ -263,7 +263,9 @@ if (!nativeBinding) {
|
||||
throw new Error(`Failed to load native binding`);
|
||||
}
|
||||
|
||||
const { Storage, Workspace } = nativeBinding;
|
||||
const { WatcherKind, Subscription, watch, FsWatcher } = nativeBinding;
|
||||
|
||||
module.exports.Storage = Storage;
|
||||
module.exports.Workspace = Workspace;
|
||||
module.exports.WatcherKind = WatcherKind;
|
||||
module.exports.Subscription = Subscription;
|
||||
module.exports.watch = watch;
|
||||
module.exports.FsWatcher = FsWatcher;
|
||||
|
@ -1,20 +1,28 @@
|
||||
{
|
||||
"name": "@affine/octobase-node",
|
||||
"name": "@affine/native",
|
||||
"private": true,
|
||||
"main": "index.js",
|
||||
"types": "index.d.ts",
|
||||
"napi": {
|
||||
"name": "octobase",
|
||||
"name": "affine",
|
||||
"triples": {
|
||||
"additional": [
|
||||
"aarch64-apple-darwin"
|
||||
"aarch64-apple-darwin",
|
||||
"aarch64-unknown-linux-gnu",
|
||||
"aarch64-pc-windows-msvc"
|
||||
]
|
||||
}
|
||||
},
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"@napi-rs/cli": "^2.15.2",
|
||||
"@types/node": "^18.16.7"
|
||||
"@types/node": "^18.16.7",
|
||||
"@types/uuid": "^9.0.1",
|
||||
"cross-env": "^7.0.3",
|
||||
"rxjs": "^7.8.1",
|
||||
"ts-node": "^10.9.1",
|
||||
"typescript": "^5.0.4",
|
||||
"uuid": "^9.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
@ -24,6 +32,7 @@
|
||||
"build": "napi build --platform --release",
|
||||
"build:debug": "napi build --platform",
|
||||
"universal": "napi universal",
|
||||
"test": "cross-env TS_NODE_PROJECT=./tsconfig.json node --test --loader ts-node/esm --experimental-specifier-resolution=node ./__tests__/**/*.mts",
|
||||
"version": "napi version"
|
||||
},
|
||||
"version": "0.6.0-canary.0"
|
||||
|
@ -1,216 +0,0 @@
|
||||
use super::DynamicValue;
|
||||
use jwst::{Block as JwstBlock, Workspace};
|
||||
use lib0::any::Any;
|
||||
|
||||
#[napi()]
|
||||
pub struct Block {
|
||||
pub workspace: Workspace,
|
||||
pub block: JwstBlock,
|
||||
}
|
||||
|
||||
#[napi()]
|
||||
impl Block {
|
||||
#[napi(constructor)]
|
||||
pub fn new(workspace: Workspace, block: JwstBlock) -> Self {
|
||||
Self { workspace, block }
|
||||
}
|
||||
|
||||
#[napi]
|
||||
pub fn get(&self, key: String) -> Option<DynamicValue> {
|
||||
self.workspace
|
||||
.with_trx(|trx| self.block.get(&trx.trx, &key).map(DynamicValue::new))
|
||||
}
|
||||
|
||||
#[napi]
|
||||
pub fn children(&self) -> Vec<String> {
|
||||
self.workspace.with_trx(|trx| self.block.children(&trx.trx))
|
||||
}
|
||||
|
||||
#[napi]
|
||||
pub fn push_children(&self, block: &Block) {
|
||||
self.workspace
|
||||
.with_trx(|mut trx| self.block.push_children(&mut trx.trx, &block.block));
|
||||
}
|
||||
|
||||
#[napi]
|
||||
pub fn insert_children_at(&self, block: &Block, pos: u32) {
|
||||
self.workspace.with_trx(|mut trx| {
|
||||
self.block
|
||||
.insert_children_at(&mut trx.trx, &block.block, pos)
|
||||
});
|
||||
}
|
||||
|
||||
#[napi]
|
||||
pub fn insert_children_before(&self, block: &Block, reference: &str) {
|
||||
self.workspace.with_trx(|mut trx| {
|
||||
self.block
|
||||
.insert_children_before(&mut trx.trx, &block.block, reference)
|
||||
});
|
||||
}
|
||||
|
||||
#[napi]
|
||||
pub fn insert_children_after(&self, block: &Block, reference: &str) {
|
||||
self.workspace.with_trx(|mut trx| {
|
||||
self.block
|
||||
.insert_children_after(&mut trx.trx, &block.block, reference)
|
||||
});
|
||||
}
|
||||
|
||||
#[napi]
|
||||
pub fn remove_children(&self, block: &Block) {
|
||||
self.workspace
|
||||
.with_trx(|mut trx| self.block.remove_children(&mut trx.trx, &block.block));
|
||||
}
|
||||
|
||||
#[napi]
|
||||
pub fn exists_children(&self, block_id: &str) -> i32 {
|
||||
self.workspace
|
||||
.with_trx(|trx| self.block.exists_children(&trx.trx, block_id))
|
||||
.map(|i| i as i32)
|
||||
.unwrap_or(-1)
|
||||
}
|
||||
|
||||
#[napi]
|
||||
pub fn parent(&self) -> String {
|
||||
self.workspace
|
||||
.with_trx(|trx| self.block.parent(&trx.trx).unwrap())
|
||||
}
|
||||
|
||||
#[napi]
|
||||
pub fn updated(&self) -> u64 {
|
||||
self.workspace.with_trx(|trx| self.block.updated(&trx.trx))
|
||||
}
|
||||
|
||||
#[napi]
|
||||
pub fn id(&self) -> String {
|
||||
self.block.block_id()
|
||||
}
|
||||
|
||||
#[napi]
|
||||
pub fn flavor(&self) -> String {
|
||||
self.workspace.with_trx(|trx| self.block.flavor(&trx.trx))
|
||||
}
|
||||
|
||||
#[napi]
|
||||
pub fn version(&self) -> String {
|
||||
self.workspace.with_trx(|trx| {
|
||||
let [major, minor] = self.block.version(&trx.trx);
|
||||
format!("{major}.{minor}")
|
||||
})
|
||||
}
|
||||
|
||||
#[napi]
|
||||
pub fn created(&self) -> u64 {
|
||||
self.workspace.with_trx(|trx| self.block.created(&trx.trx))
|
||||
}
|
||||
|
||||
#[napi]
|
||||
pub fn set_bool(&self, key: String, value: bool) {
|
||||
self.workspace
|
||||
.with_trx(|mut trx| self.block.set(&mut trx.trx, &key, value));
|
||||
}
|
||||
|
||||
#[napi]
|
||||
pub fn set_string(&self, key: String, value: String) {
|
||||
self.workspace
|
||||
.with_trx(|mut trx| self.block.set(&mut trx.trx, &key, value));
|
||||
}
|
||||
|
||||
#[napi]
|
||||
pub fn set_float(&self, key: String, value: f64) {
|
||||
self.workspace
|
||||
.with_trx(|mut trx| self.block.set(&mut trx.trx, &key, value));
|
||||
}
|
||||
|
||||
#[napi]
|
||||
pub fn set_integer(&self, key: String, value: i64) {
|
||||
self.workspace
|
||||
.with_trx(|mut trx| self.block.set(&mut trx.trx, &key, value));
|
||||
}
|
||||
|
||||
#[napi]
|
||||
pub fn set_null(&self, key: String) {
|
||||
self.workspace
|
||||
.with_trx(|mut trx| self.block.set(&mut trx.trx, &key, Any::Null));
|
||||
}
|
||||
|
||||
#[napi]
|
||||
pub fn is_bool(&self, key: String) -> bool {
|
||||
self.workspace.with_trx(|trx| {
|
||||
self.block
|
||||
.get(&trx.trx, &key)
|
||||
.map(|a| matches!(a, Any::Bool(_)))
|
||||
.unwrap_or(false)
|
||||
})
|
||||
}
|
||||
|
||||
#[napi]
|
||||
pub fn is_string(&self, key: String) -> bool {
|
||||
self.workspace.with_trx(|trx| {
|
||||
self.block
|
||||
.get(&trx.trx, &key)
|
||||
.map(|a| matches!(a, Any::String(_)))
|
||||
.unwrap_or(false)
|
||||
})
|
||||
}
|
||||
|
||||
#[napi]
|
||||
pub fn is_float(&self, key: String) -> bool {
|
||||
self.workspace.with_trx(|trx| {
|
||||
self.block
|
||||
.get(&trx.trx, &key)
|
||||
.map(|a| matches!(a, Any::Number(_)))
|
||||
.unwrap_or(false)
|
||||
})
|
||||
}
|
||||
|
||||
#[napi]
|
||||
pub fn is_integer(&self, key: String) -> bool {
|
||||
self.workspace.with_trx(|trx| {
|
||||
self.block
|
||||
.get(&trx.trx, &key)
|
||||
.map(|a| matches!(a, Any::BigInt(_)))
|
||||
.unwrap_or(false)
|
||||
})
|
||||
}
|
||||
|
||||
#[napi]
|
||||
pub fn get_bool(&self, key: String) -> Option<i64> {
|
||||
self.workspace.with_trx(|trx| {
|
||||
self.block.get(&trx.trx, &key).and_then(|a| match a {
|
||||
Any::Bool(i) => Some(i.into()),
|
||||
_ => None,
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
#[napi]
|
||||
pub fn get_string(&self, key: String) -> Option<String> {
|
||||
self.workspace.with_trx(|trx| {
|
||||
self.block.get(&trx.trx, &key).and_then(|a| match a {
|
||||
Any::String(i) => Some(i.into()),
|
||||
_ => None,
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
#[napi]
|
||||
pub fn get_float(&self, key: String) -> Option<f64> {
|
||||
self.workspace.with_trx(|trx| {
|
||||
self.block.get(&trx.trx, &key).and_then(|a| match a {
|
||||
Any::Number(i) => Some(i),
|
||||
_ => None,
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
#[napi]
|
||||
pub fn get_integer(&self, key: String) -> Option<i64> {
|
||||
self.workspace.with_trx(|trx| {
|
||||
self.block.get(&trx.trx, &key).and_then(|a| match a {
|
||||
Any::BigInt(i) => Some(i),
|
||||
_ => None,
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
@ -1,68 +0,0 @@
|
||||
use lib0::any::Any;
|
||||
use std::collections::HashMap;
|
||||
|
||||
pub type DynamicValueMap = HashMap<String, DynamicValue>;
|
||||
|
||||
pub struct DynamicValue {
|
||||
any: Any,
|
||||
}
|
||||
|
||||
impl DynamicValue {
|
||||
pub fn new(any: Any) -> Self {
|
||||
Self { any }
|
||||
}
|
||||
|
||||
pub fn as_bool(&self) -> Option<bool> {
|
||||
match self.any {
|
||||
Any::Bool(value) => Some(value),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_number(&self) -> Option<f64> {
|
||||
match self.any {
|
||||
Any::Number(value) => Some(value),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_int(&self) -> Option<i64> {
|
||||
match self.any {
|
||||
Any::BigInt(value) => Some(value),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_string(&self) -> Option<String> {
|
||||
match &self.any {
|
||||
Any::String(value) => Some(value.to_string()),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_buffer(&self) -> Option<Vec<u8>> {
|
||||
match &self.any {
|
||||
Any::Buffer(value) => Some(value.to_vec()),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_array(&self) -> Option<Vec<DynamicValue>> {
|
||||
match &self.any {
|
||||
Any::Array(value) => Some(value.iter().map(|a| DynamicValue::new(a.clone())).collect()),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_map(&self) -> Option<HashMap<String, DynamicValue>> {
|
||||
match &self.any {
|
||||
Any::Map(value) => Some(
|
||||
value
|
||||
.iter()
|
||||
.map(|(key, value)| (key.clone(), DynamicValue::new(value.clone())))
|
||||
.collect(),
|
||||
),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
189
packages/native/src/fs.rs
Normal file
189
packages/native/src/fs.rs
Normal file
@ -0,0 +1,189 @@
|
||||
use std::{collections::HashMap, path::Path, sync::Arc};
|
||||
|
||||
use napi::{
|
||||
bindgen_prelude::{FromNapiValue, ToNapiValue},
|
||||
threadsafe_function::{ErrorStrategy, ThreadsafeFunction, ThreadsafeFunctionCallMode},
|
||||
};
|
||||
use napi_derive::napi;
|
||||
use notify::{Event, RecommendedWatcher, RecursiveMode, Watcher};
|
||||
use parking_lot::Mutex;
|
||||
|
||||
#[napi(object)]
|
||||
#[derive(Default)]
|
||||
pub struct WatchOptions {
|
||||
pub recursive: Option<bool>,
|
||||
}
|
||||
|
||||
#[napi(string_enum)]
|
||||
/// Watcher kind enumeration
|
||||
pub enum WatcherKind {
|
||||
/// inotify backend (linux)
|
||||
Inotify,
|
||||
/// FS-Event backend (mac)
|
||||
Fsevent,
|
||||
/// KQueue backend (bsd,optionally mac)
|
||||
Kqueue,
|
||||
/// Polling based backend (fallback)
|
||||
PollWatcher,
|
||||
/// Windows backend
|
||||
ReadDirectoryChangesWatcher,
|
||||
/// Fake watcher for testing
|
||||
NullWatcher,
|
||||
Unknown,
|
||||
}
|
||||
|
||||
impl From<notify::WatcherKind> for WatcherKind {
|
||||
fn from(value: notify::WatcherKind) -> Self {
|
||||
match value {
|
||||
notify::WatcherKind::Inotify => WatcherKind::Inotify,
|
||||
notify::WatcherKind::Fsevent => WatcherKind::Fsevent,
|
||||
notify::WatcherKind::Kqueue => WatcherKind::Kqueue,
|
||||
notify::WatcherKind::PollWatcher => WatcherKind::PollWatcher,
|
||||
notify::WatcherKind::ReadDirectoryChangesWatcher => WatcherKind::ReadDirectoryChangesWatcher,
|
||||
notify::WatcherKind::NullWatcher => WatcherKind::NullWatcher,
|
||||
_ => WatcherKind::Unknown,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[napi]
|
||||
pub struct Subscription {
|
||||
id: uuid::Uuid,
|
||||
error_uuid: Option<uuid::Uuid>,
|
||||
event_emitter: Arc<Mutex<EventEmitter>>,
|
||||
}
|
||||
|
||||
#[napi]
|
||||
impl Subscription {
|
||||
#[napi]
|
||||
#[allow(clippy::inherent_to_string)]
|
||||
pub fn to_string(&self) -> String {
|
||||
self.id.to_string()
|
||||
}
|
||||
|
||||
#[napi]
|
||||
pub fn unsubscribe(&mut self) {
|
||||
let mut event_emitter = self.event_emitter.lock();
|
||||
event_emitter.listeners.remove(&self.id);
|
||||
if let Some(error_uuid) = &self.error_uuid {
|
||||
event_emitter.error_callbacks.remove(error_uuid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[napi]
|
||||
pub fn watch(p: String, options: Option<WatchOptions>) -> Result<FSWatcher, anyhow::Error> {
|
||||
let event_emitter = Arc::new(Mutex::new(EventEmitter {
|
||||
listeners: Default::default(),
|
||||
error_callbacks: Default::default(),
|
||||
}));
|
||||
let event_emitter_in_handler = event_emitter.clone();
|
||||
let mut watcher: RecommendedWatcher =
|
||||
notify::recommended_watcher(move |res: notify::Result<Event>| {
|
||||
event_emitter_in_handler.lock().on(res);
|
||||
})
|
||||
.map_err(anyhow::Error::from)?;
|
||||
|
||||
let options = options.unwrap_or_default();
|
||||
watcher
|
||||
.watch(
|
||||
Path::new(&p),
|
||||
if options.recursive == Some(false) {
|
||||
RecursiveMode::NonRecursive
|
||||
} else {
|
||||
RecursiveMode::Recursive
|
||||
},
|
||||
)
|
||||
.map_err(anyhow::Error::from)?;
|
||||
Ok(FSWatcher {
|
||||
inner: watcher,
|
||||
event_emitter,
|
||||
})
|
||||
}
|
||||
|
||||
#[napi]
|
||||
pub struct FSWatcher {
|
||||
inner: RecommendedWatcher,
|
||||
event_emitter: Arc<Mutex<EventEmitter>>,
|
||||
}
|
||||
|
||||
#[napi]
|
||||
impl FSWatcher {
|
||||
#[napi(getter)]
|
||||
pub fn kind(&self) -> WatcherKind {
|
||||
RecommendedWatcher::kind().into()
|
||||
}
|
||||
|
||||
#[napi]
|
||||
pub fn to_string(&self) -> napi::Result<String> {
|
||||
Ok(format!("{:?}", self.inner))
|
||||
}
|
||||
|
||||
#[napi]
|
||||
pub fn subscribe(
|
||||
&mut self,
|
||||
callback: ThreadsafeFunction<serde_json::Value, ErrorStrategy::Fatal>,
|
||||
error_callback: Option<ThreadsafeFunction<()>>,
|
||||
) -> Subscription {
|
||||
let uuid = uuid::Uuid::new_v4();
|
||||
let mut event_emitter = self.event_emitter.lock();
|
||||
event_emitter.listeners.insert(uuid, callback);
|
||||
let mut error_uuid = None;
|
||||
if let Some(error_callback) = error_callback {
|
||||
let uuid = uuid::Uuid::new_v4();
|
||||
event_emitter.error_callbacks.insert(uuid, error_callback);
|
||||
error_uuid = Some(uuid);
|
||||
}
|
||||
drop(event_emitter);
|
||||
Subscription {
|
||||
id: uuid,
|
||||
error_uuid,
|
||||
event_emitter: self.event_emitter.clone(),
|
||||
}
|
||||
}
|
||||
|
||||
#[napi]
|
||||
pub fn close(&mut self) -> napi::Result<()> {
|
||||
// drop the previous watcher
|
||||
self.inner = notify::recommended_watcher(|_| {}).map_err(anyhow::Error::from)?;
|
||||
self.event_emitter.lock().stop();
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
struct EventEmitter {
|
||||
listeners: HashMap<uuid::Uuid, ThreadsafeFunction<serde_json::Value, ErrorStrategy::Fatal>>,
|
||||
error_callbacks: HashMap<uuid::Uuid, ThreadsafeFunction<()>>,
|
||||
}
|
||||
|
||||
impl EventEmitter {
|
||||
fn on(&self, event: notify::Result<Event>) {
|
||||
match event {
|
||||
Ok(e) => match serde_json::value::to_value(e) {
|
||||
Err(err) => {
|
||||
let err: napi::Error = anyhow::Error::from(err).into();
|
||||
for on_error in self.error_callbacks.values() {
|
||||
on_error.call(Err(err.clone()), ThreadsafeFunctionCallMode::NonBlocking);
|
||||
}
|
||||
}
|
||||
Ok(v) => {
|
||||
for on_event in self.listeners.values() {
|
||||
on_event.call(v.clone(), ThreadsafeFunctionCallMode::NonBlocking);
|
||||
}
|
||||
}
|
||||
},
|
||||
Err(err) => {
|
||||
let err: napi::Error = anyhow::Error::from(err).into();
|
||||
for on_error in self.error_callbacks.values() {
|
||||
on_error.call(Err(err.clone()), ThreadsafeFunctionCallMode::NonBlocking);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn stop(&mut self) {
|
||||
self.listeners.clear();
|
||||
self.error_callbacks.clear();
|
||||
}
|
||||
}
|
@ -1,12 +1 @@
|
||||
// mod block;
|
||||
mod dynamic_value;
|
||||
mod storage;
|
||||
mod workspace;
|
||||
|
||||
// pub use block::Block;
|
||||
pub use dynamic_value::{DynamicValue, DynamicValueMap};
|
||||
pub use storage::Storage;
|
||||
pub use workspace::Workspace;
|
||||
|
||||
#[macro_use]
|
||||
extern crate napi_derive;
|
||||
pub mod fs;
|
||||
|
@ -1,125 +0,0 @@
|
||||
use crate::Workspace;
|
||||
use jwst::{error, info, BlobStorage, DocStorage};
|
||||
use jwst_rpc::start_client;
|
||||
use jwst_storage::JwstStorage as AutoStorage;
|
||||
use std::sync::Arc;
|
||||
use tokio::{runtime::Runtime, sync::RwLock};
|
||||
use napi::bindgen_prelude::*;
|
||||
use napi::{Error, Result, Status};
|
||||
|
||||
#[napi]
|
||||
#[derive(Clone)]
|
||||
pub struct Storage {
|
||||
pub(crate) storage: Option<Arc<RwLock<AutoStorage>>>,
|
||||
pub(crate) error: Option<String>,
|
||||
}
|
||||
|
||||
#[napi]
|
||||
impl Storage {
|
||||
#[napi(constructor)]
|
||||
pub fn new(path: String) -> Self {
|
||||
let rt = Runtime::new().unwrap();
|
||||
|
||||
// FIXME: do not use block_on
|
||||
match rt.block_on(AutoStorage::new(&format!("sqlite:{path}?mode=rwc"))) {
|
||||
Ok(pool) => Self {
|
||||
storage: Some(Arc::new(RwLock::new(pool))),
|
||||
error: None,
|
||||
},
|
||||
Err(e) => Self {
|
||||
storage: None,
|
||||
error: Some(e.to_string()),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
#[napi]
|
||||
pub fn error(&self) -> Option<String> {
|
||||
self.error.clone()
|
||||
}
|
||||
|
||||
#[napi]
|
||||
pub async fn get_blob(&self, workspace_id: Option<String>, id: String) -> Result<Buffer> {
|
||||
if let Some(storage) = &self.storage {
|
||||
let storage_handle = storage.read().await;
|
||||
let blobs = storage_handle.blobs();
|
||||
|
||||
let blob = blobs.get_blob(workspace_id.clone(), id.clone(), None).await.map_err(|e| {
|
||||
Error::new(
|
||||
Status::GenericFailure,
|
||||
format!(
|
||||
"Failed to get blob file {}/{} from storage, error: {}",
|
||||
workspace_id.clone().unwrap_or_default().to_string(),
|
||||
id,
|
||||
e
|
||||
),
|
||||
)
|
||||
})?;
|
||||
|
||||
Ok(blob.into())
|
||||
} else {
|
||||
return Err(Error::new(
|
||||
Status::GenericFailure,
|
||||
"Storage is not connected",
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
#[napi]
|
||||
pub fn connect(&mut self, workspace_id: String, remote: String) -> Option<Workspace> {
|
||||
match self.sync(workspace_id, remote) {
|
||||
Ok(workspace) => Some(workspace),
|
||||
Err(e) => {
|
||||
error!("Failed to connect to workspace: {}", e);
|
||||
self.error = Some(e.to_string());
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[napi]
|
||||
pub fn sync(&self, workspace_id: String, remote: String) -> Result<Workspace> {
|
||||
if let Some(storage) = &self.storage {
|
||||
let rt = Runtime::new().unwrap();
|
||||
|
||||
// FIXME: do not use block_on
|
||||
let mut workspace = rt
|
||||
.block_on(async move {
|
||||
let storage = storage.read().await;
|
||||
|
||||
start_client(&storage, workspace_id, remote).await
|
||||
})
|
||||
.map_err(|e| Error::new(Status::GenericFailure, e.to_string()))?;
|
||||
|
||||
let (sub, workspace) = {
|
||||
let id = workspace.id();
|
||||
let storage = self.storage.clone();
|
||||
let sub = workspace.observe(move |_, e| {
|
||||
let id = id.clone();
|
||||
if let Some(storage) = storage.clone() {
|
||||
let rt = Runtime::new().unwrap();
|
||||
info!("update: {:?}", &e.update);
|
||||
if let Err(e) = rt.block_on(async move {
|
||||
let storage = storage.write().await;
|
||||
storage.docs().write_update(id, &e.update).await
|
||||
}) {
|
||||
error!("Failed to write update to storage: {}", e);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
(sub, workspace)
|
||||
};
|
||||
|
||||
Ok(Workspace {
|
||||
workspace,
|
||||
_sub: sub,
|
||||
})
|
||||
} else {
|
||||
Err(Error::new(
|
||||
Status::GenericFailure,
|
||||
"Storage is not connected",
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
@ -1,84 +0,0 @@
|
||||
// use super::Block;
|
||||
use jwst::Workspace as JwstWorkspace;
|
||||
use yrs::UpdateSubscription;
|
||||
|
||||
|
||||
#[napi()]
|
||||
pub struct Workspace {
|
||||
pub(crate) workspace: JwstWorkspace,
|
||||
pub(crate) _sub: Option<UpdateSubscription>,
|
||||
}
|
||||
|
||||
#[napi()]
|
||||
impl Workspace {
|
||||
#[napi(constructor)]
|
||||
pub fn new(id: String) -> Self {
|
||||
Self {
|
||||
workspace: JwstWorkspace::new(id),
|
||||
_sub: None,
|
||||
}
|
||||
}
|
||||
|
||||
#[napi]
|
||||
pub fn id(&self) -> String {
|
||||
self.workspace.id()
|
||||
}
|
||||
|
||||
#[napi]
|
||||
pub fn client_id(&self) -> i64 {
|
||||
self.workspace.client_id() as i64
|
||||
}
|
||||
|
||||
// #[napi]
|
||||
// pub fn get(&self, block_id: String) -> Option<Block> {
|
||||
// let workspace = self.workspace.clone();
|
||||
// self.workspace.with_trx(|mut trx| {
|
||||
// let block = trx
|
||||
// .get_blocks()
|
||||
// .get(&trx.trx, &block_id)
|
||||
// .map(|b| Block::new(workspace, b));
|
||||
// drop(trx);
|
||||
// block
|
||||
// })
|
||||
// }
|
||||
|
||||
// #[napi]
|
||||
// pub fn create(&self, block_id: String, flavor: String) -> Block {
|
||||
// let workspace = self.workspace.clone();
|
||||
// self.workspace.with_trx(|mut trx| {
|
||||
// let block = Block::new(
|
||||
// workspace,
|
||||
// trx.get_blocks().create(&mut trx.trx, block_id, flavor),
|
||||
// );
|
||||
// drop(trx);
|
||||
// block
|
||||
// })
|
||||
// }
|
||||
|
||||
#[napi]
|
||||
pub fn search(&self, query: String) -> String {
|
||||
self.workspace.search_result(query)
|
||||
}
|
||||
|
||||
// #[napi]
|
||||
// pub fn get_blocks_by_flavour(&self, flavour: &str) -> Vec<Block> {
|
||||
// self.workspace
|
||||
// .with_trx(|mut trx| trx.get_blocks().get_blocks_by_flavour(&trx.trx, flavour))
|
||||
// .iter()
|
||||
// .map(|block| Block {
|
||||
// workspace: self.workspace.clone(),
|
||||
// block: block.clone(),
|
||||
// })
|
||||
// .collect()
|
||||
// }
|
||||
|
||||
#[napi]
|
||||
pub fn get_search_index(&self) -> Vec<String> {
|
||||
self.workspace.metadata().search_index
|
||||
}
|
||||
|
||||
#[napi]
|
||||
pub fn set_search_index(&self, fields: Vec<String>) -> bool {
|
||||
self.workspace.set_search_index(fields)
|
||||
}
|
||||
}
|
12
packages/native/tsconfig.json
Normal file
12
packages/native/tsconfig.json
Normal file
@ -0,0 +1,12 @@
|
||||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"noEmit": true,
|
||||
"outDir": "lib"
|
||||
},
|
||||
"include": ["index.d.ts", "__tests__/**/*.mts"],
|
||||
"ts-node": {
|
||||
"esm": true,
|
||||
"experimentalSpecifierResolution": "node"
|
||||
}
|
||||
}
|
10
rustfmt.toml
Normal file
10
rustfmt.toml
Normal file
@ -0,0 +1,10 @@
|
||||
max_width = 100
|
||||
|
||||
tab_spaces = 2
|
||||
hard_tabs = false
|
||||
|
||||
format_strings = true
|
||||
wrap_comments = true
|
||||
|
||||
imports_granularity = "Crate"
|
||||
group_imports = "StdExternalCrate"
|
29
yarn.lock
29
yarn.lock
@ -232,12 +232,18 @@ __metadata:
|
||||
languageName: unknown
|
||||
linkType: soft
|
||||
|
||||
"@affine/octobase-node@workspace:packages/native":
|
||||
"@affine/native@workspace:packages/native":
|
||||
version: 0.0.0-use.local
|
||||
resolution: "@affine/octobase-node@workspace:packages/native"
|
||||
resolution: "@affine/native@workspace:packages/native"
|
||||
dependencies:
|
||||
"@napi-rs/cli": ^2.15.2
|
||||
"@types/node": ^18.16.7
|
||||
"@types/uuid": ^9.0.1
|
||||
cross-env: ^7.0.3
|
||||
rxjs: ^7.8.1
|
||||
ts-node: ^10.9.1
|
||||
typescript: ^5.0.4
|
||||
uuid: ^9.0.0
|
||||
languageName: unknown
|
||||
linkType: soft
|
||||
|
||||
@ -8143,6 +8149,15 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@taplo/cli@npm:^0.5.2":
|
||||
version: 0.5.2
|
||||
resolution: "@taplo/cli@npm:0.5.2"
|
||||
bin:
|
||||
taplo: dist/cli.js
|
||||
checksum: c2e0e584172bfee1cca6624bdb4470259179e232472fc7f4bbbd2e0127233039b9ace21a8d6b8d5081b157d9f046dc942ab27a634e23924b8c8a6096f1d04e27
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@testing-library/dom@npm:^8.3.0":
|
||||
version: 8.20.0
|
||||
resolution: "@testing-library/dom@npm:8.20.0"
|
||||
@ -9035,6 +9050,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/uuid@npm:^9.0.1":
|
||||
version: 9.0.1
|
||||
resolution: "@types/uuid@npm:9.0.1"
|
||||
checksum: c472b8a77cbeded4bc529220b8611afa39bd64677f507838f8083d8aac8033b1f88cb9ddaa2f8589e0dcd2317291d0f6e1379f82d5ceebd6f74f3b4825288e00
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/wait-on@npm:^5.2.0":
|
||||
version: 5.3.1
|
||||
resolution: "@types/wait-on@npm:5.3.1"
|
||||
@ -9748,6 +9770,7 @@ __metadata:
|
||||
"@magic-works/i18n-codegen": ^0.5.0
|
||||
"@perfsee/sdk": ^1.6.0
|
||||
"@playwright/test": ^1.33.0
|
||||
"@taplo/cli": ^0.5.2
|
||||
"@testing-library/react": ^14.0.0
|
||||
"@types/eslint": ^8.37.0
|
||||
"@types/node": ^18.16.7
|
||||
@ -12195,7 +12218,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"cross-env@npm:7.0.3":
|
||||
"cross-env@npm:7.0.3, cross-env@npm:^7.0.3":
|
||||
version: 7.0.3
|
||||
resolution: "cross-env@npm:7.0.3"
|
||||
dependencies:
|
||||
|
Loading…
Reference in New Issue
Block a user