core-3nweb-client-lib 0.26.1 → 0.27.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (211) hide show
  1. package/build/api-defs/asmail.d.ts +1 -1
  2. package/build/api-defs/files.d.ts +281 -75
  3. package/build/core/app-files.js +7 -7
  4. package/build/core/asmail/config/common.js +2 -2
  5. package/build/core/asmail/config/index.js +2 -2
  6. package/build/core/asmail/config/published-intro-key.js +1 -1
  7. package/build/core/asmail/delivery/common.js +7 -7
  8. package/build/core/asmail/delivery/index.js +5 -5
  9. package/build/core/asmail/delivery/msg.js +4 -4
  10. package/build/core/asmail/delivery/per-recipient-wip.js +1 -1
  11. package/build/core/asmail/inbox/attachments/fs.d.ts +2 -1
  12. package/build/core/asmail/inbox/attachments/fs.js +9 -4
  13. package/build/core/asmail/inbox/cached-msgs.js +1 -1
  14. package/build/core/asmail/inbox/inbox-events.js +4 -4
  15. package/build/core/asmail/inbox/index.js +10 -10
  16. package/build/core/asmail/inbox/msg-downloader.js +1 -1
  17. package/build/core/asmail/inbox/msg-indexing.js +1 -1
  18. package/build/core/asmail/inbox/msg-on-disk.js +5 -5
  19. package/build/core/asmail/index.d.ts +3 -3
  20. package/build/core/asmail/index.js +13 -8
  21. package/build/core/asmail/key-verification.js +5 -5
  22. package/build/core/asmail/keyring/common.js +7 -6
  23. package/build/core/asmail/keyring/correspondent-keys.js +8 -7
  24. package/build/core/asmail/keyring/id-to-email-map.js +2 -1
  25. package/build/core/asmail/keyring/index.d.ts +7 -8
  26. package/build/core/asmail/keyring/index.js +15 -14
  27. package/build/core/asmail/keyring/keyring-storage.js +2 -1
  28. package/build/core/asmail/msg/opener.js +3 -3
  29. package/build/core/asmail/msg/packer.js +13 -13
  30. package/build/core/asmail/sending-params/own-params.js +2 -2
  31. package/build/core/asmail/sending-params/params-from-others.js +1 -1
  32. package/build/core/id-manager/index.d.ts +43 -0
  33. package/build/core/{id-manager.js → id-manager/index.js} +36 -114
  34. package/build/core/id-manager/key-storage.d.ts +21 -0
  35. package/build/core/id-manager/key-storage.js +96 -0
  36. package/build/core/index.d.ts +2 -1
  37. package/build/core/index.js +31 -33
  38. package/build/core/sign-in.d.ts +1 -2
  39. package/build/core/sign-in.js +8 -17
  40. package/build/core/sign-up.d.ts +2 -0
  41. package/build/core/sign-up.js +11 -10
  42. package/build/core/storage/common/json-saving.js +2 -2
  43. package/build/core/storage/common/obj-info-file.d.ts +12 -4
  44. package/build/core/storage/common/obj-info-file.js +66 -34
  45. package/build/core/storage/common/utils.d.ts +2 -0
  46. package/build/core/storage/common/utils.js +32 -0
  47. package/build/core/storage/index.d.ts +5 -17
  48. package/build/core/storage/index.js +78 -119
  49. package/build/core/storage/local/obj-files-gc.d.ts +2 -0
  50. package/build/core/storage/local/obj-files-gc.js +49 -37
  51. package/build/core/storage/local/obj-files.d.ts +4 -7
  52. package/build/core/storage/local/obj-files.js +7 -10
  53. package/build/core/storage/local/obj-status.d.ts +12 -6
  54. package/build/core/storage/local/obj-status.js +24 -9
  55. package/build/core/storage/local/storage.d.ts +10 -7
  56. package/build/core/storage/local/storage.js +29 -18
  57. package/build/core/storage/synced/downloader.js +1 -1
  58. package/build/core/storage/synced/obj-files-gc.d.ts +1 -0
  59. package/build/core/storage/synced/obj-files-gc.js +76 -39
  60. package/build/core/storage/synced/obj-files.d.ts +50 -36
  61. package/build/core/storage/synced/obj-files.js +201 -162
  62. package/build/core/storage/synced/obj-status.d.ts +99 -86
  63. package/build/core/storage/synced/obj-status.js +520 -251
  64. package/build/core/storage/synced/remote-events.d.ts +11 -12
  65. package/build/core/storage/synced/remote-events.js +73 -56
  66. package/build/core/storage/synced/storage.d.ts +24 -10
  67. package/build/core/storage/synced/storage.js +147 -47
  68. package/build/core/storage/synced/upload-header-file.d.ts +4 -0
  69. package/build/core/storage/synced/upload-header-file.js +64 -0
  70. package/build/core/storage/synced/upsyncer.d.ts +12 -7
  71. package/build/core/storage/synced/upsyncer.js +210 -280
  72. package/build/core/storage/system-folders/apps-data.d.ts +16 -0
  73. package/build/core/storage/system-folders/apps-data.js +110 -0
  74. package/build/core/storage/system-folders/index.d.ts +18 -0
  75. package/build/core/storage/system-folders/index.js +77 -0
  76. package/build/core-ipc/common-caps.js +3 -3
  77. package/build/core-ipc/generic.js +8 -8
  78. package/build/core-ipc/startup-caps.js +2 -2
  79. package/build/cryptors.js +6 -2
  80. package/build/ipc-via-protobuf/asmail-cap.js +58 -57
  81. package/build/ipc-via-protobuf/bytes.js +16 -17
  82. package/build/ipc-via-protobuf/connector-clients-side.d.ts +1 -0
  83. package/build/ipc-via-protobuf/connector-clients-side.js +14 -15
  84. package/build/ipc-via-protobuf/connector-services-side.js +10 -10
  85. package/build/ipc-via-protobuf/connector.js +4 -4
  86. package/build/ipc-via-protobuf/file.d.ts +48 -12
  87. package/build/ipc-via-protobuf/file.js +474 -126
  88. package/build/ipc-via-protobuf/fs.d.ts +8 -0
  89. package/build/ipc-via-protobuf/fs.js +577 -142
  90. package/build/ipc-via-protobuf/log-cap.js +2 -2
  91. package/build/ipc-via-protobuf/mailerid.js +3 -3
  92. package/build/ipc-via-protobuf/protobuf-msg.d.ts +1 -0
  93. package/build/ipc-via-protobuf/protobuf-msg.js +11 -7
  94. package/build/ipc-via-protobuf/startup-cap.js +21 -21
  95. package/build/ipc-via-protobuf/storage-cap.js +12 -12
  96. package/build/ipc.js +7 -2
  97. package/build/lib-client/3nstorage/exceptions.d.ts +16 -1
  98. package/build/lib-client/3nstorage/exceptions.js +21 -3
  99. package/build/lib-client/3nstorage/service.d.ts +21 -3
  100. package/build/lib-client/3nstorage/service.js +128 -46
  101. package/build/lib-client/3nstorage/util/file-based-json.d.ts +2 -1
  102. package/build/lib-client/3nstorage/util/file-based-json.js +3 -2
  103. package/build/lib-client/3nstorage/util/for-arrays.d.ts +1 -0
  104. package/build/lib-client/3nstorage/util/for-arrays.js +32 -0
  105. package/build/lib-client/3nstorage/xsp-fs/attrs.js +17 -17
  106. package/build/lib-client/3nstorage/xsp-fs/common.d.ts +44 -19
  107. package/build/lib-client/3nstorage/xsp-fs/common.js +30 -19
  108. package/build/lib-client/3nstorage/xsp-fs/file-node.d.ts +1 -0
  109. package/build/lib-client/3nstorage/xsp-fs/file-node.js +17 -13
  110. package/build/lib-client/3nstorage/xsp-fs/file.d.ts +31 -6
  111. package/build/lib-client/3nstorage/xsp-fs/file.js +73 -25
  112. package/build/lib-client/3nstorage/xsp-fs/folder-node-serialization.js +4 -4
  113. package/build/lib-client/3nstorage/xsp-fs/folder-node.d.ts +32 -13
  114. package/build/lib-client/3nstorage/xsp-fs/folder-node.js +752 -192
  115. package/build/lib-client/3nstorage/xsp-fs/fs.d.ts +35 -4
  116. package/build/lib-client/3nstorage/xsp-fs/fs.js +236 -119
  117. package/build/lib-client/3nstorage/xsp-fs/link-node.d.ts +1 -0
  118. package/build/lib-client/3nstorage/xsp-fs/link-node.js +7 -2
  119. package/build/lib-client/3nstorage/xsp-fs/node-in-fs.d.ts +30 -29
  120. package/build/lib-client/3nstorage/xsp-fs/node-in-fs.js +232 -127
  121. package/build/lib-client/3nstorage/xsp-fs/node-persistence.d.ts +1 -1
  122. package/build/lib-client/3nstorage/xsp-fs/node-persistence.js +17 -18
  123. package/build/lib-client/3nstorage/xsp-fs/xsp-payload-v1.js +3 -3
  124. package/build/lib-client/3nstorage/xsp-fs/xsp-payload-v2.js +53 -53
  125. package/build/lib-client/3nweb-signup.js +4 -4
  126. package/build/lib-client/asmail/recipient.js +15 -15
  127. package/build/lib-client/asmail/sender.js +22 -22
  128. package/build/lib-client/asmail/service-config.js +3 -3
  129. package/build/lib-client/cryptor/cryptor-in-worker.js +18 -16
  130. package/build/lib-client/cryptor/cryptor-wasm.js +1 -1
  131. package/build/lib-client/cryptor/cryptor.js +4 -2
  132. package/build/lib-client/cryptor/cryptor.wasm +0 -0
  133. package/build/lib-client/cryptor/in-proc-js.js +1 -1
  134. package/build/lib-client/cryptor/in-proc-wasm.js +6 -6
  135. package/build/lib-client/cryptor/worker-js.js +2 -2
  136. package/build/lib-client/cryptor/worker-wasm.js +2 -2
  137. package/build/lib-client/files-select.js +1 -1
  138. package/build/lib-client/files.d.ts +1 -1
  139. package/build/lib-client/files.js +71 -6
  140. package/build/lib-client/fs-collection.js +1 -1
  141. package/build/lib-client/fs-sync-utils.d.ts +5 -0
  142. package/build/lib-client/fs-sync-utils.js +61 -0
  143. package/build/lib-client/fs-view.d.ts +14 -0
  144. package/build/lib-client/fs-view.js +33 -0
  145. package/build/lib-client/key-derivation.js +1 -1
  146. package/build/lib-client/local-files/dev-file-sink.js +9 -9
  147. package/build/lib-client/local-files/dev-file-src.js +2 -2
  148. package/build/lib-client/local-files/device-fs.d.ts +1 -1
  149. package/build/lib-client/local-files/device-fs.js +56 -54
  150. package/build/lib-client/logging/log-to-file.d.ts +1 -1
  151. package/build/lib-client/logging/log-to-file.js +7 -7
  152. package/build/lib-client/mailer-id/login.js +7 -7
  153. package/build/lib-client/mailer-id/provisioner.js +12 -12
  154. package/build/lib-client/objs-on-disk/file-writing-proc.js +3 -3
  155. package/build/lib-client/objs-on-disk/obj-folders.js +31 -31
  156. package/build/lib-client/objs-on-disk/obj-on-disk.d.ts +13 -2
  157. package/build/lib-client/objs-on-disk/obj-on-disk.js +24 -9
  158. package/build/lib-client/request-utils.d.ts +1 -0
  159. package/build/lib-client/request-utils.js +13 -13
  160. package/build/lib-client/server-events.d.ts +3 -3
  161. package/build/lib-client/server-events.js +9 -8
  162. package/build/lib-client/service-locator.js +10 -10
  163. package/build/lib-client/user-with-mid-session.d.ts +2 -1
  164. package/build/lib-client/user-with-mid-session.js +14 -8
  165. package/build/lib-client/user-with-pkl-session.js +25 -25
  166. package/build/lib-client/ws-utils.js +2 -2
  167. package/build/lib-common/async-cryptor-wrap.js +4 -4
  168. package/build/lib-common/async-fs-node.d.ts +5 -3
  169. package/build/lib-common/async-fs-node.js +17 -17
  170. package/build/lib-common/byte-streaming/pipe.js +1 -1
  171. package/build/lib-common/byte-streaming/wrapping.js +13 -13
  172. package/build/lib-common/canonical-address.js +1 -1
  173. package/build/lib-common/exceptions/error.d.ts +1 -0
  174. package/build/lib-common/exceptions/error.js +7 -6
  175. package/build/lib-common/exceptions/file.d.ts +4 -2
  176. package/build/lib-common/exceptions/file.js +24 -54
  177. package/build/lib-common/ipc/generic-ipc.js +5 -4
  178. package/build/lib-common/ipc/ws-ipc.js +2 -2
  179. package/build/lib-common/mid-sigs-NaCl-Ed.js +14 -14
  180. package/build/lib-common/objs-on-disk/file-layout.d.ts +19 -0
  181. package/build/lib-common/objs-on-disk/file-layout.js +130 -12
  182. package/build/lib-common/objs-on-disk/obj-file.d.ts +13 -2
  183. package/build/lib-common/objs-on-disk/obj-file.js +96 -35
  184. package/build/lib-common/objs-on-disk/utils.d.ts +1 -0
  185. package/build/lib-common/objs-on-disk/utils.js +3 -3
  186. package/build/lib-common/objs-on-disk/v1-obj-file-format.js +14 -14
  187. package/build/lib-common/processes/labelled-exec-pools.d.ts +1 -1
  188. package/build/lib-common/processes/labelled-exec-pools.js +1 -1
  189. package/build/lib-common/processes/pressure.js +2 -2
  190. package/build/lib-common/processes/synced.js +1 -1
  191. package/build/lib-common/processes/timeout.js +2 -2
  192. package/build/lib-common/random-node.js +7 -7
  193. package/build/lib-common/service-api/3nstorage/owner.d.ts +101 -42
  194. package/build/lib-common/service-api/3nstorage/owner.js +83 -40
  195. package/build/lib-common/service-api/asmail/delivery.js +2 -2
  196. package/build/lib-common/service-api/asmail/retrieval.js +1 -1
  197. package/build/lib-common/timed-cache.d.ts +1 -0
  198. package/build/lib-common/timed-non-weak-cache.d.ts +1 -0
  199. package/build/lib-common/timed-non-weak-cache.js +11 -0
  200. package/build/lib-common/utils-for-observables.js +4 -4
  201. package/build/lib-common/weak-cache.d.ts +1 -0
  202. package/build/lib-common/weak-cache.js +12 -1
  203. package/build/lib-index.d.ts +2 -1
  204. package/build/lib-index.js +10 -7
  205. package/build/protos/asmail.proto.js +12955 -7496
  206. package/build/protos/file.proto.js +4867 -2744
  207. package/build/protos/fs.proto.js +9227 -3768
  208. package/package.json +7 -5
  209. package/protos/file.proto +91 -19
  210. package/protos/fs.proto +107 -8
  211. package/build/core/id-manager.d.ts +0 -46
@@ -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
  }
@@ -22,83 +22,100 @@ const server_events_1 = require("../../../lib-client/server-events");
22
22
  const owner_1 = require("../../../lib-common/service-api/3nstorage/owner");
23
23
  const operators_1 = require("rxjs/operators");
24
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
+ */
25
29
  class RemoteEvents {
26
- constructor(remoteStorage, files, fsNodes, logError) {
30
+ constructor(remoteStorage, files, broadcastNodeEvent, logError) {
27
31
  this.remoteStorage = remoteStorage;
28
32
  this.files = files;
29
- this.fsNodes = fsNodes;
33
+ this.broadcastNodeEvent = broadcastNodeEvent;
30
34
  this.logError = logError;
31
35
  this.absorbingRemoteEventsProc = undefined;
32
36
  Object.seal(this);
33
37
  }
34
38
  startAbsorbingRemoteEvents() {
35
39
  const serverEvents = new server_events_1.ServerEvents(() => this.remoteStorage.openEventSource(), SERVER_EVENTS_RESTART_WAIT_SECS);
36
- const objChange$ = serverEvents.observe(owner_1.objChanged.EVENT_NAME)
37
- .pipe(operators_1.filter(objChange => Number.isInteger(objChange.newVer) && (objChange.newVer > 1)), operators_1.mergeMap(objChange => this.remoteChange(objChange)));
38
- const objRemoval$ = serverEvents.observe(owner_1.objRemoved.EVENT_NAME)
39
- .pipe(operators_1.filter(objRm => !!objRm.objId), operators_1.mergeMap(objRm => this.remoteRemoval(objRm)));
40
- this.absorbingRemoteEventsProc = rxjs_1.merge(objChange$, objRemoval$)
40
+ this.absorbingRemoteEventsProc = (0, rxjs_1.merge)(this.absorbObjChange(serverEvents), this.absorbObjRemoval(serverEvents), this.absorbObjVersionArchival(serverEvents), this.absorbArchVersionRemoval(serverEvents))
41
41
  .subscribe({
42
42
  next: noop,
43
- error: err => this.logError(err),
44
- complete: () => { this.absorbingRemoteEventsProc = undefined; }
43
+ error: async (err) => {
44
+ await this.logError(err);
45
+ this.absorbingRemoteEventsProc = undefined;
46
+ },
47
+ complete: () => {
48
+ this.absorbingRemoteEventsProc = undefined;
49
+ }
45
50
  });
46
51
  }
47
52
  async close() {
48
53
  if (this.absorbingRemoteEventsProc) {
49
54
  this.absorbingRemoteEventsProc.unsubscribe();
55
+ this.absorbingRemoteEventsProc = undefined;
50
56
  }
51
57
  }
52
- /**
53
- * Information about external event is recorded into obj status before
54
- * main processing takes place. This allows to synchronize all obj changes,
55
- * while informing already scheduled processes.
56
- * @param objChange
57
- */
58
- async remoteChange(objChange) {
59
- const obj = await this.files.findObj(objChange.objId);
60
- if (!obj) {
61
- return;
62
- }
63
- if (obj.isRemoteVersionGreaterOrEqualTo(objChange.newVer)) {
64
- return;
65
- }
66
- await obj.setRemoteVersion(objChange.newVer);
67
- const nodeInFS = this.fsNodes(objChange.objId);
68
- if (!nodeInFS) {
69
- return;
70
- }
71
- await nodeInFS.processRemoteEvent({
72
- type: 'remote-change',
73
- newVer: objChange.newVer,
74
- objId: objChange.objId
75
- }).catch(async (exc) => {
76
- if (!exc.notFound) {
77
- await this.logError(exc, `Error in processing remote change event`);
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;
78
63
  }
79
- });
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));
80
75
  }
81
- async remoteRemoval(objRm) {
82
- const obj = await this.files.findObj(objRm.objId);
83
- if (!obj) {
84
- return;
85
- }
86
- if (obj.isArchived() || obj.isDeletedOnRemote()) {
87
- return;
88
- }
89
- await obj.setDeletedOnRemote();
90
- const nodeInFS = this.fsNodes(objRm.objId);
91
- if (!nodeInFS) {
92
- return;
93
- }
94
- await nodeInFS.processRemoteEvent({
95
- type: 'remote-delete',
96
- objId: objRm.objId
97
- }).catch(async (exc) => {
98
- if (!exc.notFound) {
99
- await this.logError(exc, `Error in processing remote removal event`);
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;
100
82
  }
101
- });
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));
102
119
  }
103
120
  }
104
121
  exports.RemoteEvents = RemoteEvents;
@@ -1,19 +1,21 @@
1
1
  import { IGetMailerIdSigner } from '../../../lib-client/user-with-mid-session';
2
- import { SyncedStorage as ISyncedStorage, NodesContainer, Storage as IStorage, StorageGetter, ObjId, NodeEvent } 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
7
  import { Observable } from 'rxjs';
8
+ import { UploadHeaderChange } from '../../../lib-client/3nstorage/xsp-fs/common';
8
9
  declare type FolderEvent = web3n.files.FolderEvent;
9
10
  declare type FileEvent = web3n.files.FileEvent;
10
- declare type Stats = web3n.files.Stats;
11
+ declare type SyncStatus = web3n.files.SyncStatus;
12
+ declare type OptionsToAdopteRemote = web3n.files.OptionsToAdopteRemote;
11
13
  export declare class SyncedStore implements ISyncedStorage {
12
14
  private readonly files;
13
15
  private readonly remoteStorage;
14
16
  private readonly getStorages;
15
17
  readonly cryptor: AsyncSBoxCryptor;
16
- private readonly logError;
18
+ readonly logError: LogError;
17
19
  readonly type: web3n.files.FSType;
18
20
  readonly versioned = true;
19
21
  readonly nodes: NodesContainer;
@@ -21,21 +23,33 @@ export declare class SyncedStore implements ISyncedStorage {
21
23
  private readonly uploader;
22
24
  private readonly events;
23
25
  private constructor();
24
- 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<{
25
27
  syncedStore: ISyncedStorage;
26
28
  startObjProcs: () => void;
27
29
  }>;
30
+ static makeAndStartWithoutRemote(path: string, user: string, getStorages: StorageGetter, cryptor: AsyncSBoxCryptor, remoteServiceUrl: () => Promise<string>, net: NetClient, logError: LogError): Promise<{
31
+ syncedStore: ISyncedStorage;
32
+ setupRemoteAndStartObjProcs: (getSigner: IGetMailerIdSigner) => void;
33
+ }>;
28
34
  getNodeEvents(): Observable<NodeEvent>;
29
- broadcastNodeEvent(objId: ObjId, parentObjId: ObjId | undefined, event: FolderEvent | FileEvent): void;
30
- private broadcastUpSyncEvent;
35
+ broadcastNodeEvent(objId: ObjId, parentObjId: ObjId | undefined, childObjId: ObjId | undefined, event: FolderEvent | FileEvent): void;
31
36
  storageForLinking(type: web3n.files.FSType, location?: string): IStorage;
32
- getObjSyncInfo(objId: ObjId): Promise<Stats['sync']>;
37
+ status(objId: ObjId): Promise<SyncedObjStatus>;
38
+ adoptRemote(objId: ObjId, opts: OptionsToAdopteRemote | undefined): Promise<number | undefined>;
39
+ updateStatusInfo(objId: ObjId): Promise<SyncStatus>;
40
+ isObjOnDisk(objId: ObjId): Promise<boolean>;
41
+ isRemoteVersionOnDisk(objId: ObjId, version: number): Promise<'complete' | 'partial' | 'none'>;
42
+ download(objId: ObjId, version: number): Promise<void>;
43
+ upload(objId: ObjId, localVersion: number, uploadVersion: number, uploadHeader: UploadHeaderChange | undefined, createOnRemote: boolean): Promise<void>;
44
+ uploadObjRemoval(objId: ObjId): Promise<void>;
45
+ dropCachedLocalObjVersionsLessOrEqual(objId: ObjId, version: number): void;
46
+ archiveVersionOnServer(objId: ObjId, version: number): Promise<void>;
33
47
  getRootKeyDerivParamsFromServer(): Promise<ScryptGenParams>;
34
48
  generateNewObjId(): Promise<string>;
35
49
  private objFromDiskOrDownload;
36
- private getObjNonArchOrThrow;
37
- getObj(objId: ObjId): Promise<ObjSource>;
38
- getRemoteConflictObjVersion(objId: ObjId, version: number): Promise<ObjSource>;
50
+ private getObjOrThrow;
51
+ getObjSrc(objId: ObjId, version?: number, allowArchived?: boolean): Promise<ObjSource>;
52
+ getObjSrcOfRemoteVersion(objId: ObjId, version: number): Promise<ObjSource>;
39
53
  saveObj(objId: ObjId, version: number, encSub: Subscribe): Promise<void>;
40
54
  removeObj(objId: string): Promise<void>;
41
55
  close(): Promise<void>;
@@ -24,7 +24,6 @@ const obj_files_1 = require("./obj-files");
24
24
  const random_node_1 = require("../../../lib-common/random-node");
25
25
  const buffer_utils_1 = require("../../../lib-common/buffer-utils");
26
26
  const xsp_files_1 = require("xsp-files");
27
- const downloader_1 = require("./downloader");
28
27
  const remote_events_1 = require("./remote-events");
29
28
  const upsyncer_1 = require("./upsyncer");
30
29
  const utils_for_observables_1 = require("../../../lib-common/utils-for-observables");
@@ -39,39 +38,48 @@ class SyncedStore {
39
38
  this.versioned = true;
40
39
  this.nodes = new common_1.NodesContainer();
41
40
  this.events = new utils_for_observables_1.Broadcast();
42
- const getFSNodes = (objId) => this.nodes.get(objId);
43
- this.remoteEvents = new remote_events_1.RemoteEvents(this.remoteStorage, this.files, getFSNodes, this.logError);
44
- this.uploader = new upsyncer_1.UpSyncer(this.remoteStorage, this.logError, this.broadcastUpSyncEvent.bind(this));
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);
45
43
  Object.seal(this);
46
44
  }
47
- static async makeAndStart(path, user, getSigner, getStorages, cryptor, remoteServiceUrl, makeNet, logError) {
48
- const remote = new service_1.StorageOwner(user, getSigner, remoteServiceUrl, makeNet());
49
- 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 = service_1.StorageOwner.make(user, getSigner, remoteServiceUrl, net);
47
+ const objFiles = await obj_files_1.ObjFiles.makeFor(path, remote, logError);
50
48
  const s = new SyncedStore(objFiles, remote, getStorages, cryptor, logError);
51
49
  s.uploader.start();
50
+ // XXX ??
51
+ // s.remoteEvents.startAbsorbingRemoteEvents();
52
52
  return {
53
- syncedStore: common_1.wrapSyncStorageImplementation(s),
53
+ syncedStore: (0, common_1.wrapSyncStorageImplementation)(s),
54
54
  startObjProcs: () => {
55
55
  s.remoteEvents.startAbsorbingRemoteEvents();
56
56
  }
57
57
  };
58
58
  }
59
+ static async makeAndStartWithoutRemote(path, user, getStorages, cryptor, remoteServiceUrl, net, logError) {
60
+ const { remote, setMid } = service_1.StorageOwner.makeBeforeMidSetup(user, remoteServiceUrl, net);
61
+ const objFiles = await obj_files_1.ObjFiles.makeFor(path, remote, logError);
62
+ const s = new SyncedStore(objFiles, remote, getStorages, cryptor, logError);
63
+ // XXX ??
64
+ // s.remoteEvents.startAbsorbingRemoteEvents();
65
+ return {
66
+ syncedStore: (0, common_1.wrapSyncStorageImplementation)(s),
67
+ setupRemoteAndStartObjProcs: getSigner => {
68
+ setMid(getSigner);
69
+ s.uploader.start();
70
+ s.remoteEvents.startAbsorbingRemoteEvents();
71
+ }
72
+ };
73
+ }
59
74
  getNodeEvents() {
60
75
  return this.events.event$;
61
76
  }
62
- broadcastNodeEvent(objId, parentObjId, event) {
63
- this.events.next({ objId, parentObjId, event });
64
- }
65
- broadcastUpSyncEvent(objId, task) {
66
- const node = this.nodes.get(objId);
67
- if (!node) {
68
- return;
69
- }
70
- node.broadcastUpSyncEvent(task);
77
+ broadcastNodeEvent(objId, parentObjId, childObjId, event) {
78
+ this.events.next({ objId, parentObjId, childObjId, event });
71
79
  }
72
80
  storageForLinking(type, location) {
73
81
  if (type === 'synced') {
74
- return common_1.wrapStorageImplementation(this);
82
+ return (0, common_1.wrapStorageImplementation)(this);
75
83
  }
76
84
  else if (type === 'share') {
77
85
  return this.getStorages('share', location);
@@ -80,18 +88,107 @@ class SyncedStore {
80
88
  throw new Error(`Getting ${type} storage is not implemented in local storage.`);
81
89
  }
82
90
  }
83
- async getObjSyncInfo(objId) {
91
+ async status(objId) {
92
+ const obj = await this.getObjOrThrow(objId, true);
93
+ return obj.syncStatus();
94
+ }
95
+ async adoptRemote(objId, opts) {
96
+ const obj = await this.getObjOrThrow(objId);
97
+ const objStatus = obj.statusObj();
98
+ await objStatus.adoptRemoteVersion(opts === null || opts === void 0 ? void 0 : opts.remoteVersion, opts === null || opts === void 0 ? void 0 : opts.dropLocalVer);
99
+ if (opts && opts.download) {
100
+ // XXX this needs implementation
101
+ throw new Error('SyncedStore.adoptRemote() with download option needs implementation, probably using SyncedStore.download().');
102
+ }
103
+ this.files.scheduleGC(obj);
104
+ return objStatus.syncStatus().synced.latest;
105
+ }
106
+ async updateStatusInfo(objId) {
107
+ const obj = await this.getObjOrThrow(objId, true);
108
+ try {
109
+ const statusOnServer = await this.remoteStorage.getObjStatus(objId);
110
+ const objStatus = obj.statusObj();
111
+ await objStatus.recordStatusFromServer(statusOnServer);
112
+ return objStatus.syncStatus();
113
+ }
114
+ catch (exc) {
115
+ if ((exc.type === 'storage')
116
+ && exc.objNotFound) {
117
+ const objStatus = obj.statusObj();
118
+ await objStatus.recordStatusFromServer({});
119
+ return objStatus.syncStatus();
120
+ }
121
+ throw exc;
122
+ }
123
+ }
124
+ async isObjOnDisk(objId) {
84
125
  const obj = await this.files.findObj(objId);
126
+ return !!obj;
127
+ }
128
+ async isRemoteVersionOnDisk(objId, version) {
129
+ var _a;
130
+ const obj = await this.getObjOrThrow(objId, true);
131
+ const status = obj.statusObj();
132
+ const { remote } = status.syncStatus();
133
+ if (((remote === null || remote === void 0 ? void 0 : remote.latest) !== version)
134
+ || !((_a = remote.archived) === null || _a === void 0 ? void 0 : _a.includes(version))) {
135
+ throw (0, exceptions_1.makeObjVersionNotFoundExc)(objId, version);
136
+ }
137
+ // XXX
138
+ // - get state of file
139
+ throw new Error('SyncedStore.isRemoteVersionOnDisk() not implemented.');
140
+ }
141
+ download(objId, version) {
142
+ // XXX
143
+ // - check if on disk
144
+ // - download header
145
+ // - want result of DC-296, calculation of diff to download, relative to
146
+ // latest version on the disk, using headers of both versions.
147
+ throw new Error('SyncedStore.download() not implemented.');
148
+ }
149
+ async upload(objId, localVersion, uploadVersion, uploadHeader, createOnRemote) {
150
+ const obj = await this.getObjOrThrow(objId, true);
151
+ const syncedBase = await obj.combineLocalBaseIfPresent(localVersion);
152
+ if (uploadHeader) {
153
+ await obj.saveUploadHeaderFile(uploadHeader);
154
+ }
155
+ await this.uploader.uploadFromDisk(obj, localVersion, uploadVersion, uploadHeader === null || uploadHeader === void 0 ? void 0 : uploadHeader.uploadHeader, syncedBase, createOnRemote);
156
+ await obj.recordUploadCompletion(localVersion, uploadVersion, (uploadHeader ? {
157
+ newHeader: uploadHeader.uploadHeader,
158
+ originalHeader: uploadHeader.localHeader
159
+ } : undefined));
160
+ if (localVersion > uploadVersion) {
161
+ await obj.removeLocalVersionFilesLessThan(localVersion);
162
+ }
163
+ }
164
+ async uploadObjRemoval(objId) {
165
+ if (!objId) {
166
+ return;
167
+ }
168
+ const obj = await this.getObjOrThrow(objId, true);
169
+ const status = obj.statusObj();
170
+ if (status.neverUploaded()) {
171
+ return;
172
+ }
173
+ if (await status.clearPostponeFlagInRemovalOnRemote()) {
174
+ await this.uploader.removeCurrentVersionOf(obj);
175
+ }
176
+ }
177
+ dropCachedLocalObjVersionsLessOrEqual(objId, version) {
178
+ const obj = this.files.getObjInCache(objId);
85
179
  if (!obj) {
86
180
  return;
87
181
  }
88
- return obj.sync().stat();
182
+ obj.dropCachedLocalObjVersionsLessOrEqual(version);
183
+ }
184
+ async archiveVersionOnServer(objId, version) {
185
+ await this.remoteStorage.archiveObjVersion(objId, version);
89
186
  }
90
187
  getRootKeyDerivParamsFromServer() {
91
188
  return this.remoteStorage.getKeyDerivParams();
92
189
  }
93
190
  async generateNewObjId() {
94
- const nonce = await random_node_1.bytes(xsp_files_1.NONCE_LENGTH);
191
+ const nonce = await (0, random_node_1.bytes)(xsp_files_1.NONCE_LENGTH);
95
192
  const id = buffer_utils_1.base64urlSafe.pack(nonce);
96
193
  if (this.nodes.reserveId(id)) {
97
194
  return id;
@@ -105,53 +202,56 @@ class SyncedStore {
105
202
  if (obj) {
106
203
  return obj;
107
204
  }
205
+ // XXX
206
+ // - can we create object by getting obj status
108
207
  return await this.files.makeByDownloadingCurrentVersion(objId);
109
208
  }
110
- async getObjNonArchOrThrow(objId) {
209
+ async getObjOrThrow(objId, allowArchived = false) {
111
210
  const obj = await this.objFromDiskOrDownload(objId);
112
- if (obj.isArchived()) {
113
- throw exceptions_1.makeObjNotFoundExc(objId);
211
+ if (!allowArchived && obj.statusObj().isArchived()) {
212
+ throw (0, exceptions_1.makeObjNotFoundExc)(objId);
213
+ }
214
+ else {
215
+ return obj;
114
216
  }
115
- return obj;
116
217
  }
117
- async getObj(objId) {
118
- const obj = await this.getObjNonArchOrThrow(objId);
119
- const currentVer = obj.getCurrentVersionOrThrow();
120
- return obj.getObjSrc(currentVer);
218
+ async getObjSrc(objId, version, allowArchived = false) {
219
+ const obj = await this.getObjOrThrow(objId, allowArchived);
220
+ if (!version) {
221
+ version = obj.statusObj().getCurrentLocalOrSynced();
222
+ }
223
+ return obj.getObjSrcFromLocalAndSyncedBranch(version);
121
224
  }
122
- async getRemoteConflictObjVersion(objId, version) {
123
- const obj = await this.getObjNonArchOrThrow(objId);
124
- return obj.getRemoteConflictObjVersion(version);
225
+ async getObjSrcOfRemoteVersion(objId, version) {
226
+ const obj = await this.getObjOrThrow(objId);
227
+ return obj.getObjSrcFromRemoteAndSyncedBranch(version);
125
228
  }
126
229
  async saveObj(objId, version, encSub) {
127
230
  if (version === 1) {
128
231
  const obj = await this.files.findObj(objId);
129
232
  if (obj) {
130
- throw exceptions_1.makeObjExistsExc(objId);
233
+ throw (0, exceptions_1.makeObjExistsExc)(objId);
131
234
  }
132
- const { fileWrite$, newObj } = await this.files.saveFirstVersion(objId, encSub);
133
- await fileWrite$
134
- .pipe(this.uploader.tapFileWrite(newObj, true, version))
135
- .toPromise();
235
+ const { fileWrite$ } = await this.files.saveFirstVersion(objId, encSub);
236
+ await fileWrite$.toPromise();
136
237
  }
137
238
  else {
138
- const obj = await this.files.findObj(objId);
139
- if (!obj) {
140
- throw exceptions_1.makeObjNotFoundExc(objId);
141
- }
142
- const { fileWrite$, baseVer } = await obj.saveNewVersion(version, encSub);
143
- await fileWrite$
144
- .pipe(this.uploader.tapFileWrite(obj, false, version, baseVer))
145
- .toPromise();
239
+ const obj = await this.getObjOrThrow(objId);
240
+ const { fileWrite$ } = await obj.saveNewVersion(version, encSub);
241
+ await fileWrite$.toPromise();
146
242
  }
147
243
  }
148
244
  async removeObj(objId) {
149
- const obj = await this.files.findObj(objId);
245
+ const obj = await this.getObjOrThrow(objId)
246
+ .catch((exc) => {
247
+ if (!exc.objNotFound) {
248
+ throw exc;
249
+ }
250
+ });
150
251
  if (!obj) {
151
252
  return;
152
253
  }
153
254
  await obj.removeCurrentVersion();
154
- await this.uploader.removeCurrentVersionOf(obj);
155
255
  }
156
256
  async close() {
157
257
  try {
@@ -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);
@@ -3,20 +3,25 @@ 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 { UpSyncTaskInfo } from "./obj-status";
7
- import { ObjId } from "../../../lib-client/3nstorage/xsp-fs/common";
6
+ import { NewVersionUpload } from "./obj-status";
8
7
  export declare type FileWriteTapOperator = MonoTypeOperatorFunction<FileWrite[]>;
9
- export declare type BroadcastUpSyncEvent = (objId: ObjId, task: UpSyncTaskInfo) => void;
10
8
  export declare class UpSyncer {
11
9
  private readonly remoteStorage;
12
10
  private readonly logError;
13
- private readonly broadcastUpSyncEvent;
14
11
  private readonly execPools;
15
- private readonly uploads;
16
- constructor(remoteStorage: StorageOwner, logError: LogError, broadcastUpSyncEvent: BroadcastUpSyncEvent);
17
- private getOrMakeUploadsFor;
12
+ constructor(remoteStorage: StorageOwner, logError: LogError);
18
13
  start(): void;
19
14
  stop(): Promise<void>;
15
+ /**
16
+ * Creates an rxjs operator to tap saving process, starting upload while
17
+ * writing is ongoing.
18
+ */
20
19
  tapFileWrite(obj: SyncedObj, isNew: boolean, newVersion: number, baseVersion?: number): FileWriteTapOperator;
21
20
  removeCurrentVersionOf(obj: SyncedObj): Promise<void>;
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: NewVersionUpload): Promise<void>;
25
+ recordUploadCancellation(info: NewVersionUpload): Promise<void>;
26
+ recordUploadInterimState(info: NewVersionUpload): Promise<void>;
22
27
  }