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
@@ -17,356 +17,286 @@
17
17
  */
18
18
  Object.defineProperty(exports, "__esModule", { value: true });
19
19
  exports.UpSyncer = void 0;
20
- const operators_1 = require("rxjs/operators");
21
20
  const labelled_exec_pools_1 = require("../../../lib-common/processes/labelled-exec-pools");
21
+ const exceptions_1 = require("../../../lib-client/3nstorage/exceptions");
22
22
  const assert_1 = require("../../../lib-common/assert");
23
+ const deferred_1 = require("../../../lib-common/processes/deferred");
24
+ const buffer_utils_1 = require("../../../lib-common/buffer-utils");
23
25
  const MAX_CHUNK_SIZE = 512 * 1024;
24
26
  const MAX_FAST_UPLOAD = 2 * 1024 * 1024;
25
- function executorLabelFor(info) {
26
- let uploadSize = 0;
27
- if (info.header) {
28
- uploadSize += info.header;
29
- }
30
- for (const seg of info.segs) {
31
- uploadSize += seg.len;
32
- }
33
- return ((uploadSize <= MAX_FAST_UPLOAD) ? 'fast' : 'long');
34
- }
35
- function addEventToInfo(info, writeEv) {
36
- for (const w of writeEv) {
37
- if (w.isHeader) {
38
- info.header = w.bytes.length;
39
- }
40
- else {
41
- mergeSections(info.segs, w);
42
- }
43
- }
44
- }
45
- function mergeSections(segs, w) {
46
- const wStart = w.ofs;
47
- const wLen = w.bytes.length;
48
- for (let i = 0; i < segs.length; i += 1) {
49
- const section = segs[i];
50
- const sectionEnd = section.ofs + section.len;
51
- if (sectionEnd < wStart) {
52
- continue;
53
- }
54
- if (sectionEnd === wStart) {
55
- section.len += wLen;
56
- }
57
- else if (section.ofs <= wStart) {
58
- const maxOverlap = section.len - (wStart - section.ofs);
59
- if (maxOverlap < wLen) {
60
- section.len += wLen - maxOverlap;
61
- }
62
- }
63
- else if ((wStart + wLen) === section.ofs) {
64
- section.ofs = wStart;
65
- }
66
- else {
67
- segs.splice(i, 0, { ofs: wStart, len: wLen });
68
- }
69
- return;
70
- }
71
- segs.push({ ofs: wStart, len: wLen });
72
- }
73
27
  class UpSyncer {
74
- constructor(remoteStorage, logError, broadcastUpSyncEvent) {
28
+ constructor(remoteStorage, logError) {
75
29
  this.remoteStorage = remoteStorage;
76
30
  this.logError = logError;
77
- this.broadcastUpSyncEvent = broadcastUpSyncEvent;
78
- this.uploads = new Map();
79
31
  this.execPools = new labelled_exec_pools_1.LabelledExecPools([
80
32
  { label: 'long', maxProcs: 1 },
81
33
  { label: 'fast', maxProcs: 1 }
82
34
  ], logError);
83
35
  Object.seal(this);
84
36
  }
85
- getOrMakeUploadsFor(obj) {
86
- let uploads = this.uploads.get(obj);
87
- if (!uploads) {
88
- uploads = new ObjUpSync(obj, this.remoteStorage, this.execPools, this.logError, this.broadcastUpSyncEvent);
89
- this.uploads.set(obj, uploads);
90
- }
91
- return uploads;
92
- }
93
37
  start() {
94
38
  this.execPools.start();
95
39
  }
96
40
  async stop() {
97
41
  await this.execPools.stop(); // implicitly cancels all upsync tasks
98
- this.uploads.clear();
99
42
  }
43
+ /**
44
+ * Creates an rxjs operator to tap saving process, starting upload while
45
+ * writing is ongoing.
46
+ */
100
47
  tapFileWrite(obj, isNew, newVersion, baseVersion) {
101
- const objUploads = this.getOrMakeUploadsFor(obj);
102
- return objUploads.tapFileWrite(isNew, newVersion, baseVersion);
48
+ throw new Error('UpSyncer.tapFileWrite() not implemented');
49
+ // const objUploads = this.getOrMakeUploadsFor(obj);
50
+ // return objUploads.tapFileWrite(isNew, newVersion, baseVersion);
103
51
  }
104
52
  async removeCurrentVersionOf(obj) {
105
- const objUploads = this.getOrMakeUploadsFor(obj);
106
- if (objUploads.neededExecutor()) {
107
- this.execPools.add(objUploads);
53
+ try {
54
+ await this.remoteStorage.deleteObj(obj.objId);
108
55
  }
56
+ catch (exc) {
57
+ // XXX
58
+ // - we need to distinguish errors and put this work somewhere
59
+ // to run when we go online, for example.
60
+ await this.logError(exc, `Uploading of obj removal failed.`);
61
+ return;
62
+ }
63
+ await obj.recordRemovalUploadAndGC();
64
+ }
65
+ async uploadFromDisk(obj, localVersion, uploadVersion, uploadHeader, syncedBase, createOnRemote) {
66
+ const task = await UploadTask.for(obj, localVersion, uploadVersion, uploadHeader, syncedBase, createOnRemote, this.remoteStorage, this.execPools);
67
+ this.execPools.add(task);
68
+ await task.completion();
109
69
  }
110
70
  }
111
71
  exports.UpSyncer = UpSyncer;
112
72
  Object.freeze(UpSyncer.prototype);
113
73
  Object.freeze(UpSyncer);
114
- class ObjUpSync {
115
- constructor(obj, remoteStorage, execPools, logError, broadcastUpSyncEvent) {
116
- this.obj = obj;
74
+ class UploadTask {
75
+ constructor(remoteStorage, objId, objStatus, src, execPools, info, uploadHeader) {
117
76
  this.remoteStorage = remoteStorage;
77
+ this.objId = objId;
78
+ this.objStatus = objStatus;
79
+ this.src = src;
118
80
  this.execPools = execPools;
119
- this.logError = logError;
120
- this.broadcastUpSyncEvent = broadcastUpSyncEvent;
121
- this.taskInProcess = undefined;
122
- this.isCancelled = false;
123
- this.runningProc = undefined;
81
+ this.info = info;
82
+ this.uploadHeader = uploadHeader;
83
+ this.uploadCompletion = (0, deferred_1.defer)();
84
+ this.execLabel = executorLabelFor(this.info.needUpload);
124
85
  Object.seal(this);
125
86
  }
126
- tapFileWrite(isObjNew, newVersion, baseVersion) {
127
- // XXX for now upload is started when write is complete, but tapped code
128
- // layout can adopt upload as before completion.
129
- const uploadInfo = {
130
- type: 'upload',
131
- version: newVersion,
132
- baseVersion,
133
- needUpload: {
134
- segs: []
135
- }
136
- };
137
- if (isObjNew) {
138
- uploadInfo.createObj = true;
139
- }
140
- return operators_1.tap(writeEv => {
141
- addEventToInfo(uploadInfo.needUpload, writeEv);
142
- }, async (err) => {
143
- // XXX cancel in-tap upload, when it will be added.
144
- // Something should be done in case there is a transaction that
145
- // needs cancelling.
146
- await this.cancelTransactionIfOpen(uploadInfo);
147
- await this.logError(err);
148
- }, () => {
149
- uploadInfo.needUpload.allByteOnDisk = true;
150
- this.enqueueTask(uploadInfo);
151
- });
152
- }
153
- enqueueTask(task) {
154
- this.obj.sync().queueTask(task);
155
- if (this.neededExecutor()) {
156
- this.execPools.add(this);
87
+ static async for(obj, localVersion, uploadVersion, uploadHeader, syncedBase, createObj, remoteStorage, execPools) {
88
+ const src = await obj.getObjSrcFromLocalAndSyncedBranch(localVersion);
89
+ let needUpload;
90
+ if (syncedBase) {
91
+ const { diff, newSegsPackOrder } = await obj.diffForUploadOf(localVersion);
92
+ needUpload = await diffVerUpload(src, uploadHeader, diff, newSegsPackOrder);
157
93
  }
158
94
  else {
159
- this.obj.scheduleSelfGC();
160
- }
161
- }
162
- async recordTaskCompletion(task) {
163
- this.taskInProcess = undefined;
164
- if (task.type === 'upload') {
165
- await this.obj.markVersionSynced(task.version);
166
- }
167
- await this.obj.sync().recordTaskCompletion(task);
168
- this.broadcastUpSyncEvent(this.obj.objId, task);
95
+ needUpload = await wholeVerUpload(src, uploadHeader, createObj);
96
+ }
97
+ const info = {
98
+ type: 'new-version',
99
+ localVersion,
100
+ uploadVersion,
101
+ baseVersion: syncedBase,
102
+ needUpload
103
+ };
104
+ const objStatus = obj.statusObj();
105
+ await objStatus.recordUploadStart(info);
106
+ return new UploadTask(remoteStorage, obj.objId, objStatus, src, execPools, info, uploadHeader);
169
107
  }
170
108
  neededExecutor() {
171
- const task = this.obj.sync().glanceOnNextTask();
172
- if (!task) {
173
- return;
174
- }
175
- if (task.type !== 'upload') {
176
- return 'fast';
177
- }
178
- if (!task.needUpload) {
179
- return;
180
- }
181
- return executorLabelFor(task.needUpload);
182
- }
183
- removeArchivedVersion(version) {
184
- this.enqueueTask({
185
- type: 'removal',
186
- archivedVersions: version
187
- });
109
+ return (!this.info.needUpload ? undefined : this.execLabel);
188
110
  }
189
- async cancel() {
190
- var _a;
191
- this.isCancelled = true;
192
- await ((_a = this.runningProc) === null || _a === void 0 ? void 0 : _a.catch(noop));
111
+ completion() {
112
+ return this.uploadCompletion.promise;
193
113
  }
194
114
  async process() {
195
- if (this.obj.sync().isSyncDone() || this.isCancelled) {
115
+ if (!this.info.needUpload) {
196
116
  return;
197
117
  }
198
- let task = undefined;
199
118
  try {
200
- if (!this.taskInProcess) {
201
- this.taskInProcess = (await this.obj.sync().getTaskForProcessing());
202
- if (this.isCancelled) {
203
- return;
119
+ const upload = this.info.needUpload;
120
+ if (upload.type === 'ordered-diff') {
121
+ if (upload.transactionId) {
122
+ await this.continueOrderedDiffUpload(upload);
123
+ }
124
+ else {
125
+ await this.startOrderedDiffUpload(upload);
204
126
  }
205
127
  }
206
- task = this.taskInProcess;
207
- }
208
- catch (err) {
209
- await this.logError(err, `ObjUpSync.process fails to get task`);
210
- return;
211
- }
212
- try {
213
- if (task.type === 'upload') {
214
- this.runningProc = this.processUpload(task);
215
- }
216
- else if (task.type === 'removal') {
217
- this.runningProc = this.processRemoval(task);
218
- }
219
- else if (task.type === 'archiving') {
220
- this.runningProc = this.processArchival(task);
128
+ else if (upload.type === 'ordered-whole') {
129
+ if (upload.transactionId) {
130
+ await this.continueOrderedUpload(upload);
131
+ }
132
+ else {
133
+ await this.startOrderedUpload(upload);
134
+ }
221
135
  }
222
136
  else {
223
- throw new Error(`This shouldn't be reached`);
224
- }
225
- try {
226
- await this.runningProc;
137
+ throw new Error(`Unimplemented ${upload.type} upload`);
227
138
  }
228
- finally {
229
- this.runningProc = undefined;
230
- }
231
- }
232
- catch (err) {
233
- await this.logError(err, `From ObjUpSync.process task ${task.type}`);
234
- }
235
- }
236
- async processArchival(task) {
237
- // XXX tell server to archive current version
238
- await this.logError(`Archival of current version is not implemented, yet.`);
239
- await this.recordTaskCompletion(task);
240
- }
241
- async processRemoval(task) {
242
- if (task.currentVersion) {
243
- if (this.obj.objId) {
244
- await this.remoteStorage.deleteObj(this.obj.objId);
139
+ await this.objStatus.recordUploadInterimState(this.info);
140
+ if (this.info.needUpload) {
141
+ this.execPools.add(this);
245
142
  }
246
143
  else {
247
- await this.logError(`Root obj can't be removed`);
144
+ this.uploadCompletion.resolve();
248
145
  }
249
146
  }
250
- if (task.archivedVersions) {
251
- // XXX tell server to remove given archived versions
252
- await this.logError(`Removal of archived version is not implemented, yet.`);
147
+ catch (exc) {
148
+ this.info.needUpload = undefined;
149
+ this.uploadCompletion.reject((0, exceptions_1.makeFSSyncException)(`obj-upload`, {
150
+ message: `Fail to upload local version ${this.info.uploadVersion}`,
151
+ localVersion: this.info.uploadVersion,
152
+ cause: exc
153
+ }));
154
+ await this.objStatus.recordUploadCancellation(this.info);
253
155
  }
254
- await this.recordTaskCompletion(task);
255
- this.obj.scheduleSelfGC();
256
156
  }
257
- async processUpload(task) {
258
- if (task.needUpload) {
259
- if (task.needUpload.allByteOnDisk) {
260
- if (task.transactionId) {
261
- await this.continueUploadOfCompletedVersion(task);
262
- }
263
- else {
264
- await this.startUploadOfCompletedVersion(task);
265
- }
266
- }
157
+ async startOrderedUpload(upload) {
158
+ const maxSegs = this.maxUploadChunk() - upload.header;
159
+ (0, assert_1.assert)(maxSegs > 1);
160
+ const segsToUpload = Math.min(upload.segsLeft, maxSegs);
161
+ const header = await this.headerToUpload();
162
+ let segs = undefined;
163
+ if (segsToUpload > 0) {
164
+ await this.src.segSrc.seek(upload.segsOfs);
165
+ segs = await this.src.segSrc.read(segsToUpload);
166
+ }
167
+ (0, assert_1.assert)(!!segs && (segs.length === segsToUpload));
168
+ const ver = this.info.uploadVersion;
169
+ if (segsToUpload === upload.segsLeft) {
170
+ await this.remoteStorage.saveNewObjVersion(this.objId, { ver, last: true }, undefined, { header, segs });
171
+ this.info.needUpload = undefined;
267
172
  }
268
173
  else {
269
- await this.recordTaskCompletion(task);
174
+ upload.transactionId = await this.remoteStorage.saveNewObjVersion(this.objId, { ver }, undefined, { header, segs });
175
+ if (!upload.transactionId) {
176
+ // XXX should this be runtime exception saying that remote acts badly ?
177
+ throw new Error(`Server didn't start obj saving transaction`);
178
+ }
179
+ upload.header = undefined;
180
+ upload.segsOfs += segsToUpload;
181
+ upload.segsLeft -= segsToUpload;
270
182
  }
271
183
  }
272
- async cancelTransactionIfOpen(uploadInfo) {
273
- const txnId = uploadInfo.transactionId;
274
- if (!txnId) {
275
- return;
276
- }
277
- await this.remoteStorage.cancelTransaction(this.obj.objId, txnId)
278
- .catch((exc) => {
279
- if (!exc.unknownTransaction) {
280
- throw exc;
281
- }
282
- });
184
+ async headerToUpload() {
185
+ return (this.uploadHeader ?
186
+ this.uploadHeader : await this.src.readHeader());
283
187
  }
284
- async startUploadOfCompletedVersion(uploadInfo) {
285
- const src = await this.obj.getObjSrc(uploadInfo.version);
286
- const header = await src.readHeader();
287
- const maxChunkLen = (this.remoteStorage.maxChunkSize ?
288
- this.remoteStorage.maxChunkSize - header.length : MAX_CHUNK_SIZE);
289
- assert_1.assert(maxChunkLen > 0);
290
- const srcLen = (await src.segSrc.getSize()).size;
291
- if (srcLen <= maxChunkLen) {
292
- const segs = await src.segSrc.read(maxChunkLen);
293
- await this.uploadWholeVersion(!!uploadInfo.createObj, uploadInfo.version, header, segs);
294
- uploadInfo.needUpload = undefined;
295
- await this.recordTaskCompletion(uploadInfo);
188
+ async startOrderedDiffUpload(upload) {
189
+ const diff = buffer_utils_1.utf8.pack(JSON.stringify(upload.diff));
190
+ const maxSegs = this.maxUploadChunk() - upload.header - diff.length;
191
+ (0, assert_1.assert)(maxSegs > 1);
192
+ const header = await this.headerToUpload();
193
+ const ver = this.info.uploadVersion;
194
+ if (upload.newSegsLeft.length === 0) {
195
+ await this.remoteStorage.saveNewObjVersion(this.objId, { ver, last: true }, undefined, { header, diff });
196
+ this.info.needUpload = undefined;
296
197
  }
297
198
  else {
298
- const segs = await src.segSrc.read(maxChunkLen);
299
- uploadInfo.transactionId = await this.startUploadTransaction(!!uploadInfo.createObj, uploadInfo.version, header, segs);
300
- uploadInfo.needUpload.segs = [
301
- { ofs: segs.length, len: srcLen - segs.length }
302
- ];
303
- await this.obj.sync().recordInterimStateOfCurrentTask(uploadInfo);
304
- this.execPools.add(this);
199
+ upload.transactionId = await this.remoteStorage.saveNewObjVersion(this.objId, { ver }, undefined, { header, diff });
200
+ if (!upload.transactionId) {
201
+ // XXX should this be runtime exception saying that remote acts badly ?
202
+ throw new Error(`Server didn't start obj saving transaction`);
203
+ }
204
+ upload.header = undefined;
305
205
  }
306
206
  }
307
- async uploadWholeVersion(create, ver, header, segs) {
308
- const opts = {
309
- header: header.length, ver, last: true
310
- };
311
- if (create) {
312
- opts.create = true;
313
- }
314
- const bytes = (segs ? [header, segs] : [header]);
315
- await this.remoteStorage.saveNewObjVersion(this.obj.objId, bytes, opts, undefined);
207
+ maxUploadChunk() {
208
+ return (this.remoteStorage.maxChunkSize ?
209
+ this.remoteStorage.maxChunkSize : MAX_CHUNK_SIZE);
316
210
  }
317
- async startUploadTransaction(create, ver, header, segs) {
318
- const opts = {
319
- header: header.length, ver
320
- };
321
- if (create) {
322
- opts.create = true;
211
+ async continueOrderedUpload(upload) {
212
+ const segsToUpload = Math.min(upload.segsLeft, this.maxUploadChunk());
213
+ await this.src.segSrc.seek(upload.segsOfs);
214
+ const segs = await this.src.segSrc.read(segsToUpload);
215
+ (0, assert_1.assert)(!!segs && (segs.length === segsToUpload));
216
+ const ofs = upload.segsOfs;
217
+ const trans = upload.transactionId;
218
+ if (segsToUpload === upload.segsLeft) {
219
+ await this.remoteStorage.saveNewObjVersion(this.objId, undefined, { ofs, trans, last: true }, { segs });
220
+ this.info.needUpload = undefined;
323
221
  }
324
- const txnId = await this.remoteStorage.saveNewObjVersion(this.obj.objId, [header, segs], opts, undefined);
325
- if (!txnId) {
326
- throw new Error(`Server didn't start obj saving transaction`);
222
+ else {
223
+ await this.remoteStorage.saveNewObjVersion(this.objId, undefined, { ofs, trans }, { segs });
224
+ upload.segsOfs += segsToUpload;
225
+ upload.segsLeft -= segsToUpload;
327
226
  }
328
- return txnId;
329
227
  }
330
- async continueUploadOfCompletedVersion(uploadInfo) {
331
- const section = uploadInfo.needUpload.segs[0];
332
- const lenToRead = Math.min(section.len, (this.remoteStorage.maxChunkSize ?
333
- this.remoteStorage.maxChunkSize : MAX_CHUNK_SIZE));
334
- const src = await this.obj.getObjSrc(uploadInfo.version);
335
- await src.segSrc.seek(section.ofs);
336
- const segs = await src.segSrc.read(lenToRead);
337
- if (!segs || (segs.length < lenToRead)) {
338
- throw new Error(`Unexpected end of obj source`);
339
- }
340
- const last = ((uploadInfo.needUpload.segs.length === 1) &&
341
- (segs.length === section.len));
342
- if (last) {
343
- const opts = {
344
- ofs: section.ofs,
345
- trans: uploadInfo.transactionId,
346
- last
347
- };
348
- await this.remoteStorage.saveNewObjVersion(this.obj.objId, segs, undefined, opts);
349
- uploadInfo.needUpload = undefined;
350
- await this.recordTaskCompletion(uploadInfo);
228
+ async continueOrderedDiffUpload(upload) {
229
+ const maxSegs = this.maxUploadChunk();
230
+ const segInfo = upload.newSegsLeft[0];
231
+ (0, assert_1.assert)(!!segInfo);
232
+ const len = Math.min(maxSegs, segInfo.len);
233
+ const segs = await this.src.segSrc.read(len);
234
+ (0, assert_1.assert)(!!segs && (segs.length === len));
235
+ if (segInfo.len > len) {
236
+ upload.newSegsLeft.splice(1, 0, {
237
+ len: segInfo.len - len,
238
+ thisVerOfs: segInfo.thisVerOfs + len
239
+ });
240
+ }
241
+ const ofs = segInfo.thisVerOfs;
242
+ const trans = upload.transactionId;
243
+ if (upload.newSegsLeft.length === 1) {
244
+ await this.remoteStorage.saveNewObjVersion(this.objId, undefined, { ofs, trans, last: true }, { segs });
245
+ this.info.needUpload = undefined;
351
246
  }
352
247
  else {
353
- const opts = {
354
- ofs: section.ofs,
355
- trans: uploadInfo.transactionId
356
- };
357
- await this.remoteStorage.saveNewObjVersion(this.obj.objId, segs, undefined, opts);
358
- if (segs.length === section.len) {
359
- uploadInfo.needUpload.segs.splice(0, 1);
360
- }
361
- else {
362
- section.ofs += segs.length;
363
- section.len -= segs.length;
364
- }
365
- this.execPools.add(this);
248
+ await this.remoteStorage.saveNewObjVersion(this.objId, undefined, { ofs, trans }, { segs });
249
+ upload.newSegsLeft.splice(0, 1);
366
250
  }
367
251
  }
252
+ cancel() {
253
+ // XXX
254
+ throw new Error("UploadTask.cancel() not implemented.");
255
+ }
256
+ }
257
+ Object.freeze(UploadTask.prototype);
258
+ Object.freeze(UploadTask);
259
+ async function wholeVerUpload(src, uploadHeader, createObj) {
260
+ const header = await expectedHeaderLen(src, uploadHeader);
261
+ const segsSize = (await src.segSrc.getSize()).size;
262
+ return {
263
+ type: 'ordered-whole',
264
+ createObj,
265
+ header,
266
+ segsOfs: 0,
267
+ segsLeft: segsSize
268
+ };
269
+ }
270
+ async function diffVerUpload(src, uploadHeader, diff, newSegsPackOrder) {
271
+ const header = await expectedHeaderLen(src, uploadHeader);
272
+ return {
273
+ type: 'ordered-diff',
274
+ diff,
275
+ newSegsLeft: newSegsPackOrder,
276
+ header
277
+ };
278
+ }
279
+ async function expectedHeaderLen(src, uploadHeader) {
280
+ return (uploadHeader ?
281
+ uploadHeader.length : (await src.readHeader()).length);
282
+ }
283
+ function uploadSize(info) {
284
+ if (info.type === 'ordered-whole') {
285
+ return info.header + info.segsLeft;
286
+ }
287
+ else if (info.type === 'ordered-diff') {
288
+ let uploadSize = info.header;
289
+ for (const { len } of info.newSegsLeft) {
290
+ uploadSize += len;
291
+ }
292
+ return uploadSize;
293
+ }
294
+ else {
295
+ throw new Error(`Unimplemented upload type ${info.type}`);
296
+ }
297
+ }
298
+ function executorLabelFor(info) {
299
+ return ((uploadSize(info) <= MAX_FAST_UPLOAD) ? 'fast' : 'long');
368
300
  }
369
- Object.freeze(ObjUpSync.prototype);
370
- Object.freeze(ObjUpSync);
371
301
  function noop() { }
372
302
  Object.freeze(exports);
@@ -0,0 +1,16 @@
1
+ declare type WritableFS = web3n.files.WritableFS;
2
+ export declare class AppDataFolders {
3
+ private readonly fs;
4
+ private writingSync;
5
+ private syncFolderProc;
6
+ private constructor();
7
+ static make(rootFS: WritableFS): Promise<AppDataFolders>;
8
+ getOrMake(folder: string): Promise<WritableFS>;
9
+ private syncP;
10
+ private makeSyncedFolder;
11
+ private syncBeforeChange;
12
+ private uploadAfterCreationOf;
13
+ private startSyncProc;
14
+ stopSync(): void;
15
+ }
16
+ export {};