@filen/sync 0.1.1 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/LICENSE +661 -661
  2. package/README.md +1 -1
  3. package/SECURITY.md +17 -17
  4. package/dist/constants.d.ts +7 -0
  5. package/dist/constants.js +51 -1
  6. package/dist/constants.js.map +1 -1
  7. package/dist/ignorer.d.ts +14 -0
  8. package/dist/ignorer.js +69 -0
  9. package/dist/ignorer.js.map +1 -0
  10. package/dist/index.d.ts +27 -6
  11. package/dist/index.js +113 -13
  12. package/dist/index.js.map +1 -1
  13. package/dist/lib/deltas.d.ts +9 -31
  14. package/dist/lib/deltas.js +59 -65
  15. package/dist/lib/deltas.js.map +1 -1
  16. package/dist/lib/filesystems/local.d.ts +25 -20
  17. package/dist/lib/filesystems/local.js +203 -55
  18. package/dist/lib/filesystems/local.js.map +1 -1
  19. package/dist/lib/filesystems/remote.d.ts +18 -7
  20. package/dist/lib/filesystems/remote.js +435 -61
  21. package/dist/lib/filesystems/remote.js.map +1 -1
  22. package/dist/lib/ipc.d.ts +9 -0
  23. package/dist/lib/ipc.js +56 -0
  24. package/dist/lib/ipc.js.map +1 -0
  25. package/dist/lib/logger.d.ts +14 -0
  26. package/dist/lib/logger.js +93 -0
  27. package/dist/lib/logger.js.map +1 -0
  28. package/dist/lib/state.d.ts +4 -15
  29. package/dist/lib/state.js +16 -29
  30. package/dist/lib/state.js.map +1 -1
  31. package/dist/lib/sync.d.ts +23 -9
  32. package/dist/lib/sync.js +242 -28
  33. package/dist/lib/sync.js.map +1 -1
  34. package/dist/lib/tasks.d.ts +18 -33
  35. package/dist/lib/tasks.js +52 -29
  36. package/dist/lib/tasks.js.map +1 -1
  37. package/dist/types.d.ts +175 -0
  38. package/dist/utils.d.ts +24 -0
  39. package/dist/utils.js +132 -1
  40. package/dist/utils.js.map +1 -1
  41. package/package.json +60 -58
  42. package/tsconfig.json +24 -24
  43. package/index.d.ts +0 -298
@@ -1,10 +1,6 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
6
3
  exports.Deltas = void 0;
7
- const path_1 = __importDefault(require("path"));
8
4
  /**
9
5
  * Deltas
10
6
  * @date 3/1/2024 - 11:11:32 PM
@@ -16,19 +12,16 @@ const path_1 = __importDefault(require("path"));
16
12
  class Deltas {
17
13
  /**
18
14
  * Creates an instance of Deltas.
19
- * @date 3/1/2024 - 11:11:36 PM
20
15
  *
21
16
  * @constructor
22
17
  * @public
23
- * @param {{ sync: Sync }} param0
24
- * @param {Sync} param0.sync
18
+ * @param {Sync} sync
25
19
  */
26
- constructor({ sync }) {
20
+ constructor(sync) {
27
21
  this.sync = sync;
28
22
  }
29
23
  /**
30
24
  * Process the directory trees and return all sync deltas.
31
- * @date 3/2/2024 - 8:42:25 AM
32
25
  *
33
26
  * @public
34
27
  * @async
@@ -36,54 +29,45 @@ class Deltas {
36
29
  * currentLocalTree: LocalTree
37
30
  * currentRemoteTree: RemoteTree
38
31
  * previousLocalTree: LocalTree
39
- * previousRemoteTree: RemoteTree
32
+ * previousRemoteTree: RemoteTree,
33
+ * currentLocalTreeErrors: LocalTreeError[]
40
34
  * }} param0
41
35
  * @param {LocalTree} param0.currentLocalTree
42
36
  * @param {RemoteTree} param0.currentRemoteTree
43
37
  * @param {LocalTree} param0.previousLocalTree
44
38
  * @param {RemoteTree} param0.previousRemoteTree
39
+ * @param {{}} param0.currentLocalTreeErrors
45
40
  * @returns {Promise<Delta[]>}
46
41
  */
47
- async process({ currentLocalTree, currentRemoteTree, previousLocalTree, previousRemoteTree }) {
48
- const deltas = [];
42
+ async process({ currentLocalTree, currentRemoteTree, previousLocalTree, previousRemoteTree, currentLocalTreeErrors }) {
43
+ let deltas = [];
49
44
  const pathsAdded = {};
45
+ const erroredLocalPaths = {};
46
+ for (const error of currentLocalTreeErrors) {
47
+ erroredLocalPaths[error.relativePath] = true;
48
+ }
50
49
  // Local file/directory move/rename
51
50
  for (const inode in currentLocalTree.inodes) {
52
51
  const currentItem = currentLocalTree.inodes[inode];
53
52
  const previousItem = previousLocalTree.inodes[inode];
54
- if (!currentItem || !previousItem || pathsAdded[currentItem.path] || pathsAdded[previousItem.path]) {
53
+ if (!currentItem ||
54
+ !previousItem ||
55
+ pathsAdded[currentItem.path] ||
56
+ pathsAdded[previousItem.path] ||
57
+ erroredLocalPaths[currentItem.path] ||
58
+ erroredLocalPaths[previousItem.path]) {
55
59
  continue;
56
60
  }
57
61
  // Path from current item changed, it was either renamed or moved
58
62
  if (currentItem.path !== previousItem.path) {
59
- const currentItemParentPath = path_1.default.posix.dirname(currentItem.path);
60
- const previousItemParentPath = path_1.default.posix.dirname(previousItem.path);
61
- const currentItemParent = currentLocalTree.tree[currentItemParentPath];
62
- const previousItemParent = previousLocalTree.tree[previousItemParentPath];
63
- const currentItemName = path_1.default.posix.basename(currentItem.path);
64
- const previousItemName = path_1.default.posix.basename(previousItem.path);
65
- // Names changed
66
- if (currentItemName !== previousItemName) {
67
- deltas.push({
68
- type: currentItem.type === "directory" ? "renameRemoteDirectory" : "renameRemoteFile",
69
- path: currentItem.path,
70
- from: previousItem.path,
71
- to: currentItem.path
72
- });
73
- }
74
- pathsAdded[currentItem.path] = true;
75
- pathsAdded[previousItem.path] = true;
76
- // Parents did not change, continue
77
- if ((currentItemParent === null || currentItemParent === void 0 ? void 0 : currentItemParent.inode) === (previousItemParent === null || previousItemParent === void 0 ? void 0 : previousItemParent.inode)) {
78
- continue;
79
- }
80
- // Item was also moved
81
63
  deltas.push({
82
- type: currentItem.type === "directory" ? "moveRemoteDirectory" : "moveRemoteFile",
64
+ type: currentItem.type === "directory" ? "renameRemoteDirectory" : "renameRemoteFile",
83
65
  path: currentItem.path,
84
66
  from: previousItem.path,
85
67
  to: currentItem.path
86
68
  });
69
+ pathsAdded[currentItem.path] = true;
70
+ pathsAdded[previousItem.path] = true;
87
71
  }
88
72
  }
89
73
  // Remote file/directory move/rename
@@ -95,39 +79,19 @@ class Deltas {
95
79
  }
96
80
  // Path from current item changed, it was either renamed or moved
97
81
  if (currentItem.path !== previousItem.path) {
98
- const currentItemParentPath = path_1.default.posix.dirname(currentItem.path);
99
- const previousItemParentPath = path_1.default.posix.dirname(previousItem.path);
100
- const currentItemParent = currentRemoteTree.tree[currentItemParentPath];
101
- const previousItemParent = previousRemoteTree.tree[previousItemParentPath];
102
- const currentItemName = path_1.default.posix.basename(currentItem.path);
103
- const previousItemName = path_1.default.posix.basename(previousItem.path);
104
- // Names changed
105
- if (currentItemName !== previousItemName) {
106
- deltas.push({
107
- type: currentItem.type === "directory" ? "renameRemoteDirectory" : "renameRemoteFile",
108
- path: currentItem.path,
109
- from: previousItem.path,
110
- to: currentItem.path
111
- });
112
- }
113
- pathsAdded[currentItem.path] = true;
114
- pathsAdded[previousItem.path] = true;
115
- // Parents did not change, continue
116
- if ((currentItemParent === null || currentItemParent === void 0 ? void 0 : currentItemParent.uuid) === (previousItemParent === null || previousItemParent === void 0 ? void 0 : previousItemParent.uuid)) {
117
- continue;
118
- }
119
- // Item was also moved
120
82
  deltas.push({
121
- type: currentItem.type === "directory" ? "moveRemoteDirectory" : "moveRemoteFile",
83
+ type: currentItem.type === "directory" ? "renameRemoteDirectory" : "renameRemoteFile",
122
84
  path: currentItem.path,
123
85
  from: previousItem.path,
124
86
  to: currentItem.path
125
87
  });
88
+ pathsAdded[currentItem.path] = true;
89
+ pathsAdded[previousItem.path] = true;
126
90
  }
127
91
  }
128
92
  // Local deletions
129
93
  for (const path in previousLocalTree.tree) {
130
- if (pathsAdded[path]) {
94
+ if (pathsAdded[path] || erroredLocalPaths[path]) {
131
95
  continue;
132
96
  }
133
97
  const previousLocalItem = previousLocalTree.tree[path];
@@ -155,9 +119,9 @@ class Deltas {
155
119
  pathsAdded[path] = true;
156
120
  }
157
121
  }
158
- // Local additions/changes
122
+ // Local additions/filemodifications
159
123
  for (const path in currentLocalTree.tree) {
160
- if (pathsAdded[path]) {
124
+ if (pathsAdded[path] || erroredLocalPaths[path]) {
161
125
  continue;
162
126
  }
163
127
  const currentLocalItem = currentLocalTree.tree[path];
@@ -172,9 +136,10 @@ class Deltas {
172
136
  }
173
137
  if (currentRemoteItem && currentRemoteItem.type === "file") {
174
138
  if (currentLocalItem && currentLocalItem.lastModified > currentRemoteItem.lastModified) {
175
- const itemLocalPath = path_1.default.join(this.sync.syncPair.localPath, currentLocalItem.path);
176
- if ((await this.sync.localFileSystem.createFileHash({ relativePath: path, algorithm: "sha512" })) !==
177
- this.sync.localFileHashes[itemLocalPath]) {
139
+ if ((await this.sync.localFileSystem.createFileHash({
140
+ relativePath: path,
141
+ algorithm: "md5"
142
+ })) !== this.sync.localFileHashes[currentLocalItem.path]) {
178
143
  deltas.push({
179
144
  type: "uploadFile",
180
145
  path
@@ -209,6 +174,35 @@ class Deltas {
209
174
  }
210
175
  }
211
176
  }
177
+ // Filter deltas by sync mode
178
+ if (this.sync.mode === "localToCloud") {
179
+ deltas = deltas.filter(delta => delta.type === "createRemoteDirectory" ||
180
+ delta.type === "deleteRemoteDirectory" ||
181
+ delta.type === "deleteRemoteFile" ||
182
+ delta.type === "renameRemoteDirectory" ||
183
+ delta.type === "renameRemoteFile" ||
184
+ delta.type === "uploadFile");
185
+ }
186
+ if (this.sync.mode === "localBackup") {
187
+ deltas = deltas.filter(delta => delta.type === "createRemoteDirectory" ||
188
+ delta.type === "renameRemoteDirectory" ||
189
+ delta.type === "renameRemoteFile" ||
190
+ delta.type === "uploadFile");
191
+ }
192
+ if (this.sync.mode === "cloudToLocal") {
193
+ deltas = deltas.filter(delta => delta.type === "createLocalDirectory" ||
194
+ delta.type === "deleteLocalDirectory" ||
195
+ delta.type === "deleteLocalFile" ||
196
+ delta.type === "renameLocalDirectory" ||
197
+ delta.type === "renameLocalFile" ||
198
+ delta.type === "downloadFile");
199
+ }
200
+ if (this.sync.mode === "cloudBackup") {
201
+ deltas = deltas.filter(delta => delta.type === "createLocalDirectory" ||
202
+ delta.type === "renameLocalDirectory" ||
203
+ delta.type === "renameLocalFile" ||
204
+ delta.type === "downloadFile");
205
+ }
212
206
  return deltas;
213
207
  }
214
208
  }
@@ -1 +1 @@
1
- {"version":3,"file":"deltas.js","sourceRoot":"","sources":["../../src/lib/deltas.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"deltas.js","sourceRoot":"","sources":["../../src/lib/deltas.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  /// <reference types="node" />
2
2
  import fs from "fs-extra";
3
3
  import type Sync from "../sync";
4
- import type { CloudItem } from "@filen/sdk";
4
+ import { type CloudItem } from "@filen/sdk";
5
5
  export type LocalItem = {
6
6
  lastModified: number;
7
7
  type: "file" | "directory";
@@ -16,6 +16,16 @@ export type LocalTree = {
16
16
  tree: LocalDirectoryTree;
17
17
  inodes: LocalDirectoryINodes;
18
18
  };
19
+ export type LocalTreeError = {
20
+ localPath: string;
21
+ relativePath: string;
22
+ error: Error;
23
+ };
24
+ export type LocalTreeIgnored = {
25
+ localPath: string;
26
+ relativePath: string;
27
+ reason: "dotFile" | "localIgnore" | "defaultIgnore";
28
+ };
19
29
  /**
20
30
  * LocalFileSystem
21
31
  * @date 3/2/2024 - 12:38:22 PM
@@ -36,25 +46,18 @@ export declare class LocalFileSystem {
36
46
  private watcherInstance;
37
47
  /**
38
48
  * Creates an instance of LocalFileSystem.
39
- * @date 3/2/2024 - 12:38:20 PM
40
49
  *
41
50
  * @constructor
42
51
  * @public
43
- * @param {{ sync: Sync }} param0
44
- * @param {Sync} param0.sync
45
- */
46
- constructor({ sync }: {
47
- sync: Sync;
48
- });
49
- /**
50
- * Get the local directory tree.
51
- * @date 3/2/2024 - 12:38:13 PM
52
- *
53
- * @public
54
- * @async
55
- * @returns {Promise<LocalTree>}
52
+ * @param {Sync} sync
56
53
  */
57
- getDirectoryTree(): Promise<LocalTree>;
54
+ constructor(sync: Sync);
55
+ getDirectoryTree(): Promise<{
56
+ result: LocalTree;
57
+ errors: LocalTreeError[];
58
+ ignored: LocalTreeIgnored[];
59
+ changed: boolean;
60
+ }>;
58
61
  /**
59
62
  * Start the local sync directory watcher.
60
63
  * @date 3/2/2024 - 12:38:00 PM
@@ -87,18 +90,20 @@ export declare class LocalFileSystem {
87
90
  waitForLocalDirectoryChanges(): Promise<void>;
88
91
  /**
89
92
  * Creates a hash of a file using streams.
90
- * @date 3/2/2024 - 9:29:48 AM
91
93
  *
92
94
  * @public
93
95
  * @async
94
- * @param {{ relativePath: string; algorithm: "sha512" }} param0
96
+ * @param {{
97
+ * relativePath: string
98
+ * algorithm: "sha512" | "md5" | "sha256"
99
+ * }} param0
95
100
  * @param {string} param0.relativePath
96
- * @param {"sha512"} param0.algorithm
101
+ * @param {("sha512" | "md5" | "sha256")} param0.algorithm
97
102
  * @returns {Promise<string>}
98
103
  */
99
104
  createFileHash({ relativePath, algorithm }: {
100
105
  relativePath: string;
101
- algorithm: "sha512";
106
+ algorithm: "sha512" | "md5" | "sha256";
102
107
  }): Promise<string>;
103
108
  /**
104
109
  * Create a directory inside the local sync path. Recursively creates intermediate directories if needed.
@@ -13,6 +13,8 @@ const constants_1 = require("../../constants");
13
13
  const crypto_1 = __importDefault(require("crypto"));
14
14
  const stream_1 = require("stream");
15
15
  const util_1 = require("util");
16
+ const sdk_1 = require("@filen/sdk");
17
+ const ipc_1 = require("../ipc");
16
18
  const pipelineAsync = (0, util_1.promisify)(stream_1.pipeline);
17
19
  /**
18
20
  * LocalFileSystem
@@ -25,14 +27,12 @@ const pipelineAsync = (0, util_1.promisify)(stream_1.pipeline);
25
27
  class LocalFileSystem {
26
28
  /**
27
29
  * Creates an instance of LocalFileSystem.
28
- * @date 3/2/2024 - 12:38:20 PM
29
30
  *
30
31
  * @constructor
31
32
  * @public
32
- * @param {{ sync: Sync }} param0
33
- * @param {Sync} param0.sync
33
+ * @param {Sync} sync
34
34
  */
35
- constructor({ sync }) {
35
+ constructor(sync) {
36
36
  this.lastDirectoryChangeTimestamp = Date.now() - constants_1.SYNC_INTERVAL * 2;
37
37
  this.getDirectoryTreeCache = {
38
38
  timestamp: 0,
@@ -43,62 +43,103 @@ class LocalFileSystem {
43
43
  this.watcherInstance = null;
44
44
  this.sync = sync;
45
45
  }
46
- /**
47
- * Get the local directory tree.
48
- * @date 3/2/2024 - 12:38:13 PM
49
- *
50
- * @public
51
- * @async
52
- * @returns {Promise<LocalTree>}
53
- */
54
46
  async getDirectoryTree() {
55
47
  if (this.lastDirectoryChangeTimestamp > 0 &&
56
48
  this.getDirectoryTreeCache.timestamp > 0 &&
57
49
  this.lastDirectoryChangeTimestamp < this.getDirectoryTreeCache.timestamp) {
58
50
  return {
59
- tree: this.getDirectoryTreeCache.tree,
60
- inodes: this.getDirectoryTreeCache.inodes
51
+ result: {
52
+ tree: this.getDirectoryTreeCache.tree,
53
+ inodes: this.getDirectoryTreeCache.inodes
54
+ },
55
+ errors: [],
56
+ ignored: [],
57
+ changed: false
61
58
  };
62
59
  }
60
+ const isWindows = process_1.default.platform === "win32";
63
61
  const tree = {};
64
62
  const inodes = {};
63
+ const errors = [];
64
+ const ignored = [];
65
65
  const dir = await fs_extra_1.default.readdir(this.sync.syncPair.localPath, {
66
66
  recursive: true,
67
67
  encoding: "utf-8"
68
68
  });
69
- const promises = [];
70
- for (const entry of dir) {
71
- promises.push(new Promise((resolve, reject) => {
72
- if (entry.startsWith(".filen.trash.local")) {
73
- resolve();
74
- return;
69
+ await (0, utils_1.promiseAllSettledChunked)(dir.map(async (entry) => {
70
+ if (entry.startsWith(constants_1.LOCAL_TRASH_NAME)) {
71
+ return;
72
+ }
73
+ const itemPath = path_1.default.join(this.sync.syncPair.localPath, entry);
74
+ if (this.sync.localIgnorer.ignores(entry)) {
75
+ ignored.push({
76
+ localPath: itemPath,
77
+ relativePath: entry,
78
+ reason: "localIgnore"
79
+ });
80
+ return;
81
+ }
82
+ if ((0, utils_1.isDirectoryPathIgnoredByDefault)(entry) ||
83
+ (0, utils_1.isRelativePathIgnoredByDefault)(entry) ||
84
+ (0, utils_1.isSystemPathIgnoredByDefault)(itemPath)) {
85
+ ignored.push({
86
+ localPath: itemPath,
87
+ relativePath: entry,
88
+ reason: "defaultIgnore"
89
+ });
90
+ return;
91
+ }
92
+ const entryPath = `/${isWindows ? entry.replace(/\\/g, "/") : entry}`;
93
+ const itemName = path_1.default.posix.basename(entryPath);
94
+ if (itemName.startsWith(constants_1.LOCAL_TRASH_NAME)) {
95
+ return;
96
+ }
97
+ if (this.sync.excludeDotFiles && itemName.startsWith(".")) {
98
+ ignored.push({
99
+ localPath: itemPath,
100
+ relativePath: entry,
101
+ reason: "dotFile"
102
+ });
103
+ return;
104
+ }
105
+ try {
106
+ const stats = await fs_extra_1.default.stat(itemPath);
107
+ const item = {
108
+ lastModified: parseInt(stats.mtimeMs), // Sometimes comes as a float, but we need an int
109
+ type: stats.isDirectory() ? "directory" : "file",
110
+ path: entryPath,
111
+ creation: parseInt(stats.birthtimeMs), // Sometimes comes as a float, but we need an int
112
+ size: stats.size,
113
+ inode: stats.ino
114
+ };
115
+ tree[entryPath] = item;
116
+ inodes[stats.ino] = item;
117
+ }
118
+ catch (e) {
119
+ this.sync.worker.logger.log("error", e, "filesystems.local.getDirectoryTree");
120
+ if (e instanceof Error) {
121
+ errors.push({
122
+ localPath: itemPath,
123
+ relativePath: entryPath,
124
+ error: e
125
+ });
75
126
  }
76
- const itemPath = path_1.default.join(this.sync.syncPair.localPath, entry);
77
- const entryPath = `/${process_1.default.platform === "win32" ? entry.replace(/\\/g, "/") : entry}`;
78
- fs_extra_1.default.stat(itemPath)
79
- .then(stats => {
80
- const item = {
81
- lastModified: parseInt(stats.mtimeMs), // Sometimes comes as a float, but we need an int
82
- type: stats.isDirectory() ? "directory" : "file",
83
- path: entryPath,
84
- creation: parseInt(stats.birthtimeMs), // Sometimes comes as a float, but we need an int
85
- size: stats.size,
86
- inode: stats.ino
87
- };
88
- tree[entryPath] = item;
89
- inodes[stats.ino] = item;
90
- resolve();
91
- })
92
- .catch(reject);
93
- }));
94
- }
95
- await (0, utils_1.promiseAllChunked)(promises);
127
+ }
128
+ }));
96
129
  this.getDirectoryTreeCache = {
97
130
  timestamp: Date.now(),
98
131
  tree,
99
132
  inodes
100
133
  };
101
- return { tree, inodes };
134
+ return {
135
+ result: {
136
+ tree,
137
+ inodes
138
+ },
139
+ errors,
140
+ ignored,
141
+ changed: true
142
+ };
102
143
  }
103
144
  /**
104
145
  * Start the local sync directory watcher.
@@ -145,13 +186,14 @@ class LocalFileSystem {
145
186
  * @returns {Promise<void>}
146
187
  */
147
188
  async waitForLocalDirectoryChanges() {
189
+ const waitTimeout = constants_1.SYNC_INTERVAL * 2;
148
190
  await new Promise(resolve => {
149
- if (Date.now() > this.lastDirectoryChangeTimestamp + constants_1.SYNC_INTERVAL) {
191
+ if (Date.now() > this.lastDirectoryChangeTimestamp + waitTimeout) {
150
192
  resolve();
151
193
  return;
152
194
  }
153
195
  const wait = setInterval(() => {
154
- if (Date.now() > this.lastDirectoryChangeTimestamp + constants_1.SYNC_INTERVAL) {
196
+ if (Date.now() > this.lastDirectoryChangeTimestamp + waitTimeout) {
155
197
  clearInterval(wait);
156
198
  resolve();
157
199
  }
@@ -160,13 +202,15 @@ class LocalFileSystem {
160
202
  }
161
203
  /**
162
204
  * Creates a hash of a file using streams.
163
- * @date 3/2/2024 - 9:29:48 AM
164
205
  *
165
206
  * @public
166
207
  * @async
167
- * @param {{ relativePath: string; algorithm: "sha512" }} param0
208
+ * @param {{
209
+ * relativePath: string
210
+ * algorithm: "sha512" | "md5" | "sha256"
211
+ * }} param0
168
212
  * @param {string} param0.relativePath
169
- * @param {"sha512"} param0.algorithm
213
+ * @param {("sha512" | "md5" | "sha256")} param0.algorithm
170
214
  * @returns {Promise<string>}
171
215
  */
172
216
  async createFileHash({ relativePath, algorithm }) {
@@ -205,7 +249,7 @@ class LocalFileSystem {
205
249
  async unlink({ relativePath, permanent = false }) {
206
250
  const localPath = path_1.default.join(this.sync.syncPair.localPath, relativePath);
207
251
  if (!permanent) {
208
- const localTrashPath = path_1.default.join(this.sync.syncPair.localPath, ".filen.trash.local");
252
+ const localTrashPath = path_1.default.join(this.sync.syncPair.localPath, constants_1.LOCAL_TRASH_NAME);
209
253
  await fs_extra_1.default.ensureDir(localTrashPath);
210
254
  await fs_extra_1.default.move(localPath, path_1.default.join(localTrashPath, path_1.default.posix.basename(relativePath)), {
211
255
  overwrite: true
@@ -256,16 +300,120 @@ class LocalFileSystem {
256
300
  * @returns {Promise<void>}
257
301
  */
258
302
  async upload({ relativePath }) {
303
+ var _a;
259
304
  const localPath = path_1.default.join(this.sync.syncPair.localPath, relativePath);
260
- const parentPath = path_1.default.posix.dirname(relativePath);
261
- await this.sync.remoteFileSystem.mkdir({ relativePath: parentPath });
262
- const parentUUID = await this.sync.remoteFileSystem.pathToItemUUID({ relativePath: parentPath });
263
- if (!parentUUID) {
264
- throw new Error(`Could not upload ${relativePath}: Parent path not found.`);
305
+ const signalKey = `upload:${relativePath}`;
306
+ if (!this.sync.pauseSignals[signalKey]) {
307
+ this.sync.pauseSignals[signalKey] = new sdk_1.PauseSignal();
308
+ }
309
+ if (!this.sync.abortControllers[signalKey]) {
310
+ this.sync.abortControllers[signalKey] = new AbortController();
311
+ }
312
+ (0, ipc_1.postMessageToMain)({
313
+ type: "transfer",
314
+ syncPair: this.sync.syncPair,
315
+ data: {
316
+ of: "upload",
317
+ type: "queued",
318
+ relativePath,
319
+ localPath
320
+ }
321
+ });
322
+ try {
323
+ const parentPath = path_1.default.posix.dirname(relativePath);
324
+ await this.sync.remoteFileSystem.mkdir({ relativePath: parentPath });
325
+ const parentUUID = await this.sync.remoteFileSystem.pathToItemUUID({ relativePath: parentPath });
326
+ if (!parentUUID) {
327
+ throw new Error(`Could not upload ${relativePath}: Parent path not found.`);
328
+ }
329
+ const hash = await this.createFileHash({
330
+ relativePath,
331
+ algorithm: "md5"
332
+ });
333
+ this.sync.localFileHashes[relativePath] = hash;
334
+ const item = await this.sync.sdk.cloud().uploadLocalFile({
335
+ source: localPath,
336
+ parent: parentUUID,
337
+ name: path_1.default.basename(localPath),
338
+ pauseSignal: this.sync.pauseSignals[signalKey],
339
+ abortSignal: (_a = this.sync.abortControllers[signalKey]) === null || _a === void 0 ? void 0 : _a.signal,
340
+ onError: err => {
341
+ this.sync.worker.logger.log("error", err, "filesystems.local.upload");
342
+ (0, ipc_1.postMessageToMain)({
343
+ type: "transfer",
344
+ syncPair: this.sync.syncPair,
345
+ data: {
346
+ of: "upload",
347
+ type: "error",
348
+ relativePath,
349
+ localPath,
350
+ error: (0, utils_1.serializeError)(err)
351
+ }
352
+ });
353
+ },
354
+ onProgress: bytes => {
355
+ (0, ipc_1.postMessageToMain)({
356
+ type: "transfer",
357
+ syncPair: this.sync.syncPair,
358
+ data: {
359
+ of: "upload",
360
+ type: "progress",
361
+ relativePath,
362
+ localPath,
363
+ bytes
364
+ }
365
+ });
366
+ },
367
+ onStarted: () => {
368
+ (0, ipc_1.postMessageToMain)({
369
+ type: "transfer",
370
+ syncPair: this.sync.syncPair,
371
+ data: {
372
+ of: "upload",
373
+ type: "started",
374
+ relativePath,
375
+ localPath
376
+ }
377
+ });
378
+ }
379
+ });
380
+ await this.sync.remoteFileSystem.itemsMutex.acquire();
381
+ this.sync.remoteFileSystem.getDirectoryTreeCache.tree[relativePath] = Object.assign(Object.assign({}, item), { path: relativePath });
382
+ this.sync.remoteFileSystem.getDirectoryTreeCache.uuids[item.uuid] = Object.assign(Object.assign({}, item), { path: relativePath });
383
+ this.sync.remoteFileSystem.itemsMutex.release();
384
+ (0, ipc_1.postMessageToMain)({
385
+ type: "transfer",
386
+ syncPair: this.sync.syncPair,
387
+ data: {
388
+ of: "upload",
389
+ type: "finished",
390
+ relativePath,
391
+ localPath
392
+ }
393
+ });
394
+ return item;
395
+ }
396
+ catch (e) {
397
+ this.sync.worker.logger.log("error", e, "filesystems.local.upload");
398
+ if (e instanceof Error) {
399
+ (0, ipc_1.postMessageToMain)({
400
+ type: "transfer",
401
+ syncPair: this.sync.syncPair,
402
+ data: {
403
+ of: "upload",
404
+ type: "error",
405
+ relativePath,
406
+ localPath,
407
+ error: (0, utils_1.serializeError)(e)
408
+ }
409
+ });
410
+ }
411
+ throw e;
412
+ }
413
+ finally {
414
+ delete this.sync.pauseSignals[signalKey];
415
+ delete this.sync.abortControllers[signalKey];
265
416
  }
266
- const hash = await this.createFileHash({ relativePath, algorithm: "sha512" });
267
- this.sync.localFileHashes[relativePath] = hash;
268
- return await this.sync.sdk.cloud().uploadLocalFile({ source: localPath, parent: parentUUID });
269
417
  }
270
418
  }
271
419
  exports.LocalFileSystem = LocalFileSystem;