@rsdk/nats.object-storage 5.4.0-next.6 → 5.4.0-next.8
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/CHANGELOG.md +8 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/patch.d.ts +1 -0
- package/dist/patch.js +239 -0
- package/dist/patch.js.map +1 -0
- package/package.json +2 -2
- package/src/index.ts +2 -0
- package/src/patch.ts +292 -0
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,14 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
## [5.4.0-next.8](https://github.com/R-Vision/rsdk/compare/v5.4.0-next.7...v5.4.0-next.8) (2024-11-28)
|
|
7
|
+
|
|
8
|
+
**Note:** Version bump only for package @rsdk/nats.object-storage
|
|
9
|
+
|
|
10
|
+
## [5.4.0-next.7](https://github.com/R-Vision/rsdk/compare/v5.4.0-next.6...v5.4.0-next.7) (2024-11-28)
|
|
11
|
+
|
|
12
|
+
**Note:** Version bump only for package @rsdk/nats.object-storage
|
|
13
|
+
|
|
6
14
|
## [5.4.0-next.6](https://github.com/R-Vision/rsdk/compare/v5.4.0-next.5...v5.4.0-next.6) (2024-11-28)
|
|
7
15
|
|
|
8
16
|
**Note:** Version bump only for package @rsdk/nats.object-storage
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -15,6 +15,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
17
|
exports.ObjectStorage = exports.NatsObjectStorageModule = exports.WatchObjectStorage = exports.NatsObjectStorageService = void 0;
|
|
18
|
+
require("./patch");
|
|
18
19
|
var nats_object_storage_service_1 = require("./nats-object-storage.service");
|
|
19
20
|
Object.defineProperty(exports, "NatsObjectStorageService", { enumerable: true, get: function () { return nats_object_storage_service_1.NatsObjectStorageService; } });
|
|
20
21
|
var watch_object_storage_decorator_1 = require("./watch-object-storage.decorator");
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,6EAAyE;AAAhE,uIAAA,wBAAwB,OAAA;AACjC,mFAG0C;AAFxC,oIAAA,kBAAkB,OAAA;AAGpB,2EAAuE;AAA9D,qIAAA,uBAAuB,OAAA;AAChC,mDAAiD;AAAxC,+GAAA,aAAa,OAAA;AACtB,4EAA0D;AAC1D,8CAA4B"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,mBAAiB;AAEjB,6EAAyE;AAAhE,uIAAA,wBAAwB,OAAA;AACjC,mFAG0C;AAFxC,oIAAA,kBAAkB,OAAA;AAGpB,2EAAuE;AAA9D,qIAAA,uBAAuB,OAAA;AAChC,mDAAiD;AAAxC,+GAAA,aAAa,OAAA;AACtB,4EAA0D;AAC1D,8CAA4B"}
|
package/dist/patch.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/patch.js
ADDED
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const nats_1 = require("nats");
|
|
4
|
+
const objectstore_1 = require("nats/lib/jetstream/objectstore");
|
|
5
|
+
const codec_1 = require("nats/lib/nats-base-client/codec");
|
|
6
|
+
const queued_iterator_1 = require("nats/lib/nats-base-client/queued_iterator");
|
|
7
|
+
const sha256_1 = require("nats/lib/nats-base-client/sha256");
|
|
8
|
+
function emptyReadableStream() {
|
|
9
|
+
return new ReadableStream({
|
|
10
|
+
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
|
|
11
|
+
pull(c) {
|
|
12
|
+
c.enqueue(new Uint8Array(0));
|
|
13
|
+
c.close();
|
|
14
|
+
},
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
class ObjectInfoImpl {
|
|
18
|
+
info;
|
|
19
|
+
hdrs;
|
|
20
|
+
constructor(oi) {
|
|
21
|
+
this.info = oi;
|
|
22
|
+
}
|
|
23
|
+
get name() {
|
|
24
|
+
return this.info.name;
|
|
25
|
+
}
|
|
26
|
+
get description() {
|
|
27
|
+
return this.info.description ?? '';
|
|
28
|
+
}
|
|
29
|
+
get headers() {
|
|
30
|
+
if (!this.hdrs) {
|
|
31
|
+
this.hdrs = nats_1.MsgHdrsImpl.fromRecord(this.info.headers || {});
|
|
32
|
+
}
|
|
33
|
+
return this.hdrs;
|
|
34
|
+
}
|
|
35
|
+
get options() {
|
|
36
|
+
return this.info.options;
|
|
37
|
+
}
|
|
38
|
+
get bucket() {
|
|
39
|
+
return this.info.bucket;
|
|
40
|
+
}
|
|
41
|
+
get chunks() {
|
|
42
|
+
return this.info.chunks;
|
|
43
|
+
}
|
|
44
|
+
get deleted() {
|
|
45
|
+
return this.info.deleted ?? false;
|
|
46
|
+
}
|
|
47
|
+
get digest() {
|
|
48
|
+
return this.info.digest;
|
|
49
|
+
}
|
|
50
|
+
get mtime() {
|
|
51
|
+
return this.info.mtime;
|
|
52
|
+
}
|
|
53
|
+
get nuid() {
|
|
54
|
+
return this.info.nuid;
|
|
55
|
+
}
|
|
56
|
+
get size() {
|
|
57
|
+
return this.info.size;
|
|
58
|
+
}
|
|
59
|
+
get revision() {
|
|
60
|
+
return this.info.revision;
|
|
61
|
+
}
|
|
62
|
+
get metadata() {
|
|
63
|
+
return this.info.metadata || {};
|
|
64
|
+
}
|
|
65
|
+
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
|
|
66
|
+
isLink() {
|
|
67
|
+
return (this.info.options?.link !== undefined && this.info.options?.link !== null);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
objectstore_1.ObjectStoreImpl.prototype.get = async function get(name) {
|
|
71
|
+
const info = await this.rawInfo(name);
|
|
72
|
+
if (info === null) {
|
|
73
|
+
return null;
|
|
74
|
+
}
|
|
75
|
+
if (info.deleted) {
|
|
76
|
+
return null;
|
|
77
|
+
}
|
|
78
|
+
if (info.options && info.options.link) {
|
|
79
|
+
const ln = info.options.link.name || ' ';
|
|
80
|
+
if (ln === '') {
|
|
81
|
+
throw new Error('link is a bucket');
|
|
82
|
+
}
|
|
83
|
+
const os = info.options.link.bucket === this.name
|
|
84
|
+
? this
|
|
85
|
+
: await objectstore_1.ObjectStoreImpl.create(this.js, info.options.link.bucket);
|
|
86
|
+
return os.get(ln);
|
|
87
|
+
}
|
|
88
|
+
const d = (0, nats_1.deferred)();
|
|
89
|
+
const r = {
|
|
90
|
+
info: new ObjectInfoImpl(info),
|
|
91
|
+
error: d,
|
|
92
|
+
};
|
|
93
|
+
if (info.size === 0) {
|
|
94
|
+
r.data = emptyReadableStream();
|
|
95
|
+
d.resolve(null);
|
|
96
|
+
return r;
|
|
97
|
+
}
|
|
98
|
+
let controller;
|
|
99
|
+
const oc = (0, nats_1.consumerOpts)();
|
|
100
|
+
oc.orderedConsumer();
|
|
101
|
+
const sha = new sha256_1.SHA256();
|
|
102
|
+
const subj = `$O.${this.name}.C.${info.nuid}`;
|
|
103
|
+
let sub;
|
|
104
|
+
try {
|
|
105
|
+
// eslint-disable-next-line deprecation/deprecation
|
|
106
|
+
sub = await this.js.subscribe(subj, oc);
|
|
107
|
+
}
|
|
108
|
+
catch (error) {
|
|
109
|
+
if (error.message !== 'no stream matches subject') {
|
|
110
|
+
throw error;
|
|
111
|
+
}
|
|
112
|
+
const oc = (0, nats_1.consumerOpts)({
|
|
113
|
+
ack_policy: nats_1.AckPolicy.None,
|
|
114
|
+
});
|
|
115
|
+
oc.orderedConsumer();
|
|
116
|
+
oc.bindStream('OBJ_' + this.name);
|
|
117
|
+
// HACK: for mirrored ObjectStore
|
|
118
|
+
// eslint-disable-next-line deprecation/deprecation
|
|
119
|
+
sub = await this.js.subscribe(subj, oc);
|
|
120
|
+
}
|
|
121
|
+
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
|
|
122
|
+
(async () => {
|
|
123
|
+
for await (const jm of sub) {
|
|
124
|
+
if (jm.data.length > 0) {
|
|
125
|
+
sha.update(jm.data);
|
|
126
|
+
controller.enqueue(jm.data);
|
|
127
|
+
}
|
|
128
|
+
if (jm.info.pending === 0) {
|
|
129
|
+
const hash = sha.digest('base64');
|
|
130
|
+
// go pads the hash - which should be multiple of 3 - otherwise pads with '='
|
|
131
|
+
const pad = hash.length % 3;
|
|
132
|
+
const padding = pad > 0 ? '='.repeat(pad) : '';
|
|
133
|
+
const digest = `${objectstore_1.digestType}${hash}${padding}`;
|
|
134
|
+
if (digest === info.digest) {
|
|
135
|
+
controller.close();
|
|
136
|
+
}
|
|
137
|
+
else {
|
|
138
|
+
controller.error(new Error(`received a corrupt object, digests do not match received: ${info.digest} calculated ${digest}`));
|
|
139
|
+
}
|
|
140
|
+
sub.unsubscribe();
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
})()
|
|
144
|
+
.then(() => {
|
|
145
|
+
d.resolve();
|
|
146
|
+
})
|
|
147
|
+
.catch((error) => {
|
|
148
|
+
controller.error(error);
|
|
149
|
+
d.reject(error);
|
|
150
|
+
});
|
|
151
|
+
r.data = new ReadableStream({
|
|
152
|
+
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
|
|
153
|
+
start(c) {
|
|
154
|
+
controller = c;
|
|
155
|
+
},
|
|
156
|
+
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
|
|
157
|
+
cancel() {
|
|
158
|
+
sub.unsubscribe();
|
|
159
|
+
},
|
|
160
|
+
});
|
|
161
|
+
return r;
|
|
162
|
+
};
|
|
163
|
+
objectstore_1.ObjectStoreImpl.prototype.watch = async function watch(opts = {}) {
|
|
164
|
+
opts.includeHistory = opts.includeHistory ?? false;
|
|
165
|
+
opts.ignoreDeletes = opts.ignoreDeletes ?? false;
|
|
166
|
+
let initialized = false;
|
|
167
|
+
const qi = new queued_iterator_1.QueuedIteratorImpl();
|
|
168
|
+
const subj = this._metaSubjectAll();
|
|
169
|
+
try {
|
|
170
|
+
await this.jsm.streams.getMessage(this.stream, { last_by_subj: subj });
|
|
171
|
+
}
|
|
172
|
+
catch (error) {
|
|
173
|
+
if (error.code === '404') {
|
|
174
|
+
qi.push(null);
|
|
175
|
+
initialized = true;
|
|
176
|
+
}
|
|
177
|
+
else {
|
|
178
|
+
qi.stop(error);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
const jc = (0, codec_1.JSONCodec)();
|
|
182
|
+
const copts = (0, nats_1.consumerOpts)();
|
|
183
|
+
copts.orderedConsumer();
|
|
184
|
+
if (opts.includeHistory) {
|
|
185
|
+
copts.deliverLastPerSubject();
|
|
186
|
+
}
|
|
187
|
+
else {
|
|
188
|
+
// FIXME: Go's implementation doesn't seem correct - if history is not desired
|
|
189
|
+
// the watch should only be giving notifications on new entries
|
|
190
|
+
initialized = true;
|
|
191
|
+
copts.deliverNew();
|
|
192
|
+
}
|
|
193
|
+
copts.callback((err, jm) => {
|
|
194
|
+
if (err) {
|
|
195
|
+
qi.stop(err);
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
if (jm !== null) {
|
|
199
|
+
const oi = jc.decode(jm.data);
|
|
200
|
+
if (oi.deleted && opts.ignoreDeletes === true) {
|
|
201
|
+
// do nothing
|
|
202
|
+
}
|
|
203
|
+
else {
|
|
204
|
+
qi.push(oi);
|
|
205
|
+
}
|
|
206
|
+
if (jm.info?.pending === 0 && !initialized) {
|
|
207
|
+
initialized = true;
|
|
208
|
+
qi.push(null);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
});
|
|
212
|
+
let sub;
|
|
213
|
+
try {
|
|
214
|
+
// eslint-disable-next-line deprecation/deprecation
|
|
215
|
+
sub = await this.js.subscribe(subj, copts);
|
|
216
|
+
}
|
|
217
|
+
catch (error) {
|
|
218
|
+
if (error.message !== 'no stream matches subject') {
|
|
219
|
+
throw error;
|
|
220
|
+
}
|
|
221
|
+
copts.bindStream('OBJ_' + this.name);
|
|
222
|
+
// HACK: for mirrored ObjectStore
|
|
223
|
+
// eslint-disable-next-line deprecation/deprecation
|
|
224
|
+
sub = await this.js.subscribe(subj, copts);
|
|
225
|
+
}
|
|
226
|
+
qi._data = sub;
|
|
227
|
+
qi.iterClosed.then(() => {
|
|
228
|
+
sub.unsubscribe();
|
|
229
|
+
});
|
|
230
|
+
sub.closed
|
|
231
|
+
.then(() => {
|
|
232
|
+
qi.stop();
|
|
233
|
+
})
|
|
234
|
+
.catch((error) => {
|
|
235
|
+
qi.stop(error);
|
|
236
|
+
});
|
|
237
|
+
return qi;
|
|
238
|
+
};
|
|
239
|
+
//# sourceMappingURL=patch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"patch.js","sourceRoot":"","sources":["../src/patch.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rsdk/nats.object-storage",
|
|
3
|
-
"version": "5.4.0-next.
|
|
3
|
+
"version": "5.4.0-next.8",
|
|
4
4
|
"description": "Nats NestJS object storage",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"license": "Apache License 2.0",
|
|
@@ -38,5 +38,5 @@
|
|
|
38
38
|
"rxjs": "^7.8.1"
|
|
39
39
|
},
|
|
40
40
|
"nx": {},
|
|
41
|
-
"gitHead": "
|
|
41
|
+
"gitHead": "074c1ef262b547be8daab9c721680ad2f0df2bb3"
|
|
42
42
|
}
|
package/src/index.ts
CHANGED
package/src/patch.ts
ADDED
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
2
|
+
// @ts-nocheck issue - https://github.com/nats-io/nats.js/issues/155
|
|
3
|
+
import type {
|
|
4
|
+
MsgHdrs,
|
|
5
|
+
ObjectInfo,
|
|
6
|
+
ObjectResult,
|
|
7
|
+
ObjectStoreMetaOptions,
|
|
8
|
+
} from 'nats';
|
|
9
|
+
import { AckPolicy, consumerOpts, deferred, MsgHdrsImpl } from 'nats';
|
|
10
|
+
import type { ServerObjectInfo } from 'nats/lib/jetstream/objectstore';
|
|
11
|
+
import { digestType, ObjectStoreImpl } from 'nats/lib/jetstream/objectstore';
|
|
12
|
+
import { JSONCodec } from 'nats/lib/nats-base-client/codec';
|
|
13
|
+
import { QueuedIteratorImpl } from 'nats/lib/nats-base-client/queued_iterator';
|
|
14
|
+
import { SHA256 } from 'nats/lib/nats-base-client/sha256';
|
|
15
|
+
|
|
16
|
+
function emptyReadableStream(): ReadableStream {
|
|
17
|
+
return new ReadableStream({
|
|
18
|
+
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
|
|
19
|
+
pull(c) {
|
|
20
|
+
c.enqueue(new Uint8Array(0));
|
|
21
|
+
c.close();
|
|
22
|
+
},
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
class ObjectInfoImpl implements ObjectInfo {
|
|
27
|
+
info: ServerObjectInfo;
|
|
28
|
+
hdrs!: MsgHdrs;
|
|
29
|
+
constructor(oi: ServerObjectInfo) {
|
|
30
|
+
this.info = oi;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
get name(): string {
|
|
34
|
+
return this.info.name;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
get description(): string {
|
|
38
|
+
return this.info.description ?? '';
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
get headers(): MsgHdrs {
|
|
42
|
+
if (!this.hdrs) {
|
|
43
|
+
this.hdrs = MsgHdrsImpl.fromRecord(this.info.headers || {});
|
|
44
|
+
}
|
|
45
|
+
return this.hdrs;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
get options(): ObjectStoreMetaOptions | undefined {
|
|
49
|
+
return this.info.options;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
get bucket(): string {
|
|
53
|
+
return this.info.bucket;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
get chunks(): number {
|
|
57
|
+
return this.info.chunks;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
get deleted(): boolean {
|
|
61
|
+
return this.info.deleted ?? false;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
get digest(): string {
|
|
65
|
+
return this.info.digest;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
get mtime(): string {
|
|
69
|
+
return this.info.mtime;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
get nuid(): string {
|
|
73
|
+
return this.info.nuid;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
get size(): number {
|
|
77
|
+
return this.info.size;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
get revision(): number {
|
|
81
|
+
return this.info.revision;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
get metadata(): Record<string, string> {
|
|
85
|
+
return this.info.metadata || {};
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
|
|
89
|
+
isLink() {
|
|
90
|
+
return (
|
|
91
|
+
this.info.options?.link !== undefined && this.info.options?.link !== null
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
ObjectStoreImpl.prototype.get = async function get(
|
|
97
|
+
name: string,
|
|
98
|
+
): Promise<ObjectResult | null> {
|
|
99
|
+
const info = await this.rawInfo(name);
|
|
100
|
+
if (info === null) {
|
|
101
|
+
return null;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
if (info.deleted) {
|
|
105
|
+
return null;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
if (info.options && info.options.link) {
|
|
109
|
+
const ln = info.options.link.name || ' ';
|
|
110
|
+
if (ln === '') {
|
|
111
|
+
throw new Error('link is a bucket');
|
|
112
|
+
}
|
|
113
|
+
const os =
|
|
114
|
+
info.options.link.bucket === this.name
|
|
115
|
+
? this
|
|
116
|
+
: await ObjectStoreImpl.create(this.js, info.options.link.bucket);
|
|
117
|
+
|
|
118
|
+
return os.get(ln);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
const d = deferred<Error | null>();
|
|
122
|
+
|
|
123
|
+
const r: Partial<ObjectResult> = {
|
|
124
|
+
info: new ObjectInfoImpl(info),
|
|
125
|
+
error: d,
|
|
126
|
+
};
|
|
127
|
+
if (info.size === 0) {
|
|
128
|
+
r.data = emptyReadableStream();
|
|
129
|
+
d.resolve(null);
|
|
130
|
+
return r as ObjectResult;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
let controller: ReadableStreamDefaultController;
|
|
134
|
+
|
|
135
|
+
const oc = consumerOpts();
|
|
136
|
+
|
|
137
|
+
oc.orderedConsumer();
|
|
138
|
+
const sha = new SHA256();
|
|
139
|
+
const subj = `$O.${this.name}.C.${info.nuid}`;
|
|
140
|
+
let sub;
|
|
141
|
+
|
|
142
|
+
try {
|
|
143
|
+
// eslint-disable-next-line deprecation/deprecation
|
|
144
|
+
sub = await this.js.subscribe(subj, oc);
|
|
145
|
+
} catch (error) {
|
|
146
|
+
if (error.message !== 'no stream matches subject') {
|
|
147
|
+
throw error;
|
|
148
|
+
}
|
|
149
|
+
const oc = consumerOpts({
|
|
150
|
+
ack_policy: AckPolicy.None,
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
oc.orderedConsumer();
|
|
154
|
+
oc.bindStream('OBJ_' + this.name);
|
|
155
|
+
|
|
156
|
+
// HACK: for mirrored ObjectStore
|
|
157
|
+
// eslint-disable-next-line deprecation/deprecation
|
|
158
|
+
sub = await this.js.subscribe(subj, oc);
|
|
159
|
+
}
|
|
160
|
+
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
|
|
161
|
+
(async () => {
|
|
162
|
+
for await (const jm of sub) {
|
|
163
|
+
if (jm.data.length > 0) {
|
|
164
|
+
sha.update(jm.data);
|
|
165
|
+
controller!.enqueue(jm.data);
|
|
166
|
+
}
|
|
167
|
+
if (jm.info.pending === 0) {
|
|
168
|
+
const hash = sha.digest('base64');
|
|
169
|
+
|
|
170
|
+
// go pads the hash - which should be multiple of 3 - otherwise pads with '='
|
|
171
|
+
const pad = hash.length % 3;
|
|
172
|
+
const padding = pad > 0 ? '='.repeat(pad) : '';
|
|
173
|
+
const digest = `${digestType}${hash}${padding}`;
|
|
174
|
+
if (digest === info.digest) {
|
|
175
|
+
controller!.close();
|
|
176
|
+
} else {
|
|
177
|
+
controller!.error(
|
|
178
|
+
new Error(
|
|
179
|
+
`received a corrupt object, digests do not match received: ${info.digest} calculated ${digest}`,
|
|
180
|
+
),
|
|
181
|
+
);
|
|
182
|
+
}
|
|
183
|
+
sub.unsubscribe();
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
})()
|
|
187
|
+
.then(() => {
|
|
188
|
+
d.resolve();
|
|
189
|
+
})
|
|
190
|
+
.catch((error) => {
|
|
191
|
+
controller!.error(error);
|
|
192
|
+
d.reject(error);
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
r.data = new ReadableStream({
|
|
196
|
+
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
|
|
197
|
+
start(c) {
|
|
198
|
+
controller = c;
|
|
199
|
+
},
|
|
200
|
+
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
|
|
201
|
+
cancel() {
|
|
202
|
+
sub.unsubscribe();
|
|
203
|
+
},
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
return r as ObjectResult;
|
|
207
|
+
};
|
|
208
|
+
|
|
209
|
+
ObjectStoreImpl.prototype.watch = async function watch(
|
|
210
|
+
opts: Partial<{
|
|
211
|
+
ignoreDeletes?: boolean;
|
|
212
|
+
includeHistory?: boolean;
|
|
213
|
+
}> = {},
|
|
214
|
+
): Promise<QueuedIterator<ObjectInfo | null>> {
|
|
215
|
+
opts.includeHistory = opts.includeHistory ?? false;
|
|
216
|
+
opts.ignoreDeletes = opts.ignoreDeletes ?? false;
|
|
217
|
+
let initialized = false;
|
|
218
|
+
const qi = new QueuedIteratorImpl<ObjectInfo | null>();
|
|
219
|
+
const subj = this._metaSubjectAll();
|
|
220
|
+
|
|
221
|
+
try {
|
|
222
|
+
await this.jsm.streams.getMessage(this.stream, { last_by_subj: subj });
|
|
223
|
+
} catch (error) {
|
|
224
|
+
if (error.code === '404') {
|
|
225
|
+
qi.push(null);
|
|
226
|
+
initialized = true;
|
|
227
|
+
} else {
|
|
228
|
+
qi.stop(error);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
const jc = JSONCodec<ObjectInfo>();
|
|
232
|
+
const copts = consumerOpts();
|
|
233
|
+
|
|
234
|
+
copts.orderedConsumer();
|
|
235
|
+
if (opts.includeHistory) {
|
|
236
|
+
copts.deliverLastPerSubject();
|
|
237
|
+
} else {
|
|
238
|
+
// FIXME: Go's implementation doesn't seem correct - if history is not desired
|
|
239
|
+
// the watch should only be giving notifications on new entries
|
|
240
|
+
initialized = true;
|
|
241
|
+
copts.deliverNew();
|
|
242
|
+
}
|
|
243
|
+
copts.callback((err: NatsError | null, jm: JsMsg | null) => {
|
|
244
|
+
if (err) {
|
|
245
|
+
qi.stop(err);
|
|
246
|
+
return;
|
|
247
|
+
}
|
|
248
|
+
if (jm !== null) {
|
|
249
|
+
const oi = jc.decode(jm.data);
|
|
250
|
+
if (oi.deleted && opts.ignoreDeletes === true) {
|
|
251
|
+
// do nothing
|
|
252
|
+
} else {
|
|
253
|
+
qi.push(oi);
|
|
254
|
+
}
|
|
255
|
+
if (jm.info?.pending === 0 && !initialized) {
|
|
256
|
+
initialized = true;
|
|
257
|
+
qi.push(null);
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
});
|
|
261
|
+
|
|
262
|
+
let sub;
|
|
263
|
+
|
|
264
|
+
try {
|
|
265
|
+
// eslint-disable-next-line deprecation/deprecation
|
|
266
|
+
sub = await this.js.subscribe(subj, copts);
|
|
267
|
+
} catch (error) {
|
|
268
|
+
if (error.message !== 'no stream matches subject') {
|
|
269
|
+
throw error;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
copts.bindStream('OBJ_' + this.name);
|
|
273
|
+
|
|
274
|
+
// HACK: for mirrored ObjectStore
|
|
275
|
+
// eslint-disable-next-line deprecation/deprecation
|
|
276
|
+
sub = await this.js.subscribe(subj, copts);
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
qi._data = sub;
|
|
280
|
+
qi.iterClosed.then(() => {
|
|
281
|
+
sub.unsubscribe();
|
|
282
|
+
});
|
|
283
|
+
sub.closed
|
|
284
|
+
.then(() => {
|
|
285
|
+
qi.stop();
|
|
286
|
+
})
|
|
287
|
+
.catch((error) => {
|
|
288
|
+
qi.stop(error);
|
|
289
|
+
});
|
|
290
|
+
|
|
291
|
+
return qi;
|
|
292
|
+
};
|