@dra2020/baseclient 1.0.13 → 1.0.14

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 (185) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +37 -0
  3. package/dist/all/all.d.ts +36 -0
  4. package/dist/all/allclient.d.ts +18 -0
  5. package/dist/base.js +33010 -0
  6. package/dist/base.js.map +1 -0
  7. package/dist/baseclient.js +8991 -0
  8. package/dist/baseclient.js.map +1 -0
  9. package/dist/context/all.d.ts +1 -0
  10. package/dist/context/context.d.ts +13 -0
  11. package/dist/dbabstract/all.d.ts +1 -0
  12. package/dist/dbabstract/db.d.ts +83 -0
  13. package/dist/dbdynamo/all.d.ts +1 -0
  14. package/dist/dbdynamo/dbdynamo.d.ts +190 -0
  15. package/dist/filterexpr/all.d.ts +1 -0
  16. package/dist/filterexpr/filterexpr.d.ts +64 -0
  17. package/dist/fsm/all.d.ts +1 -0
  18. package/dist/fsm/fsm.d.ts +118 -0
  19. package/dist/fsmfile/all.d.ts +1 -0
  20. package/dist/fsmfile/fsmfile.d.ts +47 -0
  21. package/dist/jsonstream/all.d.ts +1 -0
  22. package/dist/jsonstream/jsonstream.d.ts +130 -0
  23. package/dist/lambda/all.d.ts +1 -0
  24. package/dist/lambda/env.d.ts +10 -0
  25. package/dist/lambda/lambda.d.ts +18 -0
  26. package/dist/logabstract/all.d.ts +1 -0
  27. package/dist/logabstract/log.d.ts +26 -0
  28. package/dist/logclient/all.d.ts +1 -0
  29. package/dist/logclient/log.d.ts +6 -0
  30. package/dist/logserver/all.d.ts +5 -0
  31. package/dist/logserver/log.d.ts +11 -0
  32. package/dist/logserver/logaccum.d.ts +154 -0
  33. package/dist/logserver/logblob.d.ts +24 -0
  34. package/dist/logserver/logconcat.d.ts +55 -0
  35. package/dist/logserver/logkey.d.ts +28 -0
  36. package/dist/memsqs/all.d.ts +4 -0
  37. package/dist/memsqs/client.d.ts +13 -0
  38. package/dist/memsqs/loopback.d.ts +11 -0
  39. package/dist/memsqs/orderedlist.d.ts +19 -0
  40. package/dist/memsqs/queue.d.ts +84 -0
  41. package/dist/memsqs/server.d.ts +37 -0
  42. package/dist/ot-editutil/all.d.ts +2 -0
  43. package/dist/ot-editutil/oteditutil.d.ts +14 -0
  44. package/dist/ot-editutil/otmaputil.d.ts +21 -0
  45. package/dist/ot-js/all.d.ts +9 -0
  46. package/dist/ot-js/otarray.d.ts +111 -0
  47. package/dist/ot-js/otclientengine.d.ts +38 -0
  48. package/dist/ot-js/otcomposite.d.ts +37 -0
  49. package/dist/ot-js/otcounter.d.ts +17 -0
  50. package/dist/ot-js/otengine.d.ts +22 -0
  51. package/dist/ot-js/otmap.d.ts +19 -0
  52. package/dist/ot-js/otserverengine.d.ts +38 -0
  53. package/dist/ot-js/otsession.d.ts +111 -0
  54. package/dist/ot-js/ottypes.d.ts +29 -0
  55. package/dist/poly/all.d.ts +15 -0
  56. package/dist/poly/blend.d.ts +1 -0
  57. package/dist/poly/boundbox.d.ts +16 -0
  58. package/dist/poly/cartesian.d.ts +5 -0
  59. package/dist/poly/graham-scan.d.ts +8 -0
  60. package/dist/poly/hash.d.ts +1 -0
  61. package/dist/poly/matrix.d.ts +24 -0
  62. package/dist/poly/minbound.d.ts +1 -0
  63. package/dist/poly/poly.d.ts +52 -0
  64. package/dist/poly/polybin.d.ts +5 -0
  65. package/dist/poly/polylabel.d.ts +7 -0
  66. package/dist/poly/polypack.d.ts +30 -0
  67. package/dist/poly/polyround.d.ts +1 -0
  68. package/dist/poly/polysimplify.d.ts +1 -0
  69. package/dist/poly/quad.d.ts +48 -0
  70. package/dist/poly/selfintersect.d.ts +1 -0
  71. package/dist/poly/shamos.d.ts +1 -0
  72. package/dist/poly/simplify.d.ts +2 -0
  73. package/dist/poly/topo.d.ts +46 -0
  74. package/dist/poly/union.d.ts +48 -0
  75. package/dist/storage/all.d.ts +4 -0
  76. package/dist/storage/datablob.d.ts +9 -0
  77. package/dist/storage/env.d.ts +10 -0
  78. package/dist/storage/splitsblob.d.ts +13 -0
  79. package/dist/storage/storage.d.ts +166 -0
  80. package/dist/storages3/all.d.ts +1 -0
  81. package/dist/storages3/s3.d.ts +62 -0
  82. package/dist/util/all.d.ts +5 -0
  83. package/dist/util/bintrie.d.ts +93 -0
  84. package/dist/util/countedhash.d.ts +19 -0
  85. package/dist/util/gradient.d.ts +15 -0
  86. package/dist/util/indexedarray.d.ts +15 -0
  87. package/dist/util/util.d.ts +68 -0
  88. package/docs/context.md +2 -0
  89. package/docs/dbabstract.md +2 -0
  90. package/docs/dbdynamo.md +2 -0
  91. package/docs/fsm.md +243 -0
  92. package/docs/fsmfile.md +2 -0
  93. package/docs/jsonstream.md +44 -0
  94. package/docs/lambda.md +2 -0
  95. package/docs/logabstract.md +2 -0
  96. package/docs/logclient.md +2 -0
  97. package/docs/logserver.md +2 -0
  98. package/docs/ot-editutil.md +2 -0
  99. package/docs/ot-js.md +95 -0
  100. package/docs/poly.md +103 -0
  101. package/docs/storage.md +2 -0
  102. package/docs/storages3.md +2 -0
  103. package/docs/util.md +2 -0
  104. package/lib/all/all.ts +41 -0
  105. package/lib/all/allclient.ts +19 -0
  106. package/lib/context/all.ts +1 -0
  107. package/lib/context/context.ts +82 -0
  108. package/lib/dbabstract/all.ts +1 -0
  109. package/lib/dbabstract/db.ts +246 -0
  110. package/lib/dbdynamo/all.ts +1 -0
  111. package/lib/dbdynamo/dbdynamo.ts +1551 -0
  112. package/lib/filterexpr/all.ts +1 -0
  113. package/lib/filterexpr/filterexpr.ts +625 -0
  114. package/lib/fsm/all.ts +1 -0
  115. package/lib/fsm/fsm.ts +549 -0
  116. package/lib/fsmfile/all.ts +1 -0
  117. package/lib/fsmfile/fsmfile.ts +236 -0
  118. package/lib/jsonstream/all.ts +1 -0
  119. package/lib/jsonstream/jsonstream.ts +940 -0
  120. package/lib/lambda/all.ts +1 -0
  121. package/lib/lambda/env.ts +13 -0
  122. package/lib/lambda/lambda.ts +120 -0
  123. package/lib/logabstract/all.ts +1 -0
  124. package/lib/logabstract/log.ts +55 -0
  125. package/lib/logclient/all.ts +1 -0
  126. package/lib/logclient/log.ts +105 -0
  127. package/lib/logserver/all.ts +5 -0
  128. package/lib/logserver/log.ts +565 -0
  129. package/lib/logserver/logaccum.ts +1445 -0
  130. package/lib/logserver/logblob.ts +84 -0
  131. package/lib/logserver/logconcat.ts +313 -0
  132. package/lib/logserver/logkey.ts +125 -0
  133. package/lib/memsqs/all.ts +4 -0
  134. package/lib/memsqs/client.ts +268 -0
  135. package/lib/memsqs/loopback.ts +64 -0
  136. package/lib/memsqs/orderedlist.ts +74 -0
  137. package/lib/memsqs/queue.ts +395 -0
  138. package/lib/memsqs/server.ts +262 -0
  139. package/lib/ot-editutil/all.ts +2 -0
  140. package/lib/ot-editutil/oteditutil.ts +180 -0
  141. package/lib/ot-editutil/otmaputil.ts +209 -0
  142. package/lib/ot-js/all.ts +9 -0
  143. package/lib/ot-js/otarray.ts +1168 -0
  144. package/lib/ot-js/otclientengine.ts +327 -0
  145. package/lib/ot-js/otcomposite.ts +247 -0
  146. package/lib/ot-js/otcounter.ts +145 -0
  147. package/lib/ot-js/otengine.ts +71 -0
  148. package/lib/ot-js/otmap.ts +144 -0
  149. package/lib/ot-js/otserverengine.ts +329 -0
  150. package/lib/ot-js/otsession.ts +199 -0
  151. package/lib/ot-js/ottypes.ts +98 -0
  152. package/lib/poly/all.ts +15 -0
  153. package/lib/poly/blend.ts +27 -0
  154. package/lib/poly/boundbox.ts +102 -0
  155. package/lib/poly/cartesian.ts +130 -0
  156. package/lib/poly/graham-scan.ts +401 -0
  157. package/lib/poly/hash.ts +15 -0
  158. package/lib/poly/matrix.ts +309 -0
  159. package/lib/poly/minbound.ts +211 -0
  160. package/lib/poly/poly.ts +767 -0
  161. package/lib/poly/polybin.ts +218 -0
  162. package/lib/poly/polylabel.ts +204 -0
  163. package/lib/poly/polypack.ts +458 -0
  164. package/lib/poly/polyround.ts +30 -0
  165. package/lib/poly/polysimplify.ts +24 -0
  166. package/lib/poly/quad.ts +272 -0
  167. package/lib/poly/selfintersect.ts +87 -0
  168. package/lib/poly/shamos.ts +297 -0
  169. package/lib/poly/simplify.ts +119 -0
  170. package/lib/poly/topo.ts +525 -0
  171. package/lib/poly/union.ts +371 -0
  172. package/lib/storage/all.ts +4 -0
  173. package/lib/storage/datablob.ts +36 -0
  174. package/lib/storage/env.ts +14 -0
  175. package/lib/storage/splitsblob.ts +63 -0
  176. package/lib/storage/storage.ts +604 -0
  177. package/lib/storages3/all.ts +1 -0
  178. package/lib/storages3/s3.ts +576 -0
  179. package/lib/util/all.ts +5 -0
  180. package/lib/util/bintrie.ts +603 -0
  181. package/lib/util/countedhash.ts +83 -0
  182. package/lib/util/gradient.ts +108 -0
  183. package/lib/util/indexedarray.ts +80 -0
  184. package/lib/util/util.ts +695 -0
  185. package/package.json +8 -8
@@ -0,0 +1,576 @@
1
+ // Node libraries
2
+ import * as fs from 'fs';
3
+ import * as stream from 'stream';
4
+ import * as zlib from 'zlib';
5
+
6
+ // Public libraries
7
+ import * as S3 from 'aws-sdk/clients/s3';
8
+
9
+ // Shared libraries
10
+ import * as Context from '../context/all';
11
+ import * as Storage from '../storage/all';
12
+ import * as LogAbstract from '../logabstract/all';
13
+ import * as FSM from '../fsm/all';
14
+
15
+ export interface Environment
16
+ {
17
+ context: Context.IContext;
18
+ log: LogAbstract.ILog;
19
+ fsmManager: FSM.FsmManager;
20
+ storageManager: Storage.StorageManager;
21
+ }
22
+
23
+ class S3Request implements Storage.BlobRequest
24
+ {
25
+ blob: Storage.StorageBlob;
26
+ req: any;
27
+ res: any;
28
+ data: any;
29
+ err: any;
30
+
31
+ constructor(blob: Storage.StorageBlob)
32
+ {
33
+ this.blob = blob;
34
+ this.req = null;
35
+ this.res = null;
36
+ this.data = null;
37
+ this.err = null;
38
+ }
39
+
40
+ continuationToken(): string
41
+ {
42
+ if (this.data && this.data.NextContinuationToken)
43
+ return this.data.NextContinuationToken;
44
+
45
+ return undefined;
46
+ }
47
+
48
+ result(): number
49
+ {
50
+ if (this.data == null && this.blob.toLoadStream() == null && this.err == null)
51
+ return Storage.EPending;
52
+ else if (this.err != null)
53
+ {
54
+ if (this.err.statusCode && this.err.statusCode == 404)
55
+ return Storage.ENotFound;
56
+ else if (this.err.statusCode === 999)
57
+ return Storage.EBadFormat;
58
+ else
59
+ return Storage.EFail;
60
+ }
61
+ else
62
+ return Storage.ESuccess;
63
+ }
64
+
65
+ decode(): void
66
+ {
67
+ if (this.err == null && this.data && this.data.Body && this.data.ContentEncoding === 'gzip')
68
+ {
69
+ try
70
+ {
71
+ this.data.Body = zlib.gunzipSync(this.data.Body);
72
+ }
73
+ catch (err)
74
+ {
75
+ this.err = { statusCode: 999, message: 'Content not in gzip format.' };
76
+ }
77
+ }
78
+ }
79
+
80
+ asString(): string
81
+ {
82
+ if (this.err || this.res == null || this.data == null || this.data.Body == null)
83
+ return undefined;
84
+ let body: Buffer = this.data.Body;
85
+ return body.toString('utf-8');
86
+ }
87
+
88
+ // Uncompress as necessary
89
+ asBuffer(): Buffer
90
+ {
91
+ if (this.err || this.res == null || this.data == null || this.data.Body == null)
92
+ return undefined;
93
+ let body: Buffer = this.data.Body;
94
+ return body;
95
+ }
96
+
97
+ _dataToProps(data: any): Storage.BlobProperties
98
+ {
99
+ let props: Storage.BlobProperties = {};
100
+ props.ContentLength = (data.Size !== undefined) ? data.Size : 0;
101
+ props.Key = data.Key;
102
+ props.ETag = data.ETag;
103
+ props.LastModified = data.LastModified;
104
+ props.ContentEncoding = data.ContentEncoding;
105
+ return props;
106
+ }
107
+
108
+ asProps(): Storage.BlobProperties[]
109
+ {
110
+ let a: Storage.BlobProperties[] = [];
111
+
112
+ if (this.data && Array.isArray(this.data.Contents))
113
+ {
114
+ for (let i: number = 0; i < this.data.Contents.length; i++)
115
+ a.push(this._dataToProps(this.data.Contents[i]));
116
+ }
117
+ else
118
+ a.push(this._dataToProps(this.data));
119
+
120
+ return a;
121
+ }
122
+
123
+ asError(): string
124
+ {
125
+ if (this.err)
126
+ return this.err.message ? this.err.message : JSON.stringify(this.err);
127
+ return undefined;
128
+ }
129
+ }
130
+
131
+ const ChunkSize = 4000000;
132
+
133
+ export class FsmStreamLoader extends FSM.Fsm
134
+ {
135
+ sm: StorageManager;
136
+ blob: Storage.StorageBlob;
137
+ param: any;
138
+ err: any;
139
+ contentLength: number;
140
+ contentPos: number;
141
+ readStream: Storage.MultiBufferPassThrough;
142
+ passThrough: Storage.MultiBufferPassThrough;
143
+
144
+ constructor(env: Environment, sm: StorageManager, blob: Storage.StorageBlob)
145
+ {
146
+ super(env);
147
+ this.sm = sm;
148
+ this.blob = blob;
149
+ this.contentPos = 0;
150
+ this.param = { Bucket: sm.blobBucket(blob), Key: blob.params.id };
151
+
152
+ // We use passthrough stream because we want to make the load stream available
153
+ // immediately but we don't actually know whether we are going to have to pipe
154
+ // through gunzip or not until we get the first ContentEncoding header back.
155
+ this.readStream = new Storage.MultiBufferPassThrough();
156
+ this.passThrough = new Storage.MultiBufferPassThrough();
157
+ this.blob.setLoadStream(this.passThrough);
158
+ }
159
+
160
+ get env(): Environment { return this._env as Environment; }
161
+
162
+ setStreamError(): void
163
+ {
164
+ this.passThrough._done();
165
+ this.setState(FSM.FSM_ERROR);
166
+ this.err = { statusCode: 999, message: 'Content not in gzip format.' };
167
+ }
168
+
169
+ tick(): void
170
+ {
171
+ if (this.ready)
172
+ {
173
+ // Figure out next chunk
174
+ if (this.contentLength === undefined)
175
+ this.param.Range = `bytes=0-${ChunkSize-1}`;
176
+ else
177
+ this.param.Range = `bytes=${this.contentPos}-${Math.min(this.contentPos+ChunkSize-1, this.contentLength-1)}`;
178
+
179
+ switch (this.state)
180
+ {
181
+
182
+ case FSM.FSM_STARTING:
183
+ this.sm.s3.getObject(this.param, (err: any, data: any) => {
184
+ if (err == null)
185
+ {
186
+ // On first chunk, figure out if we need to pipe through gunzip
187
+ if (this.contentLength === undefined)
188
+ {
189
+ if (data.ContentEncoding && data.ContentEncoding === 'gzip')
190
+ {
191
+ let unzip = zlib.createGunzip({});
192
+ unzip.on('end', () => { this.passThrough._done(); this.setState(FSM.FSM_DONE); } );
193
+ unzip.on('error', () => { this.setStreamError() } );
194
+ this.readStream.pipe(unzip).pipe(this.passThrough);
195
+ }
196
+ else
197
+ {
198
+ this.readStream.on('end', () => { this.passThrough._done(); this.setState(FSM.FSM_DONE); } );
199
+ this.readStream.on('error', () => { this.setStreamError() } );
200
+ this.readStream.pipe(this.passThrough);
201
+ }
202
+ }
203
+
204
+ // Handle this data
205
+ if (data.Body)
206
+ this.readStream.write(data.Body);
207
+
208
+ // Update content range and content length for next time through, or noticing finish
209
+ if (data.ContentRange)
210
+ {
211
+ let re = /bytes (\d+)-(\d+)\/(\d+)/
212
+ let s: string = data.ContentRange; // "bytes start-end/total"
213
+ let matched = re.exec(s);
214
+ if (matched && matched.length === 4)
215
+ {
216
+ this.contentPos = Number(matched[2]) + 1;
217
+ this.contentLength = Number(matched[3]);
218
+ }
219
+ }
220
+ }
221
+
222
+ // Error or done reading
223
+ if (err || this.contentPos === this.contentLength)
224
+ {
225
+ this.err = err;
226
+ this.readStream._done();
227
+ if (err)
228
+ {
229
+ this.passThrough._done();
230
+ this.setState(FSM.FSM_ERROR);
231
+ }
232
+ }
233
+ else
234
+ this.setState(FSM.FSM_STARTING);
235
+ });
236
+ break;
237
+ }
238
+ }
239
+ }
240
+ }
241
+
242
+ export class FsmTransferUrl extends Storage.FsmTransferUrl
243
+ {
244
+ storageManager: StorageManager;
245
+
246
+ constructor(env: Environment, bucket: string, params: Storage.TransferParams)
247
+ {
248
+ super(env, bucket, params);
249
+ }
250
+ }
251
+
252
+ export class StorageManager extends Storage.StorageManager
253
+ {
254
+ s3: any;
255
+ count: number;
256
+
257
+ constructor(env: Environment, bucketMap?: Storage.BucketMap)
258
+ {
259
+ super(env, bucketMap);
260
+
261
+ if (this.env.context.xstring('aws_access_key_id') === undefined
262
+ || this.env.context.xstring('aws_secret_access_key') === undefined)
263
+ {
264
+ this.env.log.error('S3: not configured: exiting');
265
+ this.env.log.dump();
266
+ process.exit(1);
267
+ }
268
+
269
+ this.s3 = new S3({apiVersion: '2006-03-01', region: 'us-west-2'});
270
+ this.count = 0;
271
+ }
272
+
273
+ get env(): Environment { return this._env as Environment; }
274
+
275
+ lookupBucket(s: string): string
276
+ {
277
+ while (this.bucketMap[s] !== undefined)
278
+ s = this.bucketMap[s];
279
+ return s;
280
+ }
281
+
282
+ blobBucket(blob: Storage.StorageBlob): string
283
+ {
284
+ return this.lookupBucket(blob.params.bucket);
285
+ }
286
+
287
+ load(blob: Storage.StorageBlob): void
288
+ {
289
+ if (blob.params.id == '')
290
+ {
291
+ this.env.log.error('S3: blob load called with empty key');
292
+ return;
293
+ }
294
+ let id: string = `load+${blob.params.id}+${this.count++}`;
295
+
296
+ this.env.log.event('S3: load start', 1);
297
+ let trace = new LogAbstract.AsyncTimer(this.env.log, 'S3: load', 1);
298
+ let params = { Bucket: this.blobBucket(blob), Key: blob.params.id };
299
+ let rq = new S3Request(blob);
300
+ this.loadBlobIndex[id] = rq;
301
+ blob.setLoading();
302
+ if (blob.params.loadToType === 'stream')
303
+ {
304
+ let fsm = new FsmStreamLoader(this.env, this, blob);
305
+ rq.req = fsm;
306
+ new FSM.FsmOnDone(this.env, fsm, (f: FSM.Fsm) => {
307
+ this._finishLoad(blob, id, rq, fsm.err, undefined);
308
+ trace.log();
309
+ });
310
+ }
311
+ else
312
+ {
313
+ rq.req = this.s3.getObject(params, (err: any, data: any) => {
314
+ this._finishLoad(blob, id, rq, err, data);
315
+ trace.log();
316
+ });
317
+ }
318
+ }
319
+
320
+ _finishLoad(blob: Storage.StorageBlob, id: string, rq: S3Request, err: any, data: any)
321
+ {
322
+ rq.res = this;
323
+ if (err)
324
+ rq.err = err;
325
+ else
326
+ rq.data = data;
327
+
328
+ rq.decode();
329
+ blob.setLoaded(rq.result());
330
+ blob.endLoad(rq);
331
+ this.emit('load', blob);
332
+
333
+ delete this.loadBlobIndex[id];
334
+
335
+ this.env.log.event('S3: load end', 1);
336
+ }
337
+
338
+ head(blob: Storage.StorageBlob): void
339
+ {
340
+ if (blob.params.id == '')
341
+ {
342
+ this.env.log.error('S3: blob head called with empty key');
343
+ return;
344
+ }
345
+ let id: string = `head+${blob.params.id}+${this.count++}`;
346
+
347
+ this.env.log.event('S3: head start', 1);
348
+ let trace = new LogAbstract.AsyncTimer(this.env.log, 'S3: head', 1);
349
+ let params = { Bucket: this.blobBucket(blob), Key: blob.params.id };
350
+ let rq = new S3Request(blob);
351
+ this.headBlobIndex[id] = rq;
352
+ blob.setLoading();
353
+ rq.req = this.s3.headObject(params, (err: any, data: any) => {
354
+ rq.res = this;
355
+ if (err)
356
+ rq.err = err;
357
+ else
358
+ rq.data = data;
359
+
360
+ blob.setLoaded(rq.result());
361
+ blob.endHead(rq);
362
+ this.emit('head', blob);
363
+
364
+ delete this.headBlobIndex[id];
365
+
366
+ this.env.log.event('S3: head end', 1);
367
+ trace.log();
368
+ });
369
+ }
370
+
371
+ safeSaveFromPath(blob: Storage.StorageBlob, rq: S3Request, id: string, trace: LogAbstract.AsyncTimer): any
372
+ {
373
+ try
374
+ {
375
+ // We can't gzip the stream, so read as buffer (more size limited than stream) if required
376
+ if (blob.params.ContentEncoding === 'gzip')
377
+ return fs.readFileSync(blob.params.saveFrom);
378
+ else
379
+ return fs.createReadStream(blob.params.saveFrom);
380
+ }
381
+ catch (err)
382
+ {
383
+ rq.err = err;
384
+ process.nextTick(() => {
385
+ blob.setSaved(rq.result());
386
+ blob.endSave(rq);
387
+ this.emit('save', blob);
388
+ delete this.saveBlobIndex[id];
389
+ this.env.log.error('S3: failed to open blob path file');
390
+ trace.log();
391
+ });
392
+ }
393
+ return null;
394
+ }
395
+
396
+ save(blob: Storage.StorageBlob): void
397
+ {
398
+ if (blob.params.id == '')
399
+ {
400
+ this.env.log.error('S3: blob save called with empty key');
401
+ return;
402
+ }
403
+ let id: string = `save+${blob.params.id}+${this.count++}`;
404
+
405
+ this.env.log.event('S3: save start', 1);
406
+
407
+ let trace = new LogAbstract.AsyncTimer(this.env.log, 'S3: save', 1);
408
+ let params: any = { Bucket: this.blobBucket(blob), Key: blob.params.id };
409
+ if (blob.params.ContentEncoding)
410
+ params['ContentEncoding'] = blob.params.ContentEncoding;
411
+ if (blob.params.ContentType)
412
+ params['ContentType'] = blob.params.ContentType;
413
+ if (blob.params.CacheControl)
414
+ params['CacheControl'] = blob.params.CacheControl;
415
+ let rq = new S3Request(blob);
416
+ this.saveBlobIndex[id] = rq;
417
+ blob.setSaving();
418
+
419
+ let body: any;
420
+ let bodyStream: stream.Readable;
421
+ switch (blob.params.saveFromType)
422
+ {
423
+ case 'object':
424
+ body = Buffer.from(JSON.stringify(blob.params.saveFrom));
425
+ break;
426
+ case 'string':
427
+ body = Buffer.from(blob.params.saveFrom);
428
+ break;
429
+ case 'buffer':
430
+ body = blob.params.saveFrom;
431
+ break;
432
+ case 'stream':
433
+ body = blob.params.saveFrom;
434
+ bodyStream = body as stream.Readable;
435
+ break;
436
+ case 'filepath':
437
+ body = this.safeSaveFromPath(blob, rq, id, trace);
438
+ if (body && !Buffer.isBuffer(body)) bodyStream = body as stream.Readable;
439
+ if (body == null) return;
440
+ break;
441
+ }
442
+ if (blob.params.ContentEncoding === 'gzip' && Buffer.isBuffer(body))
443
+ body = zlib.gzipSync(body);
444
+
445
+ params.Body = body;
446
+ rq.req = this.s3.putObject(params, (err: any, data: any) => {
447
+ if (err)
448
+ rq.err = err;
449
+ else
450
+ rq.data = data;
451
+ rq.res = this;
452
+
453
+ blob.setSaved(rq.result());
454
+ blob.endSave(rq);
455
+ this.emit('save', blob);
456
+
457
+ delete this.saveBlobIndex[id];
458
+
459
+ this.env.log.event('S3: save done', 1);
460
+ trace.log();
461
+
462
+ if (bodyStream)
463
+ bodyStream.destroy();
464
+ });
465
+ }
466
+
467
+ del(blob: Storage.StorageBlob): void
468
+ {
469
+ if (blob.params.id == '')
470
+ {
471
+ this.env.log.error('S3: blob delete called with empty key');
472
+ return;
473
+ }
474
+ let id: string = `delete+${blob.params.id}+${this.count++}`;
475
+
476
+ this.env.log.event(`S3: del start`, 1);
477
+
478
+ let trace = new LogAbstract.AsyncTimer(this.env.log, 'S3: del', 1);
479
+ let params = { Bucket: this.blobBucket(blob), Key: blob.params.id };
480
+ let rq = new S3Request(blob);
481
+ this.delBlobIndex[id] = rq;
482
+ blob.setDeleting();
483
+ rq.req = this.s3.deleteObject(params, (err: any, data: any) => {
484
+ if (err)
485
+ rq.err = err;
486
+ else
487
+ rq.data = data;
488
+ rq.res = this;
489
+
490
+ blob.setDeleted(rq.result());
491
+ blob.endDelete(rq);
492
+ this.emit('del', blob);
493
+
494
+ delete this.delBlobIndex[id];
495
+
496
+ trace.log();
497
+ this.env.log.event(`S3: del done`, 1);
498
+ });
499
+ }
500
+
501
+ ls(blob: Storage.StorageBlob, continuationToken?: string): void
502
+ {
503
+ let b = this.blobBucket(blob);
504
+ if (b == '')
505
+ {
506
+ this.env.log.error('S3: blob ls called with empty bucket');
507
+ return;
508
+ }
509
+ let id: string = `ls+${b}+${this.count++}`;
510
+
511
+ this.env.log.event(`S3: ls start`, 1);
512
+
513
+ let trace = new LogAbstract.AsyncTimer(this.env.log, 'S3: ls', 1);
514
+ let params: any = { Bucket: b };
515
+ if (continuationToken)
516
+ params.ContinuationToken = continuationToken;
517
+ let rq = new S3Request(blob);
518
+ this.lsBlobIndex[id] = rq;
519
+ blob.setListing();
520
+ rq.req = this.s3.listObjectsV2(params, (err: any, data: any) => {
521
+ if (err)
522
+ rq.err = err;
523
+ else
524
+ rq.data = data;
525
+ rq.res = this;
526
+
527
+ blob.setListed();
528
+ blob.endList(rq);
529
+ this.emit('ls', blob);
530
+
531
+ delete this.lsBlobIndex[id];
532
+
533
+ trace.log();
534
+ this.env.log.event(`S3: ls done`, 1);
535
+ });
536
+ }
537
+
538
+ createTransferUrl(params: Storage.TransferParams): Storage.FsmTransferUrl
539
+ {
540
+ let fsm = new FsmTransferUrl(this.env, this.lookupBucket('transfers'), params);
541
+ if (fsm === null)
542
+ {
543
+ let params: any = { Bucket: fsm.bucket, Fields: { key: fsm.key } };
544
+ this.s3.createPresignedPost(params, (err: any, url: string) => {
545
+ if (err)
546
+ {
547
+ this.env.log.error(`S3: createPresignedPost failed: ${err}`);
548
+ fsm.setState(FSM.FSM_ERROR);
549
+ }
550
+ else
551
+ {
552
+ fsm.url = url;
553
+ fsm.setState(FSM.FSM_DONE);
554
+ }
555
+ });
556
+ }
557
+ else
558
+ {
559
+ let s3params: any = { Bucket: fsm.bucket, Key: fsm.key };
560
+ if (params.op === 'putObject') s3params.ContentType = fsm.params.contentType;
561
+ this.s3.getSignedUrl(params.op, s3params, (err: any, url: string) => {
562
+ if (err)
563
+ {
564
+ this.env.log.error(`S3: getSignedUrl failed: ${err}`);
565
+ fsm.setState(FSM.FSM_ERROR);
566
+ }
567
+ else
568
+ {
569
+ fsm.url = url;
570
+ fsm.setState(FSM.FSM_DONE);
571
+ }
572
+ });
573
+ }
574
+ return fsm;
575
+ }
576
+ }
@@ -0,0 +1,5 @@
1
+ export * from './util';
2
+ export * from './countedhash';
3
+ export * from './indexedarray';
4
+ export * from './gradient';
5
+ export * from './bintrie';