core-3nweb-client-lib 0.26.0 → 0.27.1

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