@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.
- package/LICENSE +21 -0
- package/README.md +37 -0
- package/dist/all/all.d.ts +36 -0
- package/dist/all/allclient.d.ts +18 -0
- package/dist/base.js +33010 -0
- package/dist/base.js.map +1 -0
- package/dist/baseclient.js +8991 -0
- package/dist/baseclient.js.map +1 -0
- package/dist/context/all.d.ts +1 -0
- package/dist/context/context.d.ts +13 -0
- package/dist/dbabstract/all.d.ts +1 -0
- package/dist/dbabstract/db.d.ts +83 -0
- package/dist/dbdynamo/all.d.ts +1 -0
- package/dist/dbdynamo/dbdynamo.d.ts +190 -0
- package/dist/filterexpr/all.d.ts +1 -0
- package/dist/filterexpr/filterexpr.d.ts +64 -0
- package/dist/fsm/all.d.ts +1 -0
- package/dist/fsm/fsm.d.ts +118 -0
- package/dist/fsmfile/all.d.ts +1 -0
- package/dist/fsmfile/fsmfile.d.ts +47 -0
- package/dist/jsonstream/all.d.ts +1 -0
- package/dist/jsonstream/jsonstream.d.ts +130 -0
- package/dist/lambda/all.d.ts +1 -0
- package/dist/lambda/env.d.ts +10 -0
- package/dist/lambda/lambda.d.ts +18 -0
- package/dist/logabstract/all.d.ts +1 -0
- package/dist/logabstract/log.d.ts +26 -0
- package/dist/logclient/all.d.ts +1 -0
- package/dist/logclient/log.d.ts +6 -0
- package/dist/logserver/all.d.ts +5 -0
- package/dist/logserver/log.d.ts +11 -0
- package/dist/logserver/logaccum.d.ts +154 -0
- package/dist/logserver/logblob.d.ts +24 -0
- package/dist/logserver/logconcat.d.ts +55 -0
- package/dist/logserver/logkey.d.ts +28 -0
- package/dist/memsqs/all.d.ts +4 -0
- package/dist/memsqs/client.d.ts +13 -0
- package/dist/memsqs/loopback.d.ts +11 -0
- package/dist/memsqs/orderedlist.d.ts +19 -0
- package/dist/memsqs/queue.d.ts +84 -0
- package/dist/memsqs/server.d.ts +37 -0
- package/dist/ot-editutil/all.d.ts +2 -0
- package/dist/ot-editutil/oteditutil.d.ts +14 -0
- package/dist/ot-editutil/otmaputil.d.ts +21 -0
- package/dist/ot-js/all.d.ts +9 -0
- package/dist/ot-js/otarray.d.ts +111 -0
- package/dist/ot-js/otclientengine.d.ts +38 -0
- package/dist/ot-js/otcomposite.d.ts +37 -0
- package/dist/ot-js/otcounter.d.ts +17 -0
- package/dist/ot-js/otengine.d.ts +22 -0
- package/dist/ot-js/otmap.d.ts +19 -0
- package/dist/ot-js/otserverengine.d.ts +38 -0
- package/dist/ot-js/otsession.d.ts +111 -0
- package/dist/ot-js/ottypes.d.ts +29 -0
- package/dist/poly/all.d.ts +15 -0
- package/dist/poly/blend.d.ts +1 -0
- package/dist/poly/boundbox.d.ts +16 -0
- package/dist/poly/cartesian.d.ts +5 -0
- package/dist/poly/graham-scan.d.ts +8 -0
- package/dist/poly/hash.d.ts +1 -0
- package/dist/poly/matrix.d.ts +24 -0
- package/dist/poly/minbound.d.ts +1 -0
- package/dist/poly/poly.d.ts +52 -0
- package/dist/poly/polybin.d.ts +5 -0
- package/dist/poly/polylabel.d.ts +7 -0
- package/dist/poly/polypack.d.ts +30 -0
- package/dist/poly/polyround.d.ts +1 -0
- package/dist/poly/polysimplify.d.ts +1 -0
- package/dist/poly/quad.d.ts +48 -0
- package/dist/poly/selfintersect.d.ts +1 -0
- package/dist/poly/shamos.d.ts +1 -0
- package/dist/poly/simplify.d.ts +2 -0
- package/dist/poly/topo.d.ts +46 -0
- package/dist/poly/union.d.ts +48 -0
- package/dist/storage/all.d.ts +4 -0
- package/dist/storage/datablob.d.ts +9 -0
- package/dist/storage/env.d.ts +10 -0
- package/dist/storage/splitsblob.d.ts +13 -0
- package/dist/storage/storage.d.ts +166 -0
- package/dist/storages3/all.d.ts +1 -0
- package/dist/storages3/s3.d.ts +62 -0
- package/dist/util/all.d.ts +5 -0
- package/dist/util/bintrie.d.ts +93 -0
- package/dist/util/countedhash.d.ts +19 -0
- package/dist/util/gradient.d.ts +15 -0
- package/dist/util/indexedarray.d.ts +15 -0
- package/dist/util/util.d.ts +68 -0
- package/docs/context.md +2 -0
- package/docs/dbabstract.md +2 -0
- package/docs/dbdynamo.md +2 -0
- package/docs/fsm.md +243 -0
- package/docs/fsmfile.md +2 -0
- package/docs/jsonstream.md +44 -0
- package/docs/lambda.md +2 -0
- package/docs/logabstract.md +2 -0
- package/docs/logclient.md +2 -0
- package/docs/logserver.md +2 -0
- package/docs/ot-editutil.md +2 -0
- package/docs/ot-js.md +95 -0
- package/docs/poly.md +103 -0
- package/docs/storage.md +2 -0
- package/docs/storages3.md +2 -0
- package/docs/util.md +2 -0
- package/lib/all/all.ts +41 -0
- package/lib/all/allclient.ts +19 -0
- package/lib/context/all.ts +1 -0
- package/lib/context/context.ts +82 -0
- package/lib/dbabstract/all.ts +1 -0
- package/lib/dbabstract/db.ts +246 -0
- package/lib/dbdynamo/all.ts +1 -0
- package/lib/dbdynamo/dbdynamo.ts +1551 -0
- package/lib/filterexpr/all.ts +1 -0
- package/lib/filterexpr/filterexpr.ts +625 -0
- package/lib/fsm/all.ts +1 -0
- package/lib/fsm/fsm.ts +549 -0
- package/lib/fsmfile/all.ts +1 -0
- package/lib/fsmfile/fsmfile.ts +236 -0
- package/lib/jsonstream/all.ts +1 -0
- package/lib/jsonstream/jsonstream.ts +940 -0
- package/lib/lambda/all.ts +1 -0
- package/lib/lambda/env.ts +13 -0
- package/lib/lambda/lambda.ts +120 -0
- package/lib/logabstract/all.ts +1 -0
- package/lib/logabstract/log.ts +55 -0
- package/lib/logclient/all.ts +1 -0
- package/lib/logclient/log.ts +105 -0
- package/lib/logserver/all.ts +5 -0
- package/lib/logserver/log.ts +565 -0
- package/lib/logserver/logaccum.ts +1445 -0
- package/lib/logserver/logblob.ts +84 -0
- package/lib/logserver/logconcat.ts +313 -0
- package/lib/logserver/logkey.ts +125 -0
- package/lib/memsqs/all.ts +4 -0
- package/lib/memsqs/client.ts +268 -0
- package/lib/memsqs/loopback.ts +64 -0
- package/lib/memsqs/orderedlist.ts +74 -0
- package/lib/memsqs/queue.ts +395 -0
- package/lib/memsqs/server.ts +262 -0
- package/lib/ot-editutil/all.ts +2 -0
- package/lib/ot-editutil/oteditutil.ts +180 -0
- package/lib/ot-editutil/otmaputil.ts +209 -0
- package/lib/ot-js/all.ts +9 -0
- package/lib/ot-js/otarray.ts +1168 -0
- package/lib/ot-js/otclientengine.ts +327 -0
- package/lib/ot-js/otcomposite.ts +247 -0
- package/lib/ot-js/otcounter.ts +145 -0
- package/lib/ot-js/otengine.ts +71 -0
- package/lib/ot-js/otmap.ts +144 -0
- package/lib/ot-js/otserverengine.ts +329 -0
- package/lib/ot-js/otsession.ts +199 -0
- package/lib/ot-js/ottypes.ts +98 -0
- package/lib/poly/all.ts +15 -0
- package/lib/poly/blend.ts +27 -0
- package/lib/poly/boundbox.ts +102 -0
- package/lib/poly/cartesian.ts +130 -0
- package/lib/poly/graham-scan.ts +401 -0
- package/lib/poly/hash.ts +15 -0
- package/lib/poly/matrix.ts +309 -0
- package/lib/poly/minbound.ts +211 -0
- package/lib/poly/poly.ts +767 -0
- package/lib/poly/polybin.ts +218 -0
- package/lib/poly/polylabel.ts +204 -0
- package/lib/poly/polypack.ts +458 -0
- package/lib/poly/polyround.ts +30 -0
- package/lib/poly/polysimplify.ts +24 -0
- package/lib/poly/quad.ts +272 -0
- package/lib/poly/selfintersect.ts +87 -0
- package/lib/poly/shamos.ts +297 -0
- package/lib/poly/simplify.ts +119 -0
- package/lib/poly/topo.ts +525 -0
- package/lib/poly/union.ts +371 -0
- package/lib/storage/all.ts +4 -0
- package/lib/storage/datablob.ts +36 -0
- package/lib/storage/env.ts +14 -0
- package/lib/storage/splitsblob.ts +63 -0
- package/lib/storage/storage.ts +604 -0
- package/lib/storages3/all.ts +1 -0
- package/lib/storages3/s3.ts +576 -0
- package/lib/util/all.ts +5 -0
- package/lib/util/bintrie.ts +603 -0
- package/lib/util/countedhash.ts +83 -0
- package/lib/util/gradient.ts +108 -0
- package/lib/util/indexedarray.ts +80 -0
- package/lib/util/util.ts +695 -0
- package/package.json +8 -8
|
@@ -0,0 +1,604 @@
|
|
|
1
|
+
// Node libraries
|
|
2
|
+
import * as stream from 'stream';
|
|
3
|
+
|
|
4
|
+
// Shared libraries
|
|
5
|
+
import * as Util from '../util/all';
|
|
6
|
+
import * as Context from '../context/all';
|
|
7
|
+
import * as FSM from '../fsm/all';
|
|
8
|
+
import * as LogAbstract from '../logabstract/all';
|
|
9
|
+
|
|
10
|
+
import { Environment } from './env';
|
|
11
|
+
|
|
12
|
+
export const ESuccess: number = 0;
|
|
13
|
+
export const EFail: number = 1;
|
|
14
|
+
export const ENotFound: number = 2;
|
|
15
|
+
export const EPending: number = 3;
|
|
16
|
+
export const EBadFormat: number = 4;
|
|
17
|
+
|
|
18
|
+
export type StorageState = number;
|
|
19
|
+
export const StorageStateClean = 0;
|
|
20
|
+
export const StorageStateDirty = 1;
|
|
21
|
+
export const StorageStateSaving = 2;
|
|
22
|
+
export const StorageStateLoading = 4;
|
|
23
|
+
export const StorageStateLoadCanceled = 8;
|
|
24
|
+
export const StorageStateLoadFailed = 16;
|
|
25
|
+
export const StorageStateDeleting = 32;
|
|
26
|
+
export const StorageStateDeleted = 64;
|
|
27
|
+
export const StorageStateListing = 128;
|
|
28
|
+
|
|
29
|
+
const StorageContextDefaults: Context.ContextValues = { StorageRetryDelay: 60000 };
|
|
30
|
+
|
|
31
|
+
export type BucketMap = { [key: string]: string };
|
|
32
|
+
export const BucketDefault = "default";
|
|
33
|
+
export const BucketDev = "development";
|
|
34
|
+
export const BucketProd = "production";
|
|
35
|
+
export const BucketLogs = "logs";
|
|
36
|
+
|
|
37
|
+
export type TransferUrlOp = 'putObject' | 'getObject';
|
|
38
|
+
|
|
39
|
+
export interface TransferParams
|
|
40
|
+
{
|
|
41
|
+
op: TransferUrlOp;
|
|
42
|
+
contentType?: string;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// Where does the source data for save come from?
|
|
46
|
+
export type DispositionType = 'object' | 'string' | 'buffer' | 'stream' | 'filepath';
|
|
47
|
+
export type LoadToFilter = (blob: StorageBlob, a: any) => any;
|
|
48
|
+
|
|
49
|
+
export interface BlobParams
|
|
50
|
+
{
|
|
51
|
+
id: string;
|
|
52
|
+
bucket?: string;
|
|
53
|
+
saveFromType?: DispositionType;
|
|
54
|
+
saveFrom?: any;
|
|
55
|
+
loadToType?: DispositionType;
|
|
56
|
+
loadTo?: any;
|
|
57
|
+
loadToFilter?: LoadToFilter;
|
|
58
|
+
deleteAfterLoad?: boolean;
|
|
59
|
+
suppressDeleteError?: boolean;
|
|
60
|
+
ContentEncoding?: string; // 'gzip' only
|
|
61
|
+
ContentType?: string; // 'application/json' or 'application/octet-stream'
|
|
62
|
+
CacheControl?: string; // 'no-cache' or 'max-age=14400'
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export class FsmTransferUrl extends FSM.Fsm
|
|
66
|
+
{
|
|
67
|
+
bucket: string;
|
|
68
|
+
key: string;
|
|
69
|
+
params: TransferParams;
|
|
70
|
+
url: string;
|
|
71
|
+
|
|
72
|
+
constructor(env: Environment, bucket: string, params: TransferParams)
|
|
73
|
+
{
|
|
74
|
+
super(env);
|
|
75
|
+
this.bucket = bucket;
|
|
76
|
+
this.params = Util.shallowAssignImmutable({ contentType: 'text/plain; charset=UTF-8' }, params);
|
|
77
|
+
this.key = Util.createGuid();
|
|
78
|
+
this.url = undefined;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export interface BlobProperties
|
|
83
|
+
{
|
|
84
|
+
Key?: string;
|
|
85
|
+
ContentLength?: number;
|
|
86
|
+
ContentDisposition?: string;
|
|
87
|
+
ContentEncoding?: string;
|
|
88
|
+
ContentType?: string;
|
|
89
|
+
ContentLanguage?: string;
|
|
90
|
+
LastModified?: string;
|
|
91
|
+
ETag?: string;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export interface MultiBufferList
|
|
95
|
+
{
|
|
96
|
+
buf: Buffer;
|
|
97
|
+
next: MultiBufferList;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
export class MultiBufferPassThrough extends stream.Duplex
|
|
101
|
+
{
|
|
102
|
+
_dopush: boolean;
|
|
103
|
+
_head: MultiBufferList;
|
|
104
|
+
_tail: MultiBufferList;
|
|
105
|
+
|
|
106
|
+
constructor()
|
|
107
|
+
{
|
|
108
|
+
super({});
|
|
109
|
+
this._dopush = false;
|
|
110
|
+
this._head = null;
|
|
111
|
+
this._tail = null;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
_read(): void
|
|
115
|
+
{
|
|
116
|
+
this._dopush = true;
|
|
117
|
+
this._dopushing();
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
_dopushing(): void
|
|
121
|
+
{
|
|
122
|
+
while (this._dopush && this._head)
|
|
123
|
+
{
|
|
124
|
+
this._dopush = this.push(this._head.buf);
|
|
125
|
+
this._head = this._head.next;
|
|
126
|
+
if (this._head == null)
|
|
127
|
+
this._tail = null;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
_pushChunk(chunk: any): void
|
|
132
|
+
{
|
|
133
|
+
let tail: MultiBufferList = { buf: chunk as Buffer, next: null };
|
|
134
|
+
if (this._head == null)
|
|
135
|
+
this._head = tail;
|
|
136
|
+
else
|
|
137
|
+
this._tail.next = tail;
|
|
138
|
+
this._tail = tail;
|
|
139
|
+
this._dopushing();
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
_write(chunk: any, encoding: string, cb: any): void
|
|
143
|
+
{
|
|
144
|
+
if (! Buffer.isBuffer(chunk)) throw 'MultiBufferPassThrough only supports writing Buffer type';
|
|
145
|
+
this._pushChunk(chunk);
|
|
146
|
+
cb(null);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
_done(): void
|
|
150
|
+
{
|
|
151
|
+
this._pushChunk(null);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
_flush(cb: any): void
|
|
155
|
+
{
|
|
156
|
+
this._read();
|
|
157
|
+
cb();
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
_transform(chunk: any, encoding: string, cb: any): void
|
|
161
|
+
{
|
|
162
|
+
this._write(chunk, encoding, cb);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
export class StorageBlob
|
|
167
|
+
{
|
|
168
|
+
_env: Environment;
|
|
169
|
+
params: BlobParams;
|
|
170
|
+
state: StorageState;
|
|
171
|
+
tStarted: Date;
|
|
172
|
+
fsmSave: FSM.Fsm;
|
|
173
|
+
fsmLoad: FSM.Fsm;
|
|
174
|
+
fsmDel: FSM.Fsm;
|
|
175
|
+
fsmList: FSM.Fsm;
|
|
176
|
+
_props: FSM.FsmArray;
|
|
177
|
+
_keys: FSM.FsmArray;
|
|
178
|
+
|
|
179
|
+
constructor(env: Environment, params: BlobParams)
|
|
180
|
+
{
|
|
181
|
+
this._env = env;
|
|
182
|
+
this.params = Util.shallowCopy(params);
|
|
183
|
+
this.env.context.setDefaults(StorageContextDefaults);
|
|
184
|
+
if (this.params.bucket == null) this.params.bucket = 'default';
|
|
185
|
+
this.state = StorageStateClean;
|
|
186
|
+
this.tStarted = null;
|
|
187
|
+
this.fsmSave = new FSM.Fsm(this.env);
|
|
188
|
+
this.fsmSave.setState(FSM.FSM_DONE);
|
|
189
|
+
this.fsmLoad = new FSM.Fsm(this.env);
|
|
190
|
+
this.fsmLoad.setState(FSM.FSM_DONE);
|
|
191
|
+
this.fsmDel = new FSM.Fsm(this.env);
|
|
192
|
+
this.fsmDel.setState(FSM.FSM_DONE);
|
|
193
|
+
this.fsmList = new FSM.Fsm(this.env);
|
|
194
|
+
this.fsmList.setState(FSM.FSM_DONE);
|
|
195
|
+
this._keys = new FSM.FsmArray(env);
|
|
196
|
+
this._props = new FSM.FsmArray(env);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
get env() { return this._env; }
|
|
200
|
+
|
|
201
|
+
// For listings, wait on fsmArray to get partial results, call resetList to reset fsmArray for next chunk, fsmList marked done at end.
|
|
202
|
+
// Or just wait for fsmList to get all results at once.
|
|
203
|
+
get keys(): string[] { return this._keys.a as string[] }
|
|
204
|
+
get props(): BlobProperties[] { return this._props.a as BlobProperties[] }
|
|
205
|
+
resetList(): void { this._keys.reset(); this._props.reset() }
|
|
206
|
+
get fsmArray(): FSM.Fsm { return this._keys }
|
|
207
|
+
|
|
208
|
+
setSaveFrom(t: DispositionType, data: any): void
|
|
209
|
+
{
|
|
210
|
+
this.params.saveFromType = t;
|
|
211
|
+
this.params.saveFrom = data;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
setLoadTo(t: DispositionType): void
|
|
215
|
+
{
|
|
216
|
+
this.params.loadToType = t;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
needSave(): boolean
|
|
220
|
+
{
|
|
221
|
+
if (this.state == StorageStateDirty)
|
|
222
|
+
return true;
|
|
223
|
+
if (this.state == StorageStateClean)
|
|
224
|
+
return false;
|
|
225
|
+
|
|
226
|
+
if (this.isDirty() && this.isSaving())
|
|
227
|
+
{
|
|
228
|
+
let now = new Date();
|
|
229
|
+
return now.getTime() - this.tStarted.getTime() > this.env.context.xnumber('StorageRetryDelay');
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
// Not loaded, either not yet, or load failed
|
|
233
|
+
return false;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
isSaving(): boolean
|
|
237
|
+
{
|
|
238
|
+
return (this.state & StorageStateSaving) != 0;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
isLoading(): boolean
|
|
242
|
+
{
|
|
243
|
+
return (this.state & StorageStateLoading) != 0;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
isListing(): boolean
|
|
247
|
+
{
|
|
248
|
+
return (this.state & StorageStateListing) != 0;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
setListing(): void
|
|
252
|
+
{
|
|
253
|
+
this.state |= StorageStateListing;
|
|
254
|
+
this.fsmList.setState(FSM.FSM_PENDING);
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
setListed(): void
|
|
258
|
+
{
|
|
259
|
+
this.state &= ~StorageStateListing;
|
|
260
|
+
// Don't set fsmList to DONE here - do in endList since we may continue listing
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
isDeleting(): boolean
|
|
264
|
+
{
|
|
265
|
+
return (this.state & StorageStateDeleting) != 0;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
isDeleted(): boolean
|
|
269
|
+
{
|
|
270
|
+
return (this.state & StorageStateDeleted) != 0;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
isLoadFailed(): boolean
|
|
274
|
+
{
|
|
275
|
+
return (this.state & StorageStateLoadFailed) != 0;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
isValid(): boolean
|
|
279
|
+
{
|
|
280
|
+
return !(this.isLoading() || this.isLoadFailed() || this.isDeleting() || this.isDeleted());
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
isReadable(): boolean
|
|
284
|
+
{
|
|
285
|
+
return !(this.isLoading() || this.isDeleting() || this.isDeleted());
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
isDirty(): boolean
|
|
289
|
+
{
|
|
290
|
+
return (this.state & StorageStateDirty) != 0;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
isSafeToUnload(): boolean
|
|
294
|
+
{
|
|
295
|
+
return !this.isLoading() && !this.isDirty() && !this.isSaving();
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
setDirty(): void
|
|
299
|
+
{
|
|
300
|
+
if ((this.state & StorageStateLoading) != 0)
|
|
301
|
+
{
|
|
302
|
+
this.env.log.error('storage: object being set dirty while loading');
|
|
303
|
+
}
|
|
304
|
+
this.state |= StorageStateDirty;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
setInit(): void
|
|
308
|
+
{
|
|
309
|
+
// Only used to allow auto-initialization for debugging
|
|
310
|
+
this.state = StorageStateClean;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
setLoading(): void
|
|
314
|
+
{
|
|
315
|
+
if (this.isDirty())
|
|
316
|
+
{
|
|
317
|
+
this.env.log.error('storage: object already dirty when getting loaded');
|
|
318
|
+
}
|
|
319
|
+
this.state |= StorageStateLoading;
|
|
320
|
+
this.tStarted = new Date();
|
|
321
|
+
this.fsmLoad.setState(FSM.FSM_PENDING);
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
setLoaded(result: number): void
|
|
325
|
+
{
|
|
326
|
+
if (this.isDirty())
|
|
327
|
+
{
|
|
328
|
+
this.env.log.error('storage: object already dirty when load finished');
|
|
329
|
+
}
|
|
330
|
+
if (result == ESuccess)
|
|
331
|
+
this.state = StorageStateClean;
|
|
332
|
+
else
|
|
333
|
+
this.state = StorageStateLoadFailed;
|
|
334
|
+
this.fsmLoad.setState(result === ESuccess ? FSM.FSM_DONE : FSM.FSM_ERROR);
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
setSaving(): void
|
|
338
|
+
{
|
|
339
|
+
this.state = StorageStateSaving;
|
|
340
|
+
this.tStarted = new Date();
|
|
341
|
+
this.fsmSave.setState(FSM.FSM_PENDING);
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
setSaved(result: number): void
|
|
345
|
+
{
|
|
346
|
+
if (result == ESuccess && this.state == StorageStateSaving)
|
|
347
|
+
this.state = StorageStateClean;
|
|
348
|
+
else
|
|
349
|
+
this.state = StorageStateDirty;
|
|
350
|
+
this.tStarted = null;
|
|
351
|
+
this.fsmSave.setState(result === ESuccess ? FSM.FSM_DONE : FSM.FSM_ERROR);
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
setDeleting(): void
|
|
355
|
+
{
|
|
356
|
+
this.state |= StorageStateDeleting;
|
|
357
|
+
this.fsmDel.setState(FSM.FSM_PENDING);
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
setDeleted(result: number): void
|
|
361
|
+
{
|
|
362
|
+
if (result == ESuccess)
|
|
363
|
+
this.state |= StorageStateDeleted;
|
|
364
|
+
else
|
|
365
|
+
this.env.log.error('storage: delete failed');
|
|
366
|
+
this.state &= ~StorageStateDeleting;
|
|
367
|
+
|
|
368
|
+
// Supports fire-and-forget
|
|
369
|
+
if (this.params.suppressDeleteError)
|
|
370
|
+
result = ESuccess;
|
|
371
|
+
this.fsmDel.setState(result === ESuccess ? FSM.FSM_DONE : FSM.FSM_ERROR);
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
startLoad(sm: StorageManager): void
|
|
375
|
+
{
|
|
376
|
+
sm.load(this);
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
startHead(sm: StorageManager): void
|
|
380
|
+
{
|
|
381
|
+
sm.head(this);
|
|
382
|
+
this.fsmList.setState(FSM.FSM_PENDING); // result fsmList for head request, results show up in props
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
checkSave(sm: StorageManager): void
|
|
386
|
+
{
|
|
387
|
+
if (this.needSave())
|
|
388
|
+
{
|
|
389
|
+
if (this.isSaving())
|
|
390
|
+
{
|
|
391
|
+
this.env.log.event('storage: save overlaps');
|
|
392
|
+
}
|
|
393
|
+
sm.save(this);
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
startDelete(sm: StorageManager): void
|
|
398
|
+
{
|
|
399
|
+
if (this.isDeleting())
|
|
400
|
+
{
|
|
401
|
+
this.env.log.error('storage: attempt to delete while deleting');
|
|
402
|
+
}
|
|
403
|
+
else
|
|
404
|
+
sm.del(this);
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
endSave(br: BlobRequest): void
|
|
408
|
+
{
|
|
409
|
+
// fsmSave triggered by setSaved
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
endLoad(br: BlobRequest): void
|
|
413
|
+
{
|
|
414
|
+
if (this.params.loadToType === undefined)
|
|
415
|
+
throw 'endLoad: loadToType must be set';
|
|
416
|
+
|
|
417
|
+
if (br.result() == ESuccess)
|
|
418
|
+
{
|
|
419
|
+
switch (this.params.loadToType)
|
|
420
|
+
{
|
|
421
|
+
case 'stream':
|
|
422
|
+
// No work here, processing happened in stream handlers
|
|
423
|
+
break;
|
|
424
|
+
case 'buffer':
|
|
425
|
+
this.params.loadTo = br.asBuffer(); // automatically uncompressed if necessary
|
|
426
|
+
break;
|
|
427
|
+
case 'string':
|
|
428
|
+
this.params.loadTo = br.asString(); // automatically uncompressed if necessary
|
|
429
|
+
break;
|
|
430
|
+
case 'object':
|
|
431
|
+
{
|
|
432
|
+
try
|
|
433
|
+
{
|
|
434
|
+
this.params.loadTo = JSON.parse(br.asString());
|
|
435
|
+
}
|
|
436
|
+
catch(err)
|
|
437
|
+
{
|
|
438
|
+
this.env.log.error('storage: could not parse JSON');
|
|
439
|
+
this.fsmLoad.setState(FSM.FSM_ERROR);
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
break;
|
|
443
|
+
case 'filepath':
|
|
444
|
+
throw 'endLoad: filepath is not a supported value for loadTo';
|
|
445
|
+
break;
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
if (this.params.loadToFilter)
|
|
449
|
+
this.params.loadTo = this.params.loadToFilter(this, this.params.loadTo);
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
// Support auto-delete behavior
|
|
453
|
+
if (this.params.deleteAfterLoad)
|
|
454
|
+
this.startDelete(this.env.storageManager);
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
endHead(br: BlobRequest): void
|
|
458
|
+
{
|
|
459
|
+
if (br.result() == ESuccess)
|
|
460
|
+
{
|
|
461
|
+
let a = br.asProps();
|
|
462
|
+
if (a && a.length > 0)
|
|
463
|
+
this.props.push(a[0]);
|
|
464
|
+
}
|
|
465
|
+
this.fsmList.setState(br.result() ? FSM.FSM_ERROR : FSM.FSM_DONE);
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
endDelete(br: BlobRequest): void
|
|
469
|
+
{
|
|
470
|
+
// Note that fsmDel is marked complete in setDeleted
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
startList(sm: StorageManager, continuationToken?: string): void
|
|
474
|
+
{
|
|
475
|
+
if (this.isListing())
|
|
476
|
+
{
|
|
477
|
+
this.env.log.error('storage: attempt to list while listing');
|
|
478
|
+
}
|
|
479
|
+
else
|
|
480
|
+
{
|
|
481
|
+
sm.ls(this, continuationToken);
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
endList(br: BlobRequest): void
|
|
486
|
+
{
|
|
487
|
+
if (! br.result())
|
|
488
|
+
{
|
|
489
|
+
let props = br.asProps();
|
|
490
|
+
this._keys.concat(props.map(p => p.Key));
|
|
491
|
+
this._props.concat(props);
|
|
492
|
+
if (br.continuationToken())
|
|
493
|
+
this.env.storageManager.ls(this, br.continuationToken());
|
|
494
|
+
else
|
|
495
|
+
{
|
|
496
|
+
// Set _keys and _props to done since might not have happened if no values to push
|
|
497
|
+
this._keys.setState(FSM.FSM_DONE);
|
|
498
|
+
this._props.setState(FSM.FSM_DONE);
|
|
499
|
+
this.fsmList.setState(FSM.FSM_DONE);
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
else
|
|
503
|
+
{
|
|
504
|
+
this.env.log.error(`list failed: ${br.asError()}`);
|
|
505
|
+
this._keys.setState(FSM.FSM_ERROR);
|
|
506
|
+
this._props.setState(FSM.FSM_ERROR);
|
|
507
|
+
this.fsmList.setState(FSM.FSM_ERROR);
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
toLoadStream(): stream.Readable
|
|
512
|
+
{
|
|
513
|
+
return this.params.loadToType === 'stream' ? this.params.loadTo as stream.Readable : null;
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
setLoadStream(rs: stream.Readable): void
|
|
517
|
+
{
|
|
518
|
+
this.params.loadToType = 'stream';
|
|
519
|
+
this.params.loadTo = rs;
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
export interface BlobRequest
|
|
524
|
+
{
|
|
525
|
+
blob: StorageBlob;
|
|
526
|
+
|
|
527
|
+
result(): number;
|
|
528
|
+
asBuffer(): Buffer;
|
|
529
|
+
asString(): string;
|
|
530
|
+
asError(): string;
|
|
531
|
+
asProps(): BlobProperties[];
|
|
532
|
+
continuationToken(): string;
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
export interface BlobRequestIndex
|
|
536
|
+
{
|
|
537
|
+
[key: string]: BlobRequest;
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
export class StorageManager
|
|
541
|
+
{
|
|
542
|
+
_env: Environment;
|
|
543
|
+
saveBlobIndex: BlobRequestIndex;
|
|
544
|
+
loadBlobIndex: BlobRequestIndex;
|
|
545
|
+
headBlobIndex: BlobRequestIndex;
|
|
546
|
+
delBlobIndex: BlobRequestIndex;
|
|
547
|
+
lsBlobIndex: BlobRequestIndex;
|
|
548
|
+
onList: any;
|
|
549
|
+
bucketMap: BucketMap;
|
|
550
|
+
|
|
551
|
+
constructor(env: Environment, bucketMap?: BucketMap)
|
|
552
|
+
{
|
|
553
|
+
this._env = env;
|
|
554
|
+
this.saveBlobIndex = {};
|
|
555
|
+
this.loadBlobIndex = {};
|
|
556
|
+
this.headBlobIndex = {};
|
|
557
|
+
this.delBlobIndex = {};
|
|
558
|
+
this.lsBlobIndex = {};
|
|
559
|
+
this.onList = {};
|
|
560
|
+
this.bucketMap = bucketMap;
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
save(blob: StorageBlob): void {} // override
|
|
564
|
+
load(blob: StorageBlob): void {} // override
|
|
565
|
+
del(blob: StorageBlob): void {} // override
|
|
566
|
+
head(blob: StorageBlob): void {} // override
|
|
567
|
+
ls(blob: StorageBlob, continuationToken?: string): void {} // override
|
|
568
|
+
createTransferUrl(params: TransferParams): FsmTransferUrl { return null } // override
|
|
569
|
+
|
|
570
|
+
on(eventName: string, cb: any): void
|
|
571
|
+
{
|
|
572
|
+
let aCB: any[] = this.onList[eventName];
|
|
573
|
+
if (aCB === undefined)
|
|
574
|
+
{
|
|
575
|
+
aCB = [];
|
|
576
|
+
this.onList[eventName] = aCB;
|
|
577
|
+
}
|
|
578
|
+
aCB.push(cb);
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
off(eventName: string, cb: any): void
|
|
582
|
+
{
|
|
583
|
+
let aCB: any[] = this.onList[eventName];
|
|
584
|
+
if (aCB !== undefined)
|
|
585
|
+
{
|
|
586
|
+
for (let i: number = 0; i < aCB.length; i++)
|
|
587
|
+
if (aCB[i] === cb)
|
|
588
|
+
{
|
|
589
|
+
aCB.splice(i, 1);
|
|
590
|
+
break;
|
|
591
|
+
}
|
|
592
|
+
}
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
emit(eventName: string, blob: StorageBlob): void
|
|
596
|
+
{
|
|
597
|
+
let aCB: any[] = this.onList[eventName];
|
|
598
|
+
if (aCB !== undefined)
|
|
599
|
+
{
|
|
600
|
+
for (let i: number = 0; i < aCB.length; i++)
|
|
601
|
+
(aCB[i])(blob);
|
|
602
|
+
}
|
|
603
|
+
}
|
|
604
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './s3';
|