core-3nweb-client-lib 0.25.6 → 0.27.0

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 (215) hide show
  1. package/README.md +2 -2
  2. package/build/api-defs/asmail.d.ts +1 -1
  3. package/build/api-defs/files.d.ts +282 -70
  4. package/build/core/app-files.js +7 -7
  5. package/build/core/asmail/config/common.js +4 -4
  6. package/build/core/asmail/config/index.js +2 -2
  7. package/build/core/asmail/config/published-intro-key.js +1 -1
  8. package/build/core/asmail/delivery/common.js +7 -7
  9. package/build/core/asmail/delivery/index.js +7 -6
  10. package/build/core/asmail/delivery/msg.js +8 -7
  11. package/build/core/asmail/delivery/per-recipient-wip.js +3 -3
  12. package/build/core/asmail/inbox/attachments/fs.js +11 -1
  13. package/build/core/asmail/inbox/cached-msgs.js +3 -3
  14. package/build/core/asmail/inbox/inbox-events.js +5 -4
  15. package/build/core/asmail/inbox/index.js +12 -12
  16. package/build/core/asmail/inbox/msg-downloader.js +3 -3
  17. package/build/core/asmail/inbox/msg-indexing.js +4 -4
  18. package/build/core/asmail/inbox/msg-on-disk.js +7 -7
  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 +4 -3
  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 +4 -4
  31. package/build/core/asmail/sending-params/params-from-others.js +3 -3
  32. package/build/core/id-manager.js +8 -5
  33. package/build/core/index.d.ts +2 -1
  34. package/build/core/index.js +14 -14
  35. package/build/core/sign-in.d.ts +5 -4
  36. package/build/core/sign-in.js +12 -14
  37. package/build/core/sign-up.d.ts +1 -0
  38. package/build/core/sign-up.js +15 -11
  39. package/build/core/storage/common/json-saving.d.ts +21 -0
  40. package/build/core/storage/common/json-saving.js +82 -0
  41. package/build/core/storage/common/obj-info-file.d.ts +51 -0
  42. package/build/core/storage/common/obj-info-file.js +153 -5
  43. package/build/core/storage/common/utils.d.ts +2 -0
  44. package/build/core/storage/common/utils.js +32 -0
  45. package/build/core/storage/index.d.ts +3 -17
  46. package/build/core/storage/index.js +57 -77
  47. package/build/core/storage/local/obj-files-gc.d.ts +2 -0
  48. package/build/core/storage/local/obj-files-gc.js +53 -39
  49. package/build/core/storage/local/obj-files.d.ts +6 -9
  50. package/build/core/storage/local/obj-files.js +16 -19
  51. package/build/core/storage/local/obj-status.d.ts +20 -30
  52. package/build/core/storage/local/obj-status.js +46 -113
  53. package/build/core/storage/local/storage.d.ts +15 -5
  54. package/build/core/storage/local/storage.js +37 -18
  55. package/build/core/storage/synced/downloader.js +7 -6
  56. package/build/core/storage/synced/obj-files-gc.d.ts +6 -1
  57. package/build/core/storage/synced/obj-files-gc.js +106 -13
  58. package/build/core/storage/synced/obj-files.d.ts +46 -47
  59. package/build/core/storage/synced/obj-files.js +207 -154
  60. package/build/core/storage/synced/obj-status.d.ts +103 -42
  61. package/build/core/storage/synced/obj-status.js +525 -137
  62. package/build/core/storage/synced/remote-events.d.ts +11 -12
  63. package/build/core/storage/synced/remote-events.js +80 -57
  64. package/build/core/storage/synced/storage.d.ts +24 -5
  65. package/build/core/storage/synced/storage.js +123 -38
  66. package/build/core/storage/synced/upload-header-file.d.ts +4 -0
  67. package/build/core/storage/synced/upload-header-file.js +64 -0
  68. package/build/core/storage/synced/upsyncer.d.ts +15 -9
  69. package/build/core/storage/synced/upsyncer.js +219 -246
  70. package/build/core/storage/system-folders/apps-data.d.ts +16 -0
  71. package/build/core/storage/system-folders/apps-data.js +110 -0
  72. package/build/core/storage/system-folders/index.d.ts +18 -0
  73. package/build/core/storage/system-folders/index.js +77 -0
  74. package/build/core-ipc/common-caps.js +3 -3
  75. package/build/core-ipc/generic.js +8 -8
  76. package/build/core-ipc/startup-caps.js +2 -2
  77. package/build/cryptors.js +6 -2
  78. package/build/ipc-via-protobuf/asmail-cap.js +67 -83
  79. package/build/ipc-via-protobuf/bytes.js +16 -17
  80. package/build/ipc-via-protobuf/connector-clients-side.d.ts +3 -0
  81. package/build/ipc-via-protobuf/connector-clients-side.js +62 -25
  82. package/build/ipc-via-protobuf/connector-services-side.js +10 -10
  83. package/build/ipc-via-protobuf/connector.js +4 -4
  84. package/build/ipc-via-protobuf/file.d.ts +48 -12
  85. package/build/ipc-via-protobuf/file.js +476 -120
  86. package/build/ipc-via-protobuf/fs.d.ts +8 -0
  87. package/build/ipc-via-protobuf/fs.js +592 -159
  88. package/build/ipc-via-protobuf/log-cap.js +2 -2
  89. package/build/ipc-via-protobuf/mailerid.js +3 -3
  90. package/build/ipc-via-protobuf/protobuf-msg.d.ts +1 -0
  91. package/build/ipc-via-protobuf/protobuf-msg.js +11 -7
  92. package/build/ipc-via-protobuf/startup-cap.js +23 -23
  93. package/build/ipc-via-protobuf/storage-cap.js +12 -12
  94. package/build/ipc.js +7 -2
  95. package/build/lib-client/3nstorage/exceptions.d.ts +12 -8
  96. package/build/lib-client/3nstorage/exceptions.js +31 -10
  97. package/build/lib-client/3nstorage/service.d.ts +16 -2
  98. package/build/lib-client/3nstorage/service.js +109 -39
  99. package/build/lib-client/3nstorage/util/file-based-json.d.ts +2 -1
  100. package/build/lib-client/3nstorage/util/file-based-json.js +1 -1
  101. package/build/lib-client/3nstorage/xsp-fs/attrs.js +17 -17
  102. package/build/lib-client/3nstorage/xsp-fs/common.d.ts +52 -14
  103. package/build/lib-client/3nstorage/xsp-fs/common.js +31 -16
  104. package/build/lib-client/3nstorage/xsp-fs/file-node.d.ts +1 -0
  105. package/build/lib-client/3nstorage/xsp-fs/file-node.js +18 -14
  106. package/build/lib-client/3nstorage/xsp-fs/file.d.ts +31 -6
  107. package/build/lib-client/3nstorage/xsp-fs/file.js +74 -23
  108. package/build/lib-client/3nstorage/xsp-fs/folder-node-serialization.js +4 -4
  109. package/build/lib-client/3nstorage/xsp-fs/folder-node.d.ts +24 -11
  110. package/build/lib-client/3nstorage/xsp-fs/folder-node.js +599 -189
  111. package/build/lib-client/3nstorage/xsp-fs/fs.d.ts +45 -9
  112. package/build/lib-client/3nstorage/xsp-fs/fs.js +326 -74
  113. package/build/lib-client/3nstorage/xsp-fs/link-node.d.ts +1 -0
  114. package/build/lib-client/3nstorage/xsp-fs/link-node.js +7 -2
  115. package/build/lib-client/3nstorage/xsp-fs/node-in-fs.d.ts +30 -20
  116. package/build/lib-client/3nstorage/xsp-fs/node-in-fs.js +239 -106
  117. package/build/lib-client/3nstorage/xsp-fs/node-persistence.d.ts +1 -1
  118. package/build/lib-client/3nstorage/xsp-fs/node-persistence.js +18 -19
  119. package/build/lib-client/3nstorage/xsp-fs/xsp-payload-v1.js +5 -5
  120. package/build/lib-client/3nstorage/xsp-fs/xsp-payload-v2.js +56 -56
  121. package/build/lib-client/3nweb-signup.js +4 -4
  122. package/build/lib-client/asmail/recipient.js +15 -15
  123. package/build/lib-client/asmail/sender.js +22 -22
  124. package/build/lib-client/asmail/service-config.js +3 -3
  125. package/build/lib-client/cryptor/cryptor-in-worker.js +19 -17
  126. package/build/lib-client/cryptor/cryptor-wasm.js +1 -1
  127. package/build/lib-client/cryptor/cryptor.js +4 -2
  128. package/build/lib-client/cryptor/cryptor.wasm +0 -0
  129. package/build/lib-client/cryptor/in-proc-js.js +1 -1
  130. package/build/lib-client/cryptor/in-proc-wasm.js +7 -7
  131. package/build/lib-client/cryptor/worker-js.js +2 -2
  132. package/build/lib-client/cryptor/worker-wasm.js +2 -2
  133. package/build/lib-client/files-select.js +1 -1
  134. package/build/lib-client/files.d.ts +1 -1
  135. package/build/lib-client/files.js +71 -4
  136. package/build/lib-client/fs-collection.js +3 -2
  137. package/build/lib-client/fs-sync-utils.d.ts +5 -0
  138. package/build/lib-client/fs-sync-utils.js +61 -0
  139. package/build/lib-client/fs-view.d.ts +14 -0
  140. package/build/lib-client/fs-view.js +33 -0
  141. package/build/lib-client/key-derivation.js +1 -1
  142. package/build/lib-client/local-files/dev-file-sink.js +9 -9
  143. package/build/lib-client/local-files/dev-file-src.js +2 -2
  144. package/build/lib-client/local-files/device-fs.d.ts +1 -1
  145. package/build/lib-client/local-files/device-fs.js +56 -54
  146. package/build/lib-client/logging/log-to-file.d.ts +1 -1
  147. package/build/lib-client/logging/log-to-file.js +11 -11
  148. package/build/lib-client/mailer-id/login.js +7 -7
  149. package/build/lib-client/mailer-id/provisioner.js +12 -12
  150. package/build/lib-client/objs-on-disk/file-writing-proc.js +5 -5
  151. package/build/lib-client/objs-on-disk/obj-folders.js +33 -33
  152. package/build/lib-client/objs-on-disk/obj-on-disk.d.ts +13 -2
  153. package/build/lib-client/objs-on-disk/obj-on-disk.js +24 -9
  154. package/build/lib-client/request-utils.d.ts +1 -0
  155. package/build/lib-client/request-utils.js +14 -14
  156. package/build/lib-client/server-events.d.ts +3 -3
  157. package/build/lib-client/server-events.js +12 -10
  158. package/build/lib-client/service-locator.js +10 -10
  159. package/build/lib-client/user-with-mid-session.js +7 -7
  160. package/build/lib-client/user-with-pkl-session.js +25 -25
  161. package/build/lib-client/ws-utils.js +3 -3
  162. package/build/lib-common/async-cryptor-wrap.js +4 -4
  163. package/build/lib-common/async-fs-node.d.ts +5 -3
  164. package/build/lib-common/async-fs-node.js +19 -18
  165. package/build/lib-common/byte-streaming/pipe.js +1 -1
  166. package/build/lib-common/byte-streaming/wrapping.js +17 -17
  167. package/build/lib-common/canonical-address.js +1 -1
  168. package/build/lib-common/exceptions/error.d.ts +1 -0
  169. package/build/lib-common/exceptions/error.js +7 -6
  170. package/build/lib-common/exceptions/file.js +10 -1
  171. package/build/lib-common/ipc/generic-ipc.js +2 -2
  172. package/build/lib-common/ipc/ws-ipc.js +2 -2
  173. package/build/lib-common/json-utils.js +2 -1
  174. package/build/lib-common/mid-sigs-NaCl-Ed.js +14 -14
  175. package/build/lib-common/objs-on-disk/file-layout.d.ts +19 -0
  176. package/build/lib-common/objs-on-disk/file-layout.js +130 -12
  177. package/build/lib-common/objs-on-disk/obj-file.d.ts +13 -2
  178. package/build/lib-common/objs-on-disk/obj-file.js +99 -37
  179. package/build/lib-common/objs-on-disk/utils.d.ts +1 -0
  180. package/build/lib-common/objs-on-disk/utils.js +4 -4
  181. package/build/lib-common/objs-on-disk/v1-obj-file-format.js +14 -14
  182. package/build/lib-common/processes/deferred.d.ts +6 -0
  183. package/build/lib-common/processes/deferred.js +30 -0
  184. package/build/lib-common/processes/labelled-exec-pools.d.ts +33 -0
  185. package/build/lib-common/processes/labelled-exec-pools.js +141 -0
  186. package/build/lib-common/processes/pressure.d.ts +7 -0
  187. package/build/lib-common/processes/pressure.js +56 -0
  188. package/build/lib-common/processes/sleep.d.ts +1 -0
  189. package/build/lib-common/processes/sleep.js +26 -0
  190. package/build/lib-common/{processes.d.ts → processes/synced.d.ts} +0 -40
  191. package/build/lib-common/{processes.js → processes/synced.js} +187 -204
  192. package/build/lib-common/processes/timeout.d.ts +1 -0
  193. package/build/lib-common/processes/timeout.js +51 -0
  194. package/build/lib-common/random-node.js +7 -7
  195. package/build/lib-common/service-api/3nstorage/owner.d.ts +100 -39
  196. package/build/lib-common/service-api/3nstorage/owner.js +85 -42
  197. package/build/lib-common/service-api/asmail/delivery.js +2 -2
  198. package/build/lib-common/service-api/asmail/retrieval.js +1 -1
  199. package/build/lib-common/timed-cache.d.ts +1 -0
  200. package/build/lib-common/timed-non-weak-cache.d.ts +1 -0
  201. package/build/lib-common/timed-non-weak-cache.js +11 -0
  202. package/build/lib-common/utils-for-observables.d.ts +15 -1
  203. package/build/lib-common/utils-for-observables.js +70 -19
  204. package/build/lib-common/weak-cache.d.ts +1 -0
  205. package/build/lib-common/weak-cache.js +12 -1
  206. package/build/lib-index.d.ts +2 -1
  207. package/build/lib-index.js +10 -7
  208. package/build/protos/asmail.proto.js +12912 -7127
  209. package/build/protos/file.proto.js +4848 -2399
  210. package/build/protos/fs.proto.js +9230 -3445
  211. package/package.json +8 -7
  212. package/protos/file.proto +91 -11
  213. package/protos/fs.proto +107 -8
  214. package/build/core/storage/synced/upsync-status.d.ts +0 -41
  215. package/build/core/storage/synced/upsync-status.js +0 -158
@@ -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");
@@ -31,6 +32,7 @@ const pipe_1 = require("../../../lib-common/byte-streaming/pipe");
31
32
  const buffer_utils_1 = require("../../../lib-common/buffer-utils");
32
33
  const rxjs_1 = require("rxjs");
33
34
  const operators_1 = require("rxjs/operators");
35
+ const utils_for_observables_1 = require("../../../lib-common/utils-for-observables");
34
36
  function splitPathIntoParts(path) {
35
37
  return path_1.posix.resolve('/', path).split('/').filter(part => !!part);
36
38
  }
@@ -55,33 +57,38 @@ const WRITE_NONEXCL_FLAGS = {
55
57
  truncate: true
56
58
  };
57
59
  class XspFS {
58
- constructor(storage, writable, name = '') {
59
- this.storage = storage;
60
+ constructor(storage, writable, rootNode, name = '') {
60
61
  this.writable = writable;
61
62
  this.name = name;
62
- this.v = new V();
63
- this.type = this.storage.type;
63
+ this.fsObs = new utils_for_observables_1.Broadcast();
64
+ this.store = storage;
65
+ this.type = this.store.type;
66
+ this.v = new V(rootNode, this.writable, (0, common_1.isSyncedStorage)(this.store));
64
67
  Object.seal(this);
65
68
  }
69
+ storage() {
70
+ if (!this.store) {
71
+ throw (0, file_1.makeFileException)(file_1.Code.storageClosed, this.name);
72
+ }
73
+ return this.store;
74
+ }
66
75
  async readonlySubRoot(path) {
67
76
  const pathParts = splitPathIntoParts(path);
68
- const folder = await this.v.root.getFolderInThisSubTree(pathParts, false)
69
- .catch(setExcPath(path));
77
+ const root = this.v.getRootIfNotClosed(path);
78
+ const folder = await root.getFolderInThisSubTree(pathParts, false).catch(setExcPath(path));
70
79
  const folderName = ((pathParts.length === 0) ?
71
80
  this.name : pathParts[pathParts.length - 1]);
72
- const fs = new XspFS(this.storage, false, folderName);
73
- fs.v.root = folder;
74
- return files_1.wrapReadonlyFS(fs);
81
+ const fs = new XspFS(this.storage(), false, folder, folderName);
82
+ return (0, files_1.wrapReadonlyFS)(fs);
75
83
  }
76
84
  async writableSubRoot(path, flags = WRITE_NONEXCL_FLAGS) {
77
85
  const pathParts = splitPathIntoParts(path);
78
- const folder = await this.v.root.getFolderInThisSubTree(pathParts, flags.create, flags.exclusive)
79
- .catch(setExcPath(path));
86
+ const root = this.v.getRootIfNotClosed(path);
87
+ const folder = await root.getFolderInThisSubTree(pathParts, flags.create, flags.exclusive).catch(setExcPath(path));
80
88
  const folderName = ((pathParts.length === 0) ?
81
89
  this.name : pathParts[pathParts.length - 1]);
82
- const fs = new XspFS(this.storage, true, folderName);
83
- fs.v.root = folder;
84
- return files_1.wrapWritableFS(fs);
90
+ const fs = new XspFS(this.storage(), true, folder, folderName);
91
+ return (0, files_1.wrapWritableFS)(fs);
85
92
  }
86
93
  /**
87
94
  * This creates in a root object in a given storage, returning fs object
@@ -90,9 +97,9 @@ class XspFS {
90
97
  * @param key is a file key of a root object
91
98
  */
92
99
  static async makeNewRoot(storage, key) {
93
- const fs = new XspFS(storage, true);
94
- fs.v.root = await folder_node_1.FolderNode.newRoot(fs.storage, key);
95
- return files_1.wrapWritableFS(fs);
100
+ const root = await folder_node_1.FolderNode.newRoot(storage, key);
101
+ const fs = new XspFS(storage, true, root);
102
+ return (0, files_1.wrapWritableFS)(fs);
96
103
  }
97
104
  /**
98
105
  * This creates fs object that represents existing root folder in a given
@@ -101,34 +108,37 @@ class XspFS {
101
108
  * @param key is a file key of a root object
102
109
  */
103
110
  static async fromExistingRoot(storage, key) {
104
- const fs = new XspFS(storage, true);
105
- const objSrc = await storage.getObj(null);
106
- fs.v.root = await folder_node_1.FolderNode.rootFromObjBytes(fs.storage, undefined, null, objSrc, key);
107
- return files_1.wrapWritableFS(fs);
111
+ const objSrc = await storage.getObjSrc(null);
112
+ const root = await folder_node_1.FolderNode.rootFromObjBytes(storage, undefined, null, objSrc, key);
113
+ const fs = new XspFS(storage, true, root);
114
+ return (0, files_1.wrapWritableFS)(fs);
108
115
  }
109
116
  static fromASMailMsgRootFromJSON(storage, folderJson, rootName) {
110
- const fs = new XspFS(storage, false, rootName);
111
- fs.v.root = folder_node_1.FolderNode.rootFromJSON(storage, rootName, folderJson);
112
- return files_1.wrapIntoVersionlessReadonlyFS(fs);
117
+ const root = folder_node_1.FolderNode.rootFromJSON(storage, rootName, folderJson);
118
+ const fs = new XspFS(storage, false, root, rootName);
119
+ return (0, files_1.wrapIntoVersionlessReadonlyFS)(fs);
113
120
  }
114
121
  /**
115
122
  * Note that this method doesn't close storage.
116
123
  */
117
124
  async close() {
118
- this.v.root = undefined;
119
- this.storage = undefined;
125
+ this.v.close();
126
+ this.store = undefined;
127
+ this.fsObs.done();
120
128
  }
121
129
  async makeFolder(path, exclusive = false) {
122
130
  const folderPath = splitPathIntoParts(path);
123
- await this.v.root.getFolderInThisSubTree(folderPath, true, exclusive)
131
+ const root = this.v.getRootIfNotClosed(path);
132
+ await root.getFolderInThisSubTree(folderPath, true, exclusive)
124
133
  .catch(setExcPath(path));
125
134
  }
126
135
  select(path, criteria) {
127
- return files_select_1.selectInFS(this, path, criteria);
136
+ return (0, files_select_1.selectInFS)(this, path, criteria);
128
137
  }
129
138
  async deleteFolder(path, removeContent = false) {
130
139
  const { fileName: folderName, folderPath: parentPath } = split(path);
131
- const parentFolder = await this.v.root.getFolderInThisSubTree(parentPath)
140
+ const root = this.v.getRootIfNotClosed(path);
141
+ const parentFolder = await root.getFolderInThisSubTree(parentPath)
132
142
  .catch(setExcPath(parentPath.join('/')));
133
143
  if (typeof folderName !== 'string') {
134
144
  throw new Error('Cannot remove root folder');
@@ -136,13 +146,14 @@ class XspFS {
136
146
  const folder = (await parentFolder.getFolder(folderName)
137
147
  .catch(setExcPath(path)));
138
148
  if (!removeContent && !folder.isEmpty()) {
139
- throw file_1.makeFileException(file_1.Code.notEmpty, path);
149
+ throw (0, file_1.makeFileException)(file_1.Code.notEmpty, path);
140
150
  }
141
151
  await parentFolder.removeChild(folder);
142
152
  }
143
153
  async deleteFile(path) {
144
154
  const { fileName, folderPath } = split(path);
145
- const parentFolder = await this.v.root.getFolderInThisSubTree(folderPath)
155
+ const root = this.v.getRootIfNotClosed(path);
156
+ const parentFolder = await root.getFolderInThisSubTree(folderPath)
146
157
  .catch(setExcPath(path));
147
158
  const file = await parentFolder.getFile(fileName)
148
159
  .catch(setExcPath(path));
@@ -150,7 +161,8 @@ class XspFS {
150
161
  }
151
162
  async deleteLink(path) {
152
163
  const { fileName, folderPath } = split(path);
153
- const parentFolder = await this.v.root.getFolderInThisSubTree(folderPath)
164
+ const root = this.v.getRootIfNotClosed(path);
165
+ const parentFolder = await root.getFolderInThisSubTree(folderPath)
154
166
  .catch(setExcPath(path));
155
167
  const link = await parentFolder.getLink(fileName)
156
168
  .catch(setExcPath(path));
@@ -169,10 +181,11 @@ class XspFS {
169
181
  }
170
182
  const dstFName = dstFolderPath[dstFolderPath.length - 1];
171
183
  dstFolderPath.splice(dstFolderPath.length - 1, 1);
184
+ const root = this.v.getRootIfNotClosed(initPath);
172
185
  try {
173
- const srcFolder = await this.v.root.getFolderInThisSubTree(srcFolderPath);
186
+ const srcFolder = await root.getFolderInThisSubTree(srcFolderPath);
174
187
  srcFolder.hasChild(initFName, true);
175
- const dstFolder = await this.v.root.getFolderInThisSubTree(dstFolderPath, true);
188
+ const dstFolder = await root.getFolderInThisSubTree(dstFolderPath, true);
176
189
  await srcFolder.moveChildTo(initFName, dstFolder, dstFName);
177
190
  }
178
191
  catch (exc) {
@@ -249,7 +262,7 @@ class XspFS {
249
262
  else if (type === 'link') {
250
263
  code = file_1.Code.notLink;
251
264
  }
252
- throw file_1.makeFileException(code, path);
265
+ throw (0, file_1.makeFileException)(code, path);
253
266
  }
254
267
  else {
255
268
  return false;
@@ -297,7 +310,7 @@ class XspFS {
297
310
  truncate: true
298
311
  };
299
312
  const sink = await this.getByteSink(dst, flags);
300
- await pipe_1.pipe(src, sink);
313
+ await (0, pipe_1.pipe)(src, sink);
301
314
  }
302
315
  else if (f.isFolder) {
303
316
  const subFolder = await folder.readonlySubRoot(f.name);
@@ -311,21 +324,22 @@ class XspFS {
311
324
  }
312
325
  }
313
326
  ensureLinkingAllowedTo(params) {
314
- if (this.storage.type === 'local') {
327
+ const storage = this.storage();
328
+ if (storage.type === 'local') {
315
329
  return;
316
330
  }
317
- else if (this.storage.type === 'synced') {
331
+ else if (storage.type === 'synced') {
318
332
  if ((params.storageType === 'share') ||
319
333
  (params.storageType === 'synced')) {
320
334
  return;
321
335
  }
322
336
  }
323
- else if (this.storage.type === 'share') {
337
+ else if (storage.type === 'share') {
324
338
  if (params.storageType === 'share') {
325
339
  return;
326
340
  }
327
341
  }
328
- throw new Error(`Cannot create link to ${params.storageType} from ${this.storage.type} storage.`);
342
+ throw new Error(`Cannot create link to ${params.storageType} from ${storage.type} storage.`);
329
343
  }
330
344
  async link(path, target) {
331
345
  if (!target ||
@@ -335,20 +349,21 @@ class XspFS {
335
349
  const params = await target.getLinkParams();
336
350
  this.ensureLinkingAllowedTo(params);
337
351
  const { fileName, folderPath } = split(path);
338
- const folder = await this.v.root.getFolderInThisSubTree(folderPath, true)
339
- .catch(setExcPath(path));
352
+ const root = this.v.getRootIfNotClosed(path);
353
+ const folder = await root.getFolderInThisSubTree(folderPath, true).catch(setExcPath(path));
340
354
  await folder.createLink(fileName, params);
341
355
  }
342
356
  async readLink(path) {
343
357
  const { fileName, folderPath } = split(path);
344
- const folder = await this.v.root.getFolderInThisSubTree(folderPath)
345
- .catch(setExcPath(path));
358
+ const root = this.v.getRootIfNotClosed(path);
359
+ const folder = await root.getFolderInThisSubTree(folderPath).catch(setExcPath(path));
346
360
  const link = await folder.getLink(fileName)
347
361
  .catch(setExcPath(path));
348
362
  return await link.read();
349
363
  }
350
364
  async getLinkParams() {
351
- const linkParams = this.v.root.getParamsForLink();
365
+ const root = this.v.getRootIfNotClosed(this.name);
366
+ const linkParams = root.getParamsForLink();
352
367
  linkParams.params.folderName = this.name;
353
368
  linkParams.readonly = !this.writable;
354
369
  return linkParams;
@@ -356,44 +371,60 @@ class XspFS {
356
371
  static async makeFolderFromLinkParams(storage, params) {
357
372
  const name = params.params.folderName;
358
373
  const writable = !params.readonly;
359
- const fs = new XspFS(storage, writable, name);
360
- fs.v.root = await folder_node_1.FolderNode.rootFromLinkParams(storage, params.params);
361
- return (fs.writable ? files_1.wrapWritableFS(fs) : files_1.wrapReadonlyFS(fs));
374
+ const root = await folder_node_1.FolderNode.rootFromLinkParams(storage, params.params);
375
+ const fs = new XspFS(storage, writable, root, name);
376
+ return (fs.writable ? (0, files_1.wrapWritableFS)(fs) : (0, files_1.wrapReadonlyFS)(fs));
377
+ }
378
+ getCloseEvent$() {
379
+ return this.fsObs.event$.pipe((0, operators_1.filter)(ev => (ev === 'close')));
362
380
  }
363
381
  watchFolder(path, observer) {
364
- const watchSub = rxjs_1.from(this.v.root.getFolderInThisSubTree(splitPathIntoParts(path), false))
365
- .pipe(operators_1.mergeMap(f => f.event$))
366
- .subscribe(observer);
382
+ const folderPath = splitPathIntoParts(path);
383
+ const root = this.v.getRootIfNotClosed(path);
384
+ const nodeProm = root.getFolderInThisSubTree(folderPath, false);
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));
367
388
  return () => watchSub.unsubscribe();
368
389
  }
369
390
  watchFile(path, observer) {
370
391
  const { fileName, folderPath } = split(path);
371
- const watchSub = rxjs_1.from(this.v.root.getFolderInThisSubTree(folderPath, false))
372
- .pipe(operators_1.mergeMap(folder => folder.getFile(fileName)), operators_1.mergeMap(f => f.event$))
373
- .subscribe(observer);
392
+ const root = this.v.getRootIfNotClosed(path);
393
+ const nodeProm = root.getFolderInThisSubTree(folderPath, false);
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));
374
397
  return () => watchSub.unsubscribe();
375
398
  }
376
- watchTree(path, observer) {
377
- throw new Error('Not implemented, yet');
399
+ watchTree(path, depth, observer) {
400
+ const folderPath = splitPathIntoParts(path);
401
+ const root = this.v.getRootIfNotClosed(path);
402
+ const idToPath = new ObjIdToPathMap(depth);
403
+ const setupFilterMap = root.getFolderInThisSubTree(folderPath, false)
404
+ .then(rootNode => idToPath.fillFromTree(rootNode));
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));
408
+ return () => watchSub.unsubscribe();
378
409
  }
379
410
  async readonlyFile(path) {
380
411
  const fNode = await this.v.getOrCreateFile(path, {});
381
- return files_1.wrapReadonlyFile(file_2.FileObject.makeExisting(fNode, false));
412
+ return (0, files_1.wrapReadonlyFile)(file_2.FileObject.makeExisting(fNode, false));
382
413
  }
383
414
  async writableFile(path, flags = WRITE_NONEXCL_FLAGS) {
384
415
  const exists = await this.checkFilePresence(path);
385
416
  if (exists) {
386
417
  if (flags.create && flags.exclusive) {
387
- throw file_1.makeFileException(file_1.Code.alreadyExists, path);
418
+ throw (0, file_1.makeFileException)(file_1.Code.alreadyExists, path);
388
419
  }
389
420
  const fNode = await this.v.getOrCreateFile(path, flags);
390
- return files_1.wrapWritableFile(file_2.FileObject.makeExisting(fNode, true));
421
+ return (0, files_1.wrapWritableFile)(file_2.FileObject.makeExisting(fNode, true));
391
422
  }
392
423
  else {
393
424
  if (!flags.create) {
394
- throw file_1.makeFileException(file_1.Code.notFound, path);
425
+ throw (0, file_1.makeFileException)(file_1.Code.notFound, path);
395
426
  }
396
- 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));
397
428
  }
398
429
  }
399
430
  async copyFile(src, dst, overwrite = false) {
@@ -404,7 +435,7 @@ class XspFS {
404
435
  truncate: true
405
436
  };
406
437
  const sink = await this.getByteSink(dst, flags);
407
- await pipe_1.pipe(srcBytes, sink);
438
+ await (0, pipe_1.pipe)(srcBytes, sink);
408
439
  }
409
440
  async saveFile(file, dst, overwrite = false) {
410
441
  const src = (file.v ?
@@ -415,7 +446,7 @@ class XspFS {
415
446
  truncate: true
416
447
  };
417
448
  const sink = await this.getByteSink(dst, flags);
418
- await pipe_1.pipe(src, sink);
449
+ await (0, pipe_1.pipe)(src, sink);
419
450
  }
420
451
  async listFolder(folder) {
421
452
  const { lst } = await this.v.listFolder(folder);
@@ -455,21 +486,46 @@ exports.XspFS = XspFS;
455
486
  Object.freeze(XspFS.prototype);
456
487
  Object.freeze(XspFS);
457
488
  class V {
458
- constructor() {
459
- this.root = undefined;
489
+ constructor(rootNode, writable, isInSyncedStorage) {
490
+ this.rootNode = rootNode;
491
+ this.writable = writable;
492
+ this.sync = (isInSyncedStorage ? new S(this) : undefined);
460
493
  Object.seal(this);
461
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
+ }
510
+ close() {
511
+ this.rootNode = undefined;
512
+ }
513
+ getRootIfNotClosed(excPath) {
514
+ if (!this.rootNode) {
515
+ throw (0, file_1.makeFileException)(file_1.Code.storageClosed, excPath);
516
+ }
517
+ return this.rootNode;
518
+ }
462
519
  async getOrCreateFile(path, flags) {
463
520
  const { fileName, folderPath } = split(path);
464
521
  const { create, exclusive } = flags;
465
- const folder = await this.root.getFolderInThisSubTree(folderPath, create)
466
- .catch(setExcPath(path));
522
+ const folder = await this.getRootIfNotClosed(path).getFolderInThisSubTree(folderPath, create).catch(setExcPath(path));
467
523
  const nullOnMissing = create;
468
524
  let file = await folder.getFile(fileName, nullOnMissing)
469
525
  .catch(setExcPath(path));
470
526
  if (file) {
471
527
  if (exclusive) {
472
- throw file_1.makeFileException(file_1.Code.alreadyExists, path);
528
+ throw (0, file_1.makeFileException)(file_1.Code.alreadyExists, path);
473
529
  }
474
530
  }
475
531
  else {
@@ -479,16 +535,22 @@ class V {
479
535
  }
480
536
  async get(path) {
481
537
  const { fileName, folderPath } = split(path);
482
- const folder = await this.root.getFolderInThisSubTree(folderPath, false)
483
- .catch(setExcPath(path));
538
+ const root = this.getRootIfNotClosed(path);
539
+ const folder = await root.getFolderInThisSubTree(folderPath, false).catch(setExcPath(path));
484
540
  if (fileName === undefined) {
485
- return this.root;
541
+ return root;
486
542
  }
487
543
  const node = await folder.getNode(undefined, fileName)
488
544
  .catch(setExcPath(path));
489
545
  return node;
490
546
  }
547
+ ensureIsWritable() {
548
+ if (!this.writable) {
549
+ throw new Error(`FS is not writable`);
550
+ }
551
+ }
491
552
  async updateXAttrs(path, changes) {
553
+ this.ensureIsWritable();
492
554
  const node = await this.get(path);
493
555
  return node.updateXAttrs(changes);
494
556
  }
@@ -505,10 +567,12 @@ class V {
505
567
  };
506
568
  }
507
569
  async listFolder(path) {
508
- const folder = await this.root.getFolderInThisSubTree(splitPathIntoParts(path), false).catch(setExcPath(path));
570
+ const root = this.getRootIfNotClosed(path);
571
+ const folder = await root.getFolderInThisSubTree(splitPathIntoParts(path), false).catch(setExcPath(path));
509
572
  return folder.list();
510
573
  }
511
574
  async writeBytes(path, bytes, flags = WRITE_NONEXCL_FLAGS) {
575
+ this.ensureIsWritable();
512
576
  const f = await this.getOrCreateFile(path, flags);
513
577
  return f.save(bytes);
514
578
  }
@@ -527,7 +591,7 @@ class V {
527
591
  return { txt, version };
528
592
  }
529
593
  catch (err) {
530
- throw file_1.makeFileException(file_1.Code.parsingError, path, err);
594
+ throw (0, file_1.makeFileException)(file_1.Code.parsingError, path, err);
531
595
  }
532
596
  }
533
597
  writeJSONFile(path, json, flags = WRITE_NONEXCL_FLAGS) {
@@ -541,10 +605,11 @@ class V {
541
605
  return { json, version };
542
606
  }
543
607
  catch (err) {
544
- throw file_1.makeFileException(file_1.Code.parsingError, path, err);
608
+ throw (0, file_1.makeFileException)(file_1.Code.parsingError, path, err);
545
609
  }
546
610
  }
547
611
  async getByteSink(path, flags = WRITE_NONEXCL_FLAGS) {
612
+ this.ensureIsWritable();
548
613
  const f = await this.getOrCreateFile(path, flags);
549
614
  return f.writeSink(flags.truncate, flags.currentVersion);
550
615
  }
@@ -555,4 +620,191 @@ class V {
555
620
  }
556
621
  Object.freeze(V.prototype);
557
622
  Object.freeze(V);
623
+ class ObjIdToPathMap {
624
+ constructor(maxDepth) {
625
+ this.maxDepth = maxDepth;
626
+ this.map = new Map();
627
+ Object.seal(this);
628
+ }
629
+ async fillFromTree(root) {
630
+ const listOfAll = await recursiveIdAndPathList(root, '.', this.maxDepth);
631
+ for (const [objId, path, depth] of listOfAll) {
632
+ this.map.set(objId, { path, depth });
633
+ }
634
+ }
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);
640
+ return path;
641
+ }
642
+ if (event.type === 'removed') {
643
+ return;
644
+ }
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 });
658
+ return path;
659
+ }
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}`;
672
+ }
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);
687
+ }
688
+ }
689
+ Object.freeze(ObjIdToPathMap.prototype);
690
+ Object.freeze(ObjIdToPathMap);
691
+ async function recursiveIdAndPathList(folder, path, maxDepth, depth = 0) {
692
+ const { lst } = folder.list();
693
+ const idAndPaths = [
694
+ [folder.objId, path, depth]
695
+ ];
696
+ if ((maxDepth !== undefined) && (depth === maxDepth)) {
697
+ return idAndPaths;
698
+ }
699
+ for (const item of lst) {
700
+ const childPath = `${path}/${item.name}`;
701
+ if (item.isFile || item.isLink) {
702
+ const { objId } = folder.getNodeInfo(item.name);
703
+ idAndPaths.push([objId, childPath, depth + 1]);
704
+ }
705
+ else if (item.isFolder) {
706
+ const child = await folder.getFolder(item.name);
707
+ const childLst = await recursiveIdAndPathList(child, childPath, maxDepth, depth + 1);
708
+ idAndPaths.push(...childLst);
709
+ }
710
+ }
711
+ return idAndPaths;
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);
558
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;
@@ -82,7 +82,7 @@ class LinkNode extends node_in_fs_1.NodeInFS {
82
82
  if (!name || !objId || !parentId) {
83
83
  throw new Error("Bad link parameter(s) given");
84
84
  }
85
- this.crypto = new LinkPersistance(xsp_files_1.idToHeaderNonce(this.objId), key, this.storage.cryptor);
85
+ this.crypto = new LinkPersistance((0, xsp_files_1.idToHeaderNonce)(this.objId), key, this.storage.cryptor);
86
86
  Object.seal(this);
87
87
  }
88
88
  static async makeForNew(storage, parentId, name, key) {
@@ -92,12 +92,17 @@ class LinkNode extends node_in_fs_1.NodeInFS {
92
92
  return link;
93
93
  }
94
94
  static async makeForExisting(storage, parentId, name, objId, key) {
95
- const src = await storage.getObj(objId);
95
+ const src = await storage.getObjSrc(objId);
96
96
  const link = new LinkNode(storage, name, objId, src.version, parentId, key);
97
97
  const { params, attrs, xattrs } = await link.crypto.read(src);
98
98
  link.setUpdatedState(params, src.version, attrs, xattrs);
99
+ link.setCurrentStateFrom(src);
99
100
  return link;
100
101
  }
102
+ async setCurrentStateFrom(src) {
103
+ const { params, attrs, xattrs } = await this.crypto.read(src);
104
+ this.setUpdatedState(params, src.version, attrs, xattrs);
105
+ }
101
106
  setUpdatedState(params, version, attrs, xattrs) {
102
107
  this.linkParams = params;
103
108
  super.setUpdatedParams(version, attrs, xattrs);