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
@@ -1,23 +1,22 @@
1
1
  import { StorageOwner } from '../../../lib-client/3nstorage/service';
2
2
  import { ObjFiles } from './obj-files';
3
- import { Node, ObjId } from '../../../lib-client/3nstorage/xsp-fs/common';
3
+ import { Storage } from '../../../lib-client/3nstorage/xsp-fs/common';
4
4
  import { LogError } from '../../../lib-client/logging/log-to-file';
5
- export declare type GetFSNode = (objId: ObjId) => Node | undefined;
5
+ /**
6
+ * Remote events are absorbed into objects' statuses, broadcasting respective
7
+ * events. Someone down the stream can react to these changes from remote.
8
+ */
6
9
  export declare class RemoteEvents {
7
10
  private readonly remoteStorage;
8
11
  private readonly files;
9
- private readonly fsNodes;
12
+ private readonly broadcastNodeEvent;
10
13
  private readonly logError;
11
- constructor(remoteStorage: StorageOwner, files: ObjFiles, fsNodes: GetFSNode, logError: LogError);
14
+ constructor(remoteStorage: StorageOwner, files: ObjFiles, broadcastNodeEvent: Storage['broadcastNodeEvent'], logError: LogError);
12
15
  private absorbingRemoteEventsProc;
13
16
  startAbsorbingRemoteEvents(): void;
14
17
  close(): Promise<void>;
15
- /**
16
- * Information about external event is recorded into obj status before
17
- * main processing takes place. This allows to synchronize all obj changes,
18
- * while informing already scheduled processes.
19
- * @param objChange
20
- */
21
- private remoteChange;
22
- private remoteRemoval;
18
+ private absorbObjChange;
19
+ private absorbObjRemoval;
20
+ private absorbObjVersionArchival;
21
+ private absorbArchVersionRemoval;
23
22
  }
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  /*
3
- Copyright (C) 2019 - 2020 3NSoft Inc.
3
+ Copyright (C) 2019 - 2020, 2022 3NSoft Inc.
4
4
 
5
5
  This program is free software: you can redistribute it and/or modify it under
6
6
  the terms of the GNU General Public License as published by the Free Software
@@ -13,7 +13,8 @@
13
13
  See the GNU General Public License for more details.
14
14
 
15
15
  You should have received a copy of the GNU General Public License along with
16
- this program. If not, see <http://www.gnu.org/licenses/>. */
16
+ this program. If not, see <http://www.gnu.org/licenses/>.
17
+ */
17
18
  Object.defineProperty(exports, "__esModule", { value: true });
18
19
  exports.RemoteEvents = void 0;
19
20
  const rxjs_1 = require("rxjs");
@@ -21,82 +22,104 @@ const server_events_1 = require("../../../lib-client/server-events");
21
22
  const owner_1 = require("../../../lib-common/service-api/3nstorage/owner");
22
23
  const operators_1 = require("rxjs/operators");
23
24
  const SERVER_EVENTS_RESTART_WAIT_SECS = 30;
25
+ /**
26
+ * Remote events are absorbed into objects' statuses, broadcasting respective
27
+ * events. Someone down the stream can react to these changes from remote.
28
+ */
24
29
  class RemoteEvents {
25
- constructor(remoteStorage, files, fsNodes, logError) {
30
+ constructor(remoteStorage, files, broadcastNodeEvent, logError) {
26
31
  this.remoteStorage = remoteStorage;
27
32
  this.files = files;
28
- this.fsNodes = fsNodes;
33
+ this.broadcastNodeEvent = broadcastNodeEvent;
29
34
  this.logError = logError;
30
35
  this.absorbingRemoteEventsProc = undefined;
31
36
  Object.seal(this);
32
37
  }
33
38
  startAbsorbingRemoteEvents() {
34
39
  const serverEvents = new server_events_1.ServerEvents(() => this.remoteStorage.openEventSource(), SERVER_EVENTS_RESTART_WAIT_SECS);
35
- const objChange$ = serverEvents.observe(owner_1.objChanged.EVENT_NAME)
36
- .pipe(operators_1.filter(objChange => Number.isInteger(objChange.newVer) && (objChange.newVer > 1)), operators_1.mergeMap(objChange => this.remoteChange(objChange)));
37
- const objRemoval$ = serverEvents.observe(owner_1.objRemoved.EVENT_NAME)
38
- .pipe(operators_1.filter(objRm => !!objRm.objId), operators_1.mergeMap(objRm => this.remoteRemoval(objRm)));
39
- this.absorbingRemoteEventsProc = rxjs_1.merge(objChange$, objRemoval$)
40
- .subscribe(undefined, err => this.logError(err), () => { this.absorbingRemoteEventsProc = undefined; });
40
+ this.absorbingRemoteEventsProc = (0, rxjs_1.merge)(this.absorbObjChange(serverEvents), this.absorbObjRemoval(serverEvents), this.absorbObjVersionArchival(serverEvents), this.absorbArchVersionRemoval(serverEvents))
41
+ .subscribe({
42
+ next: noop,
43
+ error: async (err) => {
44
+ await this.logError(err);
45
+ this.absorbingRemoteEventsProc = undefined;
46
+ },
47
+ complete: () => {
48
+ this.absorbingRemoteEventsProc = undefined;
49
+ }
50
+ });
41
51
  }
42
52
  async close() {
43
53
  if (this.absorbingRemoteEventsProc) {
44
54
  this.absorbingRemoteEventsProc.unsubscribe();
55
+ this.absorbingRemoteEventsProc = undefined;
45
56
  }
46
57
  }
47
- /**
48
- * Information about external event is recorded into obj status before
49
- * main processing takes place. This allows to synchronize all obj changes,
50
- * while informing already scheduled processes.
51
- * @param objChange
52
- */
53
- async remoteChange(objChange) {
54
- const obj = await this.files.findObj(objChange.objId);
55
- if (!obj) {
56
- return;
57
- }
58
- if (obj.isRemoteVersionGreaterOrEqualTo(objChange.newVer)) {
59
- return;
60
- }
61
- await obj.setRemoteVersion(objChange.newVer);
62
- try {
63
- const nodeInFS = this.fsNodes(objChange.objId);
64
- if (nodeInFS) {
65
- await nodeInFS.processRemoteEvent({
66
- type: 'remote-change',
67
- newVer: objChange.newVer,
68
- objId: objChange.objId
69
- });
58
+ absorbObjChange(serverEvents) {
59
+ return serverEvents.observe(owner_1.events.objChanged.EVENT_NAME)
60
+ .pipe((0, operators_1.mergeMap)(async ({ newVer, objId }) => {
61
+ if (!Number.isInteger(newVer) || (newVer < 1)) {
62
+ return;
70
63
  }
71
- }
72
- catch (err) {
73
- this.logError(err, `Error in processing remote change event`);
74
- }
64
+ const obj = await this.files.findObj(objId);
65
+ if (!obj) {
66
+ return;
67
+ }
68
+ obj.statusObj().recordRemoteChange(newVer);
69
+ this.broadcastNodeEvent(obj.objId, undefined, undefined, {
70
+ type: 'remote-change',
71
+ path: '',
72
+ newVersion: newVer
73
+ });
74
+ }, 1));
75
75
  }
76
- async remoteRemoval(objRm) {
77
- const obj = await this.files.findObj(objRm.objId);
78
- if (!obj) {
79
- return;
80
- }
81
- if (obj.isArchived() || obj.isDeletedOnRemote()) {
82
- return;
83
- }
84
- await obj.setDeletedOnRemote();
85
- try {
86
- const nodeInFS = this.fsNodes(objRm.objId);
87
- if (nodeInFS) {
88
- await nodeInFS.processRemoteEvent({
89
- type: 'remote-delete',
90
- objId: objRm.objId
91
- });
76
+ absorbObjRemoval(serverEvents) {
77
+ return serverEvents.observe(owner_1.events.objRemoved.EVENT_NAME)
78
+ .pipe((0, operators_1.filter)((objRm) => !!objRm.objId), (0, operators_1.mergeMap)(async ({ objId }) => {
79
+ const obj = await this.files.findObj(objId);
80
+ if (!obj) {
81
+ return;
92
82
  }
93
- }
94
- catch (err) {
95
- this.logError(err, `Error in processing remote change event`);
96
- }
83
+ obj.statusObj().recordRemoteRemoval();
84
+ this.broadcastNodeEvent(obj.objId, undefined, undefined, {
85
+ type: 'remote-removal',
86
+ path: ''
87
+ });
88
+ }, 1));
89
+ }
90
+ absorbObjVersionArchival(serverEvents) {
91
+ return serverEvents.observe(owner_1.events.objVersionArchived.EVENT_NAME)
92
+ .pipe((0, operators_1.mergeMap)(async ({ objId, archivedVer }) => {
93
+ const obj = await this.files.findObj(objId);
94
+ if (!obj) {
95
+ return;
96
+ }
97
+ obj.statusObj().recordVersionArchival(archivedVer);
98
+ this.broadcastNodeEvent(obj.objId, undefined, undefined, {
99
+ type: 'remote-version-archival',
100
+ path: '',
101
+ archivedVersion: archivedVer
102
+ });
103
+ }, 1));
104
+ }
105
+ absorbArchVersionRemoval(serverEvents) {
106
+ return serverEvents.observe(owner_1.events.objArchivedVersionRemoved.EVENT_NAME)
107
+ .pipe((0, operators_1.mergeMap)(async ({ objId, archivedVer }) => {
108
+ const obj = await this.files.findObj(objId);
109
+ if (!obj) {
110
+ return;
111
+ }
112
+ obj.statusObj().recordArchVersionRemoval(archivedVer);
113
+ this.broadcastNodeEvent(obj.objId, undefined, undefined, {
114
+ type: 'remote-arch-ver-removal',
115
+ path: '',
116
+ removedArchVer: archivedVer
117
+ });
118
+ }, 1));
97
119
  }
98
120
  }
99
121
  exports.RemoteEvents = RemoteEvents;
100
122
  Object.freeze(RemoteEvents.prototype);
101
123
  Object.freeze(RemoteEvents);
124
+ function noop() { }
102
125
  Object.freeze(exports);
@@ -1,9 +1,15 @@
1
1
  import { IGetMailerIdSigner } from '../../../lib-client/user-with-mid-session';
2
- import { SyncedStorage as ISyncedStorage, NodesContainer, Storage as IStorage, StorageGetter, ObjId } from '../../../lib-client/3nstorage/xsp-fs/common';
2
+ import { SyncedStorage as ISyncedStorage, NodesContainer, Storage as IStorage, StorageGetter, ObjId, NodeEvent, SyncedObjStatus } from '../../../lib-client/3nstorage/xsp-fs/common';
3
3
  import { ScryptGenParams } from '../../../lib-client/key-derivation';
4
4
  import { LogError } from '../../../lib-client/logging/log-to-file';
5
5
  import { AsyncSBoxCryptor, Subscribe, ObjSource } from 'xsp-files';
6
6
  import { NetClient } from '../../../lib-client/request-utils';
7
+ import { Observable } from 'rxjs';
8
+ import { UploadHeaderChange } from '../../../lib-client/3nstorage/xsp-fs/common';
9
+ declare type FolderEvent = web3n.files.FolderEvent;
10
+ declare type FileEvent = web3n.files.FileEvent;
11
+ declare type SyncStatus = web3n.files.SyncStatus;
12
+ declare type OptionsToAdopteRemote = web3n.files.OptionsToAdopteRemote;
7
13
  export declare class SyncedStore implements ISyncedStorage {
8
14
  private readonly files;
9
15
  private readonly remoteStorage;
@@ -15,19 +21,32 @@ export declare class SyncedStore implements ISyncedStorage {
15
21
  readonly nodes: NodesContainer;
16
22
  private readonly remoteEvents;
17
23
  private readonly uploader;
24
+ private readonly events;
18
25
  private constructor();
19
- static makeAndStart(path: string, user: string, getSigner: IGetMailerIdSigner, getStorages: StorageGetter, cryptor: AsyncSBoxCryptor, remoteServiceUrl: () => Promise<string>, makeNet: () => NetClient, logError: LogError): Promise<{
26
+ static makeAndStart(path: string, user: string, getSigner: IGetMailerIdSigner, getStorages: StorageGetter, cryptor: AsyncSBoxCryptor, remoteServiceUrl: () => Promise<string>, net: NetClient, logError: LogError): Promise<{
20
27
  syncedStore: ISyncedStorage;
21
28
  startObjProcs: () => void;
22
29
  }>;
30
+ getNodeEvents(): Observable<NodeEvent>;
31
+ broadcastNodeEvent(objId: ObjId, parentObjId: ObjId | undefined, childObjId: ObjId | undefined, event: FolderEvent | FileEvent): void;
23
32
  storageForLinking(type: web3n.files.FSType, location?: string): IStorage;
33
+ status(objId: ObjId): Promise<SyncedObjStatus>;
34
+ adoptRemote(objId: ObjId, opts: OptionsToAdopteRemote | undefined): Promise<number | undefined>;
35
+ updateStatusInfo(objId: ObjId): Promise<SyncStatus>;
36
+ isRemoteVersionOnDisk(objId: ObjId, version: number): Promise<'complete' | 'partial' | 'none'>;
37
+ download(objId: ObjId, version: number): Promise<void>;
38
+ upload(objId: ObjId, localVersion: number, uploadVersion: number, uploadHeader: UploadHeaderChange | undefined, createOnRemote: boolean): Promise<void>;
39
+ uploadObjRemoval(objId: ObjId): Promise<void>;
40
+ dropCachedLocalObjVersionsLessOrEqual(objId: ObjId, version: number): void;
41
+ archiveVersionOnServer(objId: ObjId, version: number): Promise<void>;
24
42
  getRootKeyDerivParamsFromServer(): Promise<ScryptGenParams>;
25
43
  generateNewObjId(): Promise<string>;
26
44
  private objFromDiskOrDownload;
27
- private getObjNonArchOrThrow;
28
- getObj(objId: ObjId): Promise<ObjSource>;
29
- getRemoteConflictObjVersion(objId: ObjId, version: number): Promise<ObjSource>;
45
+ private getObjOrThrow;
46
+ getObjSrc(objId: ObjId, version?: number): Promise<ObjSource>;
47
+ getObjSrcOfRemoteVersion(objId: ObjId, version: number): Promise<ObjSource>;
30
48
  saveObj(objId: ObjId, version: number, encSub: Subscribe): Promise<void>;
31
49
  removeObj(objId: string): Promise<void>;
32
50
  close(): Promise<void>;
33
51
  }
52
+ export {};
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  /*
3
- Copyright (C) 2015 - 2020 3NSoft Inc.
3
+ Copyright (C) 2015 - 2020, 2022 3NSoft Inc.
4
4
 
5
5
  This program is free software: you can redistribute it and/or modify it under
6
6
  the terms of the GNU General Public License as published by the Free Software
@@ -13,7 +13,8 @@
13
13
  See the GNU General Public License for more details.
14
14
 
15
15
  You should have received a copy of the GNU General Public License along with
16
- this program. If not, see <http://www.gnu.org/licenses/>. */
16
+ this program. If not, see <http://www.gnu.org/licenses/>.
17
+ */
17
18
  Object.defineProperty(exports, "__esModule", { value: true });
18
19
  exports.SyncedStore = void 0;
19
20
  const common_1 = require("../../../lib-client/3nstorage/xsp-fs/common");
@@ -23,9 +24,9 @@ const obj_files_1 = require("./obj-files");
23
24
  const random_node_1 = require("../../../lib-common/random-node");
24
25
  const buffer_utils_1 = require("../../../lib-common/buffer-utils");
25
26
  const xsp_files_1 = require("xsp-files");
26
- const downloader_1 = require("./downloader");
27
27
  const remote_events_1 = require("./remote-events");
28
28
  const upsyncer_1 = require("./upsyncer");
29
+ const utils_for_observables_1 = require("../../../lib-common/utils-for-observables");
29
30
  class SyncedStore {
30
31
  constructor(files, remoteStorage, getStorages, cryptor, logError) {
31
32
  this.files = files;
@@ -36,25 +37,32 @@ class SyncedStore {
36
37
  this.type = 'synced';
37
38
  this.versioned = true;
38
39
  this.nodes = new common_1.NodesContainer();
39
- const getFSNodes = (objId) => this.nodes.get(objId);
40
- this.remoteEvents = new remote_events_1.RemoteEvents(this.remoteStorage, this.files, getFSNodes, this.logError);
41
- this.uploader = new upsyncer_1.UpSyncer(this.remoteStorage, this.files, this.logError);
40
+ this.events = new utils_for_observables_1.Broadcast();
41
+ this.remoteEvents = new remote_events_1.RemoteEvents(this.remoteStorage, this.files, this.broadcastNodeEvent.bind(this), this.logError);
42
+ this.uploader = new upsyncer_1.UpSyncer(this.remoteStorage, this.logError);
42
43
  Object.seal(this);
43
44
  }
44
- static async makeAndStart(path, user, getSigner, getStorages, cryptor, remoteServiceUrl, makeNet, logError) {
45
- const remote = new service_1.StorageOwner(user, getSigner, remoteServiceUrl, makeNet());
46
- const objFiles = await obj_files_1.ObjFiles.makeFor(path, new downloader_1.Downloader(remote), logError);
45
+ static async makeAndStart(path, user, getSigner, getStorages, cryptor, remoteServiceUrl, net, logError) {
46
+ const remote = new service_1.StorageOwner(user, getSigner, remoteServiceUrl, net);
47
+ const objFiles = await obj_files_1.ObjFiles.makeFor(path, remote, logError);
47
48
  const s = new SyncedStore(objFiles, remote, getStorages, cryptor, logError);
49
+ s.uploader.start();
48
50
  return {
49
- syncedStore: common_1.wrapSyncStorageImplementation(s),
51
+ syncedStore: (0, common_1.wrapSyncStorageImplementation)(s),
50
52
  startObjProcs: () => {
51
53
  s.remoteEvents.startAbsorbingRemoteEvents();
52
54
  }
53
55
  };
54
56
  }
57
+ getNodeEvents() {
58
+ return this.events.event$;
59
+ }
60
+ broadcastNodeEvent(objId, parentObjId, childObjId, event) {
61
+ this.events.next({ objId, parentObjId, childObjId, event });
62
+ }
55
63
  storageForLinking(type, location) {
56
64
  if (type === 'synced') {
57
- return common_1.wrapStorageImplementation(this);
65
+ return (0, common_1.wrapStorageImplementation)(this);
58
66
  }
59
67
  else if (type === 'share') {
60
68
  return this.getStorages('share', location);
@@ -63,11 +71,86 @@ class SyncedStore {
63
71
  throw new Error(`Getting ${type} storage is not implemented in local storage.`);
64
72
  }
65
73
  }
74
+ async status(objId) {
75
+ const obj = await this.getObjOrThrow(objId);
76
+ return obj.syncStatus();
77
+ }
78
+ async adoptRemote(objId, opts) {
79
+ const obj = await this.getObjOrThrow(objId);
80
+ const objStatus = obj.statusObj();
81
+ await objStatus.adoptRemoteVersion(opts === null || opts === void 0 ? void 0 : opts.remoteVersion, opts === null || opts === void 0 ? void 0 : opts.dropLocalVer);
82
+ if (opts && opts.download) {
83
+ // XXX this needs implementation
84
+ }
85
+ this.files.scheduleGC(obj);
86
+ return objStatus.syncStatus().synced.latest;
87
+ }
88
+ async updateStatusInfo(objId) {
89
+ const obj = await this.getObjOrThrow(objId, true);
90
+ try {
91
+ const statusOnServer = await this.remoteStorage.getObjStatus(objId);
92
+ const objStatus = obj.statusObj();
93
+ await objStatus.recordStatusFromServer(statusOnServer);
94
+ return objStatus.syncStatus();
95
+ }
96
+ catch (exc) {
97
+ if ((exc.type === 'storage')
98
+ && exc.objNotFound) {
99
+ const objStatus = obj.statusObj();
100
+ await objStatus.recordStatusFromServer({});
101
+ return objStatus.syncStatus();
102
+ }
103
+ throw exc;
104
+ }
105
+ }
106
+ isRemoteVersionOnDisk(objId, version) {
107
+ // XXX
108
+ // - check that given version is synced
109
+ // - get state of file
110
+ // But, should this be renamed to isRemoteVersionOnDisk ?
111
+ //
112
+ throw new Error('SyncedStore.isRemoteVersionOnDisk() not implemented.');
113
+ }
114
+ download(objId, version) {
115
+ // XXX
116
+ throw new Error('SyncedStore.download() not implemented.');
117
+ }
118
+ async upload(objId, localVersion, uploadVersion, uploadHeader, createOnRemote) {
119
+ const obj = await this.getObjOrThrow(objId, true);
120
+ const syncedBase = await obj.combineLocalBaseIfPresent(localVersion);
121
+ if (uploadHeader) {
122
+ await obj.saveUploadHeaderFile(uploadHeader);
123
+ }
124
+ await this.uploader.uploadFromDisk(obj, localVersion, uploadVersion, uploadHeader === null || uploadHeader === void 0 ? void 0 : uploadHeader.uploadHeader, syncedBase, createOnRemote);
125
+ await obj.recordUploadCompletion(localVersion, uploadVersion, (uploadHeader ? {
126
+ newHeader: uploadHeader.uploadHeader,
127
+ originalHeader: uploadHeader.localHeader
128
+ } : undefined));
129
+ if (localVersion > uploadVersion) {
130
+ await obj.removeLocalVersionFilesLessThan(localVersion);
131
+ }
132
+ }
133
+ async uploadObjRemoval(objId) {
134
+ if (!objId) {
135
+ return;
136
+ }
137
+ await this.remoteStorage.deleteObj(objId);
138
+ }
139
+ dropCachedLocalObjVersionsLessOrEqual(objId, version) {
140
+ const obj = this.files.getObjInCache(objId);
141
+ if (!obj) {
142
+ return;
143
+ }
144
+ obj.dropCachedLocalObjVersionsLessOrEqual(version);
145
+ }
146
+ async archiveVersionOnServer(objId, version) {
147
+ await this.remoteStorage.archiveObjVersion(objId, version);
148
+ }
66
149
  getRootKeyDerivParamsFromServer() {
67
150
  return this.remoteStorage.getKeyDerivParams();
68
151
  }
69
152
  async generateNewObjId() {
70
- const nonce = await random_node_1.bytes(xsp_files_1.NONCE_LENGTH);
153
+ const nonce = await (0, random_node_1.bytes)(xsp_files_1.NONCE_LENGTH);
71
154
  const id = buffer_utils_1.base64urlSafe.pack(nonce);
72
155
  if (this.nodes.reserveId(id)) {
73
156
  return id;
@@ -83,55 +166,57 @@ class SyncedStore {
83
166
  }
84
167
  return await this.files.makeByDownloadingCurrentVersion(objId);
85
168
  }
86
- async getObjNonArchOrThrow(objId) {
169
+ async getObjOrThrow(objId, allowArchived = false) {
87
170
  const obj = await this.objFromDiskOrDownload(objId);
88
- if (obj.isArchived()) {
89
- throw exceptions_1.makeObjNotFoundExc(objId);
171
+ if (!allowArchived && obj.statusObj().isArchived()) {
172
+ throw (0, exceptions_1.makeObjNotFoundExc)(objId);
173
+ }
174
+ else {
175
+ return obj;
90
176
  }
91
- return obj;
92
177
  }
93
- async getObj(objId) {
94
- const obj = await this.getObjNonArchOrThrow(objId);
95
- const currentVer = obj.getCurrentVersionOrThrow();
96
- return obj.getObjSrc(currentVer);
178
+ async getObjSrc(objId, version) {
179
+ const obj = await this.getObjOrThrow(objId);
180
+ if (!version) {
181
+ version = obj.statusObj().getCurrentLocalOrSynced();
182
+ }
183
+ return obj.getObjSrcFromLocalAndSyncedBranch(version);
97
184
  }
98
- async getRemoteConflictObjVersion(objId, version) {
99
- const obj = await this.getObjNonArchOrThrow(objId);
100
- return obj.getRemoteConflictObjVersion(version);
185
+ async getObjSrcOfRemoteVersion(objId, version) {
186
+ const obj = await this.getObjOrThrow(objId);
187
+ return obj.getObjSrcFromRemoteAndSyncedBranch(version);
101
188
  }
102
189
  async saveObj(objId, version, encSub) {
103
190
  if (version === 1) {
104
191
  const obj = await this.files.findObj(objId);
105
192
  if (obj) {
106
- throw exceptions_1.makeObjExistsExc(objId);
193
+ throw (0, exceptions_1.makeObjExistsExc)(objId);
107
194
  }
108
- const { fileWrite$, newObj } = await this.files.saveFirstVersion(objId, encSub);
109
- await fileWrite$
110
- .pipe(this.uploader.tapFileWrite(newObj, true, version))
111
- .toPromise();
195
+ const { fileWrite$ } = await this.files.saveFirstVersion(objId, encSub);
196
+ await fileWrite$.toPromise();
112
197
  }
113
198
  else {
114
- const obj = await this.files.findObj(objId);
115
- if (!obj) {
116
- throw exceptions_1.makeObjNotFoundExc(objId);
117
- }
118
- const { fileWrite$, baseVer } = await obj.saveNewVersion(version, encSub);
119
- await fileWrite$
120
- .pipe(this.uploader.tapFileWrite(obj, false, version, baseVer))
121
- .toPromise();
199
+ const obj = await this.getObjOrThrow(objId);
200
+ const { fileWrite$ } = await obj.saveNewVersion(version, encSub);
201
+ await fileWrite$.toPromise();
122
202
  }
123
203
  }
124
204
  async removeObj(objId) {
125
- const obj = await this.files.findObj(objId);
205
+ const obj = await this.getObjOrThrow(objId)
206
+ .catch((exc) => {
207
+ if (!exc.objNotFound) {
208
+ throw exc;
209
+ }
210
+ });
126
211
  if (!obj) {
127
212
  return;
128
213
  }
129
214
  await obj.removeCurrentVersion();
130
- await this.uploader.removeCurrentVersionOf(obj);
131
215
  }
132
216
  async close() {
133
217
  try {
134
218
  await this.uploader.stop();
219
+ this.events.done();
135
220
  await this.remoteEvents.close();
136
221
  await this.remoteStorage.logout();
137
222
  }
@@ -0,0 +1,4 @@
1
+ import { UploadHeaderChange } from "../../../lib-client/3nstorage/xsp-fs/common";
2
+ export declare const UPLOAD_HEADER_FILE_NAME_EXT = "upload";
3
+ export declare function saveUploadHeaderFile(objFolder: string, headers: UploadHeaderChange): Promise<void>;
4
+ export declare function readUploadHeaderFromFile(objFolder: string, uploadVersion: number): Promise<UploadHeaderChange | undefined>;
@@ -0,0 +1,64 @@
1
+ "use strict";
2
+ /*
3
+ Copyright (C) 2022 3NSoft Inc.
4
+
5
+ This program is free software: you can redistribute it and/or modify it under
6
+ the terms of the GNU General Public License as published by the Free Software
7
+ Foundation, either version 3 of the License, or (at your option) any later
8
+ version.
9
+
10
+ This program is distributed in the hope that it will be useful, but
11
+ WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13
+ See the GNU General Public License for more details.
14
+
15
+ You should have received a copy of the GNU General Public License along with
16
+ this program. If not, see <http://www.gnu.org/licenses/>.
17
+ */
18
+ Object.defineProperty(exports, "__esModule", { value: true });
19
+ exports.readUploadHeaderFromFile = exports.saveUploadHeaderFile = exports.UPLOAD_HEADER_FILE_NAME_EXT = void 0;
20
+ const path_1 = require("path");
21
+ const async_fs_node_1 = require("../../../lib-common/async-fs-node");
22
+ const file_1 = require("../../../lib-common/exceptions/file");
23
+ const big_endian_1 = require("../../../lib-common/big-endian");
24
+ const assert_1 = require("../../../lib-common/assert");
25
+ exports.UPLOAD_HEADER_FILE_NAME_EXT = 'upload';
26
+ async function saveUploadHeaderFile(objFolder, headers) {
27
+ const bytes = packUploadHeaderChange(headers);
28
+ await (0, async_fs_node_1.writeFile)(uploadHeaderFilePath(objFolder, headers.uploadVersion), bytes);
29
+ }
30
+ exports.saveUploadHeaderFile = saveUploadHeaderFile;
31
+ async function readUploadHeaderFromFile(objFolder, uploadVersion) {
32
+ try {
33
+ const bytes = await (0, async_fs_node_1.readFile)(uploadHeaderFilePath(objFolder, uploadVersion));
34
+ return unpackUploadHeaderChange(bytes);
35
+ }
36
+ catch (exc) {
37
+ if (exc.code !== file_1.Code.notFound) {
38
+ throw exc;
39
+ }
40
+ }
41
+ }
42
+ exports.readUploadHeaderFromFile = readUploadHeaderFromFile;
43
+ function uploadHeaderFilePath(objFolder, uploadVersion) {
44
+ return (0, path_1.join)(objFolder, `${uploadVersion}.${exports.UPLOAD_HEADER_FILE_NAME_EXT}`);
45
+ }
46
+ function packUploadHeaderChange({ localHeader, localVersion, uploadHeader, uploadVersion }) {
47
+ (0, assert_1.assert)(localHeader.length === uploadHeader.length);
48
+ const bytes = Buffer.allocUnsafe(16 + 2 * localHeader.length);
49
+ (0, big_endian_1.packUintTo8Bytes)(localVersion, bytes, 0);
50
+ (0, big_endian_1.packUintTo8Bytes)(uploadVersion, bytes, 8);
51
+ bytes.set(localHeader, 16);
52
+ bytes.set(uploadHeader, 16 + localHeader.length);
53
+ return bytes;
54
+ }
55
+ function unpackUploadHeaderChange(bytes) {
56
+ const localVersion = (0, big_endian_1.uintFrom8Bytes)(bytes, 0);
57
+ const uploadVersion = (0, big_endian_1.uintFrom8Bytes)(bytes, 8);
58
+ const headerLen = (bytes.length - 16) / 2;
59
+ (0, assert_1.assert)(Number.isInteger(headerLen));
60
+ const localHeader = bytes.slice(16, 16 + headerLen);
61
+ const uploadHeader = bytes.slice(16 + headerLen);
62
+ return { localHeader, localVersion, uploadHeader, uploadVersion };
63
+ }
64
+ Object.freeze(exports);
@@ -1,21 +1,27 @@
1
1
  import { StorageOwner } from "../../../lib-client/3nstorage/service";
2
- import { SyncedObj, ObjFiles } from "./obj-files";
2
+ import { SyncedObj } from "./obj-files";
3
3
  import { MonoTypeOperatorFunction } from "rxjs";
4
4
  import { FileWrite } from "../../../lib-client/objs-on-disk/file-writing-proc";
5
5
  import { LogError } from "../../../lib-client/logging/log-to-file";
6
+ import { UploadInfo } from "./obj-status";
7
+ export declare type FileWriteTapOperator = MonoTypeOperatorFunction<FileWrite[]>;
6
8
  export declare class UpSyncer {
7
9
  private readonly remoteStorage;
8
- private readonly files;
9
10
  private readonly logError;
10
- private readonly uploads;
11
- constructor(remoteStorage: StorageOwner, files: ObjFiles, logError: LogError);
12
- private getOrMakeUploadsFor;
11
+ private readonly execPools;
12
+ constructor(remoteStorage: StorageOwner, logError: LogError);
13
13
  start(): void;
14
14
  stop(): Promise<void>;
15
- get chunkSize(): number;
16
- private readonly addToWorker;
15
+ /**
16
+ * Creates an rxjs operator to tap saving process, starting upload while
17
+ * writing is ongoing.
18
+ */
17
19
  tapFileWrite(obj: SyncedObj, isNew: boolean, newVersion: number, baseVersion?: number): FileWriteTapOperator;
18
20
  removeCurrentVersionOf(obj: SyncedObj): Promise<void>;
19
- private readonly worker;
21
+ uploadFromDisk(obj: SyncedObj, localVersion: number, uploadVersion: number, uploadHeader: Uint8Array | undefined, syncedBase: number | undefined, createOnRemote: boolean): Promise<void>;
22
+ }
23
+ export interface UploadStatusRecorder {
24
+ recordUploadStart(info: UploadInfo): Promise<void>;
25
+ recordUploadCancellation(info: UploadInfo): Promise<void>;
26
+ recordUploadInterimState(info: UploadInfo): Promise<void>;
20
27
  }
21
- export declare type FileWriteTapOperator = MonoTypeOperatorFunction<FileWrite[]>;