core-3nweb-client-lib 0.26.0 → 0.27.1

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 +204 -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 +3 -0
  77. package/build/ipc-via-protobuf/connector-clients-side.js +61 -24
  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 +15 -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 -39
  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
@@ -17,356 +17,280 @@
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);
108
- }
53
+ throw new Error('UpSyncer.removeCurrentVersionOf() not implemented');
54
+ // const objUploads = this.getOrMakeUploadsFor(obj);
55
+ // XXX is removal set in this older code? This may need to change anyway
56
+ // if (objUploads.neededExecutor()) {
57
+ // this.execPools.add(objUploads);
58
+ // }
59
+ }
60
+ async uploadFromDisk(obj, localVersion, uploadVersion, uploadHeader, syncedBase, createOnRemote) {
61
+ const task = await UploadTask.for(obj, localVersion, uploadVersion, uploadHeader, syncedBase, createOnRemote, this.remoteStorage, this.execPools);
62
+ this.execPools.add(task);
63
+ await task.completion();
109
64
  }
110
65
  }
111
66
  exports.UpSyncer = UpSyncer;
112
67
  Object.freeze(UpSyncer.prototype);
113
68
  Object.freeze(UpSyncer);
114
- class ObjUpSync {
115
- constructor(obj, remoteStorage, execPools, logError, broadcastUpSyncEvent) {
116
- this.obj = obj;
69
+ class UploadTask {
70
+ constructor(remoteStorage, objId, objStatus, src, execPools, info, uploadHeader) {
117
71
  this.remoteStorage = remoteStorage;
72
+ this.objId = objId;
73
+ this.objStatus = objStatus;
74
+ this.src = src;
118
75
  this.execPools = execPools;
119
- this.logError = logError;
120
- this.broadcastUpSyncEvent = broadcastUpSyncEvent;
121
- this.taskInProcess = undefined;
122
- this.isCancelled = false;
123
- this.runningProc = undefined;
76
+ this.info = info;
77
+ this.uploadHeader = uploadHeader;
78
+ this.uploadCompletion = (0, deferred_1.defer)();
79
+ this.execLabel = executorLabelFor(this.info.needUpload);
124
80
  Object.seal(this);
125
81
  }
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);
82
+ static async for(obj, localVersion, uploadVersion, uploadHeader, syncedBase, createObj, remoteStorage, execPools) {
83
+ const src = await obj.getObjSrcFromLocalAndSyncedBranch(localVersion);
84
+ let needUpload;
85
+ if (syncedBase) {
86
+ const { diff, newSegsPackOrder } = await obj.diffForUploadOf(localVersion);
87
+ needUpload = await diffVerUpload(src, uploadHeader, diff, newSegsPackOrder);
157
88
  }
158
89
  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);
90
+ needUpload = await wholeVerUpload(src, uploadHeader, createObj);
166
91
  }
167
- await this.obj.sync().recordTaskCompletion(task);
168
- this.broadcastUpSyncEvent(this.obj.objId, task);
92
+ const info = {
93
+ localVersion,
94
+ uploadVersion,
95
+ baseVersion: syncedBase,
96
+ needUpload
97
+ };
98
+ const objStatus = obj.statusObj();
99
+ await objStatus.recordUploadStart(info);
100
+ return new UploadTask(remoteStorage, obj.objId, objStatus, src, execPools, info, uploadHeader);
169
101
  }
170
102
  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
- });
103
+ return (!this.info.needUpload ? undefined : this.execLabel);
188
104
  }
189
- async cancel() {
190
- var _a;
191
- this.isCancelled = true;
192
- await ((_a = this.runningProc) === null || _a === void 0 ? void 0 : _a.catch(noop));
105
+ completion() {
106
+ return this.uploadCompletion.promise;
193
107
  }
194
108
  async process() {
195
- if (this.obj.sync().isSyncDone() || this.isCancelled) {
109
+ if (!this.info.needUpload) {
196
110
  return;
197
111
  }
198
- let task = undefined;
199
112
  try {
200
- if (!this.taskInProcess) {
201
- this.taskInProcess = (await this.obj.sync().getTaskForProcessing());
202
- if (this.isCancelled) {
203
- return;
113
+ const upload = this.info.needUpload;
114
+ if (upload.type === 'ordered-diff') {
115
+ if (upload.transactionId) {
116
+ await this.continueOrderedDiffUpload(upload);
117
+ }
118
+ else {
119
+ await this.startOrderedDiffUpload(upload);
204
120
  }
205
121
  }
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);
122
+ else if (upload.type === 'ordered-whole') {
123
+ if (upload.transactionId) {
124
+ await this.continueOrderedUpload(upload);
125
+ }
126
+ else {
127
+ await this.startOrderedUpload(upload);
128
+ }
221
129
  }
222
130
  else {
223
- throw new Error(`This shouldn't be reached`);
224
- }
225
- try {
226
- await this.runningProc;
227
- }
228
- finally {
229
- this.runningProc = undefined;
131
+ throw new Error(`Unimplemented ${upload.type} upload`);
230
132
  }
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);
133
+ await this.objStatus.recordUploadInterimState(this.info);
134
+ if (this.info.needUpload) {
135
+ this.execPools.add(this);
245
136
  }
246
137
  else {
247
- await this.logError(`Root obj can't be removed`);
138
+ this.uploadCompletion.resolve();
248
139
  }
249
140
  }
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.`);
141
+ catch (exc) {
142
+ this.info.needUpload = undefined;
143
+ this.uploadCompletion.reject((0, exceptions_1.makeFSSyncException)(`obj-upload`, {
144
+ message: `Fail to upload local version ${this.info.uploadVersion}`,
145
+ localVersion: this.info.uploadVersion,
146
+ cause: exc
147
+ }));
148
+ await this.objStatus.recordUploadCancellation(this.info);
253
149
  }
254
- await this.recordTaskCompletion(task);
255
- this.obj.scheduleSelfGC();
256
150
  }
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
- }
151
+ async startOrderedUpload(upload) {
152
+ const maxSegs = this.maxUploadChunk() - upload.header;
153
+ (0, assert_1.assert)(maxSegs > 1);
154
+ const segsToUpload = Math.min(upload.segsLeft, maxSegs);
155
+ const header = await this.headerToUpload();
156
+ let segs = undefined;
157
+ if (segsToUpload > 0) {
158
+ await this.src.segSrc.seek(upload.segsOfs);
159
+ segs = await this.src.segSrc.read(segsToUpload);
160
+ }
161
+ (0, assert_1.assert)(!!segs && (segs.length === segsToUpload));
162
+ const ver = this.info.uploadVersion;
163
+ if (segsToUpload === upload.segsLeft) {
164
+ await this.remoteStorage.saveNewObjVersion(this.objId, { ver, last: true }, undefined, { header, segs });
165
+ this.info.needUpload = undefined;
267
166
  }
268
167
  else {
269
- await this.recordTaskCompletion(task);
168
+ upload.transactionId = await this.remoteStorage.saveNewObjVersion(this.objId, { ver }, undefined, { header, segs });
169
+ if (!upload.transactionId) {
170
+ // XXX should this be runtime exception saying that remote acts badly ?
171
+ throw new Error(`Server didn't start obj saving transaction`);
172
+ }
173
+ upload.header = undefined;
174
+ upload.segsOfs += segsToUpload;
175
+ upload.segsLeft -= segsToUpload;
270
176
  }
271
177
  }
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
- });
178
+ async headerToUpload() {
179
+ return (this.uploadHeader ?
180
+ this.uploadHeader : await this.src.readHeader());
283
181
  }
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);
182
+ async startOrderedDiffUpload(upload) {
183
+ const diff = buffer_utils_1.utf8.pack(JSON.stringify(upload.diff));
184
+ const maxSegs = this.maxUploadChunk() - upload.header - diff.length;
185
+ (0, assert_1.assert)(maxSegs > 1);
186
+ const header = await this.headerToUpload();
187
+ const ver = this.info.uploadVersion;
188
+ if (upload.newSegsLeft.length === 0) {
189
+ await this.remoteStorage.saveNewObjVersion(this.objId, { ver, last: true }, undefined, { header, diff });
190
+ this.info.needUpload = undefined;
296
191
  }
297
192
  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);
193
+ upload.transactionId = await this.remoteStorage.saveNewObjVersion(this.objId, { ver }, undefined, { header, diff });
194
+ if (!upload.transactionId) {
195
+ // XXX should this be runtime exception saying that remote acts badly ?
196
+ throw new Error(`Server didn't start obj saving transaction`);
197
+ }
198
+ upload.header = undefined;
305
199
  }
306
200
  }
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);
201
+ maxUploadChunk() {
202
+ return (this.remoteStorage.maxChunkSize ?
203
+ this.remoteStorage.maxChunkSize : MAX_CHUNK_SIZE);
316
204
  }
317
- async startUploadTransaction(create, ver, header, segs) {
318
- const opts = {
319
- header: header.length, ver
320
- };
321
- if (create) {
322
- opts.create = true;
205
+ async continueOrderedUpload(upload) {
206
+ const segsToUpload = Math.min(upload.segsLeft, this.maxUploadChunk());
207
+ await this.src.segSrc.seek(upload.segsOfs);
208
+ const segs = await this.src.segSrc.read(segsToUpload);
209
+ (0, assert_1.assert)(!!segs && (segs.length === segsToUpload));
210
+ const ofs = upload.segsOfs;
211
+ const trans = upload.transactionId;
212
+ if (segsToUpload === upload.segsLeft) {
213
+ await this.remoteStorage.saveNewObjVersion(this.objId, undefined, { ofs, trans, last: true }, { segs });
214
+ this.info.needUpload = undefined;
323
215
  }
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`);
216
+ else {
217
+ await this.remoteStorage.saveNewObjVersion(this.objId, undefined, { ofs, trans }, { segs });
218
+ upload.segsOfs += segsToUpload;
219
+ upload.segsLeft -= segsToUpload;
327
220
  }
328
- return txnId;
329
221
  }
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);
222
+ async continueOrderedDiffUpload(upload) {
223
+ const maxSegs = this.maxUploadChunk();
224
+ const segInfo = upload.newSegsLeft[0];
225
+ (0, assert_1.assert)(!!segInfo);
226
+ const len = Math.min(maxSegs, segInfo.len);
227
+ const segs = await this.src.segSrc.read(len);
228
+ (0, assert_1.assert)(!!segs && (segs.length === len));
229
+ if (segInfo.len > len) {
230
+ upload.newSegsLeft.splice(1, 0, {
231
+ len: segInfo.len - len,
232
+ thisVerOfs: segInfo.thisVerOfs + len
233
+ });
234
+ }
235
+ const ofs = segInfo.thisVerOfs;
236
+ const trans = upload.transactionId;
237
+ if (upload.newSegsLeft.length === 1) {
238
+ await this.remoteStorage.saveNewObjVersion(this.objId, undefined, { ofs, trans, last: true }, { segs });
239
+ this.info.needUpload = undefined;
351
240
  }
352
241
  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);
242
+ await this.remoteStorage.saveNewObjVersion(this.objId, undefined, { ofs, trans }, { segs });
243
+ upload.newSegsLeft.splice(0, 1);
244
+ }
245
+ }
246
+ cancel() {
247
+ // XXX
248
+ throw new Error("UploadTask.cancel() not implemented.");
249
+ }
250
+ }
251
+ Object.freeze(UploadTask.prototype);
252
+ Object.freeze(UploadTask);
253
+ async function wholeVerUpload(src, uploadHeader, createObj) {
254
+ const header = await expectedHeaderLen(src, uploadHeader);
255
+ const segsSize = (await src.segSrc.getSize()).size;
256
+ return {
257
+ type: 'ordered-whole',
258
+ createObj,
259
+ header,
260
+ segsOfs: 0,
261
+ segsLeft: segsSize
262
+ };
263
+ }
264
+ async function diffVerUpload(src, uploadHeader, diff, newSegsPackOrder) {
265
+ const header = await expectedHeaderLen(src, uploadHeader);
266
+ return {
267
+ type: 'ordered-diff',
268
+ diff,
269
+ newSegsLeft: newSegsPackOrder,
270
+ header
271
+ };
272
+ }
273
+ async function expectedHeaderLen(src, uploadHeader) {
274
+ return (uploadHeader ?
275
+ uploadHeader.length : (await src.readHeader()).length);
276
+ }
277
+ function uploadSize(info) {
278
+ if (info.type === 'ordered-whole') {
279
+ return info.header + info.segsLeft;
280
+ }
281
+ else if (info.type === 'ordered-diff') {
282
+ let uploadSize = info.header;
283
+ for (const { len } of info.newSegsLeft) {
284
+ uploadSize += len;
366
285
  }
286
+ return uploadSize;
287
+ }
288
+ else {
289
+ throw new Error(`Unimplemented upload type ${info.type}`);
367
290
  }
368
291
  }
369
- Object.freeze(ObjUpSync.prototype);
370
- Object.freeze(ObjUpSync);
292
+ function executorLabelFor(info) {
293
+ return ((uploadSize(info) <= MAX_FAST_UPLOAD) ? 'fast' : 'long');
294
+ }
371
295
  function noop() { }
372
296
  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 {};