@rsdk/nats.object-storage 5.4.0-next.2

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 (46) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/dist/constants.d.ts +1 -0
  3. package/dist/constants.js +5 -0
  4. package/dist/constants.js.map +1 -0
  5. package/dist/index.d.ts +5 -0
  6. package/dist/index.js +27 -0
  7. package/dist/index.js.map +1 -0
  8. package/dist/inject-object-storage-service.decorator.d.ts +2 -0
  9. package/dist/inject-object-storage-service.decorator.js +19 -0
  10. package/dist/inject-object-storage-service.decorator.js.map +1 -0
  11. package/dist/nats-object-storage-module.generator.d.ts +5 -0
  12. package/dist/nats-object-storage-module.generator.js +30 -0
  13. package/dist/nats-object-storage-module.generator.js.map +1 -0
  14. package/dist/nats-object-storage.module.d.ts +9 -0
  15. package/dist/nats-object-storage.module.js +63 -0
  16. package/dist/nats-object-storage.module.js.map +1 -0
  17. package/dist/nats-object-storage.service.d.ts +34 -0
  18. package/dist/nats-object-storage.service.js +99 -0
  19. package/dist/nats-object-storage.service.js.map +1 -0
  20. package/dist/object-storage.d.ts +27 -0
  21. package/dist/object-storage.js +43 -0
  22. package/dist/object-storage.js.map +1 -0
  23. package/dist/tokens.fn.d.ts +2 -0
  24. package/dist/tokens.fn.js +8 -0
  25. package/dist/tokens.fn.js.map +1 -0
  26. package/dist/watch-object-storage.decorator.d.ts +23 -0
  27. package/dist/watch-object-storage.decorator.js +19 -0
  28. package/dist/watch-object-storage.decorator.js.map +1 -0
  29. package/dist/watch-object-storage.service.d.ts +45 -0
  30. package/dist/watch-object-storage.service.js +112 -0
  31. package/dist/watch-object-storage.service.js.map +1 -0
  32. package/jest.config.js +1 -0
  33. package/jest.config.unit.js +1 -0
  34. package/package.json +42 -0
  35. package/src/constants.ts +1 -0
  36. package/src/index.ts +8 -0
  37. package/src/inject-object-storage-service.decorator.ts +45 -0
  38. package/src/nats-object-storage-module.generator.ts +52 -0
  39. package/src/nats-object-storage.module.ts +58 -0
  40. package/src/nats-object-storage.service.ts +111 -0
  41. package/src/object-storage.ts +53 -0
  42. package/src/tokens.fn.ts +10 -0
  43. package/src/watch-object-storage.decorator.ts +30 -0
  44. package/src/watch-object-storage.service.ts +129 -0
  45. package/tsconfig.build.json +12 -0
  46. package/tsconfig.json +7 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,10 @@
1
+ # Change Log
2
+
3
+ All notable changes to this project will be documented in this file.
4
+ See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
+
6
+ ## [5.4.0-next.2](https://github.com/R-Vision/rsdk/compare/v5.4.0-next.1...v5.4.0-next.2) (2024-11-25)
7
+
8
+ ### Features
9
+
10
+ * **nats:** nats transport/kv/os + examples + docs ([#306](https://github.com/R-Vision/rsdk/issues/306)) ([de67eed](https://github.com/R-Vision/rsdk/commit/de67eed8b4cb17ec9d359067eae1e0c35d6cc736))
@@ -0,0 +1 @@
1
+ export declare const NATS_OBJECT_STORAGES_RSDK_METADATA_SCOPE = "nats-object-storages";
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.NATS_OBJECT_STORAGES_RSDK_METADATA_SCOPE = void 0;
4
+ exports.NATS_OBJECT_STORAGES_RSDK_METADATA_SCOPE = 'nats-object-storages';
5
+ //# sourceMappingURL=constants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":";;;AAAa,QAAA,wCAAwC,GAAG,sBAAsB,CAAC"}
@@ -0,0 +1,5 @@
1
+ export { NatsObjectStorageService } from './nats-object-storage.service';
2
+ export { WatchObjectStorage, type ObjectStorageWatcher, } from './watch-object-storage.decorator';
3
+ export { NatsObjectStorageModule } from './nats-object-storage.module';
4
+ export { ObjectStorage } from './object-storage';
5
+ export * from './inject-object-storage-service.decorator';
package/dist/index.js ADDED
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.ObjectStorage = exports.NatsObjectStorageModule = exports.WatchObjectStorage = exports.NatsObjectStorageService = void 0;
18
+ var nats_object_storage_service_1 = require("./nats-object-storage.service");
19
+ Object.defineProperty(exports, "NatsObjectStorageService", { enumerable: true, get: function () { return nats_object_storage_service_1.NatsObjectStorageService; } });
20
+ var watch_object_storage_decorator_1 = require("./watch-object-storage.decorator");
21
+ Object.defineProperty(exports, "WatchObjectStorage", { enumerable: true, get: function () { return watch_object_storage_decorator_1.WatchObjectStorage; } });
22
+ var nats_object_storage_module_1 = require("./nats-object-storage.module");
23
+ Object.defineProperty(exports, "NatsObjectStorageModule", { enumerable: true, get: function () { return nats_object_storage_module_1.NatsObjectStorageModule; } });
24
+ var object_storage_1 = require("./object-storage");
25
+ Object.defineProperty(exports, "ObjectStorage", { enumerable: true, get: function () { return object_storage_1.ObjectStorage; } });
26
+ __exportStar(require("./inject-object-storage-service.decorator"), exports);
27
+ //# sourceMappingURL=index.js.map
@@ -0,0 +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"}
@@ -0,0 +1,2 @@
1
+ export declare const InjectObjectStorageService: (connectionName?: string) => ParameterDecorator;
2
+ export declare const InjectNatsObjectStorage: (bucketName: string, connectionName?: string) => ParameterDecorator;
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.InjectNatsObjectStorage = exports.InjectObjectStorageService = void 0;
4
+ const common_1 = require("@nestjs/common");
5
+ const metadata_1 = require("@rsdk/metadata");
6
+ const nats_object_storage_module_generator_1 = require("./nats-object-storage-module.generator");
7
+ const tokens_fn_1 = require("./tokens.fn");
8
+ const InjectObjectStorageService = (connectionName) => (0, common_1.Inject)((0, tokens_fn_1.createObjectStorageServiceToken)(connectionName));
9
+ exports.InjectObjectStorageService = InjectObjectStorageService;
10
+ const InjectNatsObjectStorage = (bucketName, connectionName) => {
11
+ return (target, propertyKey, parameterIndex) => {
12
+ (0, common_1.Inject)((0, tokens_fn_1.createObjectStorageToken)(bucketName, connectionName))(target, propertyKey, parameterIndex);
13
+ const key = `nats-kv:${bucketName}${connectionName ? `:${connectionName}` : ''}`;
14
+ const moduleDefinition = nats_object_storage_module_generator_1.NatsObjectStorageModuleGenerator.createClientModuleDefinition(target, bucketName, connectionName);
15
+ metadata_1.RsdkMetadata.setWithScope(target, metadata_1.PLATFORM_RAW_GLOBAL_METADATA_SCOPE, key, moduleDefinition, true);
16
+ };
17
+ };
18
+ exports.InjectNatsObjectStorage = InjectNatsObjectStorage;
19
+ //# sourceMappingURL=inject-object-storage-service.decorator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inject-object-storage-service.decorator.js","sourceRoot":"","sources":["../src/inject-object-storage-service.decorator.ts"],"names":[],"mappings":";;;AAAA,2CAAwC;AACxC,6CAGwB;AAExB,iGAA0F;AAC1F,2CAGqB;AAEd,MAAM,0BAA0B,GAAG,CACxC,cAAuB,EACH,EAAE,CACtB,IAAA,eAAM,EAAC,IAAA,2CAA+B,EAAC,cAAc,CAAC,CAAC,CAAC;AAH7C,QAAA,0BAA0B,8BAGmB;AAEnD,MAAM,uBAAuB,GAAG,CACrC,UAAkB,EAClB,cAAuB,EACH,EAAE;IACtB,OAAO,CAAC,MAAM,EAAE,WAAW,EAAE,cAAc,EAAE,EAAE;QAC7C,IAAA,eAAM,EAAC,IAAA,oCAAwB,EAAC,UAAU,EAAE,cAAc,CAAC,CAAC,CAC1D,MAAM,EACN,WAAW,EACX,cAAc,CACf,CAAC;QAEF,MAAM,GAAG,GAAG,WAAW,UAAU,GAAG,cAAc,CAAC,CAAC,CAAC,IAAI,cAAc,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;QACjF,MAAM,gBAAgB,GACpB,uEAAgC,CAAC,4BAA4B,CAC3D,MAAM,EACN,UAAU,EACV,cAAc,CACf,CAAC;QAEJ,uBAAY,CAAC,YAAY,CACvB,MAAM,EACN,6CAAkC,EAClC,GAAG,EACH,gBAAgB,EAChB,IAAI,CACL,CAAC;IACJ,CAAC,CAAC;AACJ,CAAC,CAAC;AA3BW,QAAA,uBAAuB,2BA2BlC"}
@@ -0,0 +1,5 @@
1
+ import type { DynamicModule } from '@nestjs/common';
2
+ export declare class NatsObjectStorageModuleGenerator {
3
+ static createClientModuleDefinition(target: object, bucketName: string, connectionName?: string): DynamicModule;
4
+ private static createClientProvider;
5
+ }
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.NatsObjectStorageModuleGenerator = void 0;
4
+ const metadata_1 = require("@rsdk/metadata");
5
+ const constants_1 = require("./constants");
6
+ const nats_object_storage_module_1 = require("./nats-object-storage.module");
7
+ const tokens_fn_1 = require("./tokens.fn");
8
+ class NatsObjectStorageModuleGenerator {
9
+ static createClientModuleDefinition(target, bucketName, connectionName) {
10
+ const provider = NatsObjectStorageModuleGenerator.createClientProvider(bucketName, connectionName);
11
+ const moduleDefinition = {
12
+ global: true,
13
+ imports: [nats_object_storage_module_1.NatsObjectStorageModule.forFeature(connectionName)],
14
+ module: NatsObjectStorageModuleGenerator,
15
+ providers: [provider],
16
+ exports: [provider],
17
+ };
18
+ metadata_1.RsdkMetadata.add(target, { bucketName, connectionName }, constants_1.NATS_OBJECT_STORAGES_RSDK_METADATA_SCOPE);
19
+ return moduleDefinition;
20
+ }
21
+ static createClientProvider(bucketName, connectionName) {
22
+ return {
23
+ provide: (0, tokens_fn_1.createObjectStorageToken)(bucketName, connectionName),
24
+ inject: [(0, tokens_fn_1.createObjectStorageServiceToken)(connectionName)],
25
+ useFactory: (service) => service.create({ bucketName, onlyExists: true }),
26
+ };
27
+ }
28
+ }
29
+ exports.NatsObjectStorageModuleGenerator = NatsObjectStorageModuleGenerator;
30
+ //# sourceMappingURL=nats-object-storage-module.generator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nats-object-storage-module.generator.js","sourceRoot":"","sources":["../src/nats-object-storage-module.generator.ts"],"names":[],"mappings":";;;AACA,6CAA8C;AAE9C,2CAAuE;AACvE,6EAAuE;AAGvE,2CAGqB;AAErB,MAAa,gCAAgC;IAC3C,MAAM,CAAC,4BAA4B,CACjC,MAAc,EACd,UAAkB,EAClB,cAAuB;QAEvB,MAAM,QAAQ,GAAG,gCAAgC,CAAC,oBAAoB,CACpE,UAAU,EACV,cAAc,CACf,CAAC;QAEF,MAAM,gBAAgB,GAAkB;YACtC,MAAM,EAAE,IAAI;YACZ,OAAO,EAAE,CAAC,oDAAuB,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC;YAC7D,MAAM,EAAE,gCAAgC;YACxC,SAAS,EAAE,CAAC,QAAQ,CAAC;YACrB,OAAO,EAAE,CAAC,QAAQ,CAAC;SACpB,CAAC;QAEF,uBAAY,CAAC,GAAG,CACd,MAAM,EACN,EAAE,UAAU,EAAE,cAAc,EAAE,EAC9B,oDAAwC,CACzC,CAAC;QAEF,OAAO,gBAAgB,CAAC;IAC1B,CAAC;IAEO,MAAM,CAAC,oBAAoB,CACjC,UAAkB,EAClB,cAAuB;QAEvB,OAAO;YACL,OAAO,EAAE,IAAA,oCAAwB,EAAC,UAAU,EAAE,cAAc,CAAC;YAC7D,MAAM,EAAE,CAAC,IAAA,2CAA+B,EAAC,cAAc,CAAC,CAAC;YACzD,UAAU,EAAE,CAAC,OAAiC,EAA0B,EAAE,CACxE,OAAO,CAAC,MAAM,CAAC,EAAE,UAAU,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC;SACnD,CAAC;IACJ,CAAC;CACF;AAvCD,4EAuCC"}
@@ -0,0 +1,9 @@
1
+ import type { DynamicModule, OnModuleDestroy, OnModuleInit } from '@nestjs/common';
2
+ import { WatchObjectStorageService } from './watch-object-storage.service';
3
+ export declare class NatsObjectStorageModule implements OnModuleInit, OnModuleDestroy {
4
+ private readonly watchService;
5
+ constructor(watchService: WatchObjectStorageService);
6
+ static forFeature(connectionName?: string): DynamicModule;
7
+ onModuleInit(): Promise<void>;
8
+ onModuleDestroy(): Promise<void>;
9
+ }
@@ -0,0 +1,63 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ var NatsObjectStorageModule_1;
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ exports.NatsObjectStorageModule = void 0;
14
+ const common_1 = require("@nestjs/common");
15
+ const core_1 = require("@nestjs/core");
16
+ const nats_common_1 = require("@rsdk/nats.common");
17
+ const nats_object_storage_service_1 = require("./nats-object-storage.service");
18
+ const tokens_fn_1 = require("./tokens.fn");
19
+ const watch_object_storage_service_1 = require("./watch-object-storage.service");
20
+ let NatsObjectStorageModule = NatsObjectStorageModule_1 = class NatsObjectStorageModule {
21
+ watchService;
22
+ constructor(watchService) {
23
+ this.watchService = watchService;
24
+ }
25
+ static forFeature(connectionName) {
26
+ const clientProvider = {
27
+ provide: (0, tokens_fn_1.createObjectStorageServiceToken)(connectionName),
28
+ useClass: nats_object_storage_service_1.NatsObjectStorageService,
29
+ };
30
+ return {
31
+ module: NatsObjectStorageModule_1,
32
+ providers: [
33
+ {
34
+ provide: nats_common_1.NATS_CLIENT_INJECTION_TOKEN_FOR_PACKAGE,
35
+ useExisting: connectionName
36
+ ? (0, nats_common_1.createNatsClientToken)(connectionName)
37
+ : nats_common_1.NATS_CLIENT_INJECTION_TOKEN,
38
+ },
39
+ {
40
+ provide: 'CONNECTION_NAME',
41
+ useFactory: () => connectionName,
42
+ },
43
+ clientProvider,
44
+ ],
45
+ exports: [clientProvider],
46
+ };
47
+ }
48
+ async onModuleInit() {
49
+ await this.watchService?.runWatches();
50
+ }
51
+ async onModuleDestroy() {
52
+ await this.watchService?.stopWatches();
53
+ }
54
+ };
55
+ exports.NatsObjectStorageModule = NatsObjectStorageModule;
56
+ exports.NatsObjectStorageModule = NatsObjectStorageModule = NatsObjectStorageModule_1 = __decorate([
57
+ (0, common_1.Module)({
58
+ imports: [core_1.DiscoveryModule],
59
+ providers: [nats_object_storage_service_1.NatsObjectStorageService, watch_object_storage_service_1.WatchObjectStorageService],
60
+ }),
61
+ __metadata("design:paramtypes", [watch_object_storage_service_1.WatchObjectStorageService])
62
+ ], NatsObjectStorageModule);
63
+ //# sourceMappingURL=nats-object-storage.module.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nats-object-storage.module.js","sourceRoot":"","sources":["../src/nats-object-storage.module.ts"],"names":[],"mappings":";;;;;;;;;;;;;AAMA,2CAAwC;AACxC,uCAA+C;AAC/C,mDAI2B;AAE3B,+EAAyE;AACzE,2CAA8D;AAC9D,iFAA2E;AAMpE,IAAM,uBAAuB,+BAA7B,MAAM,uBAAuB;IACL;IAA7B,YAA6B,YAAuC;QAAvC,iBAAY,GAAZ,YAAY,CAA2B;IAAG,CAAC;IAEjE,MAAM,CAAC,UAAU,CAAC,cAAuB;QAC9C,MAAM,cAAc,GAAa;YAC/B,OAAO,EAAE,IAAA,2CAA+B,EAAC,cAAc,CAAC;YACxD,QAAQ,EAAE,sDAAwB;SACnC,CAAC;QAEF,OAAO;YACL,MAAM,EAAE,yBAAuB;YAC/B,SAAS,EAAE;gBACT;oBACE,OAAO,EAAE,qDAAuC;oBAChD,WAAW,EAAE,cAAc;wBACzB,CAAC,CAAC,IAAA,mCAAqB,EAAC,cAAc,CAAC;wBACvC,CAAC,CAAC,yCAA2B;iBAChC;gBACD;oBACE,OAAO,EAAE,iBAAiB;oBAC1B,UAAU,EAAE,GAAG,EAAE,CAAC,cAAc;iBACjC;gBACD,cAAc;aACf;YACD,OAAO,EAAE,CAAC,cAAc,CAAC;SAC1B,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,YAAY;QAChB,MAAM,IAAI,CAAC,YAAY,EAAE,UAAU,EAAE,CAAC;IACxC,CAAC;IAED,KAAK,CAAC,eAAe;QACnB,MAAM,IAAI,CAAC,YAAY,EAAE,WAAW,EAAE,CAAC;IACzC,CAAC;CACF,CAAA;AAnCY,0DAAuB;kCAAvB,uBAAuB;IAJnC,IAAA,eAAM,EAAC;QACN,OAAO,EAAE,CAAC,sBAAe,CAAC;QAC1B,SAAS,EAAE,CAAC,sDAAwB,EAAE,wDAAyB,CAAC;KACjE,CAAC;qCAE2C,wDAAyB;GADzD,uBAAuB,CAmCnC"}
@@ -0,0 +1,34 @@
1
+ import { ILogger } from '@rsdk/logging';
2
+ import { NatsConnection } from 'nats';
3
+ import type { ObjectStoreOptions } from 'nats/lib/jetstream/types';
4
+ import { ObjectStorage } from './object-storage';
5
+ export declare class NatsObjectStorageService {
6
+ private readonly logger;
7
+ private readonly nats;
8
+ constructor(logger: ILogger, nats: NatsConnection);
9
+ /**
10
+ * Get or create object storage
11
+ */
12
+ create({ bucketName, domain, onlyExists, ...opts }: Partial<ObjectStoreOptions> & {
13
+ bucketName: string;
14
+ domain?: string;
15
+ onlyExists?: boolean;
16
+ }): Promise<ObjectStorage>;
17
+ /**
18
+ * Waits for the specified bucket to exist.
19
+ *
20
+ * @param bucketName - The name of the bucket to wait for.
21
+ * @param timeout - The maximum time to wait for the bucket to exist, in milliseconds. Defaults to infinity.
22
+ * @throws {InternalException} If the bucket does not exist within the specified timeout.
23
+ */
24
+ waitForBucketExists(bucketName: string, timeout?: number): Promise<void>;
25
+ /**
26
+ * Checks if a bucket exists.
27
+ *
28
+ * @param bucket - The name of the bucket to check.
29
+ * @returns A promise that resolves to a boolean indicating whether the bucket exists or not.
30
+ */
31
+ isBucketExists(bucket: string, opts?: {
32
+ domain?: string;
33
+ }): Promise<boolean>;
34
+ }
@@ -0,0 +1,99 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
12
+ return function (target, key) { decorator(target, key, paramIndex); }
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.NatsObjectStorageService = void 0;
16
+ const common_1 = require("@nestjs/common");
17
+ const common_2 = require("@rsdk/common");
18
+ const core_1 = require("@rsdk/core");
19
+ const nats_common_1 = require("@rsdk/nats.common");
20
+ const object_storage_1 = require("./object-storage");
21
+ let NatsObjectStorageService = class NatsObjectStorageService {
22
+ logger;
23
+ nats;
24
+ constructor(logger, nats) {
25
+ this.logger = logger;
26
+ this.nats = nats;
27
+ }
28
+ /**
29
+ * Get or create object storage
30
+ */
31
+ async create({ bucketName, domain, onlyExists, ...opts }) {
32
+ const jsOptions = domain ? { domain } : undefined;
33
+ const js = this.nats.jetstream(jsOptions);
34
+ try {
35
+ if (onlyExists && !(await this.isBucketExists(bucketName, jsOptions))) {
36
+ throw new core_1.NotFoundException(`Object storage bucket "${bucketName}" not found`);
37
+ }
38
+ const storage = await js.views.os(bucketName, opts);
39
+ this.logger.trace('Object storage initialized', {
40
+ connectionName: this.nats.info,
41
+ bucket: bucketName,
42
+ });
43
+ return new object_storage_1.ObjectStorage(storage);
44
+ }
45
+ catch (error) {
46
+ this.logger.error('Failed to get or create object storage', {
47
+ err: error,
48
+ bucket: bucketName,
49
+ });
50
+ throw error;
51
+ }
52
+ }
53
+ /**
54
+ * Waits for the specified bucket to exist.
55
+ *
56
+ * @param bucketName - The name of the bucket to wait for.
57
+ * @param timeout - The maximum time to wait for the bucket to exist, in milliseconds. Defaults to infinity.
58
+ * @throws {InternalException} If the bucket does not exist within the specified timeout.
59
+ */
60
+ async waitForBucketExists(bucketName, timeout = Number.POSITIVE_INFINITY) {
61
+ const start = Date.now();
62
+ while (true) {
63
+ if (await this.isBucketExists(bucketName)) {
64
+ this.logger.trace('Object storage bucket exists');
65
+ return;
66
+ }
67
+ if (timeout && Date.now() - start > timeout) {
68
+ throw new core_1.InternalException(`Bucket ${bucketName} does not exist`);
69
+ }
70
+ this.logger.trace('Object storage bucket does not exist, retry after 3 seconds...', {
71
+ bucketName,
72
+ });
73
+ await (0, common_2.delay)(common_2.Timespan.second(3));
74
+ }
75
+ }
76
+ /**
77
+ * Checks if a bucket exists.
78
+ *
79
+ * @param bucket - The name of the bucket to check.
80
+ * @returns A promise that resolves to a boolean indicating whether the bucket exists or not.
81
+ */
82
+ async isBucketExists(bucket, opts) {
83
+ try {
84
+ await this.nats.jetstream(opts).streams.get(`OBJ_${bucket}`);
85
+ }
86
+ catch {
87
+ return false;
88
+ }
89
+ return true;
90
+ }
91
+ };
92
+ exports.NatsObjectStorageService = NatsObjectStorageService;
93
+ exports.NatsObjectStorageService = NatsObjectStorageService = __decorate([
94
+ (0, common_1.Injectable)(),
95
+ __param(0, (0, core_1.InjectLogger)(NatsObjectStorageService)),
96
+ __param(1, (0, common_1.Inject)(nats_common_1.NATS_CLIENT_INJECTION_TOKEN_FOR_PACKAGE)),
97
+ __metadata("design:paramtypes", [Object, Object])
98
+ ], NatsObjectStorageService);
99
+ //# sourceMappingURL=nats-object-storage.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nats-object-storage.service.js","sourceRoot":"","sources":["../src/nats-object-storage.service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ import type { ObjectInfo, ObjectResult, ObjectStore, ObjectStoreMeta, ObjectStorePutOpts, PurgeResponse } from 'nats';
2
+ export declare class ObjectStorage {
3
+ private readonly storage;
4
+ constructor(storage: ObjectStore);
5
+ /**
6
+ * Возвращает метаданные и стрим с объектом
7
+ */
8
+ get(key: string): Promise<ObjectResult | null>;
9
+ /**
10
+ * Удаляет объект
11
+ */
12
+ delete(key: string): Promise<PurgeResponse>;
13
+ /**
14
+ * Загружает объект в хранилище
15
+ */
16
+ put(meta: ObjectStoreMeta, rs: ReadableStream<Uint8Array>, opts?: ObjectStorePutOpts): Promise<ObjectInfo>;
17
+ /**
18
+ * Возвращает массив всех объектов в хранилище
19
+ */
20
+ list(): Promise<ObjectInfo[]>;
21
+ /**
22
+ * Возвращает сырой object storage Nats. Используйте этот метод
23
+ * только в крайнем случае! Рекомендуется работать с оберткой
24
+ * для безопасного взаимодействия.
25
+ */
26
+ getRawStorage(): ObjectStore;
27
+ }
@@ -0,0 +1,43 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ObjectStorage = void 0;
4
+ class ObjectStorage {
5
+ storage;
6
+ constructor(storage) {
7
+ this.storage = storage;
8
+ }
9
+ /**
10
+ * Возвращает метаданные и стрим с объектом
11
+ */
12
+ get(key) {
13
+ return this.storage.get(key);
14
+ }
15
+ /**
16
+ * Удаляет объект
17
+ */
18
+ delete(key) {
19
+ return this.storage.delete(key);
20
+ }
21
+ /**
22
+ * Загружает объект в хранилище
23
+ */
24
+ put(meta, rs, opts) {
25
+ return this.storage.put(meta, rs, opts);
26
+ }
27
+ /**
28
+ * Возвращает массив всех объектов в хранилище
29
+ */
30
+ list() {
31
+ return this.storage.list();
32
+ }
33
+ /**
34
+ * Возвращает сырой object storage Nats. Используйте этот метод
35
+ * только в крайнем случае! Рекомендуется работать с оберткой
36
+ * для безопасного взаимодействия.
37
+ */
38
+ getRawStorage() {
39
+ return this.storage;
40
+ }
41
+ }
42
+ exports.ObjectStorage = ObjectStorage;
43
+ //# sourceMappingURL=object-storage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"object-storage.js","sourceRoot":"","sources":["../src/object-storage.ts"],"names":[],"mappings":";;;AASA,MAAa,aAAa;IACK;IAA7B,YAA6B,OAAoB;QAApB,YAAO,GAAP,OAAO,CAAa;IAAG,CAAC;IAErD;;OAEG;IACI,GAAG,CAAC,GAAW;QACpB,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC/B,CAAC;IAED;;OAEG;IACI,MAAM,CAAC,GAAW;QACvB,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAClC,CAAC;IAED;;OAEG;IACI,GAAG,CACR,IAAqB,EACrB,EAA8B,EAC9B,IAAyB;QAEzB,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,EAAE,IAAI,CAAC,CAAC;IAC1C,CAAC;IAED;;OAEG;IACI,IAAI;QACT,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;IAC7B,CAAC;IAED;;;;OAIG;IACI,aAAa;QAClB,OAAO,IAAI,CAAC,OAAO,CAAC;IACtB,CAAC;CACF;AA3CD,sCA2CC"}
@@ -0,0 +1,2 @@
1
+ export declare const createObjectStorageServiceToken: (connectionName?: string) => string;
2
+ export declare const createObjectStorageToken: (bucketName: string, connectionName?: string) => string;
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createObjectStorageToken = exports.createObjectStorageServiceToken = void 0;
4
+ const createObjectStorageServiceToken = (connectionName) => `NATS_OBJECT_STORAGE_SERVICE${connectionName ? `_${connectionName}` : ''}`;
5
+ exports.createObjectStorageServiceToken = createObjectStorageServiceToken;
6
+ const createObjectStorageToken = (bucketName, connectionName) => `NATS_OBJECT_STORAGE_${bucketName}${connectionName ? `_${connectionName}` : ''}`;
7
+ exports.createObjectStorageToken = createObjectStorageToken;
8
+ //# sourceMappingURL=tokens.fn.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tokens.fn.js","sourceRoot":"","sources":["../src/tokens.fn.ts"],"names":[],"mappings":";;;AAAO,MAAM,+BAA+B,GAAG,CAC7C,cAAuB,EACf,EAAE,CACV,8BAA8B,cAAc,CAAC,CAAC,CAAC,IAAI,cAAc,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;AAHhE,QAAA,+BAA+B,mCAGiC;AAEtE,MAAM,wBAAwB,GAAG,CACtC,UAAkB,EAClB,cAAuB,EACf,EAAE,CACV,uBAAuB,UAAU,GAAG,cAAc,CAAC,CAAC,CAAC,IAAI,cAAc,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;AAJtE,QAAA,wBAAwB,4BAI8C"}
@@ -0,0 +1,23 @@
1
+ import type { ObjectInfo } from 'nats';
2
+ export type WatchConfig = {
3
+ bucket: string;
4
+ ignoreDeletes?: boolean;
5
+ includeHistory?: boolean;
6
+ connectionName?: string;
7
+ };
8
+ export interface ObjectStorageWatcher {
9
+ onDelete(entry: ObjectInfo | null): Promise<void>;
10
+ onPut(entry: ObjectInfo | null): Promise<void>;
11
+ }
12
+ /**
13
+ * Key used to mark class as a watcher for object storage.
14
+ */
15
+ export declare const WATCH_NATS_OBJECT_STORAGE_KEY = "WATCH_NATS_OBJECT_STORAGE";
16
+ /**
17
+ * Decorator used to mark class as a watcher for object storage.
18
+ * Needs to be used in conjunction with the `ObjectStorageWatcher` interface.
19
+ *
20
+ * @param {WatchConfig} config - The configuration for watching object storage.
21
+ * @returns {void}
22
+ */
23
+ export declare const WatchObjectStorage: import("@nestjs/core").ReflectableDecorator<WatchConfig, WatchConfig>;
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.WatchObjectStorage = exports.WATCH_NATS_OBJECT_STORAGE_KEY = void 0;
4
+ const core_1 = require("@nestjs/core");
5
+ /**
6
+ * Key used to mark class as a watcher for object storage.
7
+ */
8
+ exports.WATCH_NATS_OBJECT_STORAGE_KEY = 'WATCH_NATS_OBJECT_STORAGE';
9
+ /**
10
+ * Decorator used to mark class as a watcher for object storage.
11
+ * Needs to be used in conjunction with the `ObjectStorageWatcher` interface.
12
+ *
13
+ * @param {WatchConfig} config - The configuration for watching object storage.
14
+ * @returns {void}
15
+ */
16
+ exports.WatchObjectStorage = core_1.Reflector.createDecorator({
17
+ key: exports.WATCH_NATS_OBJECT_STORAGE_KEY,
18
+ });
19
+ //# sourceMappingURL=watch-object-storage.decorator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"watch-object-storage.decorator.js","sourceRoot":"","sources":["../src/watch-object-storage.decorator.ts"],"names":[],"mappings":";;;AAAA,uCAAyC;AAezC;;GAEG;AACU,QAAA,6BAA6B,GAAG,2BAA2B,CAAC;AAEzE;;;;;;GAMG;AACU,QAAA,kBAAkB,GAAG,gBAAS,CAAC,eAAe,CAAc;IACvE,GAAG,EAAE,qCAA6B;CACnC,CAAC,CAAC"}
@@ -0,0 +1,45 @@
1
+ import { DiscoveryService } from '@nestjs/core';
2
+ import { ILogger } from '@rsdk/logging';
3
+ import type { ObjectInfo, ObjectStore } from 'nats';
4
+ import { NatsObjectStorageService } from './nats-object-storage.service';
5
+ export declare class WatchObjectStorageService {
6
+ private readonly logger;
7
+ private readonly discovery;
8
+ private readonly client;
9
+ private readonly connectionName?;
10
+ constructor(logger: ILogger, discovery: DiscoveryService, client: NatsObjectStorageService, connectionName?: string | undefined);
11
+ /**
12
+ * Runs the watches for the object storage service.
13
+ * Waits for buckets to exist and starts the watch operation for each bucket.
14
+ */
15
+ runWatches(): Promise<void>;
16
+ /**
17
+ * Stops all watches.
18
+ *
19
+ * @note This method is not implemented yet.
20
+ */
21
+ stopWatches(): Promise<void>;
22
+ /**
23
+ * Register watcher callback for object storage
24
+ */
25
+ watch(storage: ObjectStore, callback: (entry: ObjectInfo | null) => Promise<void>, opts?: {
26
+ ignoreDeletes?: boolean;
27
+ includeHistory?: boolean;
28
+ }): Promise<void>;
29
+ /**
30
+ * Runs the watch operation for the given metadata and watcher.
31
+ *
32
+ * @param config - The watch configuration.
33
+ * @param watcher - The ObjectStorageWatcher instance.
34
+ * @returns A Promise that resolves when the watch operation is complete.
35
+ */
36
+ private runWatch;
37
+ /**
38
+ * Discovers and returns an array of ObjectStorageWatcher instances
39
+ * along with their corresponding metadata.
40
+ *
41
+ * @returns An array of objects containing the ObjectStorageWatcher
42
+ * instance and its metadata.
43
+ */
44
+ private discoverWatchers;
45
+ }
@@ -0,0 +1,112 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
12
+ return function (target, key) { decorator(target, key, paramIndex); }
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.WatchObjectStorageService = void 0;
16
+ const common_1 = require("@nestjs/common");
17
+ const core_1 = require("@nestjs/core");
18
+ const core_2 = require("@rsdk/core");
19
+ const nats_object_storage_service_1 = require("./nats-object-storage.service");
20
+ const watch_object_storage_decorator_1 = require("./watch-object-storage.decorator");
21
+ let WatchObjectStorageService = class WatchObjectStorageService {
22
+ logger;
23
+ discovery;
24
+ client;
25
+ connectionName;
26
+ constructor(logger, discovery, client, connectionName) {
27
+ this.logger = logger;
28
+ this.discovery = discovery;
29
+ this.client = client;
30
+ this.connectionName = connectionName;
31
+ }
32
+ /**
33
+ * Runs the watches for the object storage service.
34
+ * Waits for buckets to exist and starts the watch operation for each bucket.
35
+ */
36
+ async runWatches() {
37
+ const watchers = await this.discoverWatchers();
38
+ await Promise.all(watchers.map(async ({ instance, metadata }) => {
39
+ await this.client.waitForBucketExists(metadata.bucket, 5000);
40
+ await this.runWatch(metadata, instance);
41
+ this.logger.info('Nats object storage watcher started', { metadata });
42
+ }));
43
+ }
44
+ /**
45
+ * Stops all watches.
46
+ *
47
+ * @note This method is not implemented yet.
48
+ */
49
+ async stopWatches() {
50
+ // TODO: Implement
51
+ }
52
+ /**
53
+ * Register watcher callback for object storage
54
+ */
55
+ async watch(storage, callback, opts) {
56
+ for await (const entry of await storage.watch(opts)) {
57
+ callback(entry).catch((error) => {
58
+ this.logger.error('Error processing object storage entry', {
59
+ entry: entry,
60
+ err: error,
61
+ });
62
+ });
63
+ }
64
+ }
65
+ /**
66
+ * Runs the watch operation for the given metadata and watcher.
67
+ *
68
+ * @param config - The watch configuration.
69
+ * @param watcher - The ObjectStorageWatcher instance.
70
+ * @returns A Promise that resolves when the watch operation is complete.
71
+ */
72
+ async runWatch({ bucket, ...options }, watcher) {
73
+ const storage = await this.client.create({ bucketName: bucket });
74
+ this.watch(storage.getRawStorage(), async (event) => {
75
+ if (!event)
76
+ return;
77
+ await (event.deleted ? watcher.onDelete(event) : watcher.onPut(event));
78
+ }, options);
79
+ }
80
+ /**
81
+ * Discovers and returns an array of ObjectStorageWatcher instances
82
+ * along with their corresponding metadata.
83
+ *
84
+ * @returns An array of objects containing the ObjectStorageWatcher
85
+ * instance and its metadata.
86
+ */
87
+ discoverWatchers() {
88
+ return this.discovery.getProviders().reduce((acc, watcher) => {
89
+ /**
90
+ * NOTE: This is a fix for TypeError in call .getMetadataByDecorator() above
91
+ * because some tokens are not instances of classes and have no constructor.
92
+ * */
93
+ const clsRef = watcher.instance?.constructor ?? watcher.metatype;
94
+ if (!clsRef) {
95
+ return acc;
96
+ }
97
+ const metadata = this.discovery.getMetadataByDecorator(watch_object_storage_decorator_1.WatchObjectStorage, watcher);
98
+ if (metadata && metadata.connectionName === this.connectionName) {
99
+ acc.push({ instance: watcher.instance, metadata });
100
+ }
101
+ return acc;
102
+ }, []);
103
+ }
104
+ };
105
+ exports.WatchObjectStorageService = WatchObjectStorageService;
106
+ exports.WatchObjectStorageService = WatchObjectStorageService = __decorate([
107
+ __param(0, (0, core_2.InjectLogger)(WatchObjectStorageService)),
108
+ __param(3, (0, common_1.Inject)('CONNECTION_NAME')),
109
+ __metadata("design:paramtypes", [Object, core_1.DiscoveryService,
110
+ nats_object_storage_service_1.NatsObjectStorageService, String])
111
+ ], WatchObjectStorageService);
112
+ //# sourceMappingURL=watch-object-storage.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"watch-object-storage.service.js","sourceRoot":"","sources":["../src/watch-object-storage.service.ts"],"names":[],"mappings":"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"}
package/jest.config.js ADDED
@@ -0,0 +1 @@
1
+ module.exports = require('@rsdk/jest/jest.config');
@@ -0,0 +1 @@
1
+ module.exports = require('@rsdk/jest/jest.config.unit');
package/package.json ADDED
@@ -0,0 +1,42 @@
1
+ {
2
+ "name": "@rsdk/nats.object-storage",
3
+ "version": "5.4.0-next.2",
4
+ "description": "Nats NestJS object storage",
5
+ "main": "dist/index.js",
6
+ "license": "Apache License 2.0",
7
+ "publishConfig": {
8
+ "access": "public"
9
+ },
10
+ "repository": {
11
+ "url": "https://github.com/R-Vision/rsdk"
12
+ },
13
+ "dependencies": {
14
+ "@nestjs-plugins/nestjs-nats-jetstream-transport": "^2.2.6",
15
+ "lodash": "^4.17.21",
16
+ "nats": "^2.28.0",
17
+ "typescript": "^5.3.2"
18
+ },
19
+ "peerDependencies": {
20
+ "@grpc/grpc-js": "^1.10.9",
21
+ "@nestjs/common": "^10.0.0",
22
+ "@nestjs/config": "^3.2.3",
23
+ "@nestjs/core": "^10.0.0",
24
+ "@nestjs/microservices": "^10.0.0",
25
+ "@opentelemetry/api": "1.9.0",
26
+ "@rsdk/actx": "*",
27
+ "@rsdk/autodoc.protocol": "*",
28
+ "@rsdk/common": "*",
29
+ "@rsdk/common.nestjs": "*",
30
+ "@rsdk/common.node": "*",
31
+ "@rsdk/core": "*",
32
+ "@rsdk/decorators": "*",
33
+ "@rsdk/logging": "*",
34
+ "@rsdk/metadata": "*",
35
+ "@rsdk/nats.common": "*",
36
+ "@rsdk/nest-tools": "*",
37
+ "reflect-metadata": "^0.1.12 || ^0.2.0",
38
+ "rxjs": "^7.8.1"
39
+ },
40
+ "nx": {},
41
+ "gitHead": "be4deac03b38b3f923a08116e1dc2b55838905b0"
42
+ }
@@ -0,0 +1 @@
1
+ export const NATS_OBJECT_STORAGES_RSDK_METADATA_SCOPE = 'nats-object-storages';
package/src/index.ts ADDED
@@ -0,0 +1,8 @@
1
+ export { NatsObjectStorageService } from './nats-object-storage.service';
2
+ export {
3
+ WatchObjectStorage,
4
+ type ObjectStorageWatcher,
5
+ } from './watch-object-storage.decorator';
6
+ export { NatsObjectStorageModule } from './nats-object-storage.module';
7
+ export { ObjectStorage } from './object-storage';
8
+ export * from './inject-object-storage-service.decorator';
@@ -0,0 +1,45 @@
1
+ import { Inject } from '@nestjs/common';
2
+ import {
3
+ PLATFORM_RAW_GLOBAL_METADATA_SCOPE,
4
+ RsdkMetadata,
5
+ } from '@rsdk/metadata';
6
+
7
+ import { NatsObjectStorageModuleGenerator } from './nats-object-storage-module.generator';
8
+ import {
9
+ createObjectStorageServiceToken,
10
+ createObjectStorageToken,
11
+ } from './tokens.fn';
12
+
13
+ export const InjectObjectStorageService = (
14
+ connectionName?: string,
15
+ ): ParameterDecorator =>
16
+ Inject(createObjectStorageServiceToken(connectionName));
17
+
18
+ export const InjectNatsObjectStorage = (
19
+ bucketName: string,
20
+ connectionName?: string,
21
+ ): ParameterDecorator => {
22
+ return (target, propertyKey, parameterIndex) => {
23
+ Inject(createObjectStorageToken(bucketName, connectionName))(
24
+ target,
25
+ propertyKey,
26
+ parameterIndex,
27
+ );
28
+
29
+ const key = `nats-kv:${bucketName}${connectionName ? `:${connectionName}` : ''}`;
30
+ const moduleDefinition =
31
+ NatsObjectStorageModuleGenerator.createClientModuleDefinition(
32
+ target,
33
+ bucketName,
34
+ connectionName,
35
+ );
36
+
37
+ RsdkMetadata.setWithScope(
38
+ target,
39
+ PLATFORM_RAW_GLOBAL_METADATA_SCOPE,
40
+ key,
41
+ moduleDefinition,
42
+ true,
43
+ );
44
+ };
45
+ };
@@ -0,0 +1,52 @@
1
+ import type { DynamicModule, FactoryProvider } from '@nestjs/common';
2
+ import { RsdkMetadata } from '@rsdk/metadata';
3
+
4
+ import { NATS_OBJECT_STORAGES_RSDK_METADATA_SCOPE } from './constants';
5
+ import { NatsObjectStorageModule } from './nats-object-storage.module';
6
+ import type { NatsObjectStorageService } from './nats-object-storage.service';
7
+ import type { ObjectStorage } from './object-storage';
8
+ import {
9
+ createObjectStorageServiceToken,
10
+ createObjectStorageToken,
11
+ } from './tokens.fn';
12
+
13
+ export class NatsObjectStorageModuleGenerator {
14
+ static createClientModuleDefinition(
15
+ target: object,
16
+ bucketName: string,
17
+ connectionName?: string,
18
+ ): DynamicModule {
19
+ const provider = NatsObjectStorageModuleGenerator.createClientProvider(
20
+ bucketName,
21
+ connectionName,
22
+ );
23
+
24
+ const moduleDefinition: DynamicModule = {
25
+ global: true,
26
+ imports: [NatsObjectStorageModule.forFeature(connectionName)],
27
+ module: NatsObjectStorageModuleGenerator,
28
+ providers: [provider],
29
+ exports: [provider],
30
+ };
31
+
32
+ RsdkMetadata.add(
33
+ target,
34
+ { bucketName, connectionName },
35
+ NATS_OBJECT_STORAGES_RSDK_METADATA_SCOPE,
36
+ );
37
+
38
+ return moduleDefinition;
39
+ }
40
+
41
+ private static createClientProvider(
42
+ bucketName: string,
43
+ connectionName?: string,
44
+ ): FactoryProvider {
45
+ return {
46
+ provide: createObjectStorageToken(bucketName, connectionName),
47
+ inject: [createObjectStorageServiceToken(connectionName)],
48
+ useFactory: (service: NatsObjectStorageService): Promise<ObjectStorage> =>
49
+ service.create({ bucketName, onlyExists: true }),
50
+ };
51
+ }
52
+ }
@@ -0,0 +1,58 @@
1
+ import type {
2
+ DynamicModule,
3
+ OnModuleDestroy,
4
+ OnModuleInit,
5
+ Provider,
6
+ } from '@nestjs/common';
7
+ import { Module } from '@nestjs/common';
8
+ import { DiscoveryModule } from '@nestjs/core';
9
+ import {
10
+ createNatsClientToken,
11
+ NATS_CLIENT_INJECTION_TOKEN,
12
+ NATS_CLIENT_INJECTION_TOKEN_FOR_PACKAGE,
13
+ } from '@rsdk/nats.common';
14
+
15
+ import { NatsObjectStorageService } from './nats-object-storage.service';
16
+ import { createObjectStorageServiceToken } from './tokens.fn';
17
+ import { WatchObjectStorageService } from './watch-object-storage.service';
18
+
19
+ @Module({
20
+ imports: [DiscoveryModule],
21
+ providers: [NatsObjectStorageService, WatchObjectStorageService],
22
+ })
23
+ export class NatsObjectStorageModule implements OnModuleInit, OnModuleDestroy {
24
+ constructor(private readonly watchService: WatchObjectStorageService) {}
25
+
26
+ public static forFeature(connectionName?: string): DynamicModule {
27
+ const clientProvider: Provider = {
28
+ provide: createObjectStorageServiceToken(connectionName),
29
+ useClass: NatsObjectStorageService,
30
+ };
31
+
32
+ return {
33
+ module: NatsObjectStorageModule,
34
+ providers: [
35
+ {
36
+ provide: NATS_CLIENT_INJECTION_TOKEN_FOR_PACKAGE,
37
+ useExisting: connectionName
38
+ ? createNatsClientToken(connectionName)
39
+ : NATS_CLIENT_INJECTION_TOKEN,
40
+ },
41
+ {
42
+ provide: 'CONNECTION_NAME',
43
+ useFactory: () => connectionName,
44
+ },
45
+ clientProvider,
46
+ ],
47
+ exports: [clientProvider],
48
+ };
49
+ }
50
+
51
+ async onModuleInit(): Promise<void> {
52
+ await this.watchService?.runWatches();
53
+ }
54
+
55
+ async onModuleDestroy(): Promise<void> {
56
+ await this.watchService?.stopWatches();
57
+ }
58
+ }
@@ -0,0 +1,111 @@
1
+ import { Inject, Injectable } from '@nestjs/common';
2
+ import { delay, Timespan } from '@rsdk/common';
3
+ import { InjectLogger, InternalException, NotFoundException } from '@rsdk/core';
4
+ import { ILogger } from '@rsdk/logging';
5
+ import { NATS_CLIENT_INJECTION_TOKEN_FOR_PACKAGE } from '@rsdk/nats.common';
6
+ import { NatsConnection } from 'nats';
7
+ import type { ObjectStoreOptions } from 'nats/lib/jetstream/types';
8
+
9
+ import { ObjectStorage } from './object-storage';
10
+
11
+ @Injectable()
12
+ export class NatsObjectStorageService {
13
+ constructor(
14
+ @InjectLogger(NatsObjectStorageService)
15
+ private readonly logger: ILogger,
16
+ @Inject(NATS_CLIENT_INJECTION_TOKEN_FOR_PACKAGE)
17
+ private readonly nats: NatsConnection,
18
+ ) {}
19
+
20
+ /**
21
+ * Get or create object storage
22
+ */
23
+ public async create({
24
+ bucketName,
25
+ domain,
26
+ onlyExists,
27
+ ...opts
28
+ }: Partial<ObjectStoreOptions> & {
29
+ bucketName: string;
30
+ domain?: string;
31
+ onlyExists?: boolean;
32
+ }): Promise<ObjectStorage> {
33
+ const jsOptions = domain ? { domain } : undefined;
34
+ const js = this.nats.jetstream(jsOptions);
35
+
36
+ try {
37
+ if (onlyExists && !(await this.isBucketExists(bucketName, jsOptions))) {
38
+ throw new NotFoundException(
39
+ `Object storage bucket "${bucketName}" not found`,
40
+ );
41
+ }
42
+
43
+ const storage = await js.views.os(bucketName, opts);
44
+
45
+ this.logger.trace('Object storage initialized', {
46
+ connectionName: this.nats.info,
47
+ bucket: bucketName,
48
+ });
49
+
50
+ return new ObjectStorage(storage);
51
+ } catch (error) {
52
+ this.logger.error('Failed to get or create object storage', {
53
+ err: error,
54
+ bucket: bucketName,
55
+ });
56
+ throw error;
57
+ }
58
+ }
59
+
60
+ /**
61
+ * Waits for the specified bucket to exist.
62
+ *
63
+ * @param bucketName - The name of the bucket to wait for.
64
+ * @param timeout - The maximum time to wait for the bucket to exist, in milliseconds. Defaults to infinity.
65
+ * @throws {InternalException} If the bucket does not exist within the specified timeout.
66
+ */
67
+ async waitForBucketExists(
68
+ bucketName: string,
69
+ timeout: number = Number.POSITIVE_INFINITY,
70
+ ): Promise<void> {
71
+ const start = Date.now();
72
+
73
+ while (true) {
74
+ if (await this.isBucketExists(bucketName)) {
75
+ this.logger.trace('Object storage bucket exists');
76
+ return;
77
+ }
78
+
79
+ if (timeout && Date.now() - start > timeout) {
80
+ throw new InternalException(`Bucket ${bucketName} does not exist`);
81
+ }
82
+
83
+ this.logger.trace(
84
+ 'Object storage bucket does not exist, retry after 3 seconds...',
85
+ {
86
+ bucketName,
87
+ },
88
+ );
89
+ await delay(Timespan.second(3));
90
+ }
91
+ }
92
+
93
+ /**
94
+ * Checks if a bucket exists.
95
+ *
96
+ * @param bucket - The name of the bucket to check.
97
+ * @returns A promise that resolves to a boolean indicating whether the bucket exists or not.
98
+ */
99
+ async isBucketExists(
100
+ bucket: string,
101
+ opts?: { domain?: string },
102
+ ): Promise<boolean> {
103
+ try {
104
+ await this.nats.jetstream(opts).streams.get(`OBJ_${bucket}`);
105
+ } catch {
106
+ return false;
107
+ }
108
+
109
+ return true;
110
+ }
111
+ }
@@ -0,0 +1,53 @@
1
+ import type {
2
+ ObjectInfo,
3
+ ObjectResult,
4
+ ObjectStore,
5
+ ObjectStoreMeta,
6
+ ObjectStorePutOpts,
7
+ PurgeResponse,
8
+ } from 'nats';
9
+
10
+ export class ObjectStorage {
11
+ constructor(private readonly storage: ObjectStore) {}
12
+
13
+ /**
14
+ * Возвращает метаданные и стрим с объектом
15
+ */
16
+ public get(key: string): Promise<ObjectResult | null> {
17
+ return this.storage.get(key);
18
+ }
19
+
20
+ /**
21
+ * Удаляет объект
22
+ */
23
+ public delete(key: string): Promise<PurgeResponse> {
24
+ return this.storage.delete(key);
25
+ }
26
+
27
+ /**
28
+ * Загружает объект в хранилище
29
+ */
30
+ public put(
31
+ meta: ObjectStoreMeta,
32
+ rs: ReadableStream<Uint8Array>,
33
+ opts?: ObjectStorePutOpts,
34
+ ): Promise<ObjectInfo> {
35
+ return this.storage.put(meta, rs, opts);
36
+ }
37
+
38
+ /**
39
+ * Возвращает массив всех объектов в хранилище
40
+ */
41
+ public list(): Promise<ObjectInfo[]> {
42
+ return this.storage.list();
43
+ }
44
+
45
+ /**
46
+ * Возвращает сырой object storage Nats. Используйте этот метод
47
+ * только в крайнем случае! Рекомендуется работать с оберткой
48
+ * для безопасного взаимодействия.
49
+ */
50
+ public getRawStorage(): ObjectStore {
51
+ return this.storage;
52
+ }
53
+ }
@@ -0,0 +1,10 @@
1
+ export const createObjectStorageServiceToken = (
2
+ connectionName?: string,
3
+ ): string =>
4
+ `NATS_OBJECT_STORAGE_SERVICE${connectionName ? `_${connectionName}` : ''}`;
5
+
6
+ export const createObjectStorageToken = (
7
+ bucketName: string,
8
+ connectionName?: string,
9
+ ): string =>
10
+ `NATS_OBJECT_STORAGE_${bucketName}${connectionName ? `_${connectionName}` : ''}`;
@@ -0,0 +1,30 @@
1
+ import { Reflector } from '@nestjs/core';
2
+ import type { ObjectInfo } from 'nats';
3
+
4
+ export type WatchConfig = {
5
+ bucket: string;
6
+ ignoreDeletes?: boolean;
7
+ includeHistory?: boolean;
8
+ connectionName?: string;
9
+ };
10
+
11
+ export interface ObjectStorageWatcher {
12
+ onDelete(entry: ObjectInfo | null): Promise<void>;
13
+ onPut(entry: ObjectInfo | null): Promise<void>;
14
+ }
15
+
16
+ /**
17
+ * Key used to mark class as a watcher for object storage.
18
+ */
19
+ export const WATCH_NATS_OBJECT_STORAGE_KEY = 'WATCH_NATS_OBJECT_STORAGE';
20
+
21
+ /**
22
+ * Decorator used to mark class as a watcher for object storage.
23
+ * Needs to be used in conjunction with the `ObjectStorageWatcher` interface.
24
+ *
25
+ * @param {WatchConfig} config - The configuration for watching object storage.
26
+ * @returns {void}
27
+ */
28
+ export const WatchObjectStorage = Reflector.createDecorator<WatchConfig>({
29
+ key: WATCH_NATS_OBJECT_STORAGE_KEY,
30
+ });
@@ -0,0 +1,129 @@
1
+ import { Inject } from '@nestjs/common';
2
+ import { DiscoveryService } from '@nestjs/core';
3
+ import { InjectLogger } from '@rsdk/core';
4
+ import { ILogger } from '@rsdk/logging';
5
+ import type { ObjectInfo, ObjectStore } from 'nats';
6
+
7
+ import { NatsObjectStorageService } from './nats-object-storage.service';
8
+ import type {
9
+ ObjectStorageWatcher,
10
+ WatchConfig,
11
+ } from './watch-object-storage.decorator';
12
+ import { WatchObjectStorage } from './watch-object-storage.decorator';
13
+
14
+ export class WatchObjectStorageService {
15
+ constructor(
16
+ @InjectLogger(WatchObjectStorageService)
17
+ private readonly logger: ILogger,
18
+ private readonly discovery: DiscoveryService,
19
+ private readonly client: NatsObjectStorageService,
20
+ @Inject('CONNECTION_NAME')
21
+ private readonly connectionName?: string,
22
+ ) {}
23
+
24
+ /**
25
+ * Runs the watches for the object storage service.
26
+ * Waits for buckets to exist and starts the watch operation for each bucket.
27
+ */
28
+ public async runWatches(): Promise<void> {
29
+ const watchers = await this.discoverWatchers();
30
+
31
+ await Promise.all(
32
+ watchers.map(async ({ instance, metadata }) => {
33
+ await this.client.waitForBucketExists(metadata.bucket, 5000);
34
+ await this.runWatch(metadata, instance);
35
+ this.logger.info('Nats object storage watcher started', { metadata });
36
+ }),
37
+ );
38
+ }
39
+
40
+ /**
41
+ * Stops all watches.
42
+ *
43
+ * @note This method is not implemented yet.
44
+ */
45
+ public async stopWatches(): Promise<void> {
46
+ // TODO: Implement
47
+ }
48
+
49
+ /**
50
+ * Register watcher callback for object storage
51
+ */
52
+ public async watch(
53
+ storage: ObjectStore,
54
+ callback: (entry: ObjectInfo | null) => Promise<void>,
55
+ opts?: {
56
+ ignoreDeletes?: boolean;
57
+ includeHistory?: boolean;
58
+ },
59
+ ): Promise<void> {
60
+ for await (const entry of await storage.watch(opts)) {
61
+ callback(entry).catch((error) => {
62
+ this.logger.error('Error processing object storage entry', {
63
+ entry: entry,
64
+ err: error,
65
+ });
66
+ });
67
+ }
68
+ }
69
+
70
+ /**
71
+ * Runs the watch operation for the given metadata and watcher.
72
+ *
73
+ * @param config - The watch configuration.
74
+ * @param watcher - The ObjectStorageWatcher instance.
75
+ * @returns A Promise that resolves when the watch operation is complete.
76
+ */
77
+ private async runWatch(
78
+ { bucket, ...options }: WatchConfig,
79
+ watcher: ObjectStorageWatcher,
80
+ ): Promise<void> {
81
+ const storage = await this.client.create({ bucketName: bucket });
82
+
83
+ this.watch(
84
+ storage.getRawStorage(),
85
+ async (event) => {
86
+ if (!event) return;
87
+
88
+ await (event.deleted ? watcher.onDelete(event) : watcher.onPut(event));
89
+ },
90
+ options,
91
+ );
92
+ }
93
+
94
+ /**
95
+ * Discovers and returns an array of ObjectStorageWatcher instances
96
+ * along with their corresponding metadata.
97
+ *
98
+ * @returns An array of objects containing the ObjectStorageWatcher
99
+ * instance and its metadata.
100
+ */
101
+ private discoverWatchers(): {
102
+ instance: ObjectStorageWatcher;
103
+ metadata: WatchConfig;
104
+ }[] {
105
+ return this.discovery.getProviders().reduce(
106
+ (acc, watcher) => {
107
+ /**
108
+ * NOTE: This is a fix for TypeError in call .getMetadataByDecorator() above
109
+ * because some tokens are not instances of classes and have no constructor.
110
+ * */
111
+ const clsRef = watcher.instance?.constructor ?? watcher.metatype;
112
+ if (!clsRef) {
113
+ return acc;
114
+ }
115
+
116
+ const metadata = this.discovery.getMetadataByDecorator(
117
+ WatchObjectStorage,
118
+ watcher,
119
+ );
120
+
121
+ if (metadata && metadata.connectionName === this.connectionName) {
122
+ acc.push({ instance: watcher.instance, metadata });
123
+ }
124
+ return acc;
125
+ },
126
+ [] as { instance: ObjectStorageWatcher; metadata: WatchConfig }[],
127
+ );
128
+ }
129
+ }
@@ -0,0 +1,12 @@
1
+ {
2
+ "extends": "./tsconfig.json",
3
+ "exclude": [
4
+ "node_modules",
5
+ "dist",
6
+ "test",
7
+ "**/*.spec.ts",
8
+ "**/*.test.ts",
9
+ "**/*.test.e2e.ts",
10
+ "**/*.test.manual-e2e.ts",
11
+ ]
12
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,7 @@
1
+ {
2
+ "extends": "@rsdk/tsconfig/base.json",
3
+ "compilerOptions": {
4
+ "declaration": true,
5
+ "outDir": "dist"
6
+ }
7
+ }