WIP: Migrate to using taskfile #187

Closed
schmelczer wants to merge 26 commits from asch/taskfiles into main
17 changed files with 47 additions and 72 deletions
Showing only changes of commit 0d7d36e971 - Show all commits

Formatting & small fixes

Andras Schmelczer 2026-01-04 11:02:00 +00:00

View file

@ -6,7 +6,7 @@ on:
pull_request: pull_request:
branches: ["main"] branches: ["main"]
schedule: schedule:
- cron: '0 * * * *' - cron: "0 * * * *"
workflow_dispatch: workflow_dispatch:
concurrency: concurrency:

View file

@ -14,14 +14,15 @@ export class ServerConfig {
private response: Promise<PingResponse> | undefined; private response: Promise<PingResponse> | undefined;
private config: ServerConfigData | undefined; private config: ServerConfigData | undefined;
public constructor(private readonly syncService: SyncService) { } public constructor(private readonly syncService: SyncService) {}
private static validateConfig(config: ServerConfigData): void { private static validateConfig(config: ServerConfigData): void {
if (config.supportedApiVersion !== SUPPORTED_API_VERSION) { if (config.supportedApiVersion !== SUPPORTED_API_VERSION) {
const shouldUpgradeClient = const shouldUpgradeClient =
config.supportedApiVersion > SUPPORTED_API_VERSION; config.supportedApiVersion > SUPPORTED_API_VERSION;
throw new ServerVersionMismatchError( throw new ServerVersionMismatchError(
`Unsupported API version: ${config.supportedApiVersion}. Consider upgrading the ${shouldUpgradeClient ? "client" : "sync-server" `Unsupported API version: ${config.supportedApiVersion}. Consider upgrading the ${
shouldUpgradeClient ? "client" : "sync-server"
} to ensure compatibility` } to ensure compatibility`
); );
} }

View file

@ -73,7 +73,7 @@ export class SyncService {
relativePath: RelativePath; relativePath: RelativePath;
contentBytes: Uint8Array; contentBytes: Uint8Array;
forceMerge?: boolean; forceMerge?: boolean;
}): Promise<DocumentVersionWithoutContent> { }): Promise<DocumentUpdateResponse> {
return this.retryForever(async () => { return this.retryForever(async () => {
const formData = new FormData(); const formData = new FormData();
@ -105,8 +105,8 @@ export class SyncService {
); );
} }
const result: DocumentVersionWithoutContent = const result: DocumentUpdateResponse =
(await response.json()) as DocumentVersionWithoutContent; // eslint-disable-line @typescript-eslint/no-unsafe-type-assertion (await response.json()) as DocumentUpdateResponse; // eslint-disable-line @typescript-eslint/no-unsafe-type-assertion
this.logger.debug(`Created document ${JSON.stringify(result)}`); this.logger.debug(`Created document ${JSON.stringify(result)}`);

View file

@ -1,13 +1,7 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. // This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
export interface CreateDocumentVersion { export interface CreateDocumentVersion {
/**
* The client can decide the document id (if it wishes to) in order
* to help with syncing. If the client does not provide a document id,
* the server will generate one. If the client provides a document id
* it must not already exist in the database.
*/
document_id: string | null;
relative_path: string; relative_path: string;
force_merge: boolean | null;
content: number[]; content: number[];
} }

View file

@ -36,7 +36,7 @@ export class WebSocketManager {
private readonly logger: Logger, private readonly logger: Logger,
private readonly settings: Settings, private readonly settings: Settings,
private readonly webSocketFactoryImplementation: typeof globalThis.WebSocket = WebSocket private readonly webSocketFactoryImplementation: typeof globalThis.WebSocket = WebSocket
) { } ) {}
public get isWebSocketConnected(): boolean { public get isWebSocketConnected(): boolean {
return ( return (

View file

@ -56,7 +56,7 @@ export class SyncClient {
database: Partial<StoredDatabase>; database: Partial<StoredDatabase>;
}> }>
> >
) { } ) {}
public get documentCount(): number { public get documentCount(): number {
return this.database.length; return this.database.length;
@ -205,7 +205,6 @@ export class SyncClient {
logger, logger,
database, database,
settings, settings,
syncService,
webSocketManager, webSocketManager,
fileOperations, fileOperations,
unrestrictedSyncer unrestrictedSyncer

View file

@ -4,7 +4,6 @@ import type {
DocumentRecord, DocumentRecord,
RelativePath RelativePath
} from "../persistence/database"; } from "../persistence/database";
import type { SyncService } from "../services/sync-service";
import type { Logger } from "../tracing/logger"; import type { Logger } from "../tracing/logger";
import PQueue from "p-queue"; import PQueue from "p-queue";
import { hash } from "../utils/hash"; import { hash } from "../utils/hash";
@ -41,7 +40,6 @@ export class Syncer {
private readonly logger: Logger, private readonly logger: Logger,
private readonly database: Database, private readonly database: Database,
private readonly settings: Settings, private readonly settings: Settings,
private readonly syncService: SyncService,
private readonly webSocketManager: WebSocketManager, private readonly webSocketManager: WebSocketManager,
private readonly operations: FileOperations, private readonly operations: FileOperations,
private readonly internalSyncer: UnrestrictedSyncer private readonly internalSyncer: UnrestrictedSyncer
@ -487,8 +485,5 @@ export class Syncer {
}) })
); );
this.database.setHasInitialSyncCompleted(true);
} }
} }

View file

@ -1,5 +1,3 @@
export function createClientId(): string { export function createClientId(): string {
// @ts-expect-error, injected by webpack // @ts-expect-error, injected by webpack
const packageVersion = __CURRENT_VERSION__; // eslint-disable-line const packageVersion = __CURRENT_VERSION__; // eslint-disable-line

View file

@ -252,7 +252,7 @@ describe("reset", () => {
await sleep(1); await sleep(1);
const secondPromise = locks.withLock(testPath, async () => "second"); const secondPromise = locks.withLock(testPath, async () => "second");
void secondPromise.catch(() => { }); // eslint-disable-line @typescript-eslint/no-empty-function void secondPromise.catch(() => {}); // eslint-disable-line @typescript-eslint/no-empty-function
locks.reset(); locks.reset();
@ -273,7 +273,7 @@ describe("reset", () => {
await sleep(1); await sleep(1);
const secondPromise = locks.withLock(testPath, async () => "second"); const secondPromise = locks.withLock(testPath, async () => "second");
void secondPromise.catch(() => { }); // eslint-disable-line @typescript-eslint/no-empty-function void secondPromise.catch(() => {}); // eslint-disable-line @typescript-eslint/no-empty-function
locks.reset(); locks.reset();

View file

@ -18,7 +18,7 @@ export class Locks<T> {
[() => unknown, (err: unknown) => unknown][] [() => unknown, (err: unknown) => unknown][]
>(); >();
public constructor(private readonly logger?: Logger) { } public constructor(private readonly logger?: Logger) {}
/** /**
* Executes a function while holding exclusive locks on one or more keys. * Executes a function while holding exclusive locks on one or more keys.

View file

@ -14,13 +14,7 @@ export class MockClient implements FileSystemOperations {
protected data: Partial<{ protected data: Partial<{
settings: Partial<SyncSettings>; settings: Partial<SyncSettings>;
database: Partial<StoredDatabase>; database: Partial<StoredDatabase>;
}> = { }> = {};
database: {
// Assume all clients start at the same time so there's no need to fetch
// any shared state.
hasInitialSyncCompleted: true
}
};
public constructor( public constructor(
initialSettings: Partial<SyncSettings>, initialSettings: Partial<SyncSettings>,

View file

@ -30,8 +30,11 @@ fi
which cargo-machete || cargo install cargo-machete which cargo-machete || cargo install cargo-machete
cargo machete --with-metadata cargo machete --with-metadata
cd ..
scripts/update-api-types.sh # this will dirty up the git state if not up-to-date
echo "Running checks in frontend" echo "Running checks in frontend"
cd ../frontend cd frontend
if [[ "$FIX_MODE" == true ]]; then if [[ "$FIX_MODE" == true ]]; then
npm install npm install

View file

@ -25,15 +25,6 @@ npm run build
../scripts/utils/wait-for-server.sh ../scripts/utils/wait-for-server.sh
cd ..
scripts/update-api-types.sh
if [[ $(git status --porcelain) ]]; then
git status --porcelain
echo "Failing CI because the working directory is not clean after generating api types"
exit 1
fi
cd frontend
pids=() pids=()
for i in $(seq 1 $process_count); do for i in $(seq 1 $process_count); do
# Create a named pipe for this process # Create a named pipe for this process

View file

@ -11,7 +11,7 @@ use crate::app_state::database::models::VaultUpdateId;
pub struct CreateDocumentVersion { pub struct CreateDocumentVersion {
pub relative_path: String, pub relative_path: String,
// whether to merge with existing document at the same path if it exists // whether to merge with existing document at the same path if it already exists
pub force_merge: Option<bool>, pub force_merge: Option<bool>,
#[ts(as = "Vec<u8>")] #[ts(as = "Vec<u8>")]

View file

@ -246,8 +246,6 @@ pub async fn merge_with_stored_version(
content.clone() content.clone()
}; };
let is_different_from_request_content = merged_content != content;
// We can only update the relative path if we're the first one to do so // We can only update the relative path if we're the first one to do so
let new_relative_path = if parent_document.relative_path == latest_version.relative_path let new_relative_path = if parent_document.relative_path == latest_version.relative_path
&& latest_version.relative_path != sanitized_relative_path && latest_version.relative_path != sanitized_relative_path
@ -278,6 +276,8 @@ pub async fn merge_with_stored_version(
.await .await
.map_err(server_error)?; .map_err(server_error)?;
let is_different_from_request_content = merged_content != content;
let new_version = StoredDocumentVersion { let new_version = StoredDocumentVersion {
document_id: parent_document.document_id, document_id: parent_document.document_id,
vault_update_id: last_update_id + 1, vault_update_id: last_update_id + 1,