core-3nweb-client-lib 0.26.1 → 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 (199) hide show
  1. package/build/api-defs/asmail.d.ts +1 -1
  2. package/build/api-defs/files.d.ts +278 -69
  3. package/build/core/app-files.js +7 -7
  4. package/build/core/asmail/config/common.js +2 -2
  5. package/build/core/asmail/config/index.js +2 -2
  6. package/build/core/asmail/config/published-intro-key.js +1 -1
  7. package/build/core/asmail/delivery/common.js +7 -7
  8. package/build/core/asmail/delivery/index.js +5 -5
  9. package/build/core/asmail/delivery/msg.js +4 -4
  10. package/build/core/asmail/delivery/per-recipient-wip.js +1 -1
  11. package/build/core/asmail/inbox/attachments/fs.js +5 -1
  12. package/build/core/asmail/inbox/cached-msgs.js +1 -1
  13. package/build/core/asmail/inbox/inbox-events.js +4 -4
  14. package/build/core/asmail/inbox/index.js +10 -10
  15. package/build/core/asmail/inbox/msg-downloader.js +1 -1
  16. package/build/core/asmail/inbox/msg-indexing.js +1 -1
  17. package/build/core/asmail/inbox/msg-on-disk.js +5 -5
  18. package/build/core/asmail/index.d.ts +3 -3
  19. package/build/core/asmail/index.js +13 -8
  20. package/build/core/asmail/key-verification.js +5 -5
  21. package/build/core/asmail/keyring/common.js +7 -6
  22. package/build/core/asmail/keyring/correspondent-keys.js +8 -7
  23. package/build/core/asmail/keyring/id-to-email-map.js +2 -1
  24. package/build/core/asmail/keyring/index.d.ts +7 -8
  25. package/build/core/asmail/keyring/index.js +15 -14
  26. package/build/core/asmail/keyring/keyring-storage.js +2 -1
  27. package/build/core/asmail/msg/opener.js +3 -3
  28. package/build/core/asmail/msg/packer.js +13 -13
  29. package/build/core/asmail/sending-params/own-params.js +2 -2
  30. package/build/core/asmail/sending-params/params-from-others.js +1 -1
  31. package/build/core/id-manager.js +6 -3
  32. package/build/core/index.d.ts +2 -1
  33. package/build/core/index.js +14 -14
  34. package/build/core/sign-in.js +5 -5
  35. package/build/core/sign-up.js +9 -9
  36. package/build/core/storage/common/json-saving.js +2 -2
  37. package/build/core/storage/common/obj-info-file.d.ts +12 -4
  38. package/build/core/storage/common/obj-info-file.js +66 -34
  39. package/build/core/storage/common/utils.d.ts +2 -0
  40. package/build/core/storage/common/utils.js +32 -0
  41. package/build/core/storage/index.d.ts +3 -17
  42. package/build/core/storage/index.js +56 -76
  43. package/build/core/storage/local/obj-files-gc.d.ts +2 -0
  44. package/build/core/storage/local/obj-files-gc.js +49 -37
  45. package/build/core/storage/local/obj-files.d.ts +4 -7
  46. package/build/core/storage/local/obj-files.js +7 -10
  47. package/build/core/storage/local/obj-status.d.ts +12 -6
  48. package/build/core/storage/local/obj-status.js +24 -9
  49. package/build/core/storage/local/storage.d.ts +9 -6
  50. package/build/core/storage/local/storage.js +29 -18
  51. package/build/core/storage/synced/downloader.js +1 -1
  52. package/build/core/storage/synced/obj-files-gc.d.ts +5 -1
  53. package/build/core/storage/synced/obj-files-gc.js +91 -37
  54. package/build/core/storage/synced/obj-files.d.ts +42 -36
  55. package/build/core/storage/synced/obj-files.js +178 -147
  56. package/build/core/storage/synced/obj-status.d.ts +87 -85
  57. package/build/core/storage/synced/obj-status.js +463 -259
  58. package/build/core/storage/synced/remote-events.d.ts +11 -12
  59. package/build/core/storage/synced/remote-events.js +73 -56
  60. package/build/core/storage/synced/storage.d.ts +18 -9
  61. package/build/core/storage/synced/storage.js +108 -48
  62. package/build/core/storage/synced/upload-header-file.d.ts +4 -0
  63. package/build/core/storage/synced/upload-header-file.js +64 -0
  64. package/build/core/storage/synced/upsyncer.d.ts +12 -7
  65. package/build/core/storage/synced/upsyncer.js +205 -280
  66. package/build/core/storage/system-folders/apps-data.d.ts +16 -0
  67. package/build/core/storage/system-folders/apps-data.js +110 -0
  68. package/build/core/storage/system-folders/index.d.ts +18 -0
  69. package/build/core/storage/system-folders/index.js +77 -0
  70. package/build/core-ipc/common-caps.js +3 -3
  71. package/build/core-ipc/generic.js +8 -8
  72. package/build/core-ipc/startup-caps.js +2 -2
  73. package/build/cryptors.js +6 -2
  74. package/build/ipc-via-protobuf/asmail-cap.js +58 -57
  75. package/build/ipc-via-protobuf/bytes.js +16 -17
  76. package/build/ipc-via-protobuf/connector-clients-side.d.ts +1 -0
  77. package/build/ipc-via-protobuf/connector-clients-side.js +14 -15
  78. package/build/ipc-via-protobuf/connector-services-side.js +10 -10
  79. package/build/ipc-via-protobuf/connector.js +4 -4
  80. package/build/ipc-via-protobuf/file.d.ts +48 -12
  81. package/build/ipc-via-protobuf/file.js +474 -126
  82. package/build/ipc-via-protobuf/fs.d.ts +8 -0
  83. package/build/ipc-via-protobuf/fs.js +577 -142
  84. package/build/ipc-via-protobuf/log-cap.js +2 -2
  85. package/build/ipc-via-protobuf/mailerid.js +3 -3
  86. package/build/ipc-via-protobuf/protobuf-msg.d.ts +1 -0
  87. package/build/ipc-via-protobuf/protobuf-msg.js +11 -7
  88. package/build/ipc-via-protobuf/startup-cap.js +21 -21
  89. package/build/ipc-via-protobuf/storage-cap.js +12 -12
  90. package/build/ipc.js +7 -2
  91. package/build/lib-client/3nstorage/exceptions.d.ts +3 -0
  92. package/build/lib-client/3nstorage/exceptions.js +13 -1
  93. package/build/lib-client/3nstorage/service.d.ts +16 -2
  94. package/build/lib-client/3nstorage/service.js +104 -38
  95. package/build/lib-client/3nstorage/util/file-based-json.d.ts +2 -1
  96. package/build/lib-client/3nstorage/util/file-based-json.js +1 -1
  97. package/build/lib-client/3nstorage/xsp-fs/attrs.js +17 -17
  98. package/build/lib-client/3nstorage/xsp-fs/common.d.ts +42 -18
  99. package/build/lib-client/3nstorage/xsp-fs/common.js +29 -19
  100. package/build/lib-client/3nstorage/xsp-fs/file-node.d.ts +1 -0
  101. package/build/lib-client/3nstorage/xsp-fs/file-node.js +17 -13
  102. package/build/lib-client/3nstorage/xsp-fs/file.d.ts +31 -6
  103. package/build/lib-client/3nstorage/xsp-fs/file.js +73 -25
  104. package/build/lib-client/3nstorage/xsp-fs/folder-node-serialization.js +4 -4
  105. package/build/lib-client/3nstorage/xsp-fs/folder-node.d.ts +24 -11
  106. package/build/lib-client/3nstorage/xsp-fs/folder-node.js +575 -179
  107. package/build/lib-client/3nstorage/xsp-fs/fs.d.ts +35 -4
  108. package/build/lib-client/3nstorage/xsp-fs/fs.js +231 -110
  109. package/build/lib-client/3nstorage/xsp-fs/link-node.d.ts +1 -0
  110. package/build/lib-client/3nstorage/xsp-fs/link-node.js +7 -2
  111. package/build/lib-client/3nstorage/xsp-fs/node-in-fs.d.ts +30 -24
  112. package/build/lib-client/3nstorage/xsp-fs/node-in-fs.js +229 -123
  113. package/build/lib-client/3nstorage/xsp-fs/node-persistence.d.ts +1 -1
  114. package/build/lib-client/3nstorage/xsp-fs/node-persistence.js +17 -18
  115. package/build/lib-client/3nstorage/xsp-fs/xsp-payload-v1.js +3 -3
  116. package/build/lib-client/3nstorage/xsp-fs/xsp-payload-v2.js +53 -53
  117. package/build/lib-client/3nweb-signup.js +4 -4
  118. package/build/lib-client/asmail/recipient.js +15 -15
  119. package/build/lib-client/asmail/sender.js +22 -22
  120. package/build/lib-client/asmail/service-config.js +3 -3
  121. package/build/lib-client/cryptor/cryptor-in-worker.js +18 -16
  122. package/build/lib-client/cryptor/cryptor-wasm.js +1 -1
  123. package/build/lib-client/cryptor/cryptor.js +4 -2
  124. package/build/lib-client/cryptor/cryptor.wasm +0 -0
  125. package/build/lib-client/cryptor/in-proc-js.js +1 -1
  126. package/build/lib-client/cryptor/in-proc-wasm.js +6 -6
  127. package/build/lib-client/cryptor/worker-js.js +2 -2
  128. package/build/lib-client/cryptor/worker-wasm.js +2 -2
  129. package/build/lib-client/files-select.js +1 -1
  130. package/build/lib-client/files.d.ts +1 -1
  131. package/build/lib-client/files.js +71 -6
  132. package/build/lib-client/fs-collection.js +1 -1
  133. package/build/lib-client/fs-sync-utils.d.ts +5 -0
  134. package/build/lib-client/fs-sync-utils.js +61 -0
  135. package/build/lib-client/fs-view.d.ts +14 -0
  136. package/build/lib-client/fs-view.js +33 -0
  137. package/build/lib-client/key-derivation.js +1 -1
  138. package/build/lib-client/local-files/dev-file-sink.js +9 -9
  139. package/build/lib-client/local-files/dev-file-src.js +2 -2
  140. package/build/lib-client/local-files/device-fs.d.ts +1 -1
  141. package/build/lib-client/local-files/device-fs.js +56 -54
  142. package/build/lib-client/logging/log-to-file.d.ts +1 -1
  143. package/build/lib-client/logging/log-to-file.js +7 -7
  144. package/build/lib-client/mailer-id/login.js +7 -7
  145. package/build/lib-client/mailer-id/provisioner.js +12 -12
  146. package/build/lib-client/objs-on-disk/file-writing-proc.js +3 -3
  147. package/build/lib-client/objs-on-disk/obj-folders.js +31 -31
  148. package/build/lib-client/objs-on-disk/obj-on-disk.d.ts +13 -2
  149. package/build/lib-client/objs-on-disk/obj-on-disk.js +24 -9
  150. package/build/lib-client/request-utils.d.ts +1 -0
  151. package/build/lib-client/request-utils.js +13 -13
  152. package/build/lib-client/server-events.d.ts +3 -3
  153. package/build/lib-client/server-events.js +9 -8
  154. package/build/lib-client/service-locator.js +10 -10
  155. package/build/lib-client/user-with-mid-session.js +7 -7
  156. package/build/lib-client/user-with-pkl-session.js +25 -25
  157. package/build/lib-client/ws-utils.js +2 -2
  158. package/build/lib-common/async-cryptor-wrap.js +4 -4
  159. package/build/lib-common/async-fs-node.d.ts +5 -3
  160. package/build/lib-common/async-fs-node.js +16 -16
  161. package/build/lib-common/byte-streaming/pipe.js +1 -1
  162. package/build/lib-common/byte-streaming/wrapping.js +13 -13
  163. package/build/lib-common/canonical-address.js +1 -1
  164. package/build/lib-common/exceptions/error.d.ts +1 -0
  165. package/build/lib-common/exceptions/error.js +7 -6
  166. package/build/lib-common/exceptions/file.js +4 -0
  167. package/build/lib-common/ipc/ws-ipc.js +2 -2
  168. package/build/lib-common/mid-sigs-NaCl-Ed.js +14 -14
  169. package/build/lib-common/objs-on-disk/file-layout.d.ts +19 -0
  170. package/build/lib-common/objs-on-disk/file-layout.js +130 -12
  171. package/build/lib-common/objs-on-disk/obj-file.d.ts +13 -2
  172. package/build/lib-common/objs-on-disk/obj-file.js +96 -35
  173. package/build/lib-common/objs-on-disk/utils.d.ts +1 -0
  174. package/build/lib-common/objs-on-disk/utils.js +3 -3
  175. package/build/lib-common/objs-on-disk/v1-obj-file-format.js +14 -14
  176. package/build/lib-common/processes/labelled-exec-pools.d.ts +1 -1
  177. package/build/lib-common/processes/labelled-exec-pools.js +1 -1
  178. package/build/lib-common/processes/pressure.js +2 -2
  179. package/build/lib-common/processes/synced.js +1 -1
  180. package/build/lib-common/processes/timeout.js +2 -2
  181. package/build/lib-common/random-node.js +7 -7
  182. package/build/lib-common/service-api/3nstorage/owner.d.ts +95 -35
  183. package/build/lib-common/service-api/3nstorage/owner.js +82 -40
  184. package/build/lib-common/service-api/asmail/delivery.js +2 -2
  185. package/build/lib-common/service-api/asmail/retrieval.js +1 -1
  186. package/build/lib-common/timed-cache.d.ts +1 -0
  187. package/build/lib-common/timed-non-weak-cache.d.ts +1 -0
  188. package/build/lib-common/timed-non-weak-cache.js +11 -0
  189. package/build/lib-common/utils-for-observables.js +4 -4
  190. package/build/lib-common/weak-cache.d.ts +1 -0
  191. package/build/lib-common/weak-cache.js +12 -1
  192. package/build/lib-index.d.ts +2 -1
  193. package/build/lib-index.js +10 -7
  194. package/build/protos/asmail.proto.js +12955 -7496
  195. package/build/protos/file.proto.js +4867 -2744
  196. package/build/protos/fs.proto.js +9227 -3768
  197. package/package.json +6 -5
  198. package/protos/file.proto +91 -19
  199. package/protos/fs.proto +107 -8
@@ -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,13 +1,15 @@
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;
@@ -21,21 +23,28 @@ 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
  }>;
28
30
  getNodeEvents(): Observable<NodeEvent>;
29
- broadcastNodeEvent(objId: ObjId, parentObjId: ObjId | undefined, event: FolderEvent | FileEvent): void;
30
- private broadcastUpSyncEvent;
31
+ broadcastNodeEvent(objId: ObjId, parentObjId: ObjId | undefined, childObjId: ObjId | undefined, event: FolderEvent | FileEvent): void;
31
32
  storageForLinking(type: web3n.files.FSType, location?: string): IStorage;
32
- getObjSyncInfo(objId: ObjId): Promise<Stats['sync']>;
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>;
33
42
  getRootKeyDerivParamsFromServer(): Promise<ScryptGenParams>;
34
43
  generateNewObjId(): Promise<string>;
35
44
  private objFromDiskOrDownload;
36
- private getObjNonArchOrThrow;
37
- getObj(objId: ObjId): Promise<ObjSource>;
38
- 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>;
39
48
  saveObj(objId: ObjId, version: number, encSub: Subscribe): Promise<void>;
40
49
  removeObj(objId: string): Promise<void>;
41
50
  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,18 +38,17 @@ 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 = new service_1.StorageOwner(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();
52
50
  return {
53
- syncedStore: common_1.wrapSyncStorageImplementation(s),
51
+ syncedStore: (0, common_1.wrapSyncStorageImplementation)(s),
54
52
  startObjProcs: () => {
55
53
  s.remoteEvents.startAbsorbingRemoteEvents();
56
54
  }
@@ -59,19 +57,12 @@ class SyncedStore {
59
57
  getNodeEvents() {
60
58
  return this.events.event$;
61
59
  }
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);
60
+ broadcastNodeEvent(objId, parentObjId, childObjId, event) {
61
+ this.events.next({ objId, parentObjId, childObjId, event });
71
62
  }
72
63
  storageForLinking(type, location) {
73
64
  if (type === 'synced') {
74
- return common_1.wrapStorageImplementation(this);
65
+ return (0, common_1.wrapStorageImplementation)(this);
75
66
  }
76
67
  else if (type === 'share') {
77
68
  return this.getStorages('share', location);
@@ -80,18 +71,86 @@ class SyncedStore {
80
71
  throw new Error(`Getting ${type} storage is not implemented in local storage.`);
81
72
  }
82
73
  }
83
- async getObjSyncInfo(objId) {
84
- const obj = await this.files.findObj(objId);
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);
85
141
  if (!obj) {
86
142
  return;
87
143
  }
88
- return obj.sync().stat();
144
+ obj.dropCachedLocalObjVersionsLessOrEqual(version);
145
+ }
146
+ async archiveVersionOnServer(objId, version) {
147
+ await this.remoteStorage.archiveObjVersion(objId, version);
89
148
  }
90
149
  getRootKeyDerivParamsFromServer() {
91
150
  return this.remoteStorage.getKeyDerivParams();
92
151
  }
93
152
  async generateNewObjId() {
94
- 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);
95
154
  const id = buffer_utils_1.base64urlSafe.pack(nonce);
96
155
  if (this.nodes.reserveId(id)) {
97
156
  return id;
@@ -107,51 +166,52 @@ class SyncedStore {
107
166
  }
108
167
  return await this.files.makeByDownloadingCurrentVersion(objId);
109
168
  }
110
- async getObjNonArchOrThrow(objId) {
169
+ async getObjOrThrow(objId, allowArchived = false) {
111
170
  const obj = await this.objFromDiskOrDownload(objId);
112
- if (obj.isArchived()) {
113
- throw exceptions_1.makeObjNotFoundExc(objId);
171
+ if (!allowArchived && obj.statusObj().isArchived()) {
172
+ throw (0, exceptions_1.makeObjNotFoundExc)(objId);
173
+ }
174
+ else {
175
+ return obj;
114
176
  }
115
- return obj;
116
177
  }
117
- async getObj(objId) {
118
- const obj = await this.getObjNonArchOrThrow(objId);
119
- const currentVer = obj.getCurrentVersionOrThrow();
120
- 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);
121
184
  }
122
- async getRemoteConflictObjVersion(objId, version) {
123
- const obj = await this.getObjNonArchOrThrow(objId);
124
- return obj.getRemoteConflictObjVersion(version);
185
+ async getObjSrcOfRemoteVersion(objId, version) {
186
+ const obj = await this.getObjOrThrow(objId);
187
+ return obj.getObjSrcFromRemoteAndSyncedBranch(version);
125
188
  }
126
189
  async saveObj(objId, version, encSub) {
127
190
  if (version === 1) {
128
191
  const obj = await this.files.findObj(objId);
129
192
  if (obj) {
130
- throw exceptions_1.makeObjExistsExc(objId);
193
+ throw (0, exceptions_1.makeObjExistsExc)(objId);
131
194
  }
132
- const { fileWrite$, newObj } = await this.files.saveFirstVersion(objId, encSub);
133
- await fileWrite$
134
- .pipe(this.uploader.tapFileWrite(newObj, true, version))
135
- .toPromise();
195
+ const { fileWrite$ } = await this.files.saveFirstVersion(objId, encSub);
196
+ await fileWrite$.toPromise();
136
197
  }
137
198
  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();
199
+ const obj = await this.getObjOrThrow(objId);
200
+ const { fileWrite$ } = await obj.saveNewVersion(version, encSub);
201
+ await fileWrite$.toPromise();
146
202
  }
147
203
  }
148
204
  async removeObj(objId) {
149
- 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
+ });
150
211
  if (!obj) {
151
212
  return;
152
213
  }
153
214
  await obj.removeCurrentVersion();
154
- await this.uploader.removeCurrentVersionOf(obj);
155
215
  }
156
216
  async close() {
157
217
  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 { UploadInfo } 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: UploadInfo): Promise<void>;
25
+ recordUploadCancellation(info: UploadInfo): Promise<void>;
26
+ recordUploadInterimState(info: UploadInfo): Promise<void>;
22
27
  }