Restructure packages
This commit is contained in:
parent
812eb7a644
commit
56c1f4d58b
19 changed files with 30 additions and 73 deletions
|
|
@ -1,7 +1,7 @@
|
|||
import type { RelativePath } from "../persistence/database";
|
||||
import type { FileSystemOperations } from "./filesystem-operations";
|
||||
import type { Logger } from "../tracing/logger";
|
||||
import { Locks } from "../utils/locks";
|
||||
import { Locks } from "../utils/data-structures/locks";
|
||||
import { FileNotFoundError } from "./file-not-found-error";
|
||||
import type { TextWithCursors } from "reconcile-text";
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { logToConsole } from "./debugging/log-to-console";
|
||||
import { slowFetchFactory } from "./debugging/slow-fetch-factory";
|
||||
import { slowWebSocketFactory } from "./debugging/slow-web-socket-factory";
|
||||
import { logToConsole } from "./utils/debugging/log-to-console";
|
||||
import { slowFetchFactory } from "./utils/debugging/slow-fetch-factory";
|
||||
import { slowWebSocketFactory } from "./utils/debugging/slow-web-socket-factory";
|
||||
import { getRandomColor } from "./utils/get-random-color";
|
||||
import { lineAndColumnToPosition } from "./utils/line-and-column-to-position";
|
||||
import { positionToLineAndColumn } from "./utils/position-to-line-and-column";
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import type { Logger } from "../tracing/logger";
|
||||
import { EMPTY_HASH } from "../utils/hash";
|
||||
import { CoveredValues } from "../utils/min-covered";
|
||||
import { CoveredValues } from "../utils/data-structures/min-covered";
|
||||
|
||||
export type VaultUpdateId = number;
|
||||
export type DocumentId = string;
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ import { CursorTracker } from "./sync-operations/cursor-tracker";
|
|||
import type { CursorSpan } from "./services/types/CursorSpan";
|
||||
import type { MaybeOutdatedClientCursors } from "./types/maybe-outdated-client-cursors";
|
||||
import { FileChangeNotifier } from "./sync-operations/file-change-notifier";
|
||||
import { FixedSizeDocumentCache } from "./utils/fix-sized-cache";
|
||||
import { FixedSizeDocumentCache } from "./utils/data-structures/fix-sized-cache";
|
||||
import { setUpTelemetry } from "./utils/set-up-telemetry";
|
||||
|
||||
export class SyncClient {
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import type { MaybeOutdatedClientCursors } from "../types/maybe-outdated-client-
|
|||
import { DocumentUpToDateness } from "../types/document-up-to-dateness";
|
||||
import { hash } from "../utils/hash";
|
||||
import type { FileChangeNotifier } from "./file-change-notifier";
|
||||
import { Lock } from "../utils/locks";
|
||||
import { Lock } from "../utils/data-structures/locks";
|
||||
|
||||
// Cursor positions are updated separately from documents. However, a given cursor position is only
|
||||
// valid within a certain version of the document it belongs to. This class tracks previous and the latest
|
||||
|
|
|
|||
|
|
@ -15,9 +15,9 @@ import { findMatchingFile } from "../utils/find-matching-file";
|
|||
import type { UnrestrictedSyncer } from "./unrestricted-syncer";
|
||||
import { createPromise } from "../utils/create-promise";
|
||||
import { SyncResetError } from "../services/sync-reset-error";
|
||||
import { Locks } from "../utils/locks";
|
||||
import { Locks } from "../utils/data-structures/locks";
|
||||
import type { DocumentVersionWithoutContent } from "../services/types/DocumentVersionWithoutContent";
|
||||
import type { FixedSizeDocumentCache } from "../utils/fix-sized-cache";
|
||||
import type { FixedSizeDocumentCache } from "../utils/data-structures/fix-sized-cache";
|
||||
|
||||
export class Syncer {
|
||||
private readonly remoteDocumentsLock: Locks<DocumentId>;
|
||||
|
|
|
|||
|
|
@ -18,7 +18,8 @@ import type {
|
|||
} from "../tracing/sync-history";
|
||||
import { SyncStatus, SyncType } from "../tracing/sync-history";
|
||||
import { EMPTY_HASH, hash } from "../utils/hash";
|
||||
import { deserialize } from "../utils/deserialize";
|
||||
|
||||
import { base64ToBytes } from "byte-base64";
|
||||
import type { Settings } from "../persistence/settings";
|
||||
import type { FileOperations } from "../file-operations/file-operations";
|
||||
import { createPromise } from "../utils/create-promise";
|
||||
|
|
@ -28,7 +29,7 @@ import { globsToRegexes } from "../utils/globs-to-regexes";
|
|||
import type { DocumentVersion } from "../services/types/DocumentVersion";
|
||||
import type { DocumentUpdateResponse } from "../services/types/DocumentUpdateResponse";
|
||||
import type { DocumentVersionWithoutContent } from "../services/types/DocumentVersionWithoutContent";
|
||||
import type { FixedSizeDocumentCache } from "../utils/fix-sized-cache";
|
||||
import type { FixedSizeDocumentCache } from "../utils/data-structures/fix-sized-cache";
|
||||
import { isFileTypeMergable } from "../utils/is-file-type-mergable";
|
||||
import { isBinary } from "../utils/is-binary";
|
||||
|
||||
|
|
@ -292,7 +293,7 @@ export class UnrestrictedSyncer {
|
|||
}
|
||||
|
||||
if (!("type" in response) || response.type === "MergingUpdate") {
|
||||
const responseBytes = deserialize(response.contentBase64);
|
||||
const responseBytes = base64ToBytes(response.contentBase64);
|
||||
contentHash = hash(responseBytes);
|
||||
|
||||
this.database.updateDocumentMetadata(
|
||||
|
|
@ -439,7 +440,7 @@ export class UnrestrictedSyncer {
|
|||
return;
|
||||
}
|
||||
|
||||
const contentBytes = deserialize(content);
|
||||
const contentBytes = base64ToBytes(content);
|
||||
|
||||
await this.operations.ensureClearPath(remoteVersion.relativePath);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
// Implements an in-memory fixed-size cache for document contents,
|
||||
|
||||
import type { VaultUpdateId } from "../persistence/database";
|
||||
import type { VaultUpdateId } from "../../persistence/database";
|
||||
|
||||
// Doubly-linked list node for O(1) LRU operations
|
||||
class LRUNode {
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
import { describe, it, beforeEach } from "node:test";
|
||||
import assert from "node:assert";
|
||||
import { Logger } from "../tracing/logger";
|
||||
import type { RelativePath } from "../persistence/database";
|
||||
import { Logger } from "../../tracing/logger";
|
||||
import type { RelativePath } from "../../persistence/database";
|
||||
import { Locks } from "./locks";
|
||||
|
||||
describe("withLock", () => {
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
import type { Logger } from "../tracing/logger";
|
||||
import type { Logger } from "../../tracing/logger";
|
||||
|
||||
/**
|
||||
* Manages exclusive locks on items to prevent concurrent modifications.
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
import type { SyncClient } from "../sync-client";
|
||||
import type { LogLine } from "../tracing/logger";
|
||||
import { LogLevel } from "../tracing/logger";
|
||||
import type { SyncClient } from "../../sync-client";
|
||||
import type { LogLine } from "../../tracing/logger";
|
||||
import { LogLevel } from "../../tracing/logger";
|
||||
|
||||
export function logToConsole(client: SyncClient): void {
|
||||
client.logger.addOnMessageListener((logLine: LogLine) => {
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
import { sleep } from "../utils/sleep";
|
||||
import { sleep } from "../sleep";
|
||||
|
||||
export const slowFetchFactory =
|
||||
(jitterScaleInSeconds: number) =>
|
||||
|
|
@ -7,10 +7,14 @@ export const slowFetchFactory =
|
|||
init?: RequestInit
|
||||
): Promise<Response> => {
|
||||
if (jitterScaleInSeconds > 0) {
|
||||
await sleep(Math.random() * jitterScaleInSeconds * 1000);
|
||||
await sleep(((Math.random() * jitterScaleInSeconds) / 2) * 1000);
|
||||
}
|
||||
|
||||
const response = await fetch(input, init);
|
||||
|
||||
if (jitterScaleInSeconds > 0) {
|
||||
await sleep(((Math.random() * jitterScaleInSeconds) / 2) * 1000);
|
||||
}
|
||||
|
||||
return response;
|
||||
};
|
||||
|
|
@ -1,12 +1,11 @@
|
|||
import { sleep } from "../utils/sleep";
|
||||
import { Locks } from "../utils/locks";
|
||||
import type { Logger } from "../tracing/logger";
|
||||
import { sleep } from "../sleep";
|
||||
import { Locks } from "../data-structures/locks";
|
||||
import type { Logger } from "../../tracing/logger";
|
||||
|
||||
export function slowWebSocketFactory(
|
||||
jitterScaleInSeconds: number,
|
||||
logger: Logger
|
||||
): typeof WebSocket {
|
||||
// eslint-disable-next-line
|
||||
return class FlakyWebSocket extends WebSocket {
|
||||
private static readonly RECEIVE_KEY = "websocket-receive";
|
||||
private static readonly SEND_KEY = "websocket-send";
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
import { base64ToBytes } from "byte-base64";
|
||||
|
||||
export function deserialize(data: string): Uint8Array {
|
||||
return base64ToBytes(data);
|
||||
}
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
import { describe, it } from "node:test";
|
||||
import assert from "node:assert";
|
||||
import { isEqualBytes } from "./is-equal-bytes";
|
||||
|
||||
describe("isEqualBytes", () => {
|
||||
it("should return true for equal byte arrays", () => {
|
||||
const bytes1 = new Uint8Array([1, 2, 3, 4]);
|
||||
const bytes2 = new Uint8Array([1, 2, 3, 4]);
|
||||
assert.strictEqual(isEqualBytes(bytes1, bytes2), true);
|
||||
});
|
||||
|
||||
it("should return false for byte arrays of different lengths", () => {
|
||||
const bytes1 = new Uint8Array([1, 2, 3, 4]);
|
||||
const bytes2 = new Uint8Array([1, 2, 3]);
|
||||
assert.strictEqual(isEqualBytes(bytes1, bytes2), false);
|
||||
});
|
||||
|
||||
it("should return true for empty byte arrays", () => {
|
||||
const bytes1 = new Uint8Array([]);
|
||||
const bytes2 = new Uint8Array([]);
|
||||
assert.strictEqual(isEqualBytes(bytes1, bytes2), true);
|
||||
});
|
||||
|
||||
it("should return false for byte arrays with same length but different content", () => {
|
||||
const bytes1 = new Uint8Array([1, 2, 3, 4]);
|
||||
const bytes2 = new Uint8Array([4, 3, 2, 1]);
|
||||
assert.strictEqual(isEqualBytes(bytes1, bytes2), false);
|
||||
});
|
||||
});
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
export function isEqualBytes(bytes1: Uint8Array, bytes2: Uint8Array): boolean {
|
||||
if (bytes1.length !== bytes2.length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (let i = 0; i < bytes1.length; i++) {
|
||||
if (bytes1[i] !== bytes2[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue