mirror of
https://github.com/toeverything/AFFiNE.git
synced 2024-12-23 02:21:49 +03:00
refactor(native): remove unused code (#4651)
This commit is contained in:
parent
a430266389
commit
bb046a12dc
19
.github/workflows/build-desktop.yml
vendored
19
.github/workflows/build-desktop.yml
vendored
@ -55,6 +55,25 @@ jobs:
|
|||||||
path: ./apps/core/dist
|
path: ./apps/core/dist
|
||||||
if-no-files-found: error
|
if-no-files-found: error
|
||||||
|
|
||||||
|
build-native:
|
||||||
|
name: Build Native
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
environment: development
|
||||||
|
needs: build-core
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
- name: Setup Node.js
|
||||||
|
uses: ./.github/actions/setup-node
|
||||||
|
- name: Build AFFiNE native
|
||||||
|
uses: ./.github/actions/build-rust
|
||||||
|
with:
|
||||||
|
target: x86_64-unknown-linux-gnu
|
||||||
|
package: '@affine/native'
|
||||||
|
nx_token: ${{ secrets.NX_CLOUD_ACCESS_TOKEN }}
|
||||||
|
- name: Run tests
|
||||||
|
run: yarn test
|
||||||
|
working-directory: ./packages/native
|
||||||
|
|
||||||
desktop-test:
|
desktop-test:
|
||||||
name: Desktop Test
|
name: Desktop Test
|
||||||
runs-on: ${{ matrix.spec.os }}
|
runs-on: ${{ matrix.spec.os }}
|
||||||
|
@ -1,15 +1,12 @@
|
|||||||
import assert from 'node:assert';
|
import test from 'ava';
|
||||||
import { test } from 'node:test';
|
|
||||||
import { fileURLToPath } from 'node:url';
|
import { fileURLToPath } from 'node:url';
|
||||||
|
|
||||||
import { SqliteConnection, ValidationResult } from '../index';
|
import { SqliteConnection, ValidationResult } from '../index';
|
||||||
|
|
||||||
test('db', { concurrency: false }, async t => {
|
test('db validate', async t => {
|
||||||
await t.test('validate', async () => {
|
|
||||||
const path = fileURLToPath(
|
const path = fileURLToPath(
|
||||||
new URL('./fixtures/test01.affine', import.meta.url)
|
new URL('./fixtures/test01.affine', import.meta.url)
|
||||||
);
|
);
|
||||||
const result = await SqliteConnection.validate(path);
|
const result = await SqliteConnection.validate(path);
|
||||||
assert.equal(result, ValidationResult.MissingVersionColumn);
|
t.is(result, ValidationResult.MissingVersionColumn);
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
@ -1,80 +0,0 @@
|
|||||||
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 { FsWatcher } from '../index';
|
|
||||||
|
|
||||||
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 = FsWatcher.watch(fixture);
|
|
||||||
});
|
|
||||||
|
|
||||||
t.afterEach(async () => {
|
|
||||||
FsWatcher.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 (typeof event.type === 'object' && 'rename' in event.type) {
|
|
||||||
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());
|
|
||||||
})();
|
|
||||||
});
|
|
||||||
});
|
|
3
packages/native/fs-watcher.d.ts
vendored
3
packages/native/fs-watcher.d.ts
vendored
@ -1,3 +0,0 @@
|
|||||||
import type { FsWatcher } from './index';
|
|
||||||
|
|
||||||
export function createFSWatcher(): typeof FsWatcher;
|
|
@ -1,5 +0,0 @@
|
|||||||
module.exports.createFSWatcher = function createFSWatcher() {
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
||||||
const { FsWatcher } = require('./index');
|
|
||||||
return FsWatcher;
|
|
||||||
};
|
|
36
packages/native/index.d.ts
vendored
36
packages/native/index.d.ts
vendored
@ -3,26 +3,6 @@
|
|||||||
|
|
||||||
/* auto-generated by NAPI-RS */
|
/* auto-generated by NAPI-RS */
|
||||||
|
|
||||||
export interface WatchOptions {
|
|
||||||
recursive?: boolean;
|
|
||||||
}
|
|
||||||
/** Watcher kind enumeration */
|
|
||||||
export 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 moveFile(src: string, dst: string): Promise<void>;
|
|
||||||
export interface BlobRow {
|
export interface BlobRow {
|
||||||
key: string;
|
key: string;
|
||||||
data: Buffer;
|
data: Buffer;
|
||||||
@ -45,22 +25,6 @@ export enum ValidationResult {
|
|||||||
GeneralError = 3,
|
GeneralError = 3,
|
||||||
Valid = 4,
|
Valid = 4,
|
||||||
}
|
}
|
||||||
export class Subscription {
|
|
||||||
toString(): string;
|
|
||||||
unsubscribe(): void;
|
|
||||||
}
|
|
||||||
export type FSWatcher = FsWatcher;
|
|
||||||
export class FsWatcher {
|
|
||||||
static watch(p: string, options?: WatchOptions | undefined | null): FsWatcher;
|
|
||||||
static kind(): WatcherKind;
|
|
||||||
toString(): string;
|
|
||||||
subscribe(
|
|
||||||
callback: (event: import('./event').NotifyEvent) => void,
|
|
||||||
errorCallback?: (err: Error) => void
|
|
||||||
): Subscription;
|
|
||||||
static unwatch(p: string): void;
|
|
||||||
static close(): void;
|
|
||||||
}
|
|
||||||
export class SqliteConnection {
|
export class SqliteConnection {
|
||||||
constructor(path: string);
|
constructor(path: string);
|
||||||
connect(): Promise<void>;
|
connect(): Promise<void>;
|
||||||
|
@ -263,18 +263,7 @@ if (!nativeBinding) {
|
|||||||
throw new Error(`Failed to load native binding`);
|
throw new Error(`Failed to load native binding`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const {
|
const { SqliteConnection, ValidationResult } = nativeBinding;
|
||||||
WatcherKind,
|
|
||||||
Subscription,
|
|
||||||
FsWatcher,
|
|
||||||
moveFile,
|
|
||||||
SqliteConnection,
|
|
||||||
ValidationResult,
|
|
||||||
} = nativeBinding;
|
|
||||||
|
|
||||||
module.exports.WatcherKind = WatcherKind;
|
|
||||||
module.exports.Subscription = Subscription;
|
|
||||||
module.exports.FsWatcher = FsWatcher;
|
|
||||||
module.exports.moveFile = moveFile;
|
|
||||||
module.exports.SqliteConnection = SqliteConnection;
|
module.exports.SqliteConnection = SqliteConnection;
|
||||||
module.exports.ValidationResult = ValidationResult;
|
module.exports.ValidationResult = ValidationResult;
|
||||||
|
@ -17,10 +17,28 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"ava": {
|
||||||
|
"extensions": {
|
||||||
|
"mts": "module"
|
||||||
|
},
|
||||||
|
"nodeArguments": [
|
||||||
|
"--loader",
|
||||||
|
"ts-node/esm.mjs",
|
||||||
|
"--es-module-specifier-resolution",
|
||||||
|
"node"
|
||||||
|
],
|
||||||
|
"files": [
|
||||||
|
"__tests__/*.spec.mts"
|
||||||
|
],
|
||||||
|
"environmentVariables": {
|
||||||
|
"TS_NODE_PROJECT": "./tsconfig.json"
|
||||||
|
}
|
||||||
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@napi-rs/cli": "^2.16.3",
|
"@napi-rs/cli": "^2.16.3",
|
||||||
"@types/node": "^18.18.5",
|
"@types/node": "^18.18.5",
|
||||||
"@types/uuid": "^9.0.5",
|
"@types/uuid": "^9.0.5",
|
||||||
|
"ava": "^5.3.1",
|
||||||
"cross-env": "^7.0.3",
|
"cross-env": "^7.0.3",
|
||||||
"nx": "^16.10.0",
|
"nx": "^16.10.0",
|
||||||
"nx-cloud": "^16.5.2",
|
"nx-cloud": "^16.5.2",
|
||||||
@ -37,7 +55,7 @@
|
|||||||
"build": "napi build --platform --release --no-const-enum",
|
"build": "napi build --platform --release --no-const-enum",
|
||||||
"build:debug": "napi build --platform --no-const-enum",
|
"build:debug": "napi build --platform --no-const-enum",
|
||||||
"universal": "napi universal",
|
"universal": "napi universal",
|
||||||
"test": "cross-env TS_NODE_TRANSPILE_ONLY=1 TS_NODE_PROJECT=./tsconfig.json node --test --loader ts-node/esm --experimental-specifier-resolution=node ./__tests__/**/*.mts",
|
"test": "ava",
|
||||||
"version": "napi version"
|
"version": "napi version"
|
||||||
},
|
},
|
||||||
"version": "0.10.0-canary.1"
|
"version": "0.10.0-canary.1"
|
||||||
|
@ -1,243 +0,0 @@
|
|||||||
use std::{collections::BTreeMap, 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 once_cell::sync::Lazy;
|
|
||||||
use parking_lot::Mutex;
|
|
||||||
|
|
||||||
static GLOBAL_WATCHER: Lazy<napi::Result<GlobalWatcher>> = Lazy::new(|| {
|
|
||||||
let event_emitter = Arc::new(Mutex::new(EventEmitter {
|
|
||||||
listeners: Default::default(),
|
|
||||||
error_callbacks: Default::default(),
|
|
||||||
}));
|
|
||||||
let event_emitter_in_handler = event_emitter.clone();
|
|
||||||
let watcher: RecommendedWatcher =
|
|
||||||
notify::recommended_watcher(move |res: notify::Result<Event>| {
|
|
||||||
event_emitter_in_handler.lock().on(res);
|
|
||||||
})
|
|
||||||
.map_err(anyhow::Error::from)?;
|
|
||||||
Ok(GlobalWatcher {
|
|
||||||
inner: Mutex::new(watcher),
|
|
||||||
event_emitter,
|
|
||||||
})
|
|
||||||
});
|
|
||||||
|
|
||||||
struct GlobalWatcher {
|
|
||||||
inner: Mutex<RecommendedWatcher>,
|
|
||||||
event_emitter: Arc<Mutex<EventEmitter>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[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>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[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) -> napi::Result<()> {
|
|
||||||
let mut event_emitter = GLOBAL_WATCHER
|
|
||||||
.as_ref()
|
|
||||||
.map_err(|err| err.clone())?
|
|
||||||
.event_emitter
|
|
||||||
.lock();
|
|
||||||
event_emitter.listeners.remove(&self.id);
|
|
||||||
if let Some(error_uuid) = &self.error_uuid {
|
|
||||||
event_emitter.error_callbacks.remove(error_uuid);
|
|
||||||
};
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[napi]
|
|
||||||
pub struct FSWatcher {
|
|
||||||
path: String,
|
|
||||||
recursive: RecursiveMode,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[napi]
|
|
||||||
impl FSWatcher {
|
|
||||||
#[napi(factory)]
|
|
||||||
pub fn watch(p: String, options: Option<WatchOptions>) -> Self {
|
|
||||||
let options = options.unwrap_or_default();
|
|
||||||
FSWatcher {
|
|
||||||
path: p,
|
|
||||||
recursive: if options.recursive == Some(false) {
|
|
||||||
RecursiveMode::NonRecursive
|
|
||||||
} else {
|
|
||||||
RecursiveMode::Recursive
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[napi]
|
|
||||||
pub fn kind() -> WatcherKind {
|
|
||||||
RecommendedWatcher::kind().into()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[napi]
|
|
||||||
pub fn to_string(&self) -> napi::Result<String> {
|
|
||||||
Ok(format!(
|
|
||||||
"{:?}",
|
|
||||||
GLOBAL_WATCHER.as_ref().map_err(|err| err.clone())?.inner
|
|
||||||
))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[napi]
|
|
||||||
pub fn subscribe(
|
|
||||||
&mut self,
|
|
||||||
#[napi(ts_arg_type = "(event: import('./event').NotifyEvent) => void")]
|
|
||||||
callback: ThreadsafeFunction<serde_json::Value, ErrorStrategy::Fatal>,
|
|
||||||
#[napi(ts_arg_type = "(err: Error) => void")] error_callback: Option<ThreadsafeFunction<()>>,
|
|
||||||
) -> napi::Result<Subscription> {
|
|
||||||
GLOBAL_WATCHER
|
|
||||||
.as_ref()
|
|
||||||
.map_err(|err| err.clone())?
|
|
||||||
.inner
|
|
||||||
.lock()
|
|
||||||
.watch(Path::new(&self.path), self.recursive)
|
|
||||||
.map_err(anyhow::Error::from)?;
|
|
||||||
let uuid = uuid::Uuid::new_v4();
|
|
||||||
let mut event_emitter = GLOBAL_WATCHER
|
|
||||||
.as_ref()
|
|
||||||
.map_err(|err| err.clone())?
|
|
||||||
.event_emitter
|
|
||||||
.lock();
|
|
||||||
event_emitter
|
|
||||||
.listeners
|
|
||||||
.insert(uuid, (self.path.clone(), 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);
|
|
||||||
Ok(Subscription {
|
|
||||||
id: uuid,
|
|
||||||
error_uuid,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
#[napi]
|
|
||||||
pub fn unwatch(p: String) -> napi::Result<()> {
|
|
||||||
let mut watcher = GLOBAL_WATCHER
|
|
||||||
.as_ref()
|
|
||||||
.map_err(|err| err.clone())?
|
|
||||||
.inner
|
|
||||||
.lock();
|
|
||||||
watcher
|
|
||||||
.unwatch(Path::new(&p))
|
|
||||||
.map_err(anyhow::Error::from)?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[napi]
|
|
||||||
pub fn close() -> napi::Result<()> {
|
|
||||||
let global_watcher = GLOBAL_WATCHER.as_ref().map_err(|err| err.clone())?;
|
|
||||||
global_watcher.event_emitter.lock().stop();
|
|
||||||
let mut inner = global_watcher.inner.lock();
|
|
||||||
*inner = notify::recommended_watcher(|_| {}).map_err(anyhow::Error::from)?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
|
||||||
struct EventEmitter {
|
|
||||||
listeners: BTreeMap<
|
|
||||||
uuid::Uuid,
|
|
||||||
(
|
|
||||||
String,
|
|
||||||
ThreadsafeFunction<serde_json::Value, ErrorStrategy::Fatal>,
|
|
||||||
),
|
|
||||||
>,
|
|
||||||
error_callbacks: BTreeMap<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 (path, on_event) in self.listeners.values() {
|
|
||||||
if e.paths.iter().any(|p| p.to_str() == Some(path)) {
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[napi]
|
|
||||||
pub async fn move_file(src: String, dst: String) -> napi::Result<()> {
|
|
||||||
tokio::fs::rename(src, dst).await?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
@ -1,2 +1 @@
|
|||||||
pub mod fs;
|
|
||||||
pub mod sqlite;
|
pub mod sqlite;
|
||||||
|
@ -594,6 +594,7 @@ __metadata:
|
|||||||
"@napi-rs/cli": ^2.16.3
|
"@napi-rs/cli": ^2.16.3
|
||||||
"@types/node": ^18.18.5
|
"@types/node": ^18.18.5
|
||||||
"@types/uuid": ^9.0.5
|
"@types/uuid": ^9.0.5
|
||||||
|
ava: ^5.3.1
|
||||||
cross-env: ^7.0.3
|
cross-env: ^7.0.3
|
||||||
nx: ^16.10.0
|
nx: ^16.10.0
|
||||||
nx-cloud: ^16.5.2
|
nx-cloud: ^16.5.2
|
||||||
|
Loading…
Reference in New Issue
Block a user