Skip to content

Commit f050def

Browse files
committed
feat: toggle large deletion confirmation, physical .filenignore, bump deps
1 parent 11b1ec8 commit f050def

File tree

5 files changed

+90
-43
lines changed

5 files changed

+90
-43
lines changed

package-lock.json

+6-6
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@filen/sync",
3-
"version": "0.1.99",
3+
"version": "0.1.100",
44
"description": "Filen Sync",
55
"main": "dist/index.js",
66
"types": "dist/index.d.ts",
@@ -54,7 +54,7 @@
5454
"wait-on": "^7.2.0"
5555
},
5656
"dependencies": {
57-
"@filen/sdk": "^0.1.192",
57+
"@filen/sdk": "^0.1.193",
5858
"@parcel/watcher": "^2.5.1",
5959
"fast-glob": "^3.3.3",
6060
"fs-extra": "^11.3.0",

src/ignorer.ts

+69-32
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import type Sync from "./lib/sync"
33
import pathModule from "path"
44
import fs from "fs-extra"
55
import writeFileAtomic from "write-file-atomic"
6+
import { Semaphore } from "./semaphore"
67

78
export const IGNORER_VERSION = 1
89

@@ -11,47 +12,96 @@ export class Ignorer {
1112
public instance = ignore()
1213
public name: string = "ignorer"
1314
public pattern: string[] = []
15+
private readonly mutex = new Semaphore(1)
1416

1517
public constructor(sync: Sync, name: string = "ignorer") {
1618
this.sync = sync
1719
this.name = name
1820
}
1921

2022
public async fetch(): Promise<string> {
21-
const filePath = pathModule.join(this.sync.dbPath, this.name, `v${IGNORER_VERSION}`, this.sync.syncPair.uuid, "filenIgnore")
23+
await this.mutex.acquire()
24+
25+
try {
26+
const filePath = pathModule.join(this.sync.dbPath, this.name, `v${IGNORER_VERSION}`, this.sync.syncPair.uuid, "filenIgnore")
27+
const physicalFilePath = pathModule.join(this.sync.syncPair.localPath, ".filenignore")
28+
let content: string = ""
29+
const [exists, physicalExists] = await Promise.all([fs.exists(filePath), fs.exists(physicalFilePath)])
30+
31+
if (exists) {
32+
const stats = await fs.stat(filePath)
33+
34+
if (stats.size > 0) {
35+
content += await fs.readFile(filePath, {
36+
encoding: "utf-8"
37+
})
38+
}
39+
}
40+
41+
if (physicalExists) {
42+
const stats = await fs.stat(physicalFilePath)
43+
44+
if (stats.size > 0) {
45+
content += `${content.length > 0 ? "\n" : ""}${await fs.readFile(physicalFilePath, {
46+
encoding: "utf-8"
47+
})}`
48+
}
49+
}
50+
51+
return content
52+
} finally {
53+
this.mutex.release()
54+
}
55+
}
2256

23-
await fs.ensureDir(pathModule.dirname(filePath))
57+
public async write(content: string): Promise<void> {
58+
await this.mutex.acquire()
2459

25-
const exists = await fs.exists(filePath)
60+
try {
61+
const filePath = pathModule.join(this.sync.syncPair.localPath, ".filenignore")
2662

27-
if (!exists) {
28-
return ""
29-
}
63+
await fs.ensureDir(pathModule.dirname(filePath))
3064

31-
const stats = await fs.stat(filePath)
32-
33-
if (stats.size === 0) {
34-
return ""
65+
await writeFileAtomic(filePath, content, {
66+
encoding: "utf-8"
67+
})
68+
} finally {
69+
this.mutex.release()
3570
}
71+
}
3672

37-
return await fs.readFile(filePath, {
38-
encoding: "utf-8"
39-
})
73+
public async clearFile(): Promise<void> {
74+
await this.mutex.acquire()
75+
76+
try {
77+
const filePath = pathModule.join(this.sync.dbPath, this.name, `v${IGNORER_VERSION}`, this.sync.syncPair.uuid, "filenIgnore")
78+
const physicalFilePath = pathModule.join(this.sync.syncPair.localPath, ".filenignore")
79+
const [exists, physicalExists] = await Promise.all([fs.exists(filePath), fs.exists(physicalFilePath)])
80+
81+
if (exists) {
82+
await writeFileAtomic(filePath, "", {
83+
encoding: "utf-8"
84+
})
85+
}
86+
87+
if (physicalExists) {
88+
await writeFileAtomic(physicalFilePath, "", {
89+
encoding: "utf-8"
90+
})
91+
}
92+
} finally {
93+
this.mutex.release()
94+
}
4095
}
4196

4297
public async initialize(passedContent?: string): Promise<void> {
4398
this.sync.localFileSystem.ignoredCache.clear()
4499
this.sync.remoteFileSystem.ignoredCache.clear()
45100

46101
let content: string[] = []
47-
const filePath = pathModule.join(this.sync.dbPath, this.name, `v${IGNORER_VERSION}`, this.sync.syncPair.uuid, "filenIgnore")
48-
49-
await fs.ensureDir(pathModule.dirname(filePath))
50102

51103
if (typeof passedContent === "string") {
52-
await writeFileAtomic(filePath, passedContent, {
53-
encoding: "utf-8"
54-
})
104+
await this.write(passedContent)
55105

56106
content = passedContent
57107
.split("\n")
@@ -80,19 +130,6 @@ export class Ignorer {
80130
this.instance = ignore()
81131
}
82132

83-
public async clearFile(): Promise<void> {
84-
const filePath = pathModule.join(this.sync.dbPath, this.name, `v${IGNORER_VERSION}`, this.sync.syncPair.uuid, "filenIgnore")
85-
86-
await fs.ensureDir(pathModule.dirname(filePath))
87-
88-
await fs.rm(filePath, {
89-
force: true,
90-
maxRetries: 60 * 10,
91-
recursive: true,
92-
retryDelay: 100
93-
})
94-
}
95-
96133
public ignores(path: string): boolean {
97134
const normalizedPath = path.startsWith("\\") ? path.slice(1) : path.startsWith("/") ? path.slice(1) : path
98135

src/index.ts

+12-2
Original file line numberDiff line numberDiff line change
@@ -256,10 +256,10 @@ export class SyncWorker {
256256
}
257257
}
258258

259-
public updateIgnorerContent(uuid: string, content?: string): void {
259+
public async updateIgnorerContent(uuid: string, content?: string): Promise<void> {
260260
for (const syncUUID in this.syncs) {
261261
if (syncUUID === uuid) {
262-
this.syncs[syncUUID]!.ignorer.update(content)
262+
await this.syncs[syncUUID]!.ignorer.update(content)
263263

264264
this.syncs[syncUUID]!.localFileSystem.ignoredCache.clear()
265265
this.syncs[syncUUID]!.remoteFileSystem.ignoredCache.clear()
@@ -269,6 +269,16 @@ export class SyncWorker {
269269
}
270270
}
271271

272+
public updateRequireConfirmationOnLargeDeletion(uuid: string, requireConfirmationOnLargeDeletion: boolean): void {
273+
for (const syncUUID in this.syncs) {
274+
if (syncUUID === uuid) {
275+
this.syncs[syncUUID]!.requireConfirmationOnLargeDeletion = requireConfirmationOnLargeDeletion
276+
277+
break
278+
}
279+
}
280+
}
281+
272282
public async fetchIgnorerContent(uuid: string): Promise<string> {
273283
for (const syncUUID in this.syncs) {
274284
if (syncUUID === uuid) {

src/lib/filesystems/local.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,7 @@ export class LocalFileSystem {
252252

253253
const pathsAdded: Record<string, boolean> = {}
254254
let size = 0
255-
const entries = await FastGlob.glob("**/*", {
255+
const entries = await FastGlob.async("**/*", {
256256
dot: true,
257257
onlyDirectories: false,
258258
onlyFiles: false,

0 commit comments

Comments
 (0)