core-3nweb-client-lib 0.26.1 → 0.27.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 (211) hide show
  1. package/build/api-defs/asmail.d.ts +1 -1
  2. package/build/api-defs/files.d.ts +281 -75
  3. package/build/core/app-files.js +7 -7
  4. package/build/core/asmail/config/common.js +2 -2
  5. package/build/core/asmail/config/index.js +2 -2
  6. package/build/core/asmail/config/published-intro-key.js +1 -1
  7. package/build/core/asmail/delivery/common.js +7 -7
  8. package/build/core/asmail/delivery/index.js +5 -5
  9. package/build/core/asmail/delivery/msg.js +4 -4
  10. package/build/core/asmail/delivery/per-recipient-wip.js +1 -1
  11. package/build/core/asmail/inbox/attachments/fs.d.ts +2 -1
  12. package/build/core/asmail/inbox/attachments/fs.js +9 -4
  13. package/build/core/asmail/inbox/cached-msgs.js +1 -1
  14. package/build/core/asmail/inbox/inbox-events.js +4 -4
  15. package/build/core/asmail/inbox/index.js +10 -10
  16. package/build/core/asmail/inbox/msg-downloader.js +1 -1
  17. package/build/core/asmail/inbox/msg-indexing.js +1 -1
  18. package/build/core/asmail/inbox/msg-on-disk.js +5 -5
  19. package/build/core/asmail/index.d.ts +3 -3
  20. package/build/core/asmail/index.js +13 -8
  21. package/build/core/asmail/key-verification.js +5 -5
  22. package/build/core/asmail/keyring/common.js +7 -6
  23. package/build/core/asmail/keyring/correspondent-keys.js +8 -7
  24. package/build/core/asmail/keyring/id-to-email-map.js +2 -1
  25. package/build/core/asmail/keyring/index.d.ts +7 -8
  26. package/build/core/asmail/keyring/index.js +15 -14
  27. package/build/core/asmail/keyring/keyring-storage.js +2 -1
  28. package/build/core/asmail/msg/opener.js +3 -3
  29. package/build/core/asmail/msg/packer.js +13 -13
  30. package/build/core/asmail/sending-params/own-params.js +2 -2
  31. package/build/core/asmail/sending-params/params-from-others.js +1 -1
  32. package/build/core/id-manager/index.d.ts +43 -0
  33. package/build/core/{id-manager.js → id-manager/index.js} +36 -114
  34. package/build/core/id-manager/key-storage.d.ts +21 -0
  35. package/build/core/id-manager/key-storage.js +96 -0
  36. package/build/core/index.d.ts +2 -1
  37. package/build/core/index.js +31 -33
  38. package/build/core/sign-in.d.ts +1 -2
  39. package/build/core/sign-in.js +8 -17
  40. package/build/core/sign-up.d.ts +2 -0
  41. package/build/core/sign-up.js +11 -10
  42. package/build/core/storage/common/json-saving.js +2 -2
  43. package/build/core/storage/common/obj-info-file.d.ts +12 -4
  44. package/build/core/storage/common/obj-info-file.js +66 -34
  45. package/build/core/storage/common/utils.d.ts +2 -0
  46. package/build/core/storage/common/utils.js +32 -0
  47. package/build/core/storage/index.d.ts +5 -17
  48. package/build/core/storage/index.js +78 -119
  49. package/build/core/storage/local/obj-files-gc.d.ts +2 -0
  50. package/build/core/storage/local/obj-files-gc.js +49 -37
  51. package/build/core/storage/local/obj-files.d.ts +4 -7
  52. package/build/core/storage/local/obj-files.js +7 -10
  53. package/build/core/storage/local/obj-status.d.ts +12 -6
  54. package/build/core/storage/local/obj-status.js +24 -9
  55. package/build/core/storage/local/storage.d.ts +10 -7
  56. package/build/core/storage/local/storage.js +29 -18
  57. package/build/core/storage/synced/downloader.js +1 -1
  58. package/build/core/storage/synced/obj-files-gc.d.ts +1 -0
  59. package/build/core/storage/synced/obj-files-gc.js +76 -39
  60. package/build/core/storage/synced/obj-files.d.ts +50 -36
  61. package/build/core/storage/synced/obj-files.js +201 -162
  62. package/build/core/storage/synced/obj-status.d.ts +99 -86
  63. package/build/core/storage/synced/obj-status.js +520 -251
  64. package/build/core/storage/synced/remote-events.d.ts +11 -12
  65. package/build/core/storage/synced/remote-events.js +73 -56
  66. package/build/core/storage/synced/storage.d.ts +24 -10
  67. package/build/core/storage/synced/storage.js +147 -47
  68. package/build/core/storage/synced/upload-header-file.d.ts +4 -0
  69. package/build/core/storage/synced/upload-header-file.js +64 -0
  70. package/build/core/storage/synced/upsyncer.d.ts +12 -7
  71. package/build/core/storage/synced/upsyncer.js +210 -280
  72. package/build/core/storage/system-folders/apps-data.d.ts +16 -0
  73. package/build/core/storage/system-folders/apps-data.js +110 -0
  74. package/build/core/storage/system-folders/index.d.ts +18 -0
  75. package/build/core/storage/system-folders/index.js +77 -0
  76. package/build/core-ipc/common-caps.js +3 -3
  77. package/build/core-ipc/generic.js +8 -8
  78. package/build/core-ipc/startup-caps.js +2 -2
  79. package/build/cryptors.js +6 -2
  80. package/build/ipc-via-protobuf/asmail-cap.js +58 -57
  81. package/build/ipc-via-protobuf/bytes.js +16 -17
  82. package/build/ipc-via-protobuf/connector-clients-side.d.ts +1 -0
  83. package/build/ipc-via-protobuf/connector-clients-side.js +14 -15
  84. package/build/ipc-via-protobuf/connector-services-side.js +10 -10
  85. package/build/ipc-via-protobuf/connector.js +4 -4
  86. package/build/ipc-via-protobuf/file.d.ts +48 -12
  87. package/build/ipc-via-protobuf/file.js +474 -126
  88. package/build/ipc-via-protobuf/fs.d.ts +8 -0
  89. package/build/ipc-via-protobuf/fs.js +577 -142
  90. package/build/ipc-via-protobuf/log-cap.js +2 -2
  91. package/build/ipc-via-protobuf/mailerid.js +3 -3
  92. package/build/ipc-via-protobuf/protobuf-msg.d.ts +1 -0
  93. package/build/ipc-via-protobuf/protobuf-msg.js +11 -7
  94. package/build/ipc-via-protobuf/startup-cap.js +21 -21
  95. package/build/ipc-via-protobuf/storage-cap.js +12 -12
  96. package/build/ipc.js +7 -2
  97. package/build/lib-client/3nstorage/exceptions.d.ts +16 -1
  98. package/build/lib-client/3nstorage/exceptions.js +21 -3
  99. package/build/lib-client/3nstorage/service.d.ts +21 -3
  100. package/build/lib-client/3nstorage/service.js +128 -46
  101. package/build/lib-client/3nstorage/util/file-based-json.d.ts +2 -1
  102. package/build/lib-client/3nstorage/util/file-based-json.js +3 -2
  103. package/build/lib-client/3nstorage/util/for-arrays.d.ts +1 -0
  104. package/build/lib-client/3nstorage/util/for-arrays.js +32 -0
  105. package/build/lib-client/3nstorage/xsp-fs/attrs.js +17 -17
  106. package/build/lib-client/3nstorage/xsp-fs/common.d.ts +44 -19
  107. package/build/lib-client/3nstorage/xsp-fs/common.js +30 -19
  108. package/build/lib-client/3nstorage/xsp-fs/file-node.d.ts +1 -0
  109. package/build/lib-client/3nstorage/xsp-fs/file-node.js +17 -13
  110. package/build/lib-client/3nstorage/xsp-fs/file.d.ts +31 -6
  111. package/build/lib-client/3nstorage/xsp-fs/file.js +73 -25
  112. package/build/lib-client/3nstorage/xsp-fs/folder-node-serialization.js +4 -4
  113. package/build/lib-client/3nstorage/xsp-fs/folder-node.d.ts +32 -13
  114. package/build/lib-client/3nstorage/xsp-fs/folder-node.js +752 -192
  115. package/build/lib-client/3nstorage/xsp-fs/fs.d.ts +35 -4
  116. package/build/lib-client/3nstorage/xsp-fs/fs.js +236 -119
  117. package/build/lib-client/3nstorage/xsp-fs/link-node.d.ts +1 -0
  118. package/build/lib-client/3nstorage/xsp-fs/link-node.js +7 -2
  119. package/build/lib-client/3nstorage/xsp-fs/node-in-fs.d.ts +30 -29
  120. package/build/lib-client/3nstorage/xsp-fs/node-in-fs.js +232 -127
  121. package/build/lib-client/3nstorage/xsp-fs/node-persistence.d.ts +1 -1
  122. package/build/lib-client/3nstorage/xsp-fs/node-persistence.js +17 -18
  123. package/build/lib-client/3nstorage/xsp-fs/xsp-payload-v1.js +3 -3
  124. package/build/lib-client/3nstorage/xsp-fs/xsp-payload-v2.js +53 -53
  125. package/build/lib-client/3nweb-signup.js +4 -4
  126. package/build/lib-client/asmail/recipient.js +15 -15
  127. package/build/lib-client/asmail/sender.js +22 -22
  128. package/build/lib-client/asmail/service-config.js +3 -3
  129. package/build/lib-client/cryptor/cryptor-in-worker.js +18 -16
  130. package/build/lib-client/cryptor/cryptor-wasm.js +1 -1
  131. package/build/lib-client/cryptor/cryptor.js +4 -2
  132. package/build/lib-client/cryptor/cryptor.wasm +0 -0
  133. package/build/lib-client/cryptor/in-proc-js.js +1 -1
  134. package/build/lib-client/cryptor/in-proc-wasm.js +6 -6
  135. package/build/lib-client/cryptor/worker-js.js +2 -2
  136. package/build/lib-client/cryptor/worker-wasm.js +2 -2
  137. package/build/lib-client/files-select.js +1 -1
  138. package/build/lib-client/files.d.ts +1 -1
  139. package/build/lib-client/files.js +71 -6
  140. package/build/lib-client/fs-collection.js +1 -1
  141. package/build/lib-client/fs-sync-utils.d.ts +5 -0
  142. package/build/lib-client/fs-sync-utils.js +61 -0
  143. package/build/lib-client/fs-view.d.ts +14 -0
  144. package/build/lib-client/fs-view.js +33 -0
  145. package/build/lib-client/key-derivation.js +1 -1
  146. package/build/lib-client/local-files/dev-file-sink.js +9 -9
  147. package/build/lib-client/local-files/dev-file-src.js +2 -2
  148. package/build/lib-client/local-files/device-fs.d.ts +1 -1
  149. package/build/lib-client/local-files/device-fs.js +56 -54
  150. package/build/lib-client/logging/log-to-file.d.ts +1 -1
  151. package/build/lib-client/logging/log-to-file.js +7 -7
  152. package/build/lib-client/mailer-id/login.js +7 -7
  153. package/build/lib-client/mailer-id/provisioner.js +12 -12
  154. package/build/lib-client/objs-on-disk/file-writing-proc.js +3 -3
  155. package/build/lib-client/objs-on-disk/obj-folders.js +31 -31
  156. package/build/lib-client/objs-on-disk/obj-on-disk.d.ts +13 -2
  157. package/build/lib-client/objs-on-disk/obj-on-disk.js +24 -9
  158. package/build/lib-client/request-utils.d.ts +1 -0
  159. package/build/lib-client/request-utils.js +13 -13
  160. package/build/lib-client/server-events.d.ts +3 -3
  161. package/build/lib-client/server-events.js +9 -8
  162. package/build/lib-client/service-locator.js +10 -10
  163. package/build/lib-client/user-with-mid-session.d.ts +2 -1
  164. package/build/lib-client/user-with-mid-session.js +14 -8
  165. package/build/lib-client/user-with-pkl-session.js +25 -25
  166. package/build/lib-client/ws-utils.js +2 -2
  167. package/build/lib-common/async-cryptor-wrap.js +4 -4
  168. package/build/lib-common/async-fs-node.d.ts +5 -3
  169. package/build/lib-common/async-fs-node.js +17 -17
  170. package/build/lib-common/byte-streaming/pipe.js +1 -1
  171. package/build/lib-common/byte-streaming/wrapping.js +13 -13
  172. package/build/lib-common/canonical-address.js +1 -1
  173. package/build/lib-common/exceptions/error.d.ts +1 -0
  174. package/build/lib-common/exceptions/error.js +7 -6
  175. package/build/lib-common/exceptions/file.d.ts +4 -2
  176. package/build/lib-common/exceptions/file.js +24 -54
  177. package/build/lib-common/ipc/generic-ipc.js +5 -4
  178. package/build/lib-common/ipc/ws-ipc.js +2 -2
  179. package/build/lib-common/mid-sigs-NaCl-Ed.js +14 -14
  180. package/build/lib-common/objs-on-disk/file-layout.d.ts +19 -0
  181. package/build/lib-common/objs-on-disk/file-layout.js +130 -12
  182. package/build/lib-common/objs-on-disk/obj-file.d.ts +13 -2
  183. package/build/lib-common/objs-on-disk/obj-file.js +96 -35
  184. package/build/lib-common/objs-on-disk/utils.d.ts +1 -0
  185. package/build/lib-common/objs-on-disk/utils.js +3 -3
  186. package/build/lib-common/objs-on-disk/v1-obj-file-format.js +14 -14
  187. package/build/lib-common/processes/labelled-exec-pools.d.ts +1 -1
  188. package/build/lib-common/processes/labelled-exec-pools.js +1 -1
  189. package/build/lib-common/processes/pressure.js +2 -2
  190. package/build/lib-common/processes/synced.js +1 -1
  191. package/build/lib-common/processes/timeout.js +2 -2
  192. package/build/lib-common/random-node.js +7 -7
  193. package/build/lib-common/service-api/3nstorage/owner.d.ts +101 -42
  194. package/build/lib-common/service-api/3nstorage/owner.js +83 -40
  195. package/build/lib-common/service-api/asmail/delivery.js +2 -2
  196. package/build/lib-common/service-api/asmail/retrieval.js +1 -1
  197. package/build/lib-common/timed-cache.d.ts +1 -0
  198. package/build/lib-common/timed-non-weak-cache.d.ts +1 -0
  199. package/build/lib-common/timed-non-weak-cache.js +11 -0
  200. package/build/lib-common/utils-for-observables.js +4 -4
  201. package/build/lib-common/weak-cache.d.ts +1 -0
  202. package/build/lib-common/weak-cache.js +12 -1
  203. package/build/lib-index.d.ts +2 -1
  204. package/build/lib-index.js +10 -7
  205. package/build/protos/asmail.proto.js +12955 -7496
  206. package/build/protos/file.proto.js +4867 -2744
  207. package/build/protos/fs.proto.js +9227 -3768
  208. package/package.json +7 -5
  209. package/protos/file.proto +91 -19
  210. package/protos/fs.proto +107 -8
  211. package/build/core/id-manager.d.ts +0 -46
@@ -22,6 +22,13 @@ declare type FileFlags = web3n.files.FileFlags;
22
22
  declare type FileByteSource = web3n.files.FileByteSource;
23
23
  declare type FileByteSink = web3n.files.FileByteSink;
24
24
  declare type XAttrsChanges = web3n.files.XAttrsChanges;
25
+ declare type WritableFSSyncAPI = web3n.files.WritableFSSyncAPI;
26
+ declare type SyncStatus = web3n.files.SyncStatus;
27
+ declare type WritableFSVersionedAPI = web3n.files.WritableFSVersionedAPI;
28
+ declare type OptionsToAdopteRemote = web3n.files.OptionsToAdopteRemote;
29
+ declare type OptionsToAdoptRemoteItem = web3n.files.OptionsToAdoptRemoteItem;
30
+ declare type OptionsToUploadLocal = web3n.files.OptionsToUploadLocal;
31
+ declare type FolderDiff = web3n.files.FolderDiff;
25
32
  export declare class XspFS implements WritableFS {
26
33
  readonly writable: boolean;
27
34
  name: string;
@@ -79,7 +86,7 @@ export declare class XspFS implements WritableFS {
79
86
  private getCloseEvent$;
80
87
  watchFolder(path: string, observer: Observer<FolderEvent>): () => void;
81
88
  watchFile(path: string, observer: Observer<FileEvent>): () => void;
82
- watchTree(path: string, observer: Observer<FolderEvent | FileEvent>): () => void;
89
+ watchTree(path: string, depth: number | undefined, observer: Observer<FolderEvent | FileEvent>): () => void;
83
90
  readonlyFile(path: string): Promise<ReadonlyFile>;
84
91
  writableFile(path: string, flags?: web3n.files.VersionedFileFlags): Promise<WritableFile>;
85
92
  copyFile(src: string, dst: string, overwrite?: boolean): Promise<void>;
@@ -94,14 +101,25 @@ export declare class XspFS implements WritableFS {
94
101
  writeBytes(path: string, bytes: Uint8Array, flags?: web3n.files.VersionedFileFlags): Promise<void>;
95
102
  getByteSink(path: string, flags?: web3n.files.VersionedFileFlags): Promise<FileByteSink>;
96
103
  }
97
- declare type WritableFSVersionedAPI = web3n.files.WritableFSVersionedAPI;
98
- declare class V implements WritableFSVersionedAPI {
104
+ interface N {
105
+ get(path: string): Promise<NodeInFS<any>>;
106
+ ensureIsWritable(): void;
107
+ }
108
+ declare class V implements WritableFSVersionedAPI, N {
99
109
  private rootNode;
100
- constructor(root: FolderNode);
110
+ private readonly writable;
111
+ readonly sync: S | undefined;
112
+ constructor(rootNode: FolderNode | undefined, writable: boolean, isInSyncedStorage: boolean);
113
+ archiveCurrent(path: string, version?: number): Promise<number>;
114
+ listVersions(path: string): Promise<{
115
+ current?: number;
116
+ archived?: number[];
117
+ }>;
101
118
  close(): void;
102
119
  getRootIfNotClosed(excPath: string): FolderNode;
103
120
  getOrCreateFile(path: string, flags: FileFlags): Promise<FileNode>;
104
121
  get(path: string): Promise<NodeInFS<any>>;
122
+ ensureIsWritable(): void;
105
123
  updateXAttrs(path: string, changes: XAttrsChanges): Promise<number>;
106
124
  getXAttr(path: string, xaName: string): Promise<{
107
125
  attr: any;
@@ -139,4 +157,17 @@ declare class V implements WritableFSVersionedAPI {
139
157
  version: number;
140
158
  }>;
141
159
  }
160
+ declare class S implements WritableFSSyncAPI {
161
+ private readonly n;
162
+ constructor(n: N);
163
+ upload(path: string, opts?: OptionsToUploadLocal): Promise<void>;
164
+ status(path: string): Promise<SyncStatus>;
165
+ updateStatusInfo(path: string): Promise<SyncStatus>;
166
+ isRemoteVersionOnDisk(path: string, version: number): Promise<'complete' | 'partial' | 'none'>;
167
+ download(path: string, version: number): Promise<void>;
168
+ adoptRemote(path: string, opts?: OptionsToAdopteRemote): Promise<void>;
169
+ private getFolderNode;
170
+ diffCurrentAndRemoteFolderVersions(path: string, remoteVersion?: number): Promise<FolderDiff | undefined>;
171
+ adoptRemoteFolderItem(path: string, itemName: string, opts?: OptionsToAdoptRemoteItem): Promise<number>;
172
+ }
142
173
  export {};
@@ -24,6 +24,7 @@ exports.XspFS = void 0;
24
24
  const file_1 = require("../../../lib-common/exceptions/file");
25
25
  const folder_node_1 = require("./folder-node");
26
26
  const file_2 = require("./file");
27
+ const common_1 = require("./common");
27
28
  const files_1 = require("../../files");
28
29
  const files_select_1 = require("../../files-select");
29
30
  const path_1 = require("path");
@@ -62,12 +63,12 @@ class XspFS {
62
63
  this.fsObs = new utils_for_observables_1.Broadcast();
63
64
  this.store = storage;
64
65
  this.type = this.store.type;
65
- this.v = new V(rootNode);
66
+ this.v = new V(rootNode, this.writable, (0, common_1.isSyncedStorage)(this.store));
66
67
  Object.seal(this);
67
68
  }
68
69
  storage() {
69
70
  if (!this.store) {
70
- throw file_1.makeFileException(file_1.Code.storageClosed, this.name);
71
+ throw (0, file_1.makeFileException)('storageClosed', this.name);
71
72
  }
72
73
  return this.store;
73
74
  }
@@ -78,7 +79,7 @@ class XspFS {
78
79
  const folderName = ((pathParts.length === 0) ?
79
80
  this.name : pathParts[pathParts.length - 1]);
80
81
  const fs = new XspFS(this.storage(), false, folder, folderName);
81
- return files_1.wrapReadonlyFS(fs);
82
+ return (0, files_1.wrapReadonlyFS)(fs);
82
83
  }
83
84
  async writableSubRoot(path, flags = WRITE_NONEXCL_FLAGS) {
84
85
  const pathParts = splitPathIntoParts(path);
@@ -87,7 +88,7 @@ class XspFS {
87
88
  const folderName = ((pathParts.length === 0) ?
88
89
  this.name : pathParts[pathParts.length - 1]);
89
90
  const fs = new XspFS(this.storage(), true, folder, folderName);
90
- return files_1.wrapWritableFS(fs);
91
+ return (0, files_1.wrapWritableFS)(fs);
91
92
  }
92
93
  /**
93
94
  * This creates in a root object in a given storage, returning fs object
@@ -98,7 +99,7 @@ class XspFS {
98
99
  static async makeNewRoot(storage, key) {
99
100
  const root = await folder_node_1.FolderNode.newRoot(storage, key);
100
101
  const fs = new XspFS(storage, true, root);
101
- return files_1.wrapWritableFS(fs);
102
+ return (0, files_1.wrapWritableFS)(fs);
102
103
  }
103
104
  /**
104
105
  * This creates fs object that represents existing root folder in a given
@@ -107,15 +108,15 @@ class XspFS {
107
108
  * @param key is a file key of a root object
108
109
  */
109
110
  static async fromExistingRoot(storage, key) {
110
- const objSrc = await storage.getObj(null);
111
+ const objSrc = await storage.getObjSrc(null);
111
112
  const root = await folder_node_1.FolderNode.rootFromObjBytes(storage, undefined, null, objSrc, key);
112
113
  const fs = new XspFS(storage, true, root);
113
- return files_1.wrapWritableFS(fs);
114
+ return (0, files_1.wrapWritableFS)(fs);
114
115
  }
115
116
  static fromASMailMsgRootFromJSON(storage, folderJson, rootName) {
116
117
  const root = folder_node_1.FolderNode.rootFromJSON(storage, rootName, folderJson);
117
118
  const fs = new XspFS(storage, false, root, rootName);
118
- return files_1.wrapIntoVersionlessReadonlyFS(fs);
119
+ return (0, files_1.wrapIntoVersionlessReadonlyFS)(fs);
119
120
  }
120
121
  /**
121
122
  * Note that this method doesn't close storage.
@@ -128,29 +129,34 @@ class XspFS {
128
129
  async makeFolder(path, exclusive = false) {
129
130
  const folderPath = splitPathIntoParts(path);
130
131
  const root = this.v.getRootIfNotClosed(path);
131
- await root.getFolderInThisSubTree(folderPath, true, exclusive).catch(setExcPath(path));
132
+ await root.getFolderInThisSubTree(folderPath, true, exclusive)
133
+ .catch(setExcPath(path));
132
134
  }
133
135
  select(path, criteria) {
134
- return files_select_1.selectInFS(this, path, criteria);
136
+ return (0, files_select_1.selectInFS)(this, path, criteria);
135
137
  }
136
138
  async deleteFolder(path, removeContent = false) {
137
139
  const { fileName: folderName, folderPath: parentPath } = split(path);
138
140
  const root = this.v.getRootIfNotClosed(path);
139
- const parentFolder = await root.getFolderInThisSubTree(parentPath).catch(setExcPath(parentPath.join('/')));
141
+ const parentFolder = await root.getFolderInThisSubTree(parentPath)
142
+ .catch(setExcPath(parentPath.join('/')));
140
143
  if (typeof folderName !== 'string') {
141
144
  throw new Error('Cannot remove root folder');
142
145
  }
143
146
  const folder = (await parentFolder.getFolder(folderName)
144
147
  .catch(setExcPath(path)));
145
148
  if (!removeContent && !folder.isEmpty()) {
146
- throw file_1.makeFileException(file_1.Code.notEmpty, path);
149
+ throw (0, file_1.makeFileException)('notEmpty', path);
147
150
  }
151
+ // note that internal folder.delete() removes all children as a matter
152
+ // of not leaving inaccessible nodes, i.e. content is removed implicitly
148
153
  await parentFolder.removeChild(folder);
149
154
  }
150
155
  async deleteFile(path) {
151
156
  const { fileName, folderPath } = split(path);
152
157
  const root = this.v.getRootIfNotClosed(path);
153
- const parentFolder = await root.getFolderInThisSubTree(folderPath).catch(setExcPath(path));
158
+ const parentFolder = await root.getFolderInThisSubTree(folderPath)
159
+ .catch(setExcPath(path));
154
160
  const file = await parentFolder.getFile(fileName)
155
161
  .catch(setExcPath(path));
156
162
  await parentFolder.removeChild(file);
@@ -158,8 +164,10 @@ class XspFS {
158
164
  async deleteLink(path) {
159
165
  const { fileName, folderPath } = split(path);
160
166
  const root = this.v.getRootIfNotClosed(path);
161
- const parentFolder = await root.getFolderInThisSubTree(folderPath).catch(setExcPath(path));
162
- const link = await parentFolder.getLink(fileName).catch(setExcPath(path));
167
+ const parentFolder = await root.getFolderInThisSubTree(folderPath)
168
+ .catch(setExcPath(path));
169
+ const link = await parentFolder.getLink(fileName)
170
+ .catch(setExcPath(path));
163
171
  await parentFolder.removeChild(link);
164
172
  }
165
173
  async move(initPath, newPath) {
@@ -197,13 +205,11 @@ class XspFS {
197
205
  }
198
206
  async stat(path) {
199
207
  const node = await this.v.get(path);
200
- const sync = await node.sync();
201
208
  const attrs = node.getAttrs();
202
209
  const stats = {
203
210
  ctime: new Date(attrs.ctime),
204
211
  mtime: new Date(attrs.mtime),
205
212
  version: node.version,
206
- sync,
207
213
  writable: this.writable,
208
214
  };
209
215
  if (node.type === 'file') {
@@ -248,17 +254,11 @@ class XspFS {
248
254
  return true;
249
255
  }
250
256
  else if (throwIfMissing) {
251
- let code = '';
252
- if (type === 'file') {
253
- code = file_1.Code.notFile;
254
- }
255
- else if (type === 'folder') {
256
- code = file_1.Code.notDirectory;
257
+ switch (type) {
258
+ case 'file': throw (0, file_1.makeFileException)('notFile', path);
259
+ case 'folder': throw (0, file_1.makeFileException)('notDirectory', path);
260
+ case 'link': throw (0, file_1.makeFileException)('notLink', path);
257
261
  }
258
- else if (type === 'link') {
259
- code = file_1.Code.notLink;
260
- }
261
- throw file_1.makeFileException(code, path);
262
262
  }
263
263
  else {
264
264
  return false;
@@ -306,7 +306,7 @@ class XspFS {
306
306
  truncate: true
307
307
  };
308
308
  const sink = await this.getByteSink(dst, flags);
309
- await pipe_1.pipe(src, sink);
309
+ await (0, pipe_1.pipe)(src, sink);
310
310
  }
311
311
  else if (f.isFolder) {
312
312
  const subFolder = await folder.readonlySubRoot(f.name);
@@ -369,65 +369,58 @@ class XspFS {
369
369
  const writable = !params.readonly;
370
370
  const root = await folder_node_1.FolderNode.rootFromLinkParams(storage, params.params);
371
371
  const fs = new XspFS(storage, writable, root, name);
372
- return (fs.writable ? files_1.wrapWritableFS(fs) : files_1.wrapReadonlyFS(fs));
372
+ return (fs.writable ? (0, files_1.wrapWritableFS)(fs) : (0, files_1.wrapReadonlyFS)(fs));
373
373
  }
374
374
  getCloseEvent$() {
375
- return this.fsObs.event$.pipe(operators_1.filter(ev => (ev === 'close')));
375
+ return this.fsObs.event$.pipe((0, operators_1.filter)(ev => (ev === 'close')));
376
376
  }
377
377
  watchFolder(path, observer) {
378
378
  const folderPath = splitPathIntoParts(path);
379
379
  const root = this.v.getRootIfNotClosed(path);
380
380
  const nodeProm = root.getFolderInThisSubTree(folderPath, false);
381
- const watchSub = rxjs_1.from(nodeProm)
382
- .pipe(operators_1.mergeMap(f => f.event$), operators_1.takeUntil(this.getCloseEvent$()))
383
- .subscribe(utils_for_observables_1.toRxObserver(observer));
381
+ const watchSub = (0, rxjs_1.from)(nodeProm)
382
+ .pipe((0, operators_1.mergeMap)(f => f.event$), (0, operators_1.map)(event => shallowCopyWithPath(event, path)), (0, operators_1.takeUntil)(this.getCloseEvent$()))
383
+ .subscribe((0, utils_for_observables_1.toRxObserver)(observer));
384
384
  return () => watchSub.unsubscribe();
385
385
  }
386
386
  watchFile(path, observer) {
387
387
  const { fileName, folderPath } = split(path);
388
388
  const root = this.v.getRootIfNotClosed(path);
389
389
  const nodeProm = root.getFolderInThisSubTree(folderPath, false);
390
- const watchSub = rxjs_1.from(nodeProm)
391
- .pipe(operators_1.mergeMap(folder => folder.getFile(fileName)), operators_1.mergeMap(f => f.event$), operators_1.takeUntil(this.getCloseEvent$()))
392
- .subscribe(utils_for_observables_1.toRxObserver(observer));
390
+ const watchSub = (0, rxjs_1.from)(nodeProm)
391
+ .pipe((0, operators_1.mergeMap)(folder => folder.getFile(fileName)), (0, operators_1.mergeMap)(f => f.event$), (0, operators_1.map)(event => shallowCopyWithPath(event, path)), (0, operators_1.takeUntil)(this.getCloseEvent$()))
392
+ .subscribe((0, utils_for_observables_1.toRxObserver)(observer));
393
393
  return () => watchSub.unsubscribe();
394
394
  }
395
- watchTree(path, observer) {
395
+ watchTree(path, depth, observer) {
396
396
  const folderPath = splitPathIntoParts(path);
397
397
  const root = this.v.getRootIfNotClosed(path);
398
- const idToPath = new ObjIdToPathMap();
398
+ const idToPath = new ObjIdToPathMap(depth);
399
399
  const setupFilterMap = root.getFolderInThisSubTree(folderPath, false)
400
400
  .then(rootNode => idToPath.fillFromTree(rootNode));
401
- const watchSub = rxjs_1.from(setupFilterMap)
402
- .pipe(operators_1.mergeMap(() => this.storage().getNodeEvents()), operators_1.map(nodeEvent => {
403
- const path = idToPath.getPathCorrectingTreeMap(nodeEvent);
404
- if (path) {
405
- const event = nodeEvent.event;
406
- event.path = path;
407
- return event;
408
- }
409
- }, 1), operators_1.filter(event => !!event), operators_1.takeUntil(this.getCloseEvent$()))
410
- .subscribe(utils_for_observables_1.toRxObserver(observer));
401
+ const watchSub = (0, rxjs_1.from)(setupFilterMap)
402
+ .pipe((0, operators_1.mergeMap)(() => this.storage().getNodeEvents()), (0, operators_1.map)(nodeEvent => idToPath.copyWithLongPath(nodeEvent)), (0, operators_1.filter)(event => !!event), (0, operators_1.takeUntil)(this.getCloseEvent$()))
403
+ .subscribe((0, utils_for_observables_1.toRxObserver)(observer));
411
404
  return () => watchSub.unsubscribe();
412
405
  }
413
406
  async readonlyFile(path) {
414
407
  const fNode = await this.v.getOrCreateFile(path, {});
415
- return files_1.wrapReadonlyFile(file_2.FileObject.makeExisting(fNode, false));
408
+ return (0, files_1.wrapReadonlyFile)(file_2.FileObject.makeExisting(fNode, false));
416
409
  }
417
410
  async writableFile(path, flags = WRITE_NONEXCL_FLAGS) {
418
411
  const exists = await this.checkFilePresence(path);
419
412
  if (exists) {
420
413
  if (flags.create && flags.exclusive) {
421
- throw file_1.makeFileException(file_1.Code.alreadyExists, path);
414
+ throw (0, file_1.makeFileException)('alreadyExists', path);
422
415
  }
423
416
  const fNode = await this.v.getOrCreateFile(path, flags);
424
- return files_1.wrapWritableFile(file_2.FileObject.makeExisting(fNode, true));
417
+ return (0, files_1.wrapWritableFile)(file_2.FileObject.makeExisting(fNode, true));
425
418
  }
426
419
  else {
427
420
  if (!flags.create) {
428
- throw file_1.makeFileException(file_1.Code.notFound, path);
421
+ throw (0, file_1.makeFileException)('notFound', path);
429
422
  }
430
- return files_1.wrapWritableFile(file_2.FileObject.makeForNotExisiting(path_1.posix.basename(path), () => this.v.getOrCreateFile(path, flags)));
423
+ return (0, files_1.wrapWritableFile)(file_2.FileObject.makeForNotExisiting(path_1.posix.basename(path), () => this.v.getOrCreateFile(path, flags), !!this.v.sync));
431
424
  }
432
425
  }
433
426
  async copyFile(src, dst, overwrite = false) {
@@ -438,7 +431,7 @@ class XspFS {
438
431
  truncate: true
439
432
  };
440
433
  const sink = await this.getByteSink(dst, flags);
441
- await pipe_1.pipe(srcBytes, sink);
434
+ await (0, pipe_1.pipe)(srcBytes, sink);
442
435
  }
443
436
  async saveFile(file, dst, overwrite = false) {
444
437
  const src = (file.v ?
@@ -449,7 +442,7 @@ class XspFS {
449
442
  truncate: true
450
443
  };
451
444
  const sink = await this.getByteSink(dst, flags);
452
- await pipe_1.pipe(src, sink);
445
+ await (0, pipe_1.pipe)(src, sink);
453
446
  }
454
447
  async listFolder(folder) {
455
448
  const { lst } = await this.v.listFolder(folder);
@@ -489,16 +482,33 @@ exports.XspFS = XspFS;
489
482
  Object.freeze(XspFS.prototype);
490
483
  Object.freeze(XspFS);
491
484
  class V {
492
- constructor(root) {
493
- this.rootNode = root;
485
+ constructor(rootNode, writable, isInSyncedStorage) {
486
+ this.rootNode = rootNode;
487
+ this.writable = writable;
488
+ this.sync = (isInSyncedStorage ? new S(this) : undefined);
494
489
  Object.seal(this);
495
490
  }
491
+ async archiveCurrent(path, version) {
492
+ this.ensureIsWritable();
493
+ const node = await this.get(path);
494
+ try {
495
+ const archivedVer = await node.archiveCurrent(version);
496
+ return archivedVer;
497
+ }
498
+ catch (exc) {
499
+ throw (0, common_1.setPathInExc)(exc, path);
500
+ }
501
+ }
502
+ async listVersions(path) {
503
+ const node = await this.get(path);
504
+ return node.listVersions();
505
+ }
496
506
  close() {
497
507
  this.rootNode = undefined;
498
508
  }
499
509
  getRootIfNotClosed(excPath) {
500
510
  if (!this.rootNode) {
501
- throw file_1.makeFileException(file_1.Code.storageClosed, excPath);
511
+ throw (0, file_1.makeFileException)('storageClosed', excPath);
502
512
  }
503
513
  return this.rootNode;
504
514
  }
@@ -511,7 +521,7 @@ class V {
511
521
  .catch(setExcPath(path));
512
522
  if (file) {
513
523
  if (exclusive) {
514
- throw file_1.makeFileException(file_1.Code.alreadyExists, path);
524
+ throw (0, file_1.makeFileException)('alreadyExists', path);
515
525
  }
516
526
  }
517
527
  else {
@@ -530,7 +540,13 @@ class V {
530
540
  .catch(setExcPath(path));
531
541
  return node;
532
542
  }
543
+ ensureIsWritable() {
544
+ if (!this.writable) {
545
+ throw new Error(`FS is not writable`);
546
+ }
547
+ }
533
548
  async updateXAttrs(path, changes) {
549
+ this.ensureIsWritable();
534
550
  const node = await this.get(path);
535
551
  return node.updateXAttrs(changes);
536
552
  }
@@ -552,6 +568,7 @@ class V {
552
568
  return folder.list();
553
569
  }
554
570
  async writeBytes(path, bytes, flags = WRITE_NONEXCL_FLAGS) {
571
+ this.ensureIsWritable();
555
572
  const f = await this.getOrCreateFile(path, flags);
556
573
  return f.save(bytes);
557
574
  }
@@ -570,7 +587,7 @@ class V {
570
587
  return { txt, version };
571
588
  }
572
589
  catch (err) {
573
- throw file_1.makeFileException(file_1.Code.parsingError, path, err);
590
+ throw (0, file_1.makeFileException)('parsingError', path, err);
574
591
  }
575
592
  }
576
593
  writeJSONFile(path, json, flags = WRITE_NONEXCL_FLAGS) {
@@ -584,10 +601,11 @@ class V {
584
601
  return { json, version };
585
602
  }
586
603
  catch (err) {
587
- throw file_1.makeFileException(file_1.Code.parsingError, path, err);
604
+ throw (0, file_1.makeFileException)('parsingError', path, err);
588
605
  }
589
606
  }
590
607
  async getByteSink(path, flags = WRITE_NONEXCL_FLAGS) {
608
+ this.ensureIsWritable();
591
609
  const f = await this.getOrCreateFile(path, flags);
592
610
  return f.writeSink(flags.truncate, flags.currentVersion);
593
611
  }
@@ -599,91 +617,190 @@ class V {
599
617
  Object.freeze(V.prototype);
600
618
  Object.freeze(V);
601
619
  class ObjIdToPathMap {
602
- constructor() {
620
+ constructor(maxDepth) {
621
+ this.maxDepth = maxDepth;
603
622
  this.map = new Map();
604
- this.moves = new Map();
605
623
  Object.seal(this);
606
624
  }
607
625
  async fillFromTree(root) {
608
- for (const [objId, path] of await recursiveIdAndPathList(root, '.')) {
609
- this.map.set(objId, path);
626
+ const listOfAll = await recursiveIdAndPathList(root, '.', this.maxDepth);
627
+ for (const [objId, path, depth] of listOfAll) {
628
+ this.map.set(objId, { path, depth });
610
629
  }
611
630
  }
612
- getPathCorrectingTreeMap({ event, objId, parentObjId }) {
613
- let path = this.map.get(objId);
614
- if (path) {
615
- if (event.type === 'removed') {
616
- this.map.delete(objId);
617
- }
618
- else if (event.type === 'entry-renaming') {
619
- const { newName, oldName } = event;
620
- const child = this.findObjIdByPath(`${path}/${oldName}`);
621
- if (child) {
622
- this.map.set(child, `${path}/${newName}`);
623
- }
624
- }
625
- else if (event.type === 'entry-removal') {
626
- const { moveLabel, name } = event;
627
- if (moveLabel) {
628
- const child = this.findObjIdByPath(`${path}/${name}`);
629
- if (child) {
630
- const moveInfo = this.moves.get(moveLabel);
631
- if (moveInfo) {
632
- this.map.set(child, moveInfo.newPath);
633
- this.moves.delete(moveLabel);
634
- }
635
- else {
636
- this.moves.set(moveLabel, { objId: child });
637
- }
638
- }
639
- }
640
- }
641
- else if (event.type === 'entry-addition') {
642
- const { moveLabel, entry: { name } } = event;
643
- const newPath = `${path}/${name}`;
644
- if (moveLabel) {
645
- const moveInfo = this.moves.get(moveLabel);
646
- if (moveInfo) {
647
- this.map.set(moveInfo.objId, newPath);
648
- this.moves.delete(moveLabel);
649
- }
650
- else {
651
- this.moves.set(moveLabel, { newPath });
652
- }
653
- }
654
- }
631
+ getPathCorrectingTreeMap({ event, objId, parentObjId, childObjId }) {
632
+ let pathAndDepth = this.map.get(objId);
633
+ if (pathAndDepth) {
634
+ const { path, depth } = pathAndDepth;
635
+ this.updateFoundObjMapOnEvent(objId, path, depth, childObjId, event);
655
636
  return path;
656
637
  }
657
- const parentPath = this.map.get(parentObjId);
658
- if (!parentPath || (event.type === 'removed')) {
638
+ if (event.type === 'removed') {
639
+ return;
640
+ }
641
+ if (parentObjId === undefined) {
642
+ return;
643
+ }
644
+ const parent = this.map.get(parentObjId);
645
+ if (!parent) {
646
+ return;
647
+ }
648
+ if ((this.maxDepth !== undefined)
649
+ && (this.maxDepth <= parent.depth)) {
659
650
  return;
660
651
  }
661
- path = `${parentPath}/${event.path}`;
662
- this.map.set(objId, path);
652
+ const path = `${parent.path}/${event.path}`;
653
+ this.map.set(objId, { path, depth: parent.depth + 1 });
663
654
  return path;
664
655
  }
665
- findObjIdByPath(path) {
666
- for (const [objId, p] of this.map.entries()) {
667
- if (p === path) {
668
- return objId;
656
+ updateFoundObjMapOnEvent(objId, path, depth, childObjId, event) {
657
+ if (event.type === 'removed') {
658
+ this.map.delete(objId);
659
+ return;
660
+ }
661
+ if ((this.maxDepth !== undefined) && (this.maxDepth <= depth)) {
662
+ return;
663
+ }
664
+ if (event.type === 'entry-renaming') {
665
+ const childEntry = this.map.get(childObjId);
666
+ if (childEntry) {
667
+ childEntry.path === `${path}/${event.newName}`;
669
668
  }
670
669
  }
670
+ else if (event.type === 'entry-removal') {
671
+ const childEntry = this.map.get(childObjId);
672
+ if (childEntry && (childEntry.path === `${path}/${event.name}`)) {
673
+ this.map.delete(childObjId);
674
+ }
675
+ }
676
+ else if (event.type === 'entry-addition') {
677
+ this.map.set(childObjId, { path: `${path}/${event.entry.name}`, depth: depth + 1 });
678
+ }
679
+ }
680
+ copyWithLongPath(nodeEvent) {
681
+ const path = this.getPathCorrectingTreeMap(nodeEvent);
682
+ return (path ? shallowCopyWithPath(nodeEvent.event, path) : undefined);
671
683
  }
672
684
  }
673
685
  Object.freeze(ObjIdToPathMap.prototype);
674
686
  Object.freeze(ObjIdToPathMap);
675
- async function recursiveIdAndPathList(folder, path) {
687
+ async function recursiveIdAndPathList(folder, path, maxDepth, depth = 0) {
676
688
  const { lst } = folder.list();
677
- const idAndPaths = [[folder.objId, path]];
689
+ const idAndPaths = [
690
+ [folder.objId, path, depth]
691
+ ];
692
+ if ((maxDepth !== undefined) && (depth === maxDepth)) {
693
+ return idAndPaths;
694
+ }
678
695
  for (const item of lst) {
696
+ const childPath = `${path}/${item.name}`;
679
697
  if (item.isFile || item.isLink) {
698
+ const { objId } = folder.getNodeInfo(item.name);
699
+ idAndPaths.push([objId, childPath, depth + 1]);
680
700
  }
681
701
  else if (item.isFolder) {
682
702
  const child = await folder.getFolder(item.name);
683
- const childLst = await recursiveIdAndPathList(child, `${path}/${item.name}`);
703
+ const childLst = await recursiveIdAndPathList(child, childPath, maxDepth, depth + 1);
684
704
  idAndPaths.push(...childLst);
685
705
  }
686
706
  }
687
707
  return idAndPaths;
688
708
  }
709
+ function shallowCopyWithPath(event, path) {
710
+ const shallowCopy = {};
711
+ for (const [field, value] of Object.entries(event)) {
712
+ shallowCopy[field] = value;
713
+ }
714
+ shallowCopy.path = path;
715
+ return shallowCopy;
716
+ }
717
+ class S {
718
+ constructor(n) {
719
+ this.n = n;
720
+ Object.freeze(this);
721
+ }
722
+ async upload(path, opts) {
723
+ this.n.ensureIsWritable();
724
+ const node = await this.n.get(path);
725
+ try {
726
+ await node.upload(opts);
727
+ }
728
+ catch (exc) {
729
+ throw (0, common_1.setPathInExc)(exc, path);
730
+ }
731
+ ;
732
+ }
733
+ async status(path) {
734
+ const node = await this.n.get(path);
735
+ try {
736
+ const status = await node.syncStatus();
737
+ return status;
738
+ }
739
+ catch (exc) {
740
+ throw (0, common_1.setPathInExc)(exc, path);
741
+ }
742
+ }
743
+ async updateStatusInfo(path) {
744
+ const node = await this.n.get(path);
745
+ const status = await node.updateStatusInfo();
746
+ return status;
747
+ }
748
+ async isRemoteVersionOnDisk(path, version) {
749
+ const node = await this.n.get(path);
750
+ try {
751
+ const isOnDisk = await node.isSyncedVersionOnDisk(version);
752
+ return isOnDisk;
753
+ }
754
+ catch (exc) {
755
+ throw (0, common_1.setPathInExc)(exc, path);
756
+ }
757
+ }
758
+ async download(path, version) {
759
+ const node = await this.n.get(path);
760
+ try {
761
+ await node.download(version);
762
+ }
763
+ catch (exc) {
764
+ throw (0, common_1.setPathInExc)(exc, path);
765
+ }
766
+ }
767
+ async adoptRemote(path, opts) {
768
+ const node = await this.n.get(path);
769
+ try {
770
+ await node.adoptRemote(opts);
771
+ }
772
+ catch (exc) {
773
+ throw (0, common_1.setPathInExc)(exc, path);
774
+ }
775
+ }
776
+ async getFolderNode(path) {
777
+ const node = await this.n.get(path);
778
+ if (node.type !== 'folder') {
779
+ throw (0, file_1.makeFileException)('notDirectory', path);
780
+ }
781
+ return node;
782
+ }
783
+ async diffCurrentAndRemoteFolderVersions(path, remoteVersion) {
784
+ const node = await this.getFolderNode(path);
785
+ try {
786
+ const diff = await node.diffCurrentAndRemote(remoteVersion);
787
+ return diff;
788
+ }
789
+ catch (exc) {
790
+ throw (0, common_1.setPathInExc)(exc, path);
791
+ }
792
+ }
793
+ async adoptRemoteFolderItem(path, itemName, opts) {
794
+ const node = await this.getFolderNode(path);
795
+ try {
796
+ const newVersion = await node.adoptRemoteFolderItem(itemName, opts);
797
+ return newVersion;
798
+ }
799
+ catch (exc) {
800
+ throw (0, common_1.setPathInExc)(exc, path);
801
+ }
802
+ }
803
+ }
804
+ Object.freeze(S.prototype);
805
+ Object.freeze(S);
689
806
  Object.freeze(exports);
@@ -24,6 +24,7 @@ export declare class LinkNode extends NodeInFS<LinkPersistance> {
24
24
  constructor(storage: Storage, name: string, objId: string, version: number, parentId: string | undefined, key: Uint8Array);
25
25
  static makeForNew(storage: Storage, parentId: string, name: string, key: Uint8Array): Promise<LinkNode>;
26
26
  static makeForExisting(storage: Storage, parentId: string, name: string, objId: string, key: Uint8Array): Promise<LinkNode>;
27
+ protected setCurrentStateFrom(src: ObjSource): Promise<void>;
27
28
  private setUpdatedState;
28
29
  save(params: LinkParameters<any>, changes?: XAttrsChanges): Promise<void>;
29
30
  private getLinkParams;