mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
feat: folder web (#4580)
* chore: folder wasm * chore: folder wasm * chore: resolve deps * chore: fix trait * chore: try localset * chore: fix * chore: fix * chore: fix * chore: async init sdk * chore: fix test * chore: fix test
This commit is contained in:
parent
08938b8c70
commit
fda70ff560
@ -50,6 +50,7 @@ APP_ENVIRONMENT = "local"
|
||||
FLUTTER_FLOWY_SDK_PATH = "appflowy_flutter/packages/appflowy_backend"
|
||||
TAURI_BACKEND_SERVICE_PATH = "appflowy_tauri/src/services/backend"
|
||||
WEB_BACKEND_SERVICE_PATH = "appflowy_web/src/services/backend"
|
||||
WEB_LIB_PATH= "appflowy_web/wasm-libs/af-wasm"
|
||||
# Test default config
|
||||
TEST_CRATE_TYPE = "cdylib"
|
||||
TEST_LIB_EXT = "dylib"
|
||||
|
@ -29,8 +29,16 @@ class FlowySDK {
|
||||
Future<void> init(String configuration) async {
|
||||
final port = RustStreamReceiver.shared.port;
|
||||
ffi.set_stream_port(port);
|
||||
|
||||
ffi.store_dart_post_cobject(NativeApi.postCObject);
|
||||
ffi.init_sdk(configuration.toNativeUtf8());
|
||||
|
||||
// final completer = Completer<Uint8List>();
|
||||
// // Create a SendPort that accepts only one message.
|
||||
// final sendPort = singleCompletePort(completer);
|
||||
|
||||
final code = ffi.init_sdk(0, configuration.toNativeUtf8());
|
||||
if (code != 0) {
|
||||
throw Exception('Failed to initialize the SDK');
|
||||
}
|
||||
// return completer.future;
|
||||
}
|
||||
}
|
||||
|
@ -77,17 +77,20 @@ typedef _invoke_sync_Dart = Pointer<Uint8> Function(
|
||||
|
||||
/// C function `init_sdk`.
|
||||
int init_sdk(
|
||||
int port,
|
||||
Pointer<ffi.Utf8> data,
|
||||
) {
|
||||
return _init_sdk(data);
|
||||
return _init_sdk(port, data);
|
||||
}
|
||||
|
||||
final _init_sdk_Dart _init_sdk =
|
||||
_dart_ffi_lib.lookupFunction<_init_sdk_C, _init_sdk_Dart>('init_sdk');
|
||||
typedef _init_sdk_C = Int64 Function(
|
||||
Int64 port,
|
||||
Pointer<ffi.Utf8> path,
|
||||
);
|
||||
typedef _init_sdk_Dart = int Function(
|
||||
int port,
|
||||
Pointer<ffi.Utf8> path,
|
||||
);
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
int64_t init_sdk(char *data);
|
||||
int64_t init_sdk(int64_t port, char *data);
|
||||
|
||||
void async_event(int64_t port, const uint8_t *input, uintptr_t len);
|
||||
|
||||
|
1
frontend/appflowy_tauri/src-tauri/Cargo.lock
generated
1
frontend/appflowy_tauri/src-tauri/Cargo.lock
generated
@ -1930,6 +1930,7 @@ dependencies = [
|
||||
name = "flowy-folder"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"bytes",
|
||||
"chrono",
|
||||
"collab",
|
||||
|
@ -1,5 +1,7 @@
|
||||
use flowy_core::config::AppFlowyCoreConfig;
|
||||
use flowy_core::{AppFlowyCore, DEFAULT_NAME};
|
||||
use lib_dispatch::runtime::AFPluginRuntime;
|
||||
use std::sync::Arc;
|
||||
|
||||
pub fn init_flowy_core() -> AppFlowyCore {
|
||||
let config_json = include_str!("../tauri.conf.json");
|
||||
@ -26,5 +28,8 @@ pub fn init_flowy_core() -> AppFlowyCore {
|
||||
DEFAULT_NAME.to_string(),
|
||||
)
|
||||
.log_filter("trace", vec!["appflowy_tauri".to_string()]);
|
||||
AppFlowyCore::new(config)
|
||||
|
||||
let runtime = Arc::new(AFPluginRuntime::new().unwrap());
|
||||
let cloned_runtime = runtime.clone();
|
||||
runtime.block_on(async move { AppFlowyCore::new(config, cloned_runtime).await })
|
||||
}
|
||||
|
@ -1,2 +0,0 @@
|
||||
export * from './observer';
|
||||
export * from './parser';
|
@ -1,34 +0,0 @@
|
||||
import { listen, UnlistenFn } from "@tauri-apps/api/event";
|
||||
import { SubscribeObject } from "../models/flowy-notification";
|
||||
import { NotificationParser } from "./parser";
|
||||
|
||||
export abstract class AFNotificationObserver<T> {
|
||||
parser?: NotificationParser<T> | null;
|
||||
private _listener?: UnlistenFn;
|
||||
|
||||
protected constructor(parser?: NotificationParser<T>) {
|
||||
this.parser = parser;
|
||||
}
|
||||
|
||||
async start() {
|
||||
this._listener = await listen("af-notification", (notification) => {
|
||||
const object: SubscribeObject = SubscribeObject.fromObject(notification.payload as {});
|
||||
if (this.parser?.id !== undefined) {
|
||||
if (object.id === this.parser.id) {
|
||||
this.parser?.parse(object);
|
||||
}
|
||||
} else {
|
||||
this.parser?.parse(object);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async stop() {
|
||||
if (this._listener !== undefined) {
|
||||
// call the unlisten function before setting it to undefined
|
||||
this._listener();
|
||||
this._listener = undefined;
|
||||
}
|
||||
this.parser = null;
|
||||
}
|
||||
}
|
@ -1,44 +0,0 @@
|
||||
import { FlowyError } from "../models/flowy-error";
|
||||
import { SubscribeObject } from "../models/flowy-notification";
|
||||
import { Err, Ok, Result } from "ts-results";
|
||||
|
||||
export declare type OnNotificationPayload<T> = (ty: T, payload: Result<Uint8Array, FlowyError>) => void;
|
||||
export declare type OnNotificationError = (error: FlowyError) => void;
|
||||
export declare type NotificationTyParser<T> = (num: number) => T | null;
|
||||
export declare type ErrParser<E> = (data: Uint8Array) => E;
|
||||
|
||||
export abstract class NotificationParser<T> {
|
||||
id?: string;
|
||||
onPayload: OnNotificationPayload<T>;
|
||||
tyParser: NotificationTyParser<T>;
|
||||
|
||||
protected constructor(
|
||||
onPayload: OnNotificationPayload<T>,
|
||||
tyParser: NotificationTyParser<T>,
|
||||
id?: string
|
||||
) {
|
||||
this.id = id;
|
||||
this.onPayload = onPayload;
|
||||
this.tyParser = tyParser;
|
||||
}
|
||||
|
||||
parse(subject: SubscribeObject) {
|
||||
if (typeof this.id !== "undefined" && this.id.length === 0) {
|
||||
if (subject.id !== this.id) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
const ty = this.tyParser(subject.ty);
|
||||
if (ty === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (subject.has_error) {
|
||||
const error = FlowyError.deserializeBinary(subject.error);
|
||||
this.onPayload(ty, Err(error));
|
||||
} else {
|
||||
this.onPayload(ty, Ok(subject.payload));
|
||||
}
|
||||
}
|
||||
}
|
@ -1 +0,0 @@
|
||||
export {}
|
@ -1,18 +1,73 @@
|
||||
module.exports = {
|
||||
root: true,
|
||||
env: { browser: true, es2020: true },
|
||||
extends: [
|
||||
'eslint:recommended',
|
||||
'plugin:@typescript-eslint/recommended',
|
||||
'plugin:react-hooks/recommended',
|
||||
],
|
||||
ignorePatterns: ['dist', '.eslintrc.cjs'],
|
||||
parser: '@typescript-eslint/parser',
|
||||
plugins: ['react-refresh'],
|
||||
rules: {
|
||||
'react-refresh/only-export-components': [
|
||||
'warn',
|
||||
{ allowConstantExport: true },
|
||||
],
|
||||
// https://eslint.org/docs/latest/use/configure/configuration-files
|
||||
env: {
|
||||
browser: true,
|
||||
es6: true,
|
||||
node: true,
|
||||
},
|
||||
}
|
||||
extends: ['eslint:recommended', 'plugin:@typescript-eslint/recommended'],
|
||||
parser: '@typescript-eslint/parser',
|
||||
parserOptions: {
|
||||
project: 'tsconfig.json',
|
||||
sourceType: 'module',
|
||||
tsconfigRootDir: __dirname,
|
||||
extraFileExtensions: ['.json'],
|
||||
},
|
||||
plugins: ['@typescript-eslint', "react-hooks"],
|
||||
rules: {
|
||||
"react-hooks/rules-of-hooks": "error",
|
||||
"react-hooks/exhaustive-deps": "error",
|
||||
'@typescript-eslint/adjacent-overload-signatures': 'error',
|
||||
'@typescript-eslint/no-empty-function': 'error',
|
||||
'@typescript-eslint/no-empty-interface': 'error',
|
||||
'@typescript-eslint/no-floating-promises': 'error',
|
||||
'@typescript-eslint/await-thenable': 'error',
|
||||
'@typescript-eslint/no-namespace': 'error',
|
||||
'@typescript-eslint/no-unnecessary-type-assertion': 'error',
|
||||
'@typescript-eslint/no-redeclare': 'error',
|
||||
'@typescript-eslint/prefer-for-of': 'error',
|
||||
'@typescript-eslint/triple-slash-reference': 'error',
|
||||
'@typescript-eslint/unified-signatures': 'error',
|
||||
'no-shadow': 'off',
|
||||
'@typescript-eslint/no-shadow': 'off',
|
||||
'constructor-super': 'error',
|
||||
eqeqeq: ['error', 'always'],
|
||||
'no-cond-assign': 'error',
|
||||
'no-duplicate-case': 'error',
|
||||
'no-duplicate-imports': 'error',
|
||||
'no-empty': [
|
||||
'error',
|
||||
{
|
||||
allowEmptyCatch: true,
|
||||
},
|
||||
],
|
||||
'no-invalid-this': 'error',
|
||||
'no-new-wrappers': 'error',
|
||||
'no-param-reassign': 'error',
|
||||
'no-sequences': 'error',
|
||||
'no-throw-literal': 'error',
|
||||
'no-unsafe-finally': 'error',
|
||||
'no-unused-labels': 'error',
|
||||
'no-var': 'error',
|
||||
'no-void': 'off',
|
||||
'prefer-const': 'error',
|
||||
'prefer-spread': 'off',
|
||||
'@typescript-eslint/no-unused-vars': [
|
||||
'error',
|
||||
{
|
||||
argsIgnorePattern: '^_',
|
||||
}
|
||||
],
|
||||
'padding-line-between-statements': [
|
||||
"error",
|
||||
{ blankLine: "always", prev: ["const", "let", "var"], next: "*"},
|
||||
{ blankLine: "any", prev: ["const", "let", "var"], next: ["const", "let", "var"]},
|
||||
{ blankLine: "always", prev: "import", next: "*" },
|
||||
{ blankLine: "any", prev: "import", next: "import" },
|
||||
{ blankLine: "always", prev: "block-like", next: "*" },
|
||||
{ blankLine: "always", prev: "block", next: "*" },
|
||||
|
||||
]
|
||||
},
|
||||
ignorePatterns: ['src/**/*.test.ts', '**/__tests__/**/*.json', 'package.json']
|
||||
};
|
||||
|
@ -10,6 +10,7 @@
|
||||
"build": "tsc && vite build",
|
||||
"lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
|
||||
"clean": "cargo make --cwd .. web_clean",
|
||||
"test": "cargo test && wasm-pack test --headless",
|
||||
"preview": "vite preview"
|
||||
},
|
||||
"dependencies": {
|
||||
@ -34,6 +35,7 @@
|
||||
"eslint-plugin-react-refresh": "^0.4.5",
|
||||
"typescript": "^5.2.2",
|
||||
"vite": "^5.0.8",
|
||||
"vite-plugin-wasm": "^3.3.0"
|
||||
"vite-plugin-wasm": "^3.3.0",
|
||||
"rimraf": "^5.0.5"
|
||||
}
|
||||
}
|
||||
|
@ -54,6 +54,9 @@ devDependencies:
|
||||
eslint-plugin-react-refresh:
|
||||
specifier: ^0.4.5
|
||||
version: 0.4.5(eslint@8.55.0)
|
||||
rimraf:
|
||||
specifier: ^5.0.5
|
||||
version: 5.0.5
|
||||
typescript:
|
||||
specifier: ^5.2.2
|
||||
version: 5.2.2
|
||||
@ -559,6 +562,18 @@ packages:
|
||||
resolution: {integrity: sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==}
|
||||
dev: true
|
||||
|
||||
/@isaacs/cliui@8.0.2:
|
||||
resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==}
|
||||
engines: {node: '>=12'}
|
||||
dependencies:
|
||||
string-width: 5.1.2
|
||||
string-width-cjs: /string-width@4.2.3
|
||||
strip-ansi: 7.1.0
|
||||
strip-ansi-cjs: /strip-ansi@6.0.1
|
||||
wrap-ansi: 8.1.0
|
||||
wrap-ansi-cjs: /wrap-ansi@7.0.0
|
||||
dev: true
|
||||
|
||||
/@jridgewell/gen-mapping@0.3.3:
|
||||
resolution: {integrity: sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==}
|
||||
engines: {node: '>=6.0.0'}
|
||||
@ -610,6 +625,13 @@ packages:
|
||||
fastq: 1.16.0
|
||||
dev: true
|
||||
|
||||
/@pkgjs/parseargs@0.11.0:
|
||||
resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==}
|
||||
engines: {node: '>=14'}
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@rollup/rollup-android-arm-eabi@4.9.2:
|
||||
resolution: {integrity: sha512-RKzxFxBHq9ysZ83fn8Iduv3A283K7zPPYuhL/z9CQuyFrjwpErJx0h4aeb/bnJ+q29GRLgJpY66ceQ/Wcsn3wA==}
|
||||
cpu: [arm]
|
||||
@ -962,6 +984,11 @@ packages:
|
||||
engines: {node: '>=8'}
|
||||
dev: true
|
||||
|
||||
/ansi-regex@6.0.1:
|
||||
resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==}
|
||||
engines: {node: '>=12'}
|
||||
dev: true
|
||||
|
||||
/ansi-styles@3.2.1:
|
||||
resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==}
|
||||
engines: {node: '>=4'}
|
||||
@ -976,6 +1003,11 @@ packages:
|
||||
color-convert: 2.0.1
|
||||
dev: true
|
||||
|
||||
/ansi-styles@6.2.1:
|
||||
resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==}
|
||||
engines: {node: '>=12'}
|
||||
dev: true
|
||||
|
||||
/argparse@2.0.1:
|
||||
resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==}
|
||||
dev: true
|
||||
@ -996,6 +1028,12 @@ packages:
|
||||
concat-map: 0.0.1
|
||||
dev: true
|
||||
|
||||
/brace-expansion@2.0.1:
|
||||
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==}
|
||||
engines: {node: '>=8'}
|
||||
@ -1112,10 +1150,22 @@ packages:
|
||||
esutils: 2.0.3
|
||||
dev: true
|
||||
|
||||
/eastasianwidth@0.2.0:
|
||||
resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==}
|
||||
dev: true
|
||||
|
||||
/electron-to-chromium@1.4.620:
|
||||
resolution: {integrity: sha512-a2fcSHOHrqBJsPNXtf6ZCEZpXrFCcbK1FBxfX3txoqWzNgtEDG1f3M59M98iwxhRW4iMKESnSjbJ310/rkrp0g==}
|
||||
dev: true
|
||||
|
||||
/emoji-regex@8.0.0:
|
||||
resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==}
|
||||
dev: true
|
||||
|
||||
/emoji-regex@9.2.2:
|
||||
resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==}
|
||||
dev: true
|
||||
|
||||
/esbuild@0.19.11:
|
||||
resolution: {integrity: sha512-HJ96Hev2hX/6i5cDVwcqiJBBtuo9+FeIJOtZ9W1kA5M6AMJRHUZlpYZ1/SbEwtO0ioNAW8rUooVpC/WehY2SfA==}
|
||||
engines: {node: '>=12'}
|
||||
@ -1341,6 +1391,14 @@ packages:
|
||||
resolution: {integrity: sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==}
|
||||
dev: true
|
||||
|
||||
/foreground-child@3.1.1:
|
||||
resolution: {integrity: sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==}
|
||||
engines: {node: '>=14'}
|
||||
dependencies:
|
||||
cross-spawn: 7.0.3
|
||||
signal-exit: 4.1.0
|
||||
dev: true
|
||||
|
||||
/fs.realpath@1.0.0:
|
||||
resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==}
|
||||
dev: true
|
||||
@ -1372,6 +1430,18 @@ packages:
|
||||
is-glob: 4.0.3
|
||||
dev: true
|
||||
|
||||
/glob@10.3.10:
|
||||
resolution: {integrity: sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==}
|
||||
engines: {node: '>=16 || 14 >=14.17'}
|
||||
hasBin: true
|
||||
dependencies:
|
||||
foreground-child: 3.1.1
|
||||
jackspeak: 2.3.6
|
||||
minimatch: 9.0.3
|
||||
minipass: 7.0.4
|
||||
path-scurry: 1.10.1
|
||||
dev: true
|
||||
|
||||
/glob@7.2.3:
|
||||
resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==}
|
||||
dependencies:
|
||||
@ -1459,6 +1529,11 @@ packages:
|
||||
engines: {node: '>=0.10.0'}
|
||||
dev: true
|
||||
|
||||
/is-fullwidth-code-point@3.0.0:
|
||||
resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==}
|
||||
engines: {node: '>=8'}
|
||||
dev: true
|
||||
|
||||
/is-glob@4.0.3:
|
||||
resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
@ -1480,6 +1555,15 @@ packages:
|
||||
resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
|
||||
dev: true
|
||||
|
||||
/jackspeak@2.3.6:
|
||||
resolution: {integrity: sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==}
|
||||
engines: {node: '>=14'}
|
||||
dependencies:
|
||||
'@isaacs/cliui': 8.0.2
|
||||
optionalDependencies:
|
||||
'@pkgjs/parseargs': 0.11.0
|
||||
dev: true
|
||||
|
||||
/js-tokens@4.0.0:
|
||||
resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
|
||||
|
||||
@ -1546,6 +1630,11 @@ packages:
|
||||
js-tokens: 4.0.0
|
||||
dev: false
|
||||
|
||||
/lru-cache@10.2.0:
|
||||
resolution: {integrity: sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q==}
|
||||
engines: {node: 14 || >=16.14}
|
||||
dev: true
|
||||
|
||||
/lru-cache@5.1.1:
|
||||
resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==}
|
||||
dependencies:
|
||||
@ -1578,6 +1667,18 @@ packages:
|
||||
brace-expansion: 1.1.11
|
||||
dev: true
|
||||
|
||||
/minimatch@9.0.3:
|
||||
resolution: {integrity: sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==}
|
||||
engines: {node: '>=16 || 14 >=14.17'}
|
||||
dependencies:
|
||||
brace-expansion: 2.0.1
|
||||
dev: true
|
||||
|
||||
/minipass@7.0.4:
|
||||
resolution: {integrity: sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==}
|
||||
engines: {node: '>=16 || 14 >=14.17'}
|
||||
dev: true
|
||||
|
||||
/ms@2.1.2:
|
||||
resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==}
|
||||
dev: true
|
||||
@ -1650,6 +1751,14 @@ packages:
|
||||
engines: {node: '>=8'}
|
||||
dev: true
|
||||
|
||||
/path-scurry@1.10.1:
|
||||
resolution: {integrity: sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==}
|
||||
engines: {node: '>=16 || 14 >=14.17'}
|
||||
dependencies:
|
||||
lru-cache: 10.2.0
|
||||
minipass: 7.0.4
|
||||
dev: true
|
||||
|
||||
/path-type@4.0.0:
|
||||
resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==}
|
||||
engines: {node: '>=8'}
|
||||
@ -1731,6 +1840,14 @@ packages:
|
||||
glob: 7.2.3
|
||||
dev: true
|
||||
|
||||
/rimraf@5.0.5:
|
||||
resolution: {integrity: sha512-CqDakW+hMe/Bz202FPEymy68P+G50RfMQK+Qo5YUqc9SPipvbGjCGKd0RSKEelbsfQuw3g5NZDSrlZZAJurH1A==}
|
||||
engines: {node: '>=14'}
|
||||
hasBin: true
|
||||
dependencies:
|
||||
glob: 10.3.10
|
||||
dev: true
|
||||
|
||||
/rollup@4.9.2:
|
||||
resolution: {integrity: sha512-66RB8OtFKUTozmVEh3qyNfH+b+z2RXBVloqO2KCC/pjFaGaHtxP9fVfOQKPSGXg2mElmjmxjW/fZ7iKrEpMH5Q==}
|
||||
engines: {node: '>=18.0.0', npm: '>=8.0.0'}
|
||||
@ -1789,6 +1906,11 @@ packages:
|
||||
engines: {node: '>=8'}
|
||||
dev: true
|
||||
|
||||
/signal-exit@4.1.0:
|
||||
resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==}
|
||||
engines: {node: '>=14'}
|
||||
dev: true
|
||||
|
||||
/slash@3.0.0:
|
||||
resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==}
|
||||
engines: {node: '>=8'}
|
||||
@ -1799,6 +1921,24 @@ packages:
|
||||
engines: {node: '>=0.10.0'}
|
||||
dev: true
|
||||
|
||||
/string-width@4.2.3:
|
||||
resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==}
|
||||
engines: {node: '>=8'}
|
||||
dependencies:
|
||||
emoji-regex: 8.0.0
|
||||
is-fullwidth-code-point: 3.0.0
|
||||
strip-ansi: 6.0.1
|
||||
dev: true
|
||||
|
||||
/string-width@5.1.2:
|
||||
resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==}
|
||||
engines: {node: '>=12'}
|
||||
dependencies:
|
||||
eastasianwidth: 0.2.0
|
||||
emoji-regex: 9.2.2
|
||||
strip-ansi: 7.1.0
|
||||
dev: true
|
||||
|
||||
/strip-ansi@6.0.1:
|
||||
resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==}
|
||||
engines: {node: '>=8'}
|
||||
@ -1806,6 +1946,13 @@ packages:
|
||||
ansi-regex: 5.0.1
|
||||
dev: true
|
||||
|
||||
/strip-ansi@7.1.0:
|
||||
resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==}
|
||||
engines: {node: '>=12'}
|
||||
dependencies:
|
||||
ansi-regex: 6.0.1
|
||||
dev: true
|
||||
|
||||
/strip-json-comments@3.1.1:
|
||||
resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==}
|
||||
engines: {node: '>=8'}
|
||||
@ -1950,6 +2097,24 @@ packages:
|
||||
isexe: 2.0.0
|
||||
dev: true
|
||||
|
||||
/wrap-ansi@7.0.0:
|
||||
resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==}
|
||||
engines: {node: '>=10'}
|
||||
dependencies:
|
||||
ansi-styles: 4.3.0
|
||||
string-width: 4.2.3
|
||||
strip-ansi: 6.0.1
|
||||
dev: true
|
||||
|
||||
/wrap-ansi@8.1.0:
|
||||
resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==}
|
||||
engines: {node: '>=12'}
|
||||
dependencies:
|
||||
ansi-styles: 6.2.1
|
||||
string-width: 5.1.2
|
||||
strip-ansi: 7.1.0
|
||||
dev: true
|
||||
|
||||
/wrappy@1.0.2:
|
||||
resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==}
|
||||
dev: true
|
||||
|
@ -5,9 +5,9 @@ import { useEffect } from "react";
|
||||
import { initApp } from "@/application/app.ts";
|
||||
import { subscribeNotification } from "@/application/notification.ts";
|
||||
import { NotifyArgs } from "./@types/global";
|
||||
import {init_tracing_log, init_wasm_core} from "../wasm-libs/af-wasm/pkg";
|
||||
import { init_tracing_log, init_wasm_core } from "../wasm-libs/af-wasm/pkg";
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
import {AddUserPB, UserWasmEventAddUser} from "@/services/backend/events/af-user";
|
||||
import {AddUserPB, UserWasmEventAddUser} from "@/services/backend/events/user";
|
||||
|
||||
init_tracing_log();
|
||||
// FIXME: handle the promise that init_wasm_core returns
|
||||
|
@ -1,2 +1,5 @@
|
||||
export * from "./models/af-user";
|
||||
export * from "./models/flowy-error";
|
||||
export * from "./models/flowy-folder";
|
||||
export * from "./models/flowy-document";
|
||||
export * from "./models/flowy-notification";
|
110
frontend/appflowy_web/wasm-libs/Cargo.lock
generated
110
frontend/appflowy_web/wasm-libs/Cargo.lock
generated
@ -45,7 +45,7 @@ version = "0.8.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac1f845298e95f983ff1944b728ae08b8cebab80d684f0a832ed0fc74dfa27e2"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.0",
|
||||
"cipher",
|
||||
"cpufeatures",
|
||||
]
|
||||
@ -110,14 +110,18 @@ dependencies = [
|
||||
name = "af-wasm"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"af-persistence",
|
||||
"af-user",
|
||||
"collab",
|
||||
"collab-integrate",
|
||||
"console_error_panic_hook",
|
||||
"flowy-document",
|
||||
"flowy-error",
|
||||
"flowy-folder",
|
||||
"flowy-notification",
|
||||
"flowy-server",
|
||||
"flowy-server-pub",
|
||||
"flowy-storage",
|
||||
"flowy-user-pub",
|
||||
"js-sys",
|
||||
"lazy_static",
|
||||
@ -136,6 +140,7 @@ dependencies = [
|
||||
"wasm-bindgen-futures",
|
||||
"wasm-bindgen-test",
|
||||
"web-sys",
|
||||
"wee_alloc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -155,7 +160,7 @@ version = "0.8.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "77c3a9648d43b9cd48db467b3f87fdd6e146bcc88ab0180006cef2179fe11d01"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.0",
|
||||
"getrandom 0.2.12",
|
||||
"once_cell",
|
||||
"version_check",
|
||||
@ -284,7 +289,7 @@ checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837"
|
||||
dependencies = [
|
||||
"addr2line",
|
||||
"cc",
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.0",
|
||||
"libc",
|
||||
"miniz_oxide",
|
||||
"object",
|
||||
@ -467,6 +472,12 @@ dependencies = [
|
||||
"nom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "0.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
@ -771,7 +782,7 @@ version = "0.1.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.0",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
@ -840,7 +851,7 @@ version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -917,7 +928,7 @@ version = "5.5.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.0",
|
||||
"hashbrown",
|
||||
"lock_api",
|
||||
"once_cell",
|
||||
@ -1054,7 +1065,7 @@ version = "0.8.33"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1295,6 +1306,39 @@ dependencies = [
|
||||
"validator",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "flowy-folder"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"bytes",
|
||||
"chrono",
|
||||
"collab",
|
||||
"collab-entity",
|
||||
"collab-folder",
|
||||
"collab-integrate",
|
||||
"collab-plugins",
|
||||
"flowy-codegen",
|
||||
"flowy-derive",
|
||||
"flowy-error",
|
||||
"flowy-folder-pub",
|
||||
"flowy-notification",
|
||||
"lazy_static",
|
||||
"lib-dispatch",
|
||||
"lib-infra",
|
||||
"nanoid",
|
||||
"parking_lot 0.12.1",
|
||||
"protobuf",
|
||||
"serde_json",
|
||||
"strum_macros 0.21.1",
|
||||
"tokio",
|
||||
"tokio-stream",
|
||||
"tracing",
|
||||
"unicode-segmentation",
|
||||
"uuid",
|
||||
"validator",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "flowy-folder-pub"
|
||||
version = "0.1.0"
|
||||
@ -1577,7 +1621,7 @@ version = "0.1.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.0",
|
||||
"js-sys",
|
||||
"libc",
|
||||
"wasi 0.9.0+wasi-snapshot-preview1",
|
||||
@ -1590,7 +1634,7 @@ version = "0.2.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.0",
|
||||
"js-sys",
|
||||
"libc",
|
||||
"wasi 0.11.0+wasi-snapshot-preview1",
|
||||
@ -1955,7 +1999,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6cc2083760572ee02385ab8b7c02c20925d2dd1f97a1a25a8737a238608f1152"
|
||||
dependencies = [
|
||||
"accessory",
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.0",
|
||||
"delegate-display",
|
||||
"fancy_constructor",
|
||||
"js-sys",
|
||||
@ -2002,7 +2046,7 @@ version = "0.1.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2141,7 +2185,7 @@ version = "0.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c571b676ddfc9a8c12f1f3d3085a7b163966a8fd8098a90640953ce5f6170161"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.0",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
@ -2231,7 +2275,7 @@ version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fd94d5da95b30ae6e10621ad02340909346ad91661f3f8c0f2b62345e46a2f67"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.0",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.48",
|
||||
@ -2293,6 +2337,12 @@ version = "2.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149"
|
||||
|
||||
[[package]]
|
||||
name = "memory_units"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8452105ba047068f40ff7093dd1d9da90898e63dd61736462e9cdda6a90ad3c3"
|
||||
|
||||
[[package]]
|
||||
name = "mime"
|
||||
version = "0.3.17"
|
||||
@ -2452,7 +2502,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "15c9d69dd87a29568d4d017cfe8ec518706046a05184e5aea92d0af890b803c8"
|
||||
dependencies = [
|
||||
"bitflags 2.4.2",
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.0",
|
||||
"foreign-types",
|
||||
"libc",
|
||||
"once_cell",
|
||||
@ -2536,7 +2586,7 @@ version = "0.8.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "60a2cfe6f0ad2bfc16aefa463b497d5c7a5ecd44a23efa72aa342d90177356dc"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.0",
|
||||
"instant",
|
||||
"libc",
|
||||
"redox_syscall 0.2.16",
|
||||
@ -2550,7 +2600,7 @@ version = "0.9.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.0",
|
||||
"libc",
|
||||
"redox_syscall 0.4.1",
|
||||
"smallvec",
|
||||
@ -2853,7 +2903,7 @@ version = "0.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d52cff9d1d4dee5fe6d03729099f4a310a41179e0a10dbf542039873f2e826fb"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.0",
|
||||
"cpufeatures",
|
||||
"opaque-debug",
|
||||
"universal-hash",
|
||||
@ -3621,7 +3671,7 @@ version = "0.10.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.0",
|
||||
"cpufeatures",
|
||||
"digest",
|
||||
]
|
||||
@ -3638,7 +3688,7 @@ version = "0.10.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.0",
|
||||
"cpufeatures",
|
||||
"digest",
|
||||
]
|
||||
@ -3875,7 +3925,7 @@ version = "3.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "01ce4141aa927a6d1bd34a041795abd0db1cccba5d5f24b009f694bdf3a1f3fa"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.0",
|
||||
"fastrand",
|
||||
"redox_syscall 0.4.1",
|
||||
"rustix",
|
||||
@ -3971,7 +4021,7 @@ version = "1.1.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.0",
|
||||
"once_cell",
|
||||
]
|
||||
|
||||
@ -4465,7 +4515,7 @@ version = "0.2.90"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b1223296a201415c7fad14792dbefaace9bd52b62d33453ade1c5b5f07555406"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.0",
|
||||
"wasm-bindgen-macro",
|
||||
]
|
||||
|
||||
@ -4490,7 +4540,7 @@ version = "0.4.40"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bde2032aeb86bdfaecc8b261eef3cba735cc426c1f3a3416d1e0791be95fc461"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.0",
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
"web-sys",
|
||||
@ -4611,6 +4661,18 @@ dependencies = [
|
||||
"web-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wee_alloc"
|
||||
version = "0.4.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dbb3b5a6b2bb17cb6ad44a2e68a43e8d2722c997da10e928665c72ec6c0a0b8e"
|
||||
dependencies = [
|
||||
"cfg-if 0.1.10",
|
||||
"libc",
|
||||
"memory_units",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "which"
|
||||
version = "4.4.2"
|
||||
@ -4801,7 +4863,7 @@ version = "0.50.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.0",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
|
@ -24,6 +24,8 @@ flowy-error = { path = "../../rust-lib/flowy-error" }
|
||||
flowy-derive = { path = "../../rust-lib/build-tool/flowy-derive" }
|
||||
flowy-codegen = { path = "../../rust-lib/build-tool/flowy-codegen" }
|
||||
flowy-document = { path = "../../rust-lib/flowy-document" }
|
||||
flowy-folder = { path = "../../rust-lib/flowy-folder" }
|
||||
flowy-storage = { path = "../../rust-lib/flowy-storage" }
|
||||
lib-infra = { path = "../../rust-lib/lib-infra" }
|
||||
collab = { version = "0.1.0" }
|
||||
collab-entity = { version = "0.1.0" }
|
||||
@ -40,6 +42,7 @@ wasm-bindgen-futures = "0.4.40"
|
||||
serde-wasm-bindgen = "0.4"
|
||||
|
||||
|
||||
|
||||
[profile.dev]
|
||||
opt-level = 0
|
||||
lto = false
|
||||
@ -50,11 +53,6 @@ lto = true
|
||||
opt-level = 3
|
||||
codegen-units = 1
|
||||
|
||||
[profile.profiling]
|
||||
inherits = "release"
|
||||
debug = true
|
||||
codegen-units = 16
|
||||
lto = false
|
||||
|
||||
[patch.crates-io]
|
||||
# Please using the following command to update the revision id
|
||||
|
@ -4,8 +4,6 @@ version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
[lib]
|
||||
crate-type = ["cdylib", "rlib"]
|
||||
|
||||
[dependencies]
|
||||
indexed_db_futures = { version = "0.4" }
|
||||
|
@ -4,8 +4,6 @@ version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
[lib]
|
||||
crate-type = ["cdylib", "rlib"]
|
||||
|
||||
[dependencies]
|
||||
af-persistence.workspace = true
|
||||
|
@ -1,16 +1,15 @@
|
||||
use flowy_codegen::Project;
|
||||
|
||||
fn main() {
|
||||
let crate_name = env!("CARGO_PKG_NAME");
|
||||
|
||||
flowy_codegen::protobuf_file::ts_gen(
|
||||
crate_name,
|
||||
env!("CARGO_PKG_NAME"),
|
||||
"user",
|
||||
Project::Web {
|
||||
relative_path: "../../../".to_string(),
|
||||
},
|
||||
);
|
||||
flowy_codegen::ts_event::gen(
|
||||
crate_name,
|
||||
"user",
|
||||
Project::Web {
|
||||
relative_path: "../../../".to_string(),
|
||||
},
|
||||
|
@ -0,0 +1,20 @@
|
||||
use af_persistence::store::AppFlowyWASMStore;
|
||||
use flowy_error::FlowyResult;
|
||||
use flowy_user_pub::session::Session;
|
||||
use std::rc::Rc;
|
||||
use std::sync::Arc;
|
||||
use tokio::sync::RwLock;
|
||||
|
||||
pub struct AuthenticateUser {
|
||||
session: Arc<RwLock<Option<Session>>>,
|
||||
store: Rc<AppFlowyWASMStore>,
|
||||
}
|
||||
|
||||
impl AuthenticateUser {
|
||||
pub async fn new(store: Rc<AppFlowyWASMStore>) -> FlowyResult<Self> {
|
||||
Ok(Self {
|
||||
session: Arc::new(RwLock::new(None)),
|
||||
store,
|
||||
})
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
use crate::entities::*;
|
||||
use crate::manager::UserManagerWASM;
|
||||
use crate::manager::UserManager;
|
||||
use flowy_error::{FlowyError, FlowyResult};
|
||||
use lib_dispatch::prelude::{data_result_ok, AFPluginData, AFPluginState, DataResult};
|
||||
use lib_infra::box_any::BoxAny;
|
||||
@ -8,7 +8,7 @@ use std::rc::{Rc, Weak};
|
||||
#[tracing::instrument(level = "debug", skip(data, manager), err)]
|
||||
pub async fn oauth_sign_in_handler(
|
||||
data: AFPluginData<OauthSignInPB>,
|
||||
manager: AFPluginState<Weak<UserManagerWASM>>,
|
||||
manager: AFPluginState<Weak<UserManager>>,
|
||||
) -> DataResult<UserProfilePB, FlowyError> {
|
||||
let manager = upgrade_manager(manager)?;
|
||||
let params = data.into_inner();
|
||||
@ -19,7 +19,7 @@ pub async fn oauth_sign_in_handler(
|
||||
#[tracing::instrument(level = "debug", skip(data, manager), err)]
|
||||
pub async fn add_user_handler(
|
||||
data: AFPluginData<AddUserPB>,
|
||||
manager: AFPluginState<Weak<UserManagerWASM>>,
|
||||
manager: AFPluginState<Weak<UserManager>>,
|
||||
) -> Result<(), FlowyError> {
|
||||
let manager = upgrade_manager(manager)?;
|
||||
let params = data.into_inner();
|
||||
@ -30,7 +30,7 @@ pub async fn add_user_handler(
|
||||
#[tracing::instrument(level = "debug", skip(data, manager), err)]
|
||||
pub async fn sign_in_with_password_handler(
|
||||
data: AFPluginData<UserSignInPB>,
|
||||
manager: AFPluginState<Weak<UserManagerWASM>>,
|
||||
manager: AFPluginState<Weak<UserManager>>,
|
||||
) -> DataResult<UserProfilePB, FlowyError> {
|
||||
let manager = upgrade_manager(manager)?;
|
||||
let params = data.into_inner();
|
||||
@ -40,9 +40,7 @@ pub async fn sign_in_with_password_handler(
|
||||
data_result_ok(UserProfilePB::from(user_profile))
|
||||
}
|
||||
|
||||
fn upgrade_manager(
|
||||
manager: AFPluginState<Weak<UserManagerWASM>>,
|
||||
) -> FlowyResult<Rc<UserManagerWASM>> {
|
||||
fn upgrade_manager(manager: AFPluginState<Weak<UserManager>>) -> FlowyResult<Rc<UserManager>> {
|
||||
let manager = manager
|
||||
.upgrade()
|
||||
.ok_or(FlowyError::internal().with_context("The user session is already drop"))?;
|
||||
|
@ -1,12 +1,12 @@
|
||||
use crate::event_handler::*;
|
||||
use crate::manager::UserManagerWASM;
|
||||
use crate::manager::UserManager;
|
||||
use flowy_derive::{Flowy_Event, ProtoBuf_Enum};
|
||||
use lib_dispatch::prelude::AFPlugin;
|
||||
use std::rc::Weak;
|
||||
use strum_macros::Display;
|
||||
|
||||
#[rustfmt::skip]
|
||||
pub fn init(user_manager: Weak<UserManagerWASM>) -> AFPlugin {
|
||||
pub fn init(user_manager: Weak<UserManager>) -> AFPlugin {
|
||||
AFPlugin::new()
|
||||
.name("Flowy-User")
|
||||
.state(user_manager)
|
||||
|
@ -1,3 +1,4 @@
|
||||
pub mod authenticate_user;
|
||||
mod define;
|
||||
pub mod entities;
|
||||
mod event_handler;
|
||||
|
@ -1,3 +1,4 @@
|
||||
use crate::authenticate_user::AuthenticateUser;
|
||||
use crate::define::{user_profile_key, user_workspace_key, AF_USER_SESSION_KEY};
|
||||
use af_persistence::store::{AppFlowyWASMStore, IndexddbStore};
|
||||
use anyhow::Context;
|
||||
@ -37,22 +38,26 @@ pub trait UserCallback {
|
||||
) -> Fut<FlowyResult<()>>;
|
||||
}
|
||||
|
||||
pub struct UserManagerWASM {
|
||||
pub struct UserManager {
|
||||
device_id: String,
|
||||
pub(crate) store: Rc<AppFlowyWASMStore>,
|
||||
pub(crate) cloud_services: Rc<dyn UserCloudServiceProvider>,
|
||||
pub(crate) collab_builder: Weak<AppFlowyCollabBuilder>,
|
||||
pub(crate) store: Rc<AppFlowyWASMStore>,
|
||||
user_callbacks: Vec<Rc<dyn UserCallback>>,
|
||||
pub(crate) authenticate_user: Rc<AuthenticateUser>,
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub(crate) user_awareness: Rc<Mutex<Option<MutexUserAwareness>>>,
|
||||
pub(crate) collab_db: Arc<CollabKVDB>,
|
||||
|
||||
user_callbacks: Vec<Rc<dyn UserCallback>>,
|
||||
}
|
||||
|
||||
impl UserManagerWASM {
|
||||
impl UserManager {
|
||||
pub async fn new(
|
||||
device_id: &str,
|
||||
store: Rc<AppFlowyWASMStore>,
|
||||
cloud_services: Rc<dyn UserCloudServiceProvider>,
|
||||
authenticate_user: Rc<AuthenticateUser>,
|
||||
collab_builder: Weak<AppFlowyCollabBuilder>,
|
||||
) -> Result<Self, FlowyError> {
|
||||
let device_id = device_id.to_string();
|
||||
@ -63,6 +68,7 @@ impl UserManagerWASM {
|
||||
cloud_services,
|
||||
collab_builder,
|
||||
store,
|
||||
authenticate_user,
|
||||
user_callbacks: vec![],
|
||||
user_awareness: Rc::new(Default::default()),
|
||||
collab_db,
|
||||
|
@ -20,12 +20,15 @@ collab-integrate = { workspace = true }
|
||||
tokio-stream.workspace = true
|
||||
|
||||
af-user.workspace = true
|
||||
af-persistence.workspace = true
|
||||
flowy-storage = { workspace = true }
|
||||
flowy-notification = { workspace = true, features = ["web_ts"] }
|
||||
flowy-user-pub = { workspace = true }
|
||||
flowy-server = { workspace = true }
|
||||
flowy-server-pub = { workspace = true }
|
||||
flowy-error = { workspace = true, features = ["impl_from_dispatch_error", "web_ts"] }
|
||||
flowy-document = { workspace = true, features = ["web_ts"] }
|
||||
flowy-folder = { workspace = true, features = ["web_ts"] }
|
||||
lib-infra = { workspace = true }
|
||||
collab = { workspace = true, features = ["async-plugin"] }
|
||||
web-sys = "0.3"
|
||||
@ -34,9 +37,23 @@ uuid.workspace = true
|
||||
serde-wasm-bindgen.workspace = true
|
||||
js-sys = "0.3.67"
|
||||
|
||||
|
||||
# `wee_alloc` is a tiny allocator for wasm that is only ~1K in code size
|
||||
# compared to the default allocator's ~10K. However, it is slower than the default
|
||||
# allocator, so it's not enabled by default.
|
||||
wee_alloc = { version = "0.4.2", optional = true }
|
||||
|
||||
# The `console_error_panic_hook` crate provides better debugging of panics by
|
||||
# logging them with `console.error`. This is great for development, but requires
|
||||
# all the `std::fmt` and `std::panicking` infrastructure, so it's only enabled
|
||||
# in debug mode.
|
||||
[target."cfg(debug_assertions)".dependencies]
|
||||
console_error_panic_hook = "0.1.5"
|
||||
|
||||
[dev-dependencies]
|
||||
wasm-bindgen-test = "0.3.40"
|
||||
tokio = { version = "1.0", features = ["sync"] }
|
||||
|
||||
[features]
|
||||
#default = ["wee_alloc"]
|
||||
localhost_dev = []
|
@ -1,8 +1,15 @@
|
||||
use crate::deps_resolve::document_deps::DocumentDepsResolver;
|
||||
use crate::deps_resolve::folder_deps::FolderDepsResolver;
|
||||
use crate::integrate::server::ServerProviderWASM;
|
||||
use af_user::manager::UserManagerWASM;
|
||||
use af_persistence::store::AppFlowyWASMStore;
|
||||
use af_user::authenticate_user::AuthenticateUser;
|
||||
use af_user::manager::UserManager;
|
||||
use collab_integrate::collab_builder::AppFlowyCollabBuilder;
|
||||
use flowy_document::manager::DocumentManager;
|
||||
use flowy_error::FlowyResult;
|
||||
use flowy_folder::manager::FolderManager;
|
||||
use flowy_server_pub::af_cloud_config::AFCloudConfiguration;
|
||||
use flowy_storage::ObjectStorageService;
|
||||
use lib_dispatch::prelude::AFPluginDispatcher;
|
||||
use lib_dispatch::runtime::AFPluginRuntime;
|
||||
use std::rc::Rc;
|
||||
@ -11,7 +18,9 @@ use std::sync::Arc;
|
||||
pub struct AppFlowyWASMCore {
|
||||
pub collab_builder: Arc<AppFlowyCollabBuilder>,
|
||||
pub event_dispatcher: Rc<AFPluginDispatcher>,
|
||||
pub user_manager: Rc<UserManagerWASM>,
|
||||
pub user_manager: Rc<UserManager>,
|
||||
pub folder_manager: Rc<FolderManager>,
|
||||
pub document_manager: Rc<DocumentManager>,
|
||||
}
|
||||
|
||||
impl AppFlowyWASMCore {
|
||||
@ -23,10 +32,31 @@ impl AppFlowyWASMCore {
|
||||
device_id.to_string(),
|
||||
));
|
||||
|
||||
let store = Rc::new(AppFlowyWASMStore::new().await?);
|
||||
let auth_user = Rc::new(AuthenticateUser::new(store.clone()).await?);
|
||||
|
||||
let document_manager = DocumentDepsResolver::resolve(
|
||||
Rc::downgrade(&auth_user),
|
||||
collab_builder.clone(),
|
||||
server_provider.clone(),
|
||||
Rc::downgrade(&(server_provider.clone() as Rc<dyn ObjectStorageService>)),
|
||||
)
|
||||
.await;
|
||||
|
||||
let folder_manager = FolderDepsResolver::resolve(
|
||||
Rc::downgrade(&auth_user),
|
||||
document_manager.clone(),
|
||||
collab_builder.clone(),
|
||||
server_provider.clone(),
|
||||
)
|
||||
.await;
|
||||
|
||||
let user_manager = Rc::new(
|
||||
UserManagerWASM::new(
|
||||
UserManager::new(
|
||||
device_id,
|
||||
store,
|
||||
server_provider.clone(),
|
||||
auth_user,
|
||||
Arc::downgrade(&collab_builder),
|
||||
)
|
||||
.await?,
|
||||
@ -40,6 +70,8 @@ impl AppFlowyWASMCore {
|
||||
collab_builder,
|
||||
event_dispatcher,
|
||||
user_manager,
|
||||
folder_manager,
|
||||
document_manager,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,19 @@
|
||||
use crate::integrate::server::ServerProviderWASM;
|
||||
use af_user::authenticate_user::AuthenticateUser;
|
||||
use collab_integrate::collab_builder::AppFlowyCollabBuilder;
|
||||
use flowy_document::manager::DocumentManager;
|
||||
use flowy_storage::ObjectStorageService;
|
||||
use std::rc::{Rc, Weak};
|
||||
use std::sync::Arc;
|
||||
|
||||
pub struct DocumentDepsResolver;
|
||||
impl DocumentDepsResolver {
|
||||
pub async fn resolve(
|
||||
authenticate_user: Weak<AuthenticateUser>,
|
||||
collab_builder: Arc<AppFlowyCollabBuilder>,
|
||||
server_provider: Rc<ServerProviderWASM>,
|
||||
storage_service: Weak<dyn ObjectStorageService>,
|
||||
) -> Rc<DocumentManager> {
|
||||
todo!()
|
||||
}
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
use crate::integrate::server::ServerProviderWASM;
|
||||
use af_user::authenticate_user::AuthenticateUser;
|
||||
use collab_integrate::collab_builder::AppFlowyCollabBuilder;
|
||||
use flowy_document::manager::DocumentManager;
|
||||
use flowy_folder::manager::FolderManager;
|
||||
use std::rc::{Rc, Weak};
|
||||
use std::sync::Arc;
|
||||
|
||||
pub struct FolderDepsResolver;
|
||||
|
||||
impl FolderDepsResolver {
|
||||
pub async fn resolve(
|
||||
authenticate_user: Weak<AuthenticateUser>,
|
||||
document_manager: Rc<DocumentManager>,
|
||||
collab_builder: Arc<AppFlowyCollabBuilder>,
|
||||
server_provider: Rc<ServerProviderWASM>,
|
||||
) -> Rc<FolderManager> {
|
||||
todo!()
|
||||
}
|
||||
}
|
@ -0,0 +1,2 @@
|
||||
pub(crate) mod document_deps;
|
||||
pub(crate) mod folder_deps;
|
@ -6,11 +6,10 @@ use flowy_error::FlowyError;
|
||||
use flowy_server::af_cloud::AppFlowyCloudServer;
|
||||
use flowy_server::AppFlowyServer;
|
||||
use flowy_server_pub::af_cloud_config::AFCloudConfiguration;
|
||||
use flowy_user_pub::cloud::{
|
||||
UserCloudService, UserCloudServiceProvider, UserCloudServiceProviderBase,
|
||||
};
|
||||
use flowy_storage::{ObjectIdentity, ObjectStorageService, ObjectValue};
|
||||
use flowy_user_pub::cloud::{UserCloudService, UserCloudServiceProvider};
|
||||
use flowy_user_pub::entities::{Authenticator, UserTokenState};
|
||||
use lib_infra::future::{to_fut, Fut};
|
||||
use lib_infra::future::{to_fut, Fut, FutureResult};
|
||||
use parking_lot::RwLock;
|
||||
use std::rc::Rc;
|
||||
use std::sync::Arc;
|
||||
@ -64,9 +63,7 @@ impl CollabCloudPluginProvider for ServerProviderWASM {
|
||||
}
|
||||
}
|
||||
|
||||
impl UserCloudServiceProvider for ServerProviderWASM {}
|
||||
|
||||
impl UserCloudServiceProviderBase for ServerProviderWASM {
|
||||
impl UserCloudServiceProvider for ServerProviderWASM {
|
||||
fn set_token(&self, token: &str) -> Result<(), FlowyError> {
|
||||
self.get_server().set_token(token)?;
|
||||
Ok(())
|
||||
@ -104,3 +101,21 @@ impl UserCloudServiceProviderBase for ServerProviderWASM {
|
||||
self.config.base_url.clone()
|
||||
}
|
||||
}
|
||||
|
||||
impl ObjectStorageService for ServerProviderWASM {
|
||||
fn get_object_url(&self, object_id: ObjectIdentity) -> FutureResult<String, FlowyError> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn put_object(&self, url: String, object_value: ObjectValue) -> FutureResult<(), FlowyError> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn delete_object(&self, url: String) -> FutureResult<(), FlowyError> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn get_object(&self, url: String) -> FutureResult<ObjectValue, FlowyError> {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ use std::cell::RefCell;
|
||||
use std::rc::Rc;
|
||||
|
||||
pub mod core;
|
||||
mod deps_resolve;
|
||||
mod integrate;
|
||||
pub mod notification;
|
||||
|
||||
@ -23,6 +24,10 @@ lazy_static! {
|
||||
static ref APPFLOWY_CORE: RefCellAppFlowyCore = RefCellAppFlowyCore::new();
|
||||
}
|
||||
|
||||
#[cfg(feature = "wee_alloc")]
|
||||
#[global_allocator]
|
||||
static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT;
|
||||
|
||||
#[wasm_bindgen]
|
||||
extern "C" {
|
||||
#[wasm_bindgen(js_namespace = console)]
|
||||
@ -37,6 +42,10 @@ pub fn init_tracing_log() {
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn init_wasm_core() -> js_sys::Promise {
|
||||
// It's disabled in release mode so it doesn't bloat up the file size.
|
||||
#[cfg(debug_assertions)]
|
||||
console_error_panic_hook::set_once();
|
||||
|
||||
#[cfg(feature = "localhost_dev")]
|
||||
let config = AFCloudConfiguration {
|
||||
base_url: "http://localhost".to_string(),
|
||||
|
@ -7,6 +7,11 @@ use flowy_error::FlowyResult;
|
||||
use flowy_server_pub::af_cloud_config::AFCloudConfiguration;
|
||||
use parking_lot::Once;
|
||||
|
||||
use flowy_document::deps::DocumentData;
|
||||
use flowy_document::entities::{CreateDocumentPayloadPB, DocumentDataPB, OpenDocumentPayloadPB};
|
||||
use flowy_document::event_map::DocumentEvent;
|
||||
use flowy_folder::entities::{CreateViewPayloadPB, ViewLayoutPB, ViewPB};
|
||||
use flowy_folder::event_map::FolderEvent;
|
||||
use std::sync::Arc;
|
||||
use uuid::Uuid;
|
||||
|
||||
@ -48,6 +53,44 @@ impl WASMEventTester {
|
||||
.parse::<UserProfilePB>();
|
||||
Ok(user_profile)
|
||||
}
|
||||
|
||||
pub async fn create_and_open_document(&self, parent_id: &str) -> ViewPB {
|
||||
let payload = CreateViewPayloadPB {
|
||||
parent_view_id: parent_id.to_string(),
|
||||
name,
|
||||
desc: "".to_string(),
|
||||
thumbnail: None,
|
||||
layout: ViewLayoutPB::Document,
|
||||
initial_data,
|
||||
meta: Default::default(),
|
||||
set_as_current: true,
|
||||
index: None,
|
||||
};
|
||||
let view = self
|
||||
.event_builder()
|
||||
.event(FolderEvent::CreateView)
|
||||
.payload(payload)
|
||||
.async_send()
|
||||
.await
|
||||
.parse::<ViewPB>();
|
||||
|
||||
let payload = OpenDocumentPayloadPB {
|
||||
document_id: view.id.clone(),
|
||||
};
|
||||
|
||||
let _ = self
|
||||
.event_builder()
|
||||
.event(DocumentEvent::OpenDocument)
|
||||
.payload(payload)
|
||||
.async_send()
|
||||
.await
|
||||
.parse::<DocumentDataPB>();
|
||||
view
|
||||
}
|
||||
|
||||
fn event_builder(&self) -> EventBuilder {
|
||||
EventBuilder::new(self.core.clone())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn unique_email() -> String {
|
||||
|
1
frontend/rust-lib/Cargo.lock
generated
1
frontend/rust-lib/Cargo.lock
generated
@ -1920,6 +1920,7 @@ dependencies = [
|
||||
name = "flowy-folder"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"bytes",
|
||||
"chrono",
|
||||
"collab",
|
||||
|
@ -76,7 +76,7 @@ pub fn dart_gen(crate_name: &str) {
|
||||
}
|
||||
|
||||
#[allow(unused_variables)]
|
||||
pub fn ts_gen(crate_name: &str, project: Project) {
|
||||
pub fn ts_gen(crate_name: &str, dest_folder_name: &str, project: Project) {
|
||||
// 1. generate the proto files to proto_file_dir
|
||||
#[cfg(feature = "proto_gen")]
|
||||
let proto_crates = gen_proto_files(crate_name);
|
||||
@ -116,7 +116,7 @@ pub fn ts_gen(crate_name: &str, project: Project) {
|
||||
// 2. generate the protobuf files(Dart)
|
||||
#[cfg(feature = "ts")]
|
||||
generate_ts_protobuf_files(
|
||||
crate_name,
|
||||
dest_folder_name,
|
||||
&proto_file_output_path,
|
||||
&proto_file_paths,
|
||||
&file_names,
|
||||
|
@ -13,7 +13,7 @@ use std::path::PathBuf;
|
||||
use syn::Item;
|
||||
use walkdir::WalkDir;
|
||||
|
||||
pub fn gen(crate_name: &str, project: Project) {
|
||||
pub fn gen(dest_folder_name: &str, project: Project) {
|
||||
let root = project.event_root();
|
||||
let backend_service_path = project.dst();
|
||||
|
||||
@ -40,7 +40,7 @@ pub fn gen(crate_name: &str, project: Project) {
|
||||
}
|
||||
render_result.push_str(TS_FOOTER);
|
||||
|
||||
let ts_event_folder: PathBuf = [&root, &backend_service_path, "events", crate_name]
|
||||
let ts_event_folder: PathBuf = [&root, &backend_service_path, "events", dest_folder_name]
|
||||
.iter()
|
||||
.collect();
|
||||
if !ts_event_folder.as_path().exists() {
|
||||
@ -82,7 +82,10 @@ pub fn gen(crate_name: &str, project: Project) {
|
||||
Ok(ref mut file) => {
|
||||
let mut export = String::new();
|
||||
export.push_str("// Auto-generated, do not edit \n");
|
||||
export.push_str(&format!("export * from '../../models/{}';\n", crate_name));
|
||||
export.push_str(&format!(
|
||||
"export * from '../../models/{}';\n",
|
||||
dest_folder_name
|
||||
));
|
||||
export.push_str(&format!("export * from './{}';\n", event_file));
|
||||
file.write_all(export.as_bytes()).unwrap();
|
||||
File::flush(file).unwrap();
|
||||
|
@ -3,7 +3,7 @@
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
int64_t init_sdk(char *data);
|
||||
int64_t init_sdk(int64_t port, char *data);
|
||||
|
||||
void async_event(int64_t port, const uint8_t *input, uintptr_t len);
|
||||
|
||||
|
@ -13,6 +13,7 @@ use flowy_notification::{register_notification_sender, unregister_all_notificati
|
||||
use flowy_server_pub::AuthenticatorType;
|
||||
use lib_dispatch::prelude::ToBytes;
|
||||
use lib_dispatch::prelude::*;
|
||||
use lib_dispatch::runtime::AFPluginRuntime;
|
||||
|
||||
use crate::appflowy_yaml::save_appflowy_cloud_config;
|
||||
use crate::env_serde::AppFlowyDartConfiguration;
|
||||
@ -52,7 +53,9 @@ unsafe impl Sync for MutexAppFlowyCore {}
|
||||
unsafe impl Send for MutexAppFlowyCore {}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn init_sdk(data: *mut c_char) -> i64 {
|
||||
pub extern "C" fn init_sdk(_port: i64, data: *mut c_char) -> i64 {
|
||||
// and sent it the `Rust's` result
|
||||
// no need to convert anything :)
|
||||
let c_str = unsafe { CStr::from_ptr(data) };
|
||||
let serde_str = c_str.to_str().unwrap();
|
||||
let configuration = AppFlowyDartConfiguration::from_str(serde_str);
|
||||
@ -78,7 +81,13 @@ pub extern "C" fn init_sdk(data: *mut c_char) -> i64 {
|
||||
core.close_db();
|
||||
}
|
||||
|
||||
*APPFLOWY_CORE.0.lock() = Some(AppFlowyCore::new(config));
|
||||
let runtime = Arc::new(AFPluginRuntime::new().unwrap());
|
||||
let cloned_runtime = runtime.clone();
|
||||
// let isolate = allo_isolate::Isolate::new(port);
|
||||
*APPFLOWY_CORE.0.lock() = runtime.block_on(async move {
|
||||
Some(AppFlowyCore::new(config, cloned_runtime).await)
|
||||
// isolate.post("".to_string());
|
||||
});
|
||||
0
|
||||
}
|
||||
|
||||
|
@ -19,6 +19,7 @@ use flowy_notification::register_notification_sender;
|
||||
use flowy_server::AppFlowyServer;
|
||||
use flowy_user::entities::AuthenticatorPB;
|
||||
use flowy_user::errors::FlowyError;
|
||||
use lib_dispatch::runtime::AFPluginRuntime;
|
||||
|
||||
use crate::user_event::TestNotificationSender;
|
||||
|
||||
@ -134,19 +135,14 @@ pub fn document_from_document_doc_state(doc_id: &str, doc_state: CollabDocState)
|
||||
Document::from_doc_state(CollabOrigin::Empty, doc_state, doc_id, vec![]).unwrap()
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
async fn init_core(config: AppFlowyCoreConfig) -> AppFlowyCore {
|
||||
// let runtime = tokio::runtime::Runtime::new().unwrap();
|
||||
// let local_set = tokio::task::LocalSet::new();
|
||||
// runtime.block_on(AppFlowyCore::new(config))
|
||||
AppFlowyCore::new(config).await
|
||||
}
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
async fn init_core(config: AppFlowyCoreConfig) -> AppFlowyCore {
|
||||
std::thread::spawn(|| AppFlowyCore::new(config))
|
||||
.join()
|
||||
.unwrap()
|
||||
std::thread::spawn(|| {
|
||||
let runtime = Arc::new(AFPluginRuntime::new().unwrap());
|
||||
let cloned_runtime = runtime.clone();
|
||||
runtime.block_on(async move { AppFlowyCore::new(config, cloned_runtime).await })
|
||||
})
|
||||
.join()
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
impl std::ops::Deref for EventIntegrationTest {
|
||||
|
@ -8,6 +8,10 @@ fn main() {
|
||||
#[cfg(feature = "tauri_ts")]
|
||||
{
|
||||
flowy_codegen::ts_event::gen(env!("CARGO_PKG_NAME"), flowy_codegen::Project::Tauri);
|
||||
flowy_codegen::protobuf_file::ts_gen(env!("CARGO_PKG_NAME"), flowy_codegen::Project::Tauri);
|
||||
flowy_codegen::protobuf_file::ts_gen(
|
||||
env!("CARGO_PKG_NAME"),
|
||||
env!("CARGO_PKG_NAME"),
|
||||
flowy_codegen::Project::Tauri,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -60,9 +60,9 @@ dart = [
|
||||
]
|
||||
ts = [
|
||||
"flowy-user/tauri_ts",
|
||||
"flowy-folder/ts",
|
||||
"flowy-folder/tauri_ts",
|
||||
"flowy-database2/ts",
|
||||
"flowy-config/tauri_ts",
|
||||
]
|
||||
rev-sqlite = ["flowy-user/rev-sqlite"]
|
||||
openssl_vendored = ["flowy-sqlite/openssl_vendored"]
|
||||
openssl_vendored = ["flowy-sqlite/openssl_vendored"]
|
@ -24,9 +24,7 @@ use flowy_folder_pub::cloud::{
|
||||
use flowy_server_pub::af_cloud_config::AFCloudConfiguration;
|
||||
use flowy_server_pub::supabase_config::SupabaseConfiguration;
|
||||
use flowy_storage::ObjectValue;
|
||||
use flowy_user_pub::cloud::{
|
||||
UserCloudService, UserCloudServiceProvider, UserCloudServiceProviderBase,
|
||||
};
|
||||
use flowy_user_pub::cloud::{UserCloudService, UserCloudServiceProvider};
|
||||
use flowy_user_pub::entities::{Authenticator, UserTokenState};
|
||||
use lib_infra::future::{to_fut, Fut, FutureResult};
|
||||
|
||||
@ -65,9 +63,8 @@ impl ObjectStorageService for ServerProvider {
|
||||
})
|
||||
}
|
||||
}
|
||||
impl UserCloudServiceProvider for ServerProvider {}
|
||||
|
||||
impl UserCloudServiceProviderBase for ServerProvider {
|
||||
impl UserCloudServiceProvider for ServerProvider {
|
||||
fn set_token(&self, token: &str) -> Result<(), FlowyError> {
|
||||
let server = self.get_server()?;
|
||||
server.set_token(token)?;
|
||||
|
@ -10,7 +10,7 @@ use flowy_document::manager::DocumentManager;
|
||||
use flowy_error::FlowyResult;
|
||||
use flowy_folder::manager::{FolderInitDataSource, FolderManager};
|
||||
use flowy_user::event_map::UserStatusCallback;
|
||||
use flowy_user_pub::cloud::{UserCloudConfig, UserCloudServiceProviderBase};
|
||||
use flowy_user_pub::cloud::{UserCloudConfig, UserCloudServiceProvider};
|
||||
use flowy_user_pub::entities::{Authenticator, UserProfile, UserWorkspace};
|
||||
use lib_infra::future::{to_fut, Fut};
|
||||
|
||||
|
@ -2,9 +2,7 @@
|
||||
|
||||
use flowy_storage::ObjectStorageService;
|
||||
use std::sync::Arc;
|
||||
|
||||
use std::time::Duration;
|
||||
|
||||
use tokio::sync::RwLock;
|
||||
use tracing::{debug, error, event, info, instrument};
|
||||
|
||||
@ -53,19 +51,10 @@ pub struct AppFlowyCore {
|
||||
}
|
||||
|
||||
impl AppFlowyCore {
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
pub async fn new(config: AppFlowyCoreConfig) -> Self {
|
||||
let runtime = Arc::new(AFPluginRuntime::new().unwrap());
|
||||
pub async fn new(config: AppFlowyCoreConfig, runtime: Arc<AFPluginRuntime>) -> Self {
|
||||
Self::init(config, runtime).await
|
||||
}
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
pub fn new(config: AppFlowyCoreConfig) -> Self {
|
||||
let runtime = Arc::new(AFPluginRuntime::new().unwrap());
|
||||
let cloned_runtime = runtime.clone();
|
||||
runtime.block_on(Self::init(config, cloned_runtime))
|
||||
}
|
||||
|
||||
pub fn close_db(&self) {
|
||||
self.user_manager.close_db();
|
||||
}
|
||||
|
@ -9,6 +9,6 @@ fn main() {
|
||||
#[cfg(feature = "ts")]
|
||||
{
|
||||
flowy_codegen::ts_event::gen(crate_name, flowy_codegen::Project::Tauri);
|
||||
flowy_codegen::protobuf_file::ts_gen(crate_name, flowy_codegen::Project::Tauri);
|
||||
flowy_codegen::protobuf_file::ts_gen(crate_name, crate_name, flowy_codegen::Project::Tauri);
|
||||
}
|
||||
}
|
||||
|
@ -8,6 +8,10 @@ fn main() {
|
||||
#[cfg(feature = "tauri_ts")]
|
||||
{
|
||||
flowy_codegen::ts_event::gen(env!("CARGO_PKG_NAME"), flowy_codegen::Project::Tauri);
|
||||
flowy_codegen::protobuf_file::ts_gen(env!("CARGO_PKG_NAME"), flowy_codegen::Project::Tauri);
|
||||
flowy_codegen::protobuf_file::ts_gen(
|
||||
env!("CARGO_PKG_NAME"),
|
||||
env!("CARGO_PKG_NAME"),
|
||||
flowy_codegen::Project::Tauri,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -8,19 +8,24 @@ fn main() {
|
||||
#[cfg(feature = "tauri_ts")]
|
||||
{
|
||||
flowy_codegen::ts_event::gen(env!("CARGO_PKG_NAME"), flowy_codegen::Project::Tauri);
|
||||
flowy_codegen::protobuf_file::ts_gen(env!("CARGO_PKG_NAME"), flowy_codegen::Project::Tauri);
|
||||
flowy_codegen::protobuf_file::ts_gen(
|
||||
env!("CARGO_PKG_NAME"),
|
||||
env!("CARGO_PKG_NAME"),
|
||||
flowy_codegen::Project::Tauri,
|
||||
);
|
||||
}
|
||||
|
||||
#[cfg(feature = "web_ts")]
|
||||
{
|
||||
flowy_codegen::ts_event::gen(
|
||||
env!("CARGO_PKG_NAME"),
|
||||
"document",
|
||||
flowy_codegen::Project::Web {
|
||||
relative_path: "../../".to_string(),
|
||||
},
|
||||
);
|
||||
flowy_codegen::protobuf_file::ts_gen(
|
||||
env!("CARGO_PKG_NAME"),
|
||||
"document",
|
||||
flowy_codegen::Project::Web {
|
||||
relative_path: "../../".to_string(),
|
||||
},
|
||||
|
@ -3,11 +3,16 @@ fn main() {
|
||||
flowy_codegen::protobuf_file::dart_gen(env!("CARGO_PKG_NAME"));
|
||||
|
||||
#[cfg(feature = "tauri_ts")]
|
||||
flowy_codegen::protobuf_file::ts_gen(env!("CARGO_PKG_NAME"), flowy_codegen::Project::Tauri);
|
||||
flowy_codegen::protobuf_file::ts_gen(
|
||||
env!("CARGO_PKG_NAME"),
|
||||
env!("CARGO_PKG_NAME"),
|
||||
flowy_codegen::Project::Tauri,
|
||||
);
|
||||
|
||||
#[cfg(feature = "web_ts")]
|
||||
flowy_codegen::protobuf_file::ts_gen(
|
||||
env!("CARGO_PKG_NAME"),
|
||||
"error",
|
||||
flowy_codegen::Project::Web {
|
||||
relative_path: "../../".to_string(),
|
||||
},
|
||||
|
@ -22,7 +22,7 @@ flowy-error = { path = "../flowy-error", features = ["impl_from_dispatch_error"]
|
||||
lib-dispatch = { workspace = true }
|
||||
bytes.workspace = true
|
||||
lib-infra = { workspace = true }
|
||||
tokio = { workspace = true, features = ["full"] }
|
||||
tokio = { workspace = true, features = ["sync"] }
|
||||
nanoid = "0.4.0"
|
||||
lazy_static = "1.4.0"
|
||||
chrono = { workspace = true, default-features = false, features = ["clock"] }
|
||||
@ -32,11 +32,13 @@ uuid.workspace = true
|
||||
tokio-stream = { workspace = true, features = ["sync"] }
|
||||
serde_json.workspace = true
|
||||
validator = "0.16.0"
|
||||
async-trait.workspace = true
|
||||
|
||||
[build-dependencies]
|
||||
flowy-codegen.workspace = true
|
||||
|
||||
[features]
|
||||
dart = ["flowy-codegen/dart", "flowy-notification/dart"]
|
||||
ts = ["flowy-codegen/ts", "flowy-notification/tauri_ts"]
|
||||
tauri_ts = ["flowy-codegen/ts", "flowy-notification/tauri_ts"]
|
||||
web_ts = ["flowy-codegen/ts", "flowy-notification/web_ts"]
|
||||
test_helper = []
|
||||
|
@ -5,9 +5,30 @@ fn main() {
|
||||
flowy_codegen::dart_event::gen(env!("CARGO_PKG_NAME"));
|
||||
}
|
||||
|
||||
#[cfg(feature = "ts")]
|
||||
#[cfg(feature = "tauri_ts")]
|
||||
{
|
||||
flowy_codegen::ts_event::gen(env!("CARGO_PKG_NAME"), flowy_codegen::Project::Tauri);
|
||||
flowy_codegen::protobuf_file::ts_gen(env!("CARGO_PKG_NAME"), flowy_codegen::Project::Tauri);
|
||||
flowy_codegen::protobuf_file::ts_gen(
|
||||
env!("CARGO_PKG_NAME"),
|
||||
env!("CARGO_PKG_NAME"),
|
||||
flowy_codegen::Project::Tauri,
|
||||
);
|
||||
}
|
||||
|
||||
#[cfg(feature = "web_ts")]
|
||||
{
|
||||
flowy_codegen::ts_event::gen(
|
||||
"folder",
|
||||
flowy_codegen::Project::Web {
|
||||
relative_path: "../../".to_string(),
|
||||
},
|
||||
);
|
||||
flowy_codegen::protobuf_file::ts_gen(
|
||||
env!("CARGO_PKG_NAME"),
|
||||
"folder",
|
||||
flowy_codegen::Project::Web {
|
||||
relative_path: "../../".to_string(),
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ use collab_integrate::{CollabKVDB, CollabPersistenceConfig};
|
||||
use flowy_error::{ErrorCode, FlowyError, FlowyResult};
|
||||
use flowy_folder_pub::cloud::{gen_view_id, FolderCloudService};
|
||||
use flowy_folder_pub::folder_builder::ParentChildViews;
|
||||
use lib_infra::async_trait::async_trait;
|
||||
use lib_infra::conditional_send_sync_trait;
|
||||
|
||||
use crate::entities::icon::UpdateViewIconParams;
|
||||
use crate::entities::{
|
||||
@ -35,11 +35,12 @@ use crate::util::{
|
||||
};
|
||||
use crate::view_operation::{create_view, FolderOperationHandler, FolderOperationHandlers};
|
||||
|
||||
/// [FolderUser] represents the user for folder.
|
||||
#[async_trait]
|
||||
pub trait FolderUser: Send + Sync {
|
||||
fn user_id(&self) -> Result<i64, FlowyError>;
|
||||
fn collab_db(&self, uid: i64) -> Result<Weak<CollabKVDB>, FlowyError>;
|
||||
conditional_send_sync_trait! {
|
||||
"[crate::manager::FolderUser] represents the user for folder.";
|
||||
FolderUser {
|
||||
fn user_id(&self) -> Result<i64, FlowyError>;
|
||||
fn collab_db(&self, uid: i64) -> Result<Weak<CollabKVDB>, FlowyError>;
|
||||
}
|
||||
}
|
||||
|
||||
pub struct FolderManager {
|
||||
|
@ -12,7 +12,6 @@ use crate::manager_observer::{
|
||||
subscribe_folder_trash_changed, subscribe_folder_view_changed,
|
||||
};
|
||||
use crate::user_default::DefaultFolderBuilder;
|
||||
use crate::util::is_exist_in_local_disk;
|
||||
|
||||
impl FolderManager {
|
||||
/// Called immediately after the application launched if the user already sign in/sign up.
|
||||
@ -47,7 +46,7 @@ impl FolderManager {
|
||||
FolderInitDataSource::LocalDisk {
|
||||
create_if_not_exist,
|
||||
} => {
|
||||
let is_exist = is_exist_in_local_disk(&self.user, &workspace_id).unwrap_or(false);
|
||||
let is_exist = self.is_workspace_exist_in_local(uid, &workspace_id).await;
|
||||
if is_exist {
|
||||
self
|
||||
.open_local_folder(uid, &workspace_id, collab_db, folder_notifier)
|
||||
@ -104,6 +103,15 @@ impl FolderManager {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn is_workspace_exist_in_local(&self, uid: i64, workspace_id: &str) -> bool {
|
||||
if let Ok(weak_collab) = self.user.collab_db(uid) {
|
||||
if let Some(collab_db) = weak_collab.upgrade() {
|
||||
return collab_db.is_exist(uid, workspace_id).await.unwrap_or(false);
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
async fn create_default_folder(
|
||||
&self,
|
||||
uid: i64,
|
||||
|
@ -1,31 +1,13 @@
|
||||
use collab_folder::Folder;
|
||||
use collab_integrate::CollabKVAction;
|
||||
use collab_plugins::local_storage::kv::KVTransactionDB;
|
||||
use flowy_error::{ErrorCode, FlowyError, FlowyResult};
|
||||
use flowy_folder_pub::folder_builder::ParentChildViews;
|
||||
use std::sync::Arc;
|
||||
use tracing::{event, instrument};
|
||||
|
||||
use crate::entities::UserFolderPB;
|
||||
use crate::manager::FolderUser;
|
||||
use collab_folder::Folder;
|
||||
use flowy_error::{ErrorCode, FlowyError};
|
||||
use flowy_folder_pub::folder_builder::ParentChildViews;
|
||||
use tracing::{event, instrument};
|
||||
|
||||
pub(crate) fn folder_not_init_error() -> FlowyError {
|
||||
FlowyError::internal().with_context("Folder not initialized")
|
||||
}
|
||||
|
||||
pub(crate) fn is_exist_in_local_disk(
|
||||
user: &Arc<dyn FolderUser>,
|
||||
doc_id: &str,
|
||||
) -> FlowyResult<bool> {
|
||||
let uid = user.user_id()?;
|
||||
if let Some(collab_db) = user.collab_db(uid)?.upgrade() {
|
||||
let read_txn = collab_db.read_txn();
|
||||
Ok(read_txn.is_exist(uid, doc_id))
|
||||
} else {
|
||||
Ok(false)
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn workspace_data_not_sync_error(uid: i64, workspace_id: &str) -> FlowyError {
|
||||
FlowyError::from(ErrorCode::WorkspaceDataNotSync).with_payload(UserFolderPB {
|
||||
uid,
|
||||
|
@ -3,11 +3,16 @@ fn main() {
|
||||
flowy_codegen::protobuf_file::dart_gen(env!("CARGO_PKG_NAME"));
|
||||
|
||||
#[cfg(feature = "tauri_ts")]
|
||||
flowy_codegen::protobuf_file::ts_gen(env!("CARGO_PKG_NAME"), flowy_codegen::Project::Tauri);
|
||||
flowy_codegen::protobuf_file::ts_gen(
|
||||
env!("CARGO_PKG_NAME"),
|
||||
env!("CARGO_PKG_NAME"),
|
||||
flowy_codegen::Project::Tauri,
|
||||
);
|
||||
|
||||
#[cfg(feature = "web_ts")]
|
||||
flowy_codegen::protobuf_file::ts_gen(
|
||||
env!("CARGO_PKG_NAME"),
|
||||
"notification",
|
||||
flowy_codegen::Project::Web {
|
||||
relative_path: "../../".to_string(),
|
||||
},
|
||||
|
@ -2,7 +2,6 @@ pub use server::*;
|
||||
|
||||
pub mod af_cloud;
|
||||
pub mod local_server;
|
||||
// mod request;
|
||||
mod response;
|
||||
mod server;
|
||||
|
||||
|
@ -1,198 +0,0 @@
|
||||
use std::{sync::Arc, time::Duration};
|
||||
|
||||
use bytes::Bytes;
|
||||
use hyper::http;
|
||||
use reqwest::{header::HeaderMap, Client, Method, Response};
|
||||
use tokio::sync::oneshot;
|
||||
|
||||
use flowy_error::{internal_error, FlowyError};
|
||||
|
||||
use crate::af_cloud::configuration::HEADER_TOKEN;
|
||||
use crate::response::HttpResponse;
|
||||
|
||||
pub trait ResponseMiddleware {
|
||||
fn receive_response(&self, token: &Option<String>, response: &HttpResponse);
|
||||
}
|
||||
|
||||
pub struct HttpRequestBuilder {
|
||||
url: String,
|
||||
body: Option<Bytes>,
|
||||
response: Option<Bytes>,
|
||||
headers: HeaderMap,
|
||||
method: Method,
|
||||
middleware: Vec<Arc<dyn ResponseMiddleware + Send + Sync>>,
|
||||
}
|
||||
|
||||
impl std::default::Default for HttpRequestBuilder {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
url: "".to_owned(),
|
||||
body: None,
|
||||
response: None,
|
||||
headers: HeaderMap::new(),
|
||||
method: Method::GET,
|
||||
middleware: Vec::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl HttpRequestBuilder {
|
||||
pub fn new() -> Self {
|
||||
HttpRequestBuilder::default()
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn middleware<T>(mut self, middleware: Arc<T>) -> Self
|
||||
where
|
||||
T: 'static + ResponseMiddleware + Send + Sync,
|
||||
{
|
||||
self.middleware.push(middleware);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn get(mut self, url: &str) -> Self {
|
||||
self.url = url.to_owned();
|
||||
self.method = Method::GET;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn post(mut self, url: &str) -> Self {
|
||||
self.url = url.to_owned();
|
||||
self.method = Method::POST;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn patch(mut self, url: &str) -> Self {
|
||||
self.url = url.to_owned();
|
||||
self.method = Method::PATCH;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn delete(mut self, url: &str) -> Self {
|
||||
self.url = url.to_owned();
|
||||
self.method = Method::DELETE;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn header(mut self, key: &'static str, value: &str) -> Self {
|
||||
self.headers.insert(key, value.parse().unwrap());
|
||||
self
|
||||
}
|
||||
|
||||
pub fn json<T>(self, body: T) -> Result<Self, FlowyError>
|
||||
where
|
||||
T: serde::Serialize,
|
||||
{
|
||||
let bytes = Bytes::from(serde_json::to_vec(&body)?);
|
||||
self.bytes(bytes)
|
||||
}
|
||||
|
||||
pub fn bytes(mut self, body: Bytes) -> Result<Self, FlowyError> {
|
||||
self.body = Some(body);
|
||||
Ok(self)
|
||||
}
|
||||
|
||||
pub async fn send(self) -> Result<(), FlowyError> {
|
||||
let _ = self.inner_send().await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn response<T>(self) -> Result<T, FlowyError>
|
||||
where
|
||||
T: serde::de::DeserializeOwned,
|
||||
{
|
||||
let builder = self.inner_send().await?;
|
||||
match builder.response {
|
||||
None => Err(unexpected_empty_payload(&builder.url)),
|
||||
Some(data) => {
|
||||
let value = serde_json::from_slice(&data)?;
|
||||
Ok(value)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn token(&self) -> Option<String> {
|
||||
match self.headers.get(HEADER_TOKEN) {
|
||||
None => None,
|
||||
Some(header) => match header.to_str() {
|
||||
Ok(val) => Some(val.to_owned()),
|
||||
Err(_) => None,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
async fn inner_send(mut self) -> Result<Self, FlowyError> {
|
||||
let (tx, rx) = oneshot::channel::<Result<Response, _>>();
|
||||
let url = self.url.clone();
|
||||
let body = self.body.take();
|
||||
let method = self.method.clone();
|
||||
let headers = self.headers.clone();
|
||||
|
||||
// reqwest client is not 'Sync' but channel is.
|
||||
tokio::spawn(async move {
|
||||
let client = default_client();
|
||||
let mut builder = client.request(method.clone(), url).headers(headers);
|
||||
if let Some(body) = body {
|
||||
builder = builder.body(body);
|
||||
}
|
||||
|
||||
let response = builder.send().await;
|
||||
let _ = tx.send(response);
|
||||
});
|
||||
|
||||
let response = rx.await.map_err(internal_error)?;
|
||||
tracing::trace!("Http Response: {:?}", response);
|
||||
let flowy_response = flowy_response_from(response?).await?;
|
||||
let token = self.token();
|
||||
self.middleware.iter().for_each(|middleware| {
|
||||
middleware.receive_response(&token, &flowy_response);
|
||||
});
|
||||
match flowy_response.error {
|
||||
None => {
|
||||
self.response = Some(flowy_response.data);
|
||||
Ok(self)
|
||||
},
|
||||
Some(error) => Err(FlowyError::new(error.code, &error.msg)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn unexpected_empty_payload(url: &str) -> FlowyError {
|
||||
let msg = format!("Request: {} receives unexpected empty payload", url);
|
||||
FlowyError::payload_none().with_context(msg)
|
||||
}
|
||||
|
||||
async fn flowy_response_from(original: Response) -> Result<HttpResponse, FlowyError> {
|
||||
let bytes = original.bytes().await?;
|
||||
let response: HttpResponse = serde_json::from_slice(&bytes)?;
|
||||
Ok(response)
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
async fn get_response_data(original: Response) -> Result<Bytes, FlowyError> {
|
||||
if original.status() == http::StatusCode::OK {
|
||||
let bytes = original.bytes().await?;
|
||||
let response: HttpResponse = serde_json::from_slice(&bytes)?;
|
||||
match response.error {
|
||||
None => Ok(response.data),
|
||||
Some(error) => Err(FlowyError::new(error.code, &error.msg)),
|
||||
}
|
||||
} else {
|
||||
Err(FlowyError::http().with_context(original))
|
||||
}
|
||||
}
|
||||
|
||||
fn default_client() -> Client {
|
||||
let result = reqwest::Client::builder()
|
||||
.connect_timeout(Duration::from_millis(500))
|
||||
.timeout(Duration::from_secs(5))
|
||||
.build();
|
||||
|
||||
match result {
|
||||
Ok(client) => client,
|
||||
Err(e) => {
|
||||
tracing::error!("Create reqwest client failed: {}", e);
|
||||
reqwest::Client::new()
|
||||
},
|
||||
}
|
||||
}
|
@ -12,7 +12,7 @@ use bytes::Bytes;
|
||||
|
||||
use flowy_error::FlowyError;
|
||||
use lib_infra::future::FutureResult;
|
||||
use lib_infra::{if_native, if_wasm};
|
||||
use lib_infra::{conditional_send_sync_trait, if_native, if_wasm};
|
||||
use mime::Mime;
|
||||
|
||||
pub struct ObjectIdentity {
|
||||
@ -26,50 +26,49 @@ pub struct ObjectValue {
|
||||
pub raw: Bytes,
|
||||
pub mime: Mime,
|
||||
}
|
||||
conditional_send_sync_trait! {
|
||||
"Provides a service for object storage. The trait includes methods for CRUD operations on storage objects.";
|
||||
ObjectStorageService {
|
||||
/// Creates a new storage object.
|
||||
///
|
||||
/// # Parameters
|
||||
/// - `url`: url of the object to be created.
|
||||
///
|
||||
/// # Returns
|
||||
/// - `Ok()`
|
||||
/// - `Err(Error)`: An error occurred during the operation.
|
||||
fn get_object_url(&self, object_id: ObjectIdentity) -> FutureResult<String, FlowyError>;
|
||||
|
||||
/// Provides a service for object storage.
|
||||
///
|
||||
/// The trait includes methods for CRUD operations on storage objects.
|
||||
pub trait ObjectStorageService: Send + Sync + 'static {
|
||||
/// Creates a new storage object.
|
||||
///
|
||||
/// # Parameters
|
||||
/// - `url`: url of the object to be created.
|
||||
///
|
||||
/// # Returns
|
||||
/// - `Ok()`
|
||||
/// - `Err(Error)`: An error occurred during the operation.
|
||||
fn get_object_url(&self, object_id: ObjectIdentity) -> FutureResult<String, FlowyError>;
|
||||
/// Creates a new storage object.
|
||||
///
|
||||
/// # Parameters
|
||||
/// - `url`: url of the object to be created.
|
||||
///
|
||||
/// # Returns
|
||||
/// - `Ok()`
|
||||
/// - `Err(Error)`: An error occurred during the operation.
|
||||
fn put_object(&self, url: String, object_value: ObjectValue) -> FutureResult<(), FlowyError>;
|
||||
|
||||
/// Creates a new storage object.
|
||||
///
|
||||
/// # Parameters
|
||||
/// - `url`: url of the object to be created.
|
||||
///
|
||||
/// # Returns
|
||||
/// - `Ok()`
|
||||
/// - `Err(Error)`: An error occurred during the operation.
|
||||
fn put_object(&self, url: String, object_value: ObjectValue) -> FutureResult<(), FlowyError>;
|
||||
/// Deletes a storage object by its URL.
|
||||
///
|
||||
/// # Parameters
|
||||
/// - `url`: url of the object to be deleted.
|
||||
///
|
||||
/// # Returns
|
||||
/// - `Ok()`
|
||||
/// - `Err(Error)`: An error occurred during the operation.
|
||||
fn delete_object(&self, url: String) -> FutureResult<(), FlowyError>;
|
||||
|
||||
/// Deletes a storage object by its URL.
|
||||
///
|
||||
/// # Parameters
|
||||
/// - `url`: url of the object to be deleted.
|
||||
///
|
||||
/// # Returns
|
||||
/// - `Ok()`
|
||||
/// - `Err(Error)`: An error occurred during the operation.
|
||||
fn delete_object(&self, url: String) -> FutureResult<(), FlowyError>;
|
||||
|
||||
/// Fetches a storage object by its URL.
|
||||
///
|
||||
/// # Parameters
|
||||
/// - `url`: url of the object
|
||||
///
|
||||
/// # Returns
|
||||
/// - `Ok(File)`: The returned file object.
|
||||
/// - `Err(Error)`: An error occurred during the operation.
|
||||
fn get_object(&self, url: String) -> FutureResult<ObjectValue, FlowyError>;
|
||||
/// Fetches a storage object by its URL.
|
||||
///
|
||||
/// # Parameters
|
||||
/// - `url`: url of the object
|
||||
///
|
||||
/// # Returns
|
||||
/// - `Ok(File)`: The returned file object.
|
||||
/// - `Err(Error)`: An error occurred during the operation.
|
||||
fn get_object(&self, url: String) -> FutureResult<ObjectValue, FlowyError>;
|
||||
}
|
||||
}
|
||||
|
||||
pub trait FileStoragePlan: Send + Sync + 'static {
|
||||
|
@ -14,8 +14,8 @@ use uuid::Uuid;
|
||||
use flowy_error::{ErrorCode, FlowyError};
|
||||
|
||||
use lib_infra::box_any::BoxAny;
|
||||
use lib_infra::conditional_send_sync_trait;
|
||||
use lib_infra::future::FutureResult;
|
||||
use lib_infra::{if_native, if_wasm};
|
||||
|
||||
use crate::entities::{
|
||||
AuthResponse, Authenticator, Role, UpdateUserProfileParams, UserCredentials, UserProfile,
|
||||
@ -57,21 +57,12 @@ impl Display for UserCloudConfig {
|
||||
}
|
||||
}
|
||||
|
||||
if_native! {
|
||||
pub trait UserCloudServiceProvider: UserCloudServiceProviderBase + Send + Sync + 'static {}
|
||||
}
|
||||
conditional_send_sync_trait! {
|
||||
"This trait is intended for implementation by providers that offer cloud-based services for users.
|
||||
It includes methods for handling authentication tokens, enabling/disabling synchronization,
|
||||
setting network reachability, managing encryption secrets, and accessing user-specific cloud services.";
|
||||
|
||||
if_wasm! {
|
||||
pub trait UserCloudServiceProvider: UserCloudServiceProviderBase + 'static {}
|
||||
}
|
||||
|
||||
/// `UserCloudServiceProvider` defines a set of methods for managing user cloud services,
|
||||
/// including token management, synchronization settings, network reachability, and authentication.
|
||||
///
|
||||
/// This trait is intended for implementation by providers that offer cloud-based services for users.
|
||||
/// It includes methods for handling authentication tokens, enabling/disabling synchronization,
|
||||
/// setting network reachability, managing encryption secrets, and accessing user-specific cloud services.
|
||||
pub trait UserCloudServiceProviderBase {
|
||||
UserCloudServiceProvider {
|
||||
/// Sets the authentication token for the cloud service.
|
||||
///
|
||||
/// # Arguments
|
||||
@ -126,8 +117,8 @@ pub trait UserCloudServiceProviderBase {
|
||||
/// # Returns
|
||||
/// A `String` representing the service URL.
|
||||
fn service_url(&self) -> String;
|
||||
}
|
||||
}
|
||||
|
||||
/// Provide the generic interface for the user cloud service
|
||||
/// The user cloud service is responsible for the user authentication and user profile management
|
||||
#[allow(unused_variables)]
|
||||
|
@ -8,6 +8,10 @@ fn main() {
|
||||
#[cfg(feature = "tauri_ts")]
|
||||
{
|
||||
flowy_codegen::ts_event::gen(env!("CARGO_PKG_NAME"), flowy_codegen::Project::Tauri);
|
||||
flowy_codegen::protobuf_file::ts_gen(env!("CARGO_PKG_NAME"), flowy_codegen::Project::Tauri);
|
||||
flowy_codegen::protobuf_file::ts_gen(
|
||||
env!("CARGO_PKG_NAME"),
|
||||
env!("CARGO_PKG_NAME"),
|
||||
flowy_codegen::Project::Tauri,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -44,5 +44,6 @@ futures-util = "0.3.26"
|
||||
default = ["use_protobuf"]
|
||||
use_serde = ["bincode", "serde_json", "serde", "serde_repr"]
|
||||
use_protobuf= ["protobuf"]
|
||||
local_set = []
|
||||
|
||||
|
||||
|
@ -16,51 +16,51 @@ use crate::{
|
||||
service::{AFPluginServiceFactory, Service},
|
||||
};
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
#[cfg(any(target_arch = "wasm32", feature = "local_set"))]
|
||||
pub trait AFConcurrent {}
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
#[cfg(any(target_arch = "wasm32", feature = "local_set"))]
|
||||
impl<T> AFConcurrent for T where T: ?Sized {}
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
#[cfg(all(not(target_arch = "wasm32"), not(feature = "local_set")))]
|
||||
pub trait AFConcurrent: Send + Sync {}
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
#[cfg(all(not(target_arch = "wasm32"), not(feature = "local_set")))]
|
||||
impl<T> AFConcurrent for T where T: Send + Sync {}
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
#[cfg(any(target_arch = "wasm32", feature = "local_set"))]
|
||||
pub type AFBoxFuture<'a, T> = futures_core::future::LocalBoxFuture<'a, T>;
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
#[cfg(all(not(target_arch = "wasm32"), not(feature = "local_set")))]
|
||||
pub type AFBoxFuture<'a, T> = futures_core::future::BoxFuture<'a, T>;
|
||||
|
||||
pub type AFStateMap = std::sync::Arc<AFPluginStateMap>;
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
#[cfg(any(target_arch = "wasm32", feature = "local_set"))]
|
||||
pub(crate) fn downcast_owned<T: 'static>(boxed: AFBox) -> Option<T> {
|
||||
boxed.downcast().ok().map(|boxed| *boxed)
|
||||
}
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
#[cfg(all(not(target_arch = "wasm32"), not(feature = "local_set")))]
|
||||
pub(crate) fn downcast_owned<T: 'static + Send + Sync>(boxed: AFBox) -> Option<T> {
|
||||
boxed.downcast().ok().map(|boxed| *boxed)
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
#[cfg(any(target_arch = "wasm32", feature = "local_set"))]
|
||||
pub(crate) type AFBox = Box<dyn Any>;
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
#[cfg(all(not(target_arch = "wasm32"), not(feature = "local_set")))]
|
||||
pub(crate) type AFBox = Box<dyn Any + Send + Sync>;
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
#[cfg(any(target_arch = "wasm32", feature = "local_set"))]
|
||||
pub type BoxFutureCallback =
|
||||
Box<dyn FnOnce(AFPluginEventResponse) -> AFBoxFuture<'static, ()> + 'static>;
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
#[cfg(all(not(target_arch = "wasm32"), not(feature = "local_set")))]
|
||||
pub type BoxFutureCallback =
|
||||
Box<dyn FnOnce(AFPluginEventResponse) -> AFBoxFuture<'static, ()> + Send + Sync + 'static>;
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
#[cfg(any(target_arch = "wasm32", feature = "local_set"))]
|
||||
pub fn af_spawn<T>(future: T) -> tokio::task::JoinHandle<T::Output>
|
||||
where
|
||||
T: Future + 'static,
|
||||
@ -69,7 +69,7 @@ where
|
||||
tokio::task::spawn_local(future)
|
||||
}
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
#[cfg(all(not(target_arch = "wasm32"), not(feature = "local_set")))]
|
||||
pub fn af_spawn<T>(future: T) -> tokio::task::JoinHandle<T::Output>
|
||||
where
|
||||
T: Future + Send + 'static,
|
||||
@ -170,15 +170,6 @@ impl AFPluginDispatcher {
|
||||
callback: Some(Box::new(callback)),
|
||||
};
|
||||
|
||||
// Spawns a future onto the runtime.
|
||||
//
|
||||
// This spawns the given future onto the runtime's executor, usually a
|
||||
// thread pool. The thread pool is then responsible for polling the future
|
||||
// until it completes.
|
||||
//
|
||||
// The provided future will start running in the background immediately
|
||||
// when `spawn` is called, even if you don't await the returned
|
||||
// `JoinHandle`.
|
||||
let handle = dispatch.runtime.spawn(async move {
|
||||
service.call(service_ctx).await.unwrap_or_else(|e| {
|
||||
tracing::error!("Dispatch runtime error: {:?}", e);
|
||||
@ -186,17 +177,35 @@ impl AFPluginDispatcher {
|
||||
})
|
||||
});
|
||||
|
||||
let runtime = dispatch.runtime.clone();
|
||||
DispatchFuture {
|
||||
fut: Box::pin(async move {
|
||||
let result = runtime.run_until(handle).await;
|
||||
result.unwrap_or_else(|e| {
|
||||
let msg = format!("EVENT_DISPATCH join error: {:?}", e);
|
||||
tracing::error!("{}", msg);
|
||||
let error = InternalError::JoinError(msg);
|
||||
error.as_response()
|
||||
})
|
||||
}),
|
||||
#[cfg(any(target_arch = "wasm32", feature = "local_set"))]
|
||||
{
|
||||
let result = dispatch.runtime.block_on(handle);
|
||||
DispatchFuture {
|
||||
fut: Box::pin(async move {
|
||||
result.unwrap_or_else(|e| {
|
||||
let msg = format!("EVENT_DISPATCH join error: {:?}", e);
|
||||
tracing::error!("{}", msg);
|
||||
let error = InternalError::JoinError(msg);
|
||||
error.as_response()
|
||||
})
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(all(not(target_arch = "wasm32"), not(feature = "local_set")))]
|
||||
{
|
||||
let runtime = dispatch.runtime.clone();
|
||||
DispatchFuture {
|
||||
fut: Box::pin(async move {
|
||||
let result = runtime.run_until(handle).await;
|
||||
result.unwrap_or_else(|e| {
|
||||
let msg = format!("EVENT_DISPATCH join error: {:?}", e);
|
||||
tracing::error!("{}", msg);
|
||||
let error = InternalError::JoinError(msg);
|
||||
error.as_response()
|
||||
})
|
||||
}),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -212,7 +221,7 @@ impl AFPluginDispatcher {
|
||||
))
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
#[cfg(any(target_arch = "wasm32", feature = "local_set"))]
|
||||
#[track_caller]
|
||||
pub fn spawn<F>(&self, future: F) -> tokio::task::JoinHandle<F::Output>
|
||||
where
|
||||
@ -221,7 +230,7 @@ impl AFPluginDispatcher {
|
||||
self.runtime.spawn(future)
|
||||
}
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
#[cfg(all(not(target_arch = "wasm32"), not(feature = "local_set")))]
|
||||
#[track_caller]
|
||||
pub fn spawn<F>(&self, future: F) -> tokio::task::JoinHandle<F::Output>
|
||||
where
|
||||
@ -231,7 +240,7 @@ impl AFPluginDispatcher {
|
||||
self.runtime.spawn(future)
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
#[cfg(any(target_arch = "wasm32", feature = "local_set"))]
|
||||
pub async fn run_until<F>(&self, future: F) -> F::Output
|
||||
where
|
||||
F: Future + 'static,
|
||||
@ -240,7 +249,7 @@ impl AFPluginDispatcher {
|
||||
self.runtime.run_until(handle).await.unwrap()
|
||||
}
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
#[cfg(all(not(target_arch = "wasm32"), not(feature = "local_set")))]
|
||||
pub async fn run_until<'a, F>(&self, future: F) -> F::Output
|
||||
where
|
||||
F: Future + Send + 'a,
|
||||
|
@ -8,14 +8,14 @@ use tokio::task::JoinHandle;
|
||||
|
||||
pub struct AFPluginRuntime {
|
||||
inner: Runtime,
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
#[cfg(any(target_arch = "wasm32", feature = "local_set"))]
|
||||
local: tokio::task::LocalSet,
|
||||
}
|
||||
|
||||
impl Display for AFPluginRuntime {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
if cfg!(target_arch = "wasm32") {
|
||||
write!(f, "Runtime(single_thread)")
|
||||
if cfg!(any(target_arch = "wasm32", feature = "local_set")) {
|
||||
write!(f, "Runtime(current_thread)")
|
||||
} else {
|
||||
write!(f, "Runtime(multi_thread)")
|
||||
}
|
||||
@ -27,12 +27,12 @@ impl AFPluginRuntime {
|
||||
let inner = default_tokio_runtime()?;
|
||||
Ok(Self {
|
||||
inner,
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
#[cfg(any(target_arch = "wasm32", feature = "local_set"))]
|
||||
local: tokio::task::LocalSet::new(),
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
#[cfg(any(target_arch = "wasm32", feature = "local_set"))]
|
||||
#[track_caller]
|
||||
pub fn spawn<F>(&self, future: F) -> JoinHandle<F::Output>
|
||||
where
|
||||
@ -41,7 +41,7 @@ impl AFPluginRuntime {
|
||||
self.local.spawn_local(future)
|
||||
}
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
#[cfg(all(not(target_arch = "wasm32"), not(feature = "local_set")))]
|
||||
#[track_caller]
|
||||
pub fn spawn<F>(&self, future: F) -> JoinHandle<F::Output>
|
||||
where
|
||||
@ -51,7 +51,7 @@ impl AFPluginRuntime {
|
||||
self.inner.spawn(future)
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
#[cfg(any(target_arch = "wasm32", feature = "local_set"))]
|
||||
pub async fn run_until<F>(&self, future: F) -> F::Output
|
||||
where
|
||||
F: Future,
|
||||
@ -59,7 +59,7 @@ impl AFPluginRuntime {
|
||||
self.local.run_until(future).await
|
||||
}
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
#[cfg(all(not(target_arch = "wasm32"), not(feature = "local_set")))]
|
||||
pub async fn run_until<F>(&self, future: F) -> F::Output
|
||||
where
|
||||
F: Future,
|
||||
@ -67,7 +67,7 @@ impl AFPluginRuntime {
|
||||
future.await
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
#[cfg(any(target_arch = "wasm32", feature = "local_set"))]
|
||||
#[track_caller]
|
||||
pub fn block_on<F>(&self, f: F) -> F::Output
|
||||
where
|
||||
@ -76,7 +76,7 @@ impl AFPluginRuntime {
|
||||
self.local.block_on(&self.inner, f)
|
||||
}
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
#[cfg(all(not(target_arch = "wasm32"), not(feature = "local_set")))]
|
||||
#[track_caller]
|
||||
pub fn block_on<F>(&self, f: F) -> F::Output
|
||||
where
|
||||
@ -86,14 +86,14 @@ impl AFPluginRuntime {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
#[cfg(any(target_arch = "wasm32", feature = "local_set"))]
|
||||
pub fn default_tokio_runtime() -> io::Result<Runtime> {
|
||||
runtime::Builder::new_current_thread()
|
||||
.thread_name("dispatch-rt-st")
|
||||
.build()
|
||||
}
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
#[cfg(all(not(target_arch = "wasm32"), not(feature = "local_set")))]
|
||||
pub fn default_tokio_runtime() -> io::Result<Runtime> {
|
||||
runtime::Builder::new_multi_thread()
|
||||
.thread_name("dispatch-rt-mt")
|
||||
|
@ -16,7 +16,7 @@ where
|
||||
BoxServiceFactory(Box::new(FactoryWrapper(factory)))
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
#[cfg(any(target_arch = "wasm32", feature = "local_set"))]
|
||||
type Inner<Cfg, Req, Res, Err> = Box<
|
||||
dyn AFPluginServiceFactory<
|
||||
Req,
|
||||
@ -27,7 +27,7 @@ type Inner<Cfg, Req, Res, Err> = Box<
|
||||
Future = AFBoxFuture<'static, Result<BoxService<Req, Res, Err>, Err>>,
|
||||
>,
|
||||
>;
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
#[cfg(all(not(target_arch = "wasm32"), not(feature = "local_set")))]
|
||||
type Inner<Cfg, Req, Res, Err> = Box<
|
||||
dyn AFPluginServiceFactory<
|
||||
Req,
|
||||
@ -58,12 +58,12 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
#[cfg(any(target_arch = "wasm32", feature = "local_set"))]
|
||||
pub type BoxService<Req, Res, Err> = Box<
|
||||
dyn Service<Req, Response = Res, Error = Err, Future = AFBoxFuture<'static, Result<Res, Err>>>,
|
||||
>;
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
#[cfg(all(not(target_arch = "wasm32"), not(feature = "local_set")))]
|
||||
pub type BoxService<Req, Res, Err> = Box<
|
||||
dyn Service<Req, Response = Res, Error = Err, Future = AFBoxFuture<'static, Result<Res, Err>>>
|
||||
+ Sync
|
||||
|
@ -13,6 +13,21 @@ macro_rules! if_wasm {
|
||||
$item
|
||||
)*}
|
||||
}
|
||||
// Define a generic macro to conditionally apply Send and Sync traits with documentation
|
||||
#[macro_export]
|
||||
macro_rules! conditional_send_sync_trait {
|
||||
($doc:expr; $trait_name:ident { $( $item:tt )* }) => {
|
||||
// For wasm32 targets, define the trait without Send + Sync
|
||||
#[doc = $doc]
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
pub trait $trait_name { $( $item )* }
|
||||
|
||||
// For non-wasm32 targets, define the trait with Send + Sync
|
||||
#[doc = $doc]
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
pub trait $trait_name: Send + Sync { $( $item )* }
|
||||
};
|
||||
}
|
||||
|
||||
pub fn move_vec_element<T, F>(
|
||||
vec: &mut Vec<T>,
|
||||
|
@ -26,9 +26,18 @@ run_task = { name = [
|
||||
"rm_rust_generated_files",
|
||||
"rm_web_generated_protobuf_files",
|
||||
"rm_web_generated_event_files",
|
||||
"rm_pkg",
|
||||
] }
|
||||
|
||||
|
||||
[tasks.rm_pkg]
|
||||
private = true
|
||||
script = ["""
|
||||
cd ${WEB_LIB_PATH}
|
||||
rimraf dist pkg
|
||||
"""]
|
||||
script_runner = "@duckscript"
|
||||
|
||||
[tasks.rm_web_generated_protobuf_files]
|
||||
private = true
|
||||
script = ["""
|
||||
|
Loading…
Reference in New Issue
Block a user