core-3nweb-client-lib 0.25.6 → 0.27.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (215) hide show
  1. package/README.md +2 -2
  2. package/build/api-defs/asmail.d.ts +1 -1
  3. package/build/api-defs/files.d.ts +282 -70
  4. package/build/core/app-files.js +7 -7
  5. package/build/core/asmail/config/common.js +4 -4
  6. package/build/core/asmail/config/index.js +2 -2
  7. package/build/core/asmail/config/published-intro-key.js +1 -1
  8. package/build/core/asmail/delivery/common.js +7 -7
  9. package/build/core/asmail/delivery/index.js +7 -6
  10. package/build/core/asmail/delivery/msg.js +8 -7
  11. package/build/core/asmail/delivery/per-recipient-wip.js +3 -3
  12. package/build/core/asmail/inbox/attachments/fs.js +11 -1
  13. package/build/core/asmail/inbox/cached-msgs.js +3 -3
  14. package/build/core/asmail/inbox/inbox-events.js +5 -4
  15. package/build/core/asmail/inbox/index.js +12 -12
  16. package/build/core/asmail/inbox/msg-downloader.js +3 -3
  17. package/build/core/asmail/inbox/msg-indexing.js +4 -4
  18. package/build/core/asmail/inbox/msg-on-disk.js +7 -7
  19. package/build/core/asmail/index.d.ts +3 -3
  20. package/build/core/asmail/index.js +13 -8
  21. package/build/core/asmail/key-verification.js +5 -5
  22. package/build/core/asmail/keyring/common.js +7 -6
  23. package/build/core/asmail/keyring/correspondent-keys.js +8 -7
  24. package/build/core/asmail/keyring/id-to-email-map.js +2 -1
  25. package/build/core/asmail/keyring/index.d.ts +7 -8
  26. package/build/core/asmail/keyring/index.js +15 -14
  27. package/build/core/asmail/keyring/keyring-storage.js +4 -3
  28. package/build/core/asmail/msg/opener.js +3 -3
  29. package/build/core/asmail/msg/packer.js +13 -13
  30. package/build/core/asmail/sending-params/own-params.js +4 -4
  31. package/build/core/asmail/sending-params/params-from-others.js +3 -3
  32. package/build/core/id-manager.js +8 -5
  33. package/build/core/index.d.ts +2 -1
  34. package/build/core/index.js +14 -14
  35. package/build/core/sign-in.d.ts +5 -4
  36. package/build/core/sign-in.js +12 -14
  37. package/build/core/sign-up.d.ts +1 -0
  38. package/build/core/sign-up.js +15 -11
  39. package/build/core/storage/common/json-saving.d.ts +21 -0
  40. package/build/core/storage/common/json-saving.js +82 -0
  41. package/build/core/storage/common/obj-info-file.d.ts +51 -0
  42. package/build/core/storage/common/obj-info-file.js +153 -5
  43. package/build/core/storage/common/utils.d.ts +2 -0
  44. package/build/core/storage/common/utils.js +32 -0
  45. package/build/core/storage/index.d.ts +3 -17
  46. package/build/core/storage/index.js +57 -77
  47. package/build/core/storage/local/obj-files-gc.d.ts +2 -0
  48. package/build/core/storage/local/obj-files-gc.js +53 -39
  49. package/build/core/storage/local/obj-files.d.ts +6 -9
  50. package/build/core/storage/local/obj-files.js +16 -19
  51. package/build/core/storage/local/obj-status.d.ts +20 -30
  52. package/build/core/storage/local/obj-status.js +46 -113
  53. package/build/core/storage/local/storage.d.ts +15 -5
  54. package/build/core/storage/local/storage.js +37 -18
  55. package/build/core/storage/synced/downloader.js +7 -6
  56. package/build/core/storage/synced/obj-files-gc.d.ts +6 -1
  57. package/build/core/storage/synced/obj-files-gc.js +106 -13
  58. package/build/core/storage/synced/obj-files.d.ts +46 -47
  59. package/build/core/storage/synced/obj-files.js +207 -154
  60. package/build/core/storage/synced/obj-status.d.ts +103 -42
  61. package/build/core/storage/synced/obj-status.js +525 -137
  62. package/build/core/storage/synced/remote-events.d.ts +11 -12
  63. package/build/core/storage/synced/remote-events.js +80 -57
  64. package/build/core/storage/synced/storage.d.ts +24 -5
  65. package/build/core/storage/synced/storage.js +123 -38
  66. package/build/core/storage/synced/upload-header-file.d.ts +4 -0
  67. package/build/core/storage/synced/upload-header-file.js +64 -0
  68. package/build/core/storage/synced/upsyncer.d.ts +15 -9
  69. package/build/core/storage/synced/upsyncer.js +219 -246
  70. package/build/core/storage/system-folders/apps-data.d.ts +16 -0
  71. package/build/core/storage/system-folders/apps-data.js +110 -0
  72. package/build/core/storage/system-folders/index.d.ts +18 -0
  73. package/build/core/storage/system-folders/index.js +77 -0
  74. package/build/core-ipc/common-caps.js +3 -3
  75. package/build/core-ipc/generic.js +8 -8
  76. package/build/core-ipc/startup-caps.js +2 -2
  77. package/build/cryptors.js +6 -2
  78. package/build/ipc-via-protobuf/asmail-cap.js +67 -83
  79. package/build/ipc-via-protobuf/bytes.js +16 -17
  80. package/build/ipc-via-protobuf/connector-clients-side.d.ts +3 -0
  81. package/build/ipc-via-protobuf/connector-clients-side.js +62 -25
  82. package/build/ipc-via-protobuf/connector-services-side.js +10 -10
  83. package/build/ipc-via-protobuf/connector.js +4 -4
  84. package/build/ipc-via-protobuf/file.d.ts +48 -12
  85. package/build/ipc-via-protobuf/file.js +476 -120
  86. package/build/ipc-via-protobuf/fs.d.ts +8 -0
  87. package/build/ipc-via-protobuf/fs.js +592 -159
  88. package/build/ipc-via-protobuf/log-cap.js +2 -2
  89. package/build/ipc-via-protobuf/mailerid.js +3 -3
  90. package/build/ipc-via-protobuf/protobuf-msg.d.ts +1 -0
  91. package/build/ipc-via-protobuf/protobuf-msg.js +11 -7
  92. package/build/ipc-via-protobuf/startup-cap.js +23 -23
  93. package/build/ipc-via-protobuf/storage-cap.js +12 -12
  94. package/build/ipc.js +7 -2
  95. package/build/lib-client/3nstorage/exceptions.d.ts +12 -8
  96. package/build/lib-client/3nstorage/exceptions.js +31 -10
  97. package/build/lib-client/3nstorage/service.d.ts +16 -2
  98. package/build/lib-client/3nstorage/service.js +109 -39
  99. package/build/lib-client/3nstorage/util/file-based-json.d.ts +2 -1
  100. package/build/lib-client/3nstorage/util/file-based-json.js +1 -1
  101. package/build/lib-client/3nstorage/xsp-fs/attrs.js +17 -17
  102. package/build/lib-client/3nstorage/xsp-fs/common.d.ts +52 -14
  103. package/build/lib-client/3nstorage/xsp-fs/common.js +31 -16
  104. package/build/lib-client/3nstorage/xsp-fs/file-node.d.ts +1 -0
  105. package/build/lib-client/3nstorage/xsp-fs/file-node.js +18 -14
  106. package/build/lib-client/3nstorage/xsp-fs/file.d.ts +31 -6
  107. package/build/lib-client/3nstorage/xsp-fs/file.js +74 -23
  108. package/build/lib-client/3nstorage/xsp-fs/folder-node-serialization.js +4 -4
  109. package/build/lib-client/3nstorage/xsp-fs/folder-node.d.ts +24 -11
  110. package/build/lib-client/3nstorage/xsp-fs/folder-node.js +599 -189
  111. package/build/lib-client/3nstorage/xsp-fs/fs.d.ts +45 -9
  112. package/build/lib-client/3nstorage/xsp-fs/fs.js +326 -74
  113. package/build/lib-client/3nstorage/xsp-fs/link-node.d.ts +1 -0
  114. package/build/lib-client/3nstorage/xsp-fs/link-node.js +7 -2
  115. package/build/lib-client/3nstorage/xsp-fs/node-in-fs.d.ts +30 -20
  116. package/build/lib-client/3nstorage/xsp-fs/node-in-fs.js +239 -106
  117. package/build/lib-client/3nstorage/xsp-fs/node-persistence.d.ts +1 -1
  118. package/build/lib-client/3nstorage/xsp-fs/node-persistence.js +18 -19
  119. package/build/lib-client/3nstorage/xsp-fs/xsp-payload-v1.js +5 -5
  120. package/build/lib-client/3nstorage/xsp-fs/xsp-payload-v2.js +56 -56
  121. package/build/lib-client/3nweb-signup.js +4 -4
  122. package/build/lib-client/asmail/recipient.js +15 -15
  123. package/build/lib-client/asmail/sender.js +22 -22
  124. package/build/lib-client/asmail/service-config.js +3 -3
  125. package/build/lib-client/cryptor/cryptor-in-worker.js +19 -17
  126. package/build/lib-client/cryptor/cryptor-wasm.js +1 -1
  127. package/build/lib-client/cryptor/cryptor.js +4 -2
  128. package/build/lib-client/cryptor/cryptor.wasm +0 -0
  129. package/build/lib-client/cryptor/in-proc-js.js +1 -1
  130. package/build/lib-client/cryptor/in-proc-wasm.js +7 -7
  131. package/build/lib-client/cryptor/worker-js.js +2 -2
  132. package/build/lib-client/cryptor/worker-wasm.js +2 -2
  133. package/build/lib-client/files-select.js +1 -1
  134. package/build/lib-client/files.d.ts +1 -1
  135. package/build/lib-client/files.js +71 -4
  136. package/build/lib-client/fs-collection.js +3 -2
  137. package/build/lib-client/fs-sync-utils.d.ts +5 -0
  138. package/build/lib-client/fs-sync-utils.js +61 -0
  139. package/build/lib-client/fs-view.d.ts +14 -0
  140. package/build/lib-client/fs-view.js +33 -0
  141. package/build/lib-client/key-derivation.js +1 -1
  142. package/build/lib-client/local-files/dev-file-sink.js +9 -9
  143. package/build/lib-client/local-files/dev-file-src.js +2 -2
  144. package/build/lib-client/local-files/device-fs.d.ts +1 -1
  145. package/build/lib-client/local-files/device-fs.js +56 -54
  146. package/build/lib-client/logging/log-to-file.d.ts +1 -1
  147. package/build/lib-client/logging/log-to-file.js +11 -11
  148. package/build/lib-client/mailer-id/login.js +7 -7
  149. package/build/lib-client/mailer-id/provisioner.js +12 -12
  150. package/build/lib-client/objs-on-disk/file-writing-proc.js +5 -5
  151. package/build/lib-client/objs-on-disk/obj-folders.js +33 -33
  152. package/build/lib-client/objs-on-disk/obj-on-disk.d.ts +13 -2
  153. package/build/lib-client/objs-on-disk/obj-on-disk.js +24 -9
  154. package/build/lib-client/request-utils.d.ts +1 -0
  155. package/build/lib-client/request-utils.js +14 -14
  156. package/build/lib-client/server-events.d.ts +3 -3
  157. package/build/lib-client/server-events.js +12 -10
  158. package/build/lib-client/service-locator.js +10 -10
  159. package/build/lib-client/user-with-mid-session.js +7 -7
  160. package/build/lib-client/user-with-pkl-session.js +25 -25
  161. package/build/lib-client/ws-utils.js +3 -3
  162. package/build/lib-common/async-cryptor-wrap.js +4 -4
  163. package/build/lib-common/async-fs-node.d.ts +5 -3
  164. package/build/lib-common/async-fs-node.js +19 -18
  165. package/build/lib-common/byte-streaming/pipe.js +1 -1
  166. package/build/lib-common/byte-streaming/wrapping.js +17 -17
  167. package/build/lib-common/canonical-address.js +1 -1
  168. package/build/lib-common/exceptions/error.d.ts +1 -0
  169. package/build/lib-common/exceptions/error.js +7 -6
  170. package/build/lib-common/exceptions/file.js +10 -1
  171. package/build/lib-common/ipc/generic-ipc.js +2 -2
  172. package/build/lib-common/ipc/ws-ipc.js +2 -2
  173. package/build/lib-common/json-utils.js +2 -1
  174. package/build/lib-common/mid-sigs-NaCl-Ed.js +14 -14
  175. package/build/lib-common/objs-on-disk/file-layout.d.ts +19 -0
  176. package/build/lib-common/objs-on-disk/file-layout.js +130 -12
  177. package/build/lib-common/objs-on-disk/obj-file.d.ts +13 -2
  178. package/build/lib-common/objs-on-disk/obj-file.js +99 -37
  179. package/build/lib-common/objs-on-disk/utils.d.ts +1 -0
  180. package/build/lib-common/objs-on-disk/utils.js +4 -4
  181. package/build/lib-common/objs-on-disk/v1-obj-file-format.js +14 -14
  182. package/build/lib-common/processes/deferred.d.ts +6 -0
  183. package/build/lib-common/processes/deferred.js +30 -0
  184. package/build/lib-common/processes/labelled-exec-pools.d.ts +33 -0
  185. package/build/lib-common/processes/labelled-exec-pools.js +141 -0
  186. package/build/lib-common/processes/pressure.d.ts +7 -0
  187. package/build/lib-common/processes/pressure.js +56 -0
  188. package/build/lib-common/processes/sleep.d.ts +1 -0
  189. package/build/lib-common/processes/sleep.js +26 -0
  190. package/build/lib-common/{processes.d.ts → processes/synced.d.ts} +0 -40
  191. package/build/lib-common/{processes.js → processes/synced.js} +187 -204
  192. package/build/lib-common/processes/timeout.d.ts +1 -0
  193. package/build/lib-common/processes/timeout.js +51 -0
  194. package/build/lib-common/random-node.js +7 -7
  195. package/build/lib-common/service-api/3nstorage/owner.d.ts +100 -39
  196. package/build/lib-common/service-api/3nstorage/owner.js +85 -42
  197. package/build/lib-common/service-api/asmail/delivery.js +2 -2
  198. package/build/lib-common/service-api/asmail/retrieval.js +1 -1
  199. package/build/lib-common/timed-cache.d.ts +1 -0
  200. package/build/lib-common/timed-non-weak-cache.d.ts +1 -0
  201. package/build/lib-common/timed-non-weak-cache.js +11 -0
  202. package/build/lib-common/utils-for-observables.d.ts +15 -1
  203. package/build/lib-common/utils-for-observables.js +70 -19
  204. package/build/lib-common/weak-cache.d.ts +1 -0
  205. package/build/lib-common/weak-cache.js +12 -1
  206. package/build/lib-index.d.ts +2 -1
  207. package/build/lib-index.js +10 -7
  208. package/build/protos/asmail.proto.js +12912 -7127
  209. package/build/protos/file.proto.js +4848 -2399
  210. package/build/protos/fs.proto.js +9230 -3445
  211. package/package.json +8 -7
  212. package/protos/file.proto +91 -11
  213. package/protos/fs.proto +107 -8
  214. package/build/core/storage/synced/upsync-status.d.ts +0 -41
  215. package/build/core/storage/synced/upsync-status.js +0 -158
@@ -17,168 +17,101 @@
17
17
  */
18
18
  Object.defineProperty(exports, "__esModule", { value: true });
19
19
  exports.ObjStatus = void 0;
20
- const fs = require("../../../lib-common/async-fs-node");
21
- const processes_1 = require("../../../lib-common/processes");
22
20
  const path_1 = require("path");
23
21
  const exceptions_1 = require("../../../lib-client/3nstorage/exceptions");
24
22
  const obj_info_file_1 = require("../common/obj-info-file");
23
+ const json_saving_1 = require("../common/json-saving");
24
+ const obj_info_file_2 = require("../common/obj-info-file");
25
+ const assert_1 = require("../../../lib-common/assert");
25
26
  const STATUS_FILE_NAME = 'status';
26
27
  class ObjStatus {
27
- constructor(objFolder, status) {
28
+ constructor(objFolder, status, logError) {
28
29
  this.objFolder = objFolder;
29
30
  this.status = status;
30
- this.saveProc = new processes_1.DeduppedRunner(() => this.saveFile());
31
+ this.logError = logError;
32
+ this.saveProc = new json_saving_1.JSONSavingProc((0, path_1.join)(this.objFolder, STATUS_FILE_NAME), () => this.status);
31
33
  Object.freeze(this);
32
34
  }
33
- static async readFrom(objFolder, objId) {
35
+ static async readFrom(objFolder, objId, logError) {
34
36
  const status = await readAndCheckStatus(objFolder, objId);
35
- return new ObjStatus(objFolder, status);
37
+ return new ObjStatus(objFolder, status, logError);
36
38
  }
37
- static async makeNew(objFolder, objId) {
39
+ static async makeNew(objFolder, objId, logError) {
38
40
  const status = {
39
41
  objId,
40
- archivedVersions: [],
41
- baseToDiff: {},
42
- diffToBase: {}
42
+ versions: {
43
+ baseToDiff: {},
44
+ diffToBase: {}
45
+ }
43
46
  };
44
- const s = new ObjStatus(objFolder, status);
45
- await s.saveProc.trigger();
47
+ const s = new ObjStatus(objFolder, status, logError);
48
+ await s.triggerSaveProc();
46
49
  return s;
47
50
  }
48
- async saveFile() {
49
- await fs.writeFile(path_1.join(this.objFolder, STATUS_FILE_NAME), JSON.stringify(this.status), { encoding: 'utf8' });
51
+ triggerSaveProc(captureErrors = false) {
52
+ let p = this.saveProc.trigger();
53
+ return (captureErrors ? p.catch(this.logError) : p);
50
54
  }
51
55
  isArchived() {
52
56
  return !!this.status.isArchived;
53
57
  }
54
58
  getCurrentVersionOrThrow() {
55
- if (typeof this.status.currentVersion !== 'number') {
59
+ if (typeof this.status.versions.current !== 'number') {
56
60
  throw new Error(`Object ${this.status.objId} has no current version.`);
57
61
  }
58
- return this.status.currentVersion;
62
+ return this.status.versions.current;
59
63
  }
60
64
  getNonGarbageVersions() {
61
65
  return {
62
- nonGarbage: nonGarbageVersions(this.status),
63
- gcMaxVer: this.status.currentVersion
66
+ nonGarbage: (0, obj_info_file_2.nonGarbageVersionsIn)(this.status.versions),
67
+ gcMaxVer: this.status.versions.current
64
68
  };
65
69
  }
66
70
  async setNewCurrentVersion(newVersion, baseVer) {
67
- if (baseVer !== undefined) {
68
- // base->diff links should be added before removals
69
- addBaseToDiffLinkInStatus(this.status, newVersion, baseVer);
70
- }
71
- if (typeof this.status.currentVersion === 'number') {
72
- rmNonArchVersionsIn(this.status, this.status.currentVersion);
73
- }
74
- this.status.currentVersion = newVersion;
75
- await this.saveProc.trigger();
71
+ (0, obj_info_file_2.setCurrentVersionIn)(this.status.versions, newVersion, baseVer);
72
+ await this.triggerSaveProc();
76
73
  }
77
74
  async removeCurrentVersion(verObjs) {
78
75
  this.status.isArchived = true;
79
- if (typeof this.status.currentVersion === 'number') {
80
- verObjs.delete(this.status.currentVersion);
81
- rmNonArchVersionsIn(this.status, this.status.currentVersion);
82
- delete this.status.currentVersion;
76
+ const current = (0, obj_info_file_2.rmCurrentVersionIn)(this.status.versions);
77
+ if (typeof current === 'number') {
78
+ verObjs.delete(current);
83
79
  }
84
- await this.saveProc.trigger();
80
+ await this.triggerSaveProc();
85
81
  }
86
82
  async removeArchivedVersion(version, verObjs) {
87
83
  verObjs.delete(version);
88
- const arch = this.status.archivedVersions;
89
- const vInd = arch.indexOf(version);
90
- if (vInd < 0) {
91
- return;
92
- }
93
- arch.splice(vInd, 1);
94
- rmNonArchVersionsIn(this.status, version);
95
- await this.saveProc.trigger();
84
+ (0, obj_info_file_2.rmArchVersionFrom)(this.status.versions, version);
85
+ await this.triggerSaveProc();
86
+ }
87
+ async archiveCurrentVersion() {
88
+ const versions = this.status.versions;
89
+ (0, assert_1.assert)(!!versions.current);
90
+ (0, obj_info_file_1.addArchived)(versions, versions.current);
91
+ await this.triggerSaveProc();
92
+ }
93
+ listVersions() {
94
+ const archived = this.status.versions.archived;
95
+ return {
96
+ current: this.status.versions.current,
97
+ archived: (archived ? archived.slice() : [])
98
+ };
96
99
  }
97
100
  }
98
101
  exports.ObjStatus = ObjStatus;
99
102
  Object.freeze(ObjStatus.prototype);
100
103
  Object.freeze(ObjStatus);
101
- /**
102
- * This function adds base->diff link to status. Status object is changed in
103
- * this call.
104
- * @param status into which a link between versions should be added
105
- * @param diffVer
106
- * @param baseVer
107
- */
108
- function addBaseToDiffLinkInStatus(status, diffVer, baseVer) {
109
- if (diffVer <= baseVer) {
110
- throw new Error(`Given diff version ${diffVer} is not greater than base version ${baseVer}`);
111
- }
112
- status.diffToBase[diffVer] = baseVer;
113
- const diffs = status.baseToDiff[baseVer];
114
- if (diffs) {
115
- if (diffs.indexOf(diffVer) < 0) {
116
- diffs.push(diffVer);
117
- }
118
- }
119
- else {
120
- status.baseToDiff[baseVer] = [diffVer];
121
- }
122
- }
123
- /**
124
- * This function removes given version from status object, if it is neither
125
- * archived, nor is a base for another version. If given version is itself
126
- * based on another, this function is recursively applied to base version, as
127
- * well.
128
- * @param status in which version(s) should be removed
129
- * @param ver
130
- */
131
- function rmNonArchVersionsIn(status, ver) {
132
- if (status.archivedVersions.indexOf(ver) >= 0) {
133
- return;
134
- }
135
- if (status.baseToDiff[ver]) {
136
- return;
137
- }
138
- const base = status.diffToBase[ver];
139
- if (typeof base !== 'number') {
140
- return;
141
- }
142
- delete status.diffToBase[ver];
143
- const diffs = status.baseToDiff[base];
144
- if (!diffs) {
145
- return;
146
- }
147
- const diffInd = diffs.indexOf(ver);
148
- if (diffInd < 0) {
149
- return;
150
- }
151
- diffs.splice(diffInd, 1);
152
- if (diffs.length === 0) {
153
- delete status.baseToDiff[base];
154
- rmNonArchVersionsIn(status, base);
155
- }
156
- }
157
104
  async function readAndCheckStatus(objFolder, objId) {
158
- const status = await obj_info_file_1.readJSONInfoFileIn(objFolder, STATUS_FILE_NAME);
105
+ const status = await (0, obj_info_file_2.readJSONInfoFileIn)(objFolder, STATUS_FILE_NAME);
159
106
  if (!status) {
160
- throw exceptions_1.makeStorageException({
107
+ throw (0, exceptions_1.makeStorageException)({
161
108
  message: `Obj status file is not found in obj folder ${objFolder}`
162
109
  });
163
110
  }
164
111
  // XXX we may do some checks and sanitization here
165
112
  if (objId !== status.objId) {
166
- throw exceptions_1.makeStorageException({ message: `Invalid objId in status file for obj ${objId}, in folder ${objFolder}.\nInvalid content:\n${JSON.stringify(status, null, 2)}` });
113
+ throw (0, exceptions_1.makeStorageException)({ message: `Invalid objId in status file for obj ${objId}, in folder ${objFolder}.\nInvalid content:\n${JSON.stringify(status, null, 2)}` });
167
114
  }
168
115
  return status;
169
116
  }
170
- function nonGarbageVersions(status) {
171
- const nonGarbage = new Set();
172
- addWithBasesTo(nonGarbage, status.currentVersion, status);
173
- for (const archVer of status.archivedVersions) {
174
- addWithBasesTo(nonGarbage, archVer, status);
175
- }
176
- return nonGarbage;
177
- }
178
- function addWithBasesTo(nonGarbage, ver, status) {
179
- while (typeof ver === 'number') {
180
- nonGarbage.add(ver);
181
- ver = status.diffToBase[ver];
182
- }
183
- }
184
117
  Object.freeze(exports);
@@ -1,21 +1,31 @@
1
- import { Storage, NodesContainer, StorageGetter, ObjId } from '../../../lib-client/3nstorage/xsp-fs/common';
1
+ import { Storage, NodesContainer, StorageGetter, ObjId, NodeEvent, LocalObjStatus } from '../../../lib-client/3nstorage/xsp-fs/common';
2
2
  import { LogError } from '../../../lib-client/logging/log-to-file';
3
3
  import { AsyncSBoxCryptor, Subscribe, ObjSource } from 'xsp-files';
4
+ import { Observable } from 'rxjs';
5
+ declare type FolderEvent = web3n.files.FolderEvent;
6
+ declare type FileEvent = web3n.files.FileEvent;
7
+ declare type FSType = web3n.files.FSType;
4
8
  export declare class LocalStorage implements Storage {
5
9
  private readonly files;
6
10
  private readonly getStorages;
7
11
  readonly cryptor: AsyncSBoxCryptor;
8
12
  private readonly logError;
9
- readonly type: web3n.files.FSType;
13
+ readonly type = "local";
10
14
  readonly versioned = true;
11
15
  readonly nodes: NodesContainer;
16
+ readonly connect: undefined;
17
+ private readonly events;
12
18
  private constructor();
13
19
  static makeAndStart(path: string, getStorages: StorageGetter, cryptor: AsyncSBoxCryptor, logError: LogError): Promise<Storage>;
14
- storageForLinking(type: web3n.files.FSType, location?: string): Storage;
20
+ getNodeEvents(): Observable<NodeEvent>;
21
+ broadcastNodeEvent(objId: ObjId, parentObjId: ObjId | undefined, childObjId: ObjId | undefined, event: FolderEvent | FileEvent): void;
22
+ storageForLinking(type: FSType, location?: string): Storage;
23
+ private getObjOrThrow;
24
+ status(objId: ObjId): Promise<LocalObjStatus>;
15
25
  generateNewObjId(): Promise<string>;
16
- private getObjNonArchOrThrow;
17
- getObj(objId: ObjId): Promise<ObjSource>;
26
+ getObjSrc(objId: ObjId, version?: number): Promise<ObjSource>;
18
27
  saveObj(objId: string, version: number, encSub: Subscribe): Promise<void>;
19
28
  removeObj(objId: string): Promise<void>;
20
29
  close(): Promise<void>;
21
30
  }
31
+ export {};
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  /*
3
- Copyright (C) 2016 - 2020 3NSoft Inc.
3
+ Copyright (C) 2016 - 2020, 2022 3NSoft Inc.
4
4
 
5
5
  This program is free software: you can redistribute it and/or modify it under
6
6
  the terms of the GNU General Public License as published by the Free Software
@@ -13,7 +13,8 @@
13
13
  See the GNU General Public License for more details.
14
14
 
15
15
  You should have received a copy of the GNU General Public License along with
16
- this program. If not, see <http://www.gnu.org/licenses/>. */
16
+ this program. If not, see <http://www.gnu.org/licenses/>.
17
+ */
17
18
  Object.defineProperty(exports, "__esModule", { value: true });
18
19
  exports.LocalStorage = void 0;
19
20
  const common_1 = require("../../../lib-client/3nstorage/xsp-fs/common");
@@ -22,6 +23,7 @@ const random_node_1 = require("../../../lib-common/random-node");
22
23
  const ecma_nacl_1 = require("ecma-nacl");
23
24
  const buffer_utils_1 = require("../../../lib-common/buffer-utils");
24
25
  const obj_files_1 = require("./obj-files");
26
+ const utils_for_observables_1 = require("../../../lib-common/utils-for-observables");
25
27
  class LocalStorage {
26
28
  constructor(files, getStorages, cryptor, logError) {
27
29
  this.files = files;
@@ -31,12 +33,20 @@ class LocalStorage {
31
33
  this.type = 'local';
32
34
  this.versioned = true;
33
35
  this.nodes = new common_1.NodesContainer();
36
+ this.connect = undefined;
37
+ this.events = new utils_for_observables_1.Broadcast();
34
38
  Object.seal(this);
35
39
  }
36
40
  static async makeAndStart(path, getStorages, cryptor, logError) {
37
41
  const files = await obj_files_1.ObjFiles.makeFor(path, logError);
38
42
  const s = new LocalStorage(files, getStorages, cryptor, logError);
39
- return common_1.wrapStorageImplementation(s);
43
+ return (0, common_1.wrapStorageImplementation)(s);
44
+ }
45
+ getNodeEvents() {
46
+ return this.events.event$;
47
+ }
48
+ broadcastNodeEvent(objId, parentObjId, childObjId, event) {
49
+ this.events.next({ objId, parentObjId, childObjId, event });
40
50
  }
41
51
  storageForLinking(type, location) {
42
52
  if ((type === 'local') || (type === 'synced')) {
@@ -49,8 +59,22 @@ class LocalStorage {
49
59
  throw new Error(`Getting ${type} storage is not implemented in local storage.`);
50
60
  }
51
61
  }
62
+ async getObjOrThrow(objId, allowArchived = false) {
63
+ const obj = await this.files.findObj(objId);
64
+ if (!obj
65
+ || (!allowArchived && obj.statusObj().isArchived())) {
66
+ throw (0, exceptions_1.makeObjNotFoundExc)(objId);
67
+ }
68
+ else {
69
+ return obj;
70
+ }
71
+ }
72
+ async status(objId) {
73
+ const obj = await this.getObjOrThrow(objId);
74
+ return obj.localStatus();
75
+ }
52
76
  async generateNewObjId() {
53
- const nonce = await random_node_1.bytes(ecma_nacl_1.secret_box.NONCE_LENGTH);
77
+ const nonce = await (0, random_node_1.bytes)(ecma_nacl_1.secret_box.NONCE_LENGTH);
54
78
  const id = buffer_utils_1.base64urlSafe.pack(nonce);
55
79
  if (this.nodes.reserveId(id)) {
56
80
  return id;
@@ -59,40 +83,35 @@ class LocalStorage {
59
83
  return this.generateNewObjId();
60
84
  }
61
85
  }
62
- async getObjNonArchOrThrow(objId) {
63
- const obj = await this.files.findObj(objId);
64
- if (!obj || obj.isArchived()) {
65
- throw exceptions_1.makeObjNotFoundExc(objId);
86
+ async getObjSrc(objId, version) {
87
+ const obj = await this.getObjOrThrow(objId);
88
+ if (!version) {
89
+ version = obj.statusObj().getCurrentVersionOrThrow();
66
90
  }
67
- return obj;
68
- }
69
- async getObj(objId) {
70
- const obj = await this.getObjNonArchOrThrow(objId);
71
- const currentVer = obj.getCurrentVersionOrThrow();
72
- return obj.getObjSrc(currentVer);
91
+ return obj.getObjSrc(version);
73
92
  }
74
93
  async saveObj(objId, version, encSub) {
75
94
  const obj = await this.files.findObj(objId);
76
95
  if (version === 1) {
77
96
  if (obj) {
78
- throw exceptions_1.makeObjExistsExc(objId);
97
+ throw (0, exceptions_1.makeObjExistsExc)(objId);
79
98
  }
80
99
  await this.files.saveFirstVersion(objId, encSub);
81
100
  }
82
101
  else {
83
102
  if (!obj) {
84
- throw exceptions_1.makeObjNotFoundExc(objId);
103
+ throw (0, exceptions_1.makeObjNotFoundExc)(objId);
85
104
  }
86
105
  await obj.saveNewVersion(version, encSub);
87
106
  }
88
107
  }
89
108
  async removeObj(objId) {
90
- const obj = await this.getObjNonArchOrThrow(objId);
109
+ const obj = await this.getObjOrThrow(objId);
91
110
  await obj.removeCurrentVersion();
92
111
  }
93
112
  async close() {
94
113
  try {
95
- // XXX add cleanups
114
+ this.events.done();
96
115
  }
97
116
  catch (err) {
98
117
  await this.logError(err);
@@ -13,10 +13,11 @@
13
13
  See the GNU General Public License for more details.
14
14
 
15
15
  You should have received a copy of the GNU General Public License along with
16
- this program. If not, see <http://www.gnu.org/licenses/>. */
16
+ this program. If not, see <http://www.gnu.org/licenses/>.
17
+ */
17
18
  Object.defineProperty(exports, "__esModule", { value: true });
18
19
  exports.Downloader = void 0;
19
- const processes_1 = require("../../../lib-common/processes");
20
+ const synced_1 = require("../../../lib-common/processes/synced");
20
21
  const buffer_utils_1 = require("../../../lib-common/buffer-utils");
21
22
  const MAX_GETTING_CHUNK = 512 * 1024;
22
23
  const DOWNLOAD_START_CHUNK = 128 * 1024;
@@ -28,7 +29,7 @@ class Downloader {
28
29
  * When it comes to the download start, if chain exists, it means that
29
30
  * process has already started.
30
31
  */
31
- this.downloadProcs = new processes_1.NamedProcs();
32
+ this.downloadProcs = new synced_1.NamedProcs();
32
33
  Object.seal(this);
33
34
  }
34
35
  async sync(objId, version, action) {
@@ -63,12 +64,12 @@ class Downloader {
63
64
  chunks.push(chunk);
64
65
  ofs += chunk.length;
65
66
  }
66
- return buffer_utils_1.joinByteArrs(chunks);
67
+ return (0, buffer_utils_1.joinByteArrs)(chunks);
67
68
  }
68
69
  });
69
70
  }
70
- getCurrentObjVersion(objId) {
71
- return this.sync(objId, -1, async () => {
71
+ async getCurrentObjVersion(objId) {
72
+ return await this.sync(objId, -1, async () => {
72
73
  const { header, segsTotalLen, version, segsChunk } = await this.remoteStorage.getCurrentObj(objId, DOWNLOAD_START_CHUNK);
73
74
  const layout = {
74
75
  sections: [{ src: 'new', ofs: 0, len: segsTotalLen }]
@@ -1,8 +1,10 @@
1
1
  import { SynchronizerOnObjId, SyncedObj } from './obj-files';
2
+ import { StorageOwner as RemoteStorage } from '../../../lib-client/3nstorage/service';
2
3
  export declare class GC {
3
4
  private readonly sync;
4
5
  private readonly rmObjFromCache;
5
6
  private readonly rmObjFolder;
7
+ private readonly remote;
6
8
  private isStopped;
7
9
  /**
8
10
  * All gc steps are done in this process.
@@ -18,8 +20,11 @@ export declare class GC {
18
20
  * with wip set.
19
21
  */
20
22
  private scheduled;
21
- constructor(sync: SynchronizerOnObjId, rmObjFromCache: (obj: SyncedObj) => void, rmObjFolder: (objId: string) => Promise<void>);
23
+ constructor(sync: SynchronizerOnObjId, rmObjFromCache: (obj: SyncedObj) => void, rmObjFolder: (objId: string) => Promise<void>, remote: RemoteStorage);
22
24
  scheduleCollection: (obj: SyncedObj) => void;
23
25
  stop(): Promise<void>;
24
26
  private objCollecting;
27
+ private collectIn;
28
+ private upsyncObjRemovalWhenNeeded;
29
+ private checkAndRemoveWholeObjFolder;
25
30
  }
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  /*
3
- Copyright (C) 2020 3NSoft Inc.
3
+ Copyright (C) 2020, 2022 3NSoft Inc.
4
4
 
5
5
  This program is free software: you can redistribute it and/or modify it under
6
6
  the terms of the GNU General Public License as published by the Free Software
@@ -13,20 +13,27 @@
13
13
  See the GNU General Public License for more details.
14
14
 
15
15
  You should have received a copy of the GNU General Public License along with
16
- this program. If not, see <http://www.gnu.org/licenses/>. */
16
+ this program. If not, see <http://www.gnu.org/licenses/>.
17
+ */
17
18
  Object.defineProperty(exports, "__esModule", { value: true });
18
19
  exports.GC = void 0;
19
- const processes_1 = require("../../../lib-common/processes");
20
+ const obj_files_1 = require("./obj-files");
21
+ const synced_1 = require("../../../lib-common/processes/synced");
22
+ const fs = require("../../../lib-common/async-fs-node");
23
+ const path_1 = require("path");
24
+ const utils_1 = require("../common/utils");
25
+ const upload_header_file_1 = require("./upload-header-file");
20
26
  class GC {
21
- constructor(sync, rmObjFromCache, rmObjFolder) {
27
+ constructor(sync, rmObjFromCache, rmObjFolder, remote) {
22
28
  this.sync = sync;
23
29
  this.rmObjFromCache = rmObjFromCache;
24
30
  this.rmObjFolder = rmObjFolder;
31
+ this.remote = remote;
25
32
  this.isStopped = false;
26
33
  /**
27
34
  * All gc steps are done in this process.
28
35
  */
29
- this.gcProc = new processes_1.SingleProc();
36
+ this.gcProc = new synced_1.SingleProc();
30
37
  /**
31
38
  * wip are objects that are currently processed. When wip set is empty,
32
39
  * it gets swapped with non-empty scheduled set.
@@ -51,11 +58,11 @@ class GC {
51
58
  if (this.wip.size === 0) {
52
59
  [this.wip, this.scheduled] = [this.scheduled, this.wip];
53
60
  }
54
- const obj = getAndRemoveOneFrom(this.wip);
61
+ const obj = (0, utils_1.getAndRemoveOneFrom)(this.wip);
55
62
  if (!obj) {
56
63
  return;
57
64
  }
58
- // XXX
65
+ await this.sync(obj.objId, () => this.collectIn(obj).catch(utils_1.noop));
59
66
  return this.objCollecting();
60
67
  };
61
68
  Object.seal(this);
@@ -63,17 +70,103 @@ class GC {
63
70
  async stop() {
64
71
  this.isStopped = true;
65
72
  }
73
+ async collectIn(obj) {
74
+ if (obj.statusObj().isArchived()) {
75
+ await this.upsyncObjRemovalWhenNeeded(obj);
76
+ }
77
+ const nonGarbage = obj.statusObj().getNonGarbageVersions();
78
+ if (!(await this.checkAndRemoveWholeObjFolder(obj, nonGarbage))) {
79
+ await removeGarbageFiles(obj, nonGarbage);
80
+ }
81
+ }
82
+ async upsyncObjRemovalWhenNeeded(obj) {
83
+ if (!needsUpsyncOfRemoval(obj)) {
84
+ return;
85
+ }
86
+ try {
87
+ await this.remote.deleteObj(obj.objId);
88
+ }
89
+ catch (exc) {
90
+ // XXX will need to schedule other attempt to delete on remote
91
+ return;
92
+ }
93
+ await obj.statusObj().recordSyncOfObjRemoval();
94
+ }
95
+ async checkAndRemoveWholeObjFolder(obj, { local, remote }) {
96
+ if (obj.objId
97
+ && obj.statusObj().isArchived()
98
+ && !needsUpsyncOfRemoval(obj)
99
+ && (!local || (local.nonGarbage.size === 0))
100
+ && (remote.nonGarbage.size === 0)) {
101
+ this.rmObjFromCache(obj);
102
+ await this.rmObjFolder(obj.objId);
103
+ return true;
104
+ }
105
+ else {
106
+ return false;
107
+ }
108
+ }
66
109
  }
67
110
  exports.GC = GC;
68
111
  Object.freeze(GC.prototype);
69
112
  Object.freeze(GC);
70
- function getAndRemoveOneFrom(set) {
71
- const iter = set.values();
72
- const { value, done } = iter.next();
73
- if (done) {
113
+ function needsUpsyncOfRemoval(obj) {
114
+ const s = obj.statusObj();
115
+ return !(s.neverUploaded() || (s.syncStatus().state === 'synced'));
116
+ }
117
+ function canRemove(f, { local, remote, uploadVersion }) {
118
+ if (f.endsWith(obj_files_1.UNSYNCED_FILE_NAME_EXT)) {
119
+ const verStr = f.slice(0, f.length - 1 - obj_files_1.UNSYNCED_FILE_NAME_EXT.length);
120
+ return (local ? canGC(verStr, local) : true);
121
+ }
122
+ else if (f.endsWith(obj_files_1.REMOTE_FILE_NAME_EXT)) {
123
+ const verStr = f.slice(0, f.length - 1 - obj_files_1.REMOTE_FILE_NAME_EXT.length);
124
+ return canGC(verStr, remote);
125
+ }
126
+ else if (!!uploadVersion
127
+ && f.endsWith(upload_header_file_1.UPLOAD_HEADER_FILE_NAME_EXT)) {
128
+ const verStr = f.slice(0, f.length - 1 - upload_header_file_1.UPLOAD_HEADER_FILE_NAME_EXT.length);
129
+ return canGCUploadHeader(verStr, uploadVersion);
130
+ }
131
+ else {
132
+ return false;
133
+ }
134
+ }
135
+ function canGC(verStr, nonGC) {
136
+ const ver = parseInt(verStr);
137
+ if (isNaN(ver)) {
138
+ return true;
139
+ }
140
+ else if (!nonGC.nonGarbage.has(ver)
141
+ && (!nonGC.gcMaxVer || (ver < nonGC.gcMaxVer))) {
142
+ return true;
143
+ }
144
+ else {
145
+ return false;
146
+ }
147
+ }
148
+ function canGCUploadHeader(verStr, uploadVersion) {
149
+ const ver = parseInt(verStr);
150
+ if (isNaN(ver)) {
151
+ return true;
152
+ }
153
+ else {
154
+ return (ver === uploadVersion);
155
+ }
156
+ }
157
+ async function removeGarbageFiles(obj, nonGarbage) {
158
+ const lst = await fs.readdir(obj.objFolder).catch(utils_1.noop);
159
+ if (!lst) {
74
160
  return;
75
161
  }
76
- set.delete(value);
77
- return value;
162
+ const rmProcs = [];
163
+ for (const f of lst) {
164
+ if (canRemove(f, nonGarbage)) {
165
+ rmProcs.push(fs.unlink((0, path_1.join)(obj.objFolder, f)).catch(utils_1.noop));
166
+ }
167
+ }
168
+ if (rmProcs.length > 0) {
169
+ await Promise.all(rmProcs);
170
+ }
78
171
  }
79
172
  Object.freeze(exports);