rac-delta 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (144) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +1 -0
  3. package/dist/core/adapters/index.d.ts +2 -0
  4. package/dist/core/adapters/index.d.ts.map +1 -0
  5. package/dist/core/adapters/index.js +17 -0
  6. package/dist/core/adapters/storage-adapter.d.ts +125 -0
  7. package/dist/core/adapters/storage-adapter.d.ts.map +1 -0
  8. package/dist/core/adapters/storage-adapter.js +14 -0
  9. package/dist/core/config/index.d.ts +2 -0
  10. package/dist/core/config/index.d.ts.map +1 -0
  11. package/dist/core/config/index.js +17 -0
  12. package/dist/core/config/rac-delta-config.d.ts +132 -0
  13. package/dist/core/config/rac-delta-config.d.ts.map +1 -0
  14. package/dist/core/config/rac-delta-config.js +2 -0
  15. package/dist/core/exceptions.d.ts +25 -0
  16. package/dist/core/exceptions.d.ts.map +1 -0
  17. package/dist/core/exceptions.js +51 -0
  18. package/dist/core/models/chunk.d.ts +12 -0
  19. package/dist/core/models/chunk.d.ts.map +1 -0
  20. package/dist/core/models/chunk.js +2 -0
  21. package/dist/core/models/delta-plan.d.ts +12 -0
  22. package/dist/core/models/delta-plan.d.ts.map +1 -0
  23. package/dist/core/models/delta-plan.js +2 -0
  24. package/dist/core/models/file-entry.d.ts +9 -0
  25. package/dist/core/models/file-entry.d.ts.map +1 -0
  26. package/dist/core/models/file-entry.js +2 -0
  27. package/dist/core/models/index.d.ts +5 -0
  28. package/dist/core/models/index.d.ts.map +1 -0
  29. package/dist/core/models/index.js +20 -0
  30. package/dist/core/models/rd-index.d.ts +8 -0
  31. package/dist/core/models/rd-index.d.ts.map +1 -0
  32. package/dist/core/models/rd-index.js +2 -0
  33. package/dist/core/pipelines/download-pipeline.d.ts +142 -0
  34. package/dist/core/pipelines/download-pipeline.d.ts.map +1 -0
  35. package/dist/core/pipelines/download-pipeline.js +64 -0
  36. package/dist/core/pipelines/index.d.ts +3 -0
  37. package/dist/core/pipelines/index.d.ts.map +1 -0
  38. package/dist/core/pipelines/index.js +18 -0
  39. package/dist/core/pipelines/upload-pipeline.d.ts +60 -0
  40. package/dist/core/pipelines/upload-pipeline.d.ts.map +1 -0
  41. package/dist/core/pipelines/upload-pipeline.js +34 -0
  42. package/dist/core/services/delta-service.d.ts +76 -0
  43. package/dist/core/services/delta-service.d.ts.map +1 -0
  44. package/dist/core/services/delta-service.js +2 -0
  45. package/dist/core/services/hasher-service.d.ts +47 -0
  46. package/dist/core/services/hasher-service.d.ts.map +1 -0
  47. package/dist/core/services/hasher-service.js +2 -0
  48. package/dist/core/services/index.d.ts +5 -0
  49. package/dist/core/services/index.d.ts.map +1 -0
  50. package/dist/core/services/index.js +20 -0
  51. package/dist/core/services/reconstruction-service.d.ts +99 -0
  52. package/dist/core/services/reconstruction-service.d.ts.map +1 -0
  53. package/dist/core/services/reconstruction-service.js +4 -0
  54. package/dist/core/services/validation-service.d.ts +18 -0
  55. package/dist/core/services/validation-service.d.ts.map +1 -0
  56. package/dist/core/services/validation-service.js +2 -0
  57. package/dist/core/types/index.d.ts +2 -0
  58. package/dist/core/types/index.d.ts.map +1 -0
  59. package/dist/core/types/index.js +17 -0
  60. package/dist/core/types/types.d.ts +3 -0
  61. package/dist/core/types/types.d.ts.map +1 -0
  62. package/dist/core/types/types.js +2 -0
  63. package/dist/core/utils/index.d.ts +3 -0
  64. package/dist/core/utils/index.d.ts.map +1 -0
  65. package/dist/core/utils/index.js +18 -0
  66. package/dist/core/utils/invariant.d.ts +2 -0
  67. package/dist/core/utils/invariant.d.ts.map +1 -0
  68. package/dist/core/utils/invariant.js +11 -0
  69. package/dist/core/utils/stream-to-buffer.d.ts +3 -0
  70. package/dist/core/utils/stream-to-buffer.d.ts.map +1 -0
  71. package/dist/core/utils/stream-to-buffer.js +10 -0
  72. package/dist/index.d.ts +9 -0
  73. package/dist/index.d.ts.map +1 -0
  74. package/dist/index.js +29 -0
  75. package/dist/infrastructure/adapters/azure-blob-storage-adapter.d.ts +24 -0
  76. package/dist/infrastructure/adapters/azure-blob-storage-adapter.d.ts.map +1 -0
  77. package/dist/infrastructure/adapters/azure-blob-storage-adapter.js +149 -0
  78. package/dist/infrastructure/adapters/gcs-storage-adapter.d.ts +20 -0
  79. package/dist/infrastructure/adapters/gcs-storage-adapter.d.ts.map +1 -0
  80. package/dist/infrastructure/adapters/gcs-storage-adapter.js +101 -0
  81. package/dist/infrastructure/adapters/http-storage-adapter.d.ts +23 -0
  82. package/dist/infrastructure/adapters/http-storage-adapter.d.ts.map +1 -0
  83. package/dist/infrastructure/adapters/http-storage-adapter.js +154 -0
  84. package/dist/infrastructure/adapters/local-storage-adapter.d.ts +23 -0
  85. package/dist/infrastructure/adapters/local-storage-adapter.d.ts.map +1 -0
  86. package/dist/infrastructure/adapters/local-storage-adapter.js +124 -0
  87. package/dist/infrastructure/adapters/s3-storage-adapter.d.ts +24 -0
  88. package/dist/infrastructure/adapters/s3-storage-adapter.d.ts.map +1 -0
  89. package/dist/infrastructure/adapters/s3-storage-adapter.js +139 -0
  90. package/dist/infrastructure/adapters/ssh-storage-adapter.d.ts +28 -0
  91. package/dist/infrastructure/adapters/ssh-storage-adapter.d.ts.map +1 -0
  92. package/dist/infrastructure/adapters/ssh-storage-adapter.js +237 -0
  93. package/dist/infrastructure/adapters/url-storage-adapter.d.ts +14 -0
  94. package/dist/infrastructure/adapters/url-storage-adapter.d.ts.map +1 -0
  95. package/dist/infrastructure/adapters/url-storage-adapter.js +92 -0
  96. package/dist/infrastructure/chunk-sources/disk-chunk-source.d.ts +12 -0
  97. package/dist/infrastructure/chunk-sources/disk-chunk-source.d.ts.map +1 -0
  98. package/dist/infrastructure/chunk-sources/disk-chunk-source.js +61 -0
  99. package/dist/infrastructure/chunk-sources/index.d.ts +4 -0
  100. package/dist/infrastructure/chunk-sources/index.d.ts.map +1 -0
  101. package/dist/infrastructure/chunk-sources/index.js +19 -0
  102. package/dist/infrastructure/chunk-sources/memory-chunk-source.d.ts +9 -0
  103. package/dist/infrastructure/chunk-sources/memory-chunk-source.d.ts.map +1 -0
  104. package/dist/infrastructure/chunk-sources/memory-chunk-source.js +29 -0
  105. package/dist/infrastructure/chunk-sources/storage-chunk-source.d.ts +21 -0
  106. package/dist/infrastructure/chunk-sources/storage-chunk-source.d.ts.map +1 -0
  107. package/dist/infrastructure/chunk-sources/storage-chunk-source.js +150 -0
  108. package/dist/infrastructure/client.d.ts +45 -0
  109. package/dist/infrastructure/client.d.ts.map +1 -0
  110. package/dist/infrastructure/client.js +52 -0
  111. package/dist/infrastructure/factories/pipeline-factory.d.ts +15 -0
  112. package/dist/infrastructure/factories/pipeline-factory.d.ts.map +1 -0
  113. package/dist/infrastructure/factories/pipeline-factory.js +26 -0
  114. package/dist/infrastructure/factories/service-factory.d.ts +11 -0
  115. package/dist/infrastructure/factories/service-factory.d.ts.map +1 -0
  116. package/dist/infrastructure/factories/service-factory.js +17 -0
  117. package/dist/infrastructure/factories/storage-adpater-factory.d.ts +41 -0
  118. package/dist/infrastructure/factories/storage-adpater-factory.d.ts.map +1 -0
  119. package/dist/infrastructure/factories/storage-adpater-factory.js +33 -0
  120. package/dist/infrastructure/pipelines/default-hash-download-pipeline.d.ts +27 -0
  121. package/dist/infrastructure/pipelines/default-hash-download-pipeline.d.ts.map +1 -0
  122. package/dist/infrastructure/pipelines/default-hash-download-pipeline.js +211 -0
  123. package/dist/infrastructure/pipelines/default-hash-upload-pipeline.d.ts +19 -0
  124. package/dist/infrastructure/pipelines/default-hash-upload-pipeline.d.ts.map +1 -0
  125. package/dist/infrastructure/pipelines/default-hash-upload-pipeline.js +170 -0
  126. package/dist/infrastructure/pipelines/default-url-download-pipeline.d.ts +30 -0
  127. package/dist/infrastructure/pipelines/default-url-download-pipeline.d.ts.map +1 -0
  128. package/dist/infrastructure/pipelines/default-url-download-pipeline.js +198 -0
  129. package/dist/infrastructure/pipelines/default-url-upload-pipeline.d.ts +20 -0
  130. package/dist/infrastructure/pipelines/default-url-upload-pipeline.d.ts.map +1 -0
  131. package/dist/infrastructure/pipelines/default-url-upload-pipeline.js +126 -0
  132. package/dist/infrastructure/services/hash-wasm-hasher-service.d.ts +13 -0
  133. package/dist/infrastructure/services/hash-wasm-hasher-service.d.ts.map +1 -0
  134. package/dist/infrastructure/services/hash-wasm-hasher-service.js +113 -0
  135. package/dist/infrastructure/services/memory-delta-service.d.ts +17 -0
  136. package/dist/infrastructure/services/memory-delta-service.d.ts.map +1 -0
  137. package/dist/infrastructure/services/memory-delta-service.js +198 -0
  138. package/dist/infrastructure/services/memory-reconstruction-service.d.ts +25 -0
  139. package/dist/infrastructure/services/memory-reconstruction-service.d.ts.map +1 -0
  140. package/dist/infrastructure/services/memory-reconstruction-service.js +329 -0
  141. package/dist/infrastructure/services/memory-validation-service.d.ts +9 -0
  142. package/dist/infrastructure/services/memory-validation-service.d.ts.map +1 -0
  143. package/dist/infrastructure/services/memory-validation-service.js +33 -0
  144. package/package.json +43 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validation-service.d.ts","sourceRoot":"","sources":["../../../src/core/services/validation-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAE/C,MAAM,WAAW,iBAAiB;IAChC;;;;;OAKG;IACH,YAAY,CAAC,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAE/D;;;;;OAKG;IACH,aAAa,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CACnE"}
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,2 @@
1
+ export * from './types';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/types/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC"}
@@ -0,0 +1,17 @@
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
+ __exportStar(require("./types"), exports);
@@ -0,0 +1,3 @@
1
+ export type UnknownAny = any;
2
+ export type Nullish<T> = T | undefined;
3
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/core/types/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,UAAU,GAAG,GAAG,CAAC;AAC7B,MAAM,MAAM,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,SAAS,CAAC"}
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,3 @@
1
+ export * from './invariant';
2
+ export * from './stream-to-buffer';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,oBAAoB,CAAC"}
@@ -0,0 +1,18 @@
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
+ __exportStar(require("./invariant"), exports);
18
+ __exportStar(require("./stream-to-buffer"), exports);
@@ -0,0 +1,2 @@
1
+ export declare function invariant(message: string, condition: unknown, exception?: Error): asserts condition;
2
+ //# sourceMappingURL=invariant.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"invariant.d.ts","sourceRoot":"","sources":["../../../src/core/utils/invariant.ts"],"names":[],"mappings":"AAAA,wBAAgB,SAAS,CACvB,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,OAAO,EAClB,SAAS,CAAC,EAAE,KAAK,GAChB,OAAO,CAAC,SAAS,CAQnB"}
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.invariant = invariant;
4
+ function invariant(message, condition, exception) {
5
+ if (!condition && exception) {
6
+ throw exception;
7
+ }
8
+ if (!condition && !exception) {
9
+ throw new Error(message);
10
+ }
11
+ }
@@ -0,0 +1,3 @@
1
+ import { Readable } from 'stream';
2
+ export declare function streamToBuffer(stream: Readable): Promise<Buffer>;
3
+ //# sourceMappingURL=stream-to-buffer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stream-to-buffer.d.ts","sourceRoot":"","sources":["../../../src/core/utils/stream-to-buffer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAElC,wBAAsB,cAAc,CAAC,MAAM,EAAE,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,CAQtE"}
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.streamToBuffer = streamToBuffer;
4
+ async function streamToBuffer(stream) {
5
+ const buffers = [];
6
+ for await (const chunk of stream) {
7
+ buffers.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
8
+ }
9
+ return Buffer.concat(buffers);
10
+ }
@@ -0,0 +1,9 @@
1
+ export { RacDeltaClient } from './infrastructure/client';
2
+ export { DiskChunkSource, MemoryChunkSource, StorageChunkSource, } from './infrastructure/chunk-sources';
3
+ export * from './core/pipelines';
4
+ export * from './core/adapters';
5
+ export * from './core/services';
6
+ export * from './core/config';
7
+ export * from './core/models';
8
+ export * from './core/utils';
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACzD,OAAO,EACL,eAAe,EACf,iBAAiB,EACjB,kBAAkB,GACnB,MAAM,gCAAgC,CAAC;AACxC,cAAc,kBAAkB,CAAC;AACjC,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,29 @@
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.StorageChunkSource = exports.MemoryChunkSource = exports.DiskChunkSource = exports.RacDeltaClient = void 0;
18
+ var client_1 = require("./infrastructure/client");
19
+ Object.defineProperty(exports, "RacDeltaClient", { enumerable: true, get: function () { return client_1.RacDeltaClient; } });
20
+ var chunk_sources_1 = require("./infrastructure/chunk-sources");
21
+ Object.defineProperty(exports, "DiskChunkSource", { enumerable: true, get: function () { return chunk_sources_1.DiskChunkSource; } });
22
+ Object.defineProperty(exports, "MemoryChunkSource", { enumerable: true, get: function () { return chunk_sources_1.MemoryChunkSource; } });
23
+ Object.defineProperty(exports, "StorageChunkSource", { enumerable: true, get: function () { return chunk_sources_1.StorageChunkSource; } });
24
+ __exportStar(require("./core/pipelines"), exports);
25
+ __exportStar(require("./core/adapters"), exports);
26
+ __exportStar(require("./core/services"), exports);
27
+ __exportStar(require("./core/config"), exports);
28
+ __exportStar(require("./core/models"), exports);
29
+ __exportStar(require("./core/utils"), exports);
@@ -0,0 +1,24 @@
1
+ import { Readable } from 'stream';
2
+ import { BlobInfo, HashStorageAdapter } from '../../core/adapters';
3
+ import { AzureBlobStorageConfig } from '../../core/config';
4
+ import { RDIndex } from '../../core/models';
5
+ export declare class AzureBlobStorageAdapter extends HashStorageAdapter {
6
+ private readonly config;
7
+ private container;
8
+ private readonly prefix;
9
+ constructor(config: AzureBlobStorageConfig);
10
+ dispose(): Promise<void>;
11
+ private getChunkPath;
12
+ private getIndexPath;
13
+ getChunk(hash: string): Promise<Readable | null>;
14
+ putChunk(hash: string, data: Readable, opts?: {
15
+ overwrite?: boolean;
16
+ }): Promise<void>;
17
+ chunkExists(hash: string): Promise<boolean>;
18
+ deleteChunk(hash: string): Promise<void>;
19
+ listChunks(): Promise<string[]>;
20
+ getChunkInfo(hash: string): Promise<BlobInfo | null>;
21
+ getRemoteIndex(): Promise<RDIndex | null>;
22
+ putRemoteIndex(index: RDIndex): Promise<void>;
23
+ }
24
+ //# sourceMappingURL=azure-blob-storage-adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"azure-blob-storage-adapter.d.ts","sourceRoot":"","sources":["../../../src/infrastructure/adapters/azure-blob-storage-adapter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AASlC,OAAO,EAAE,QAAQ,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AACnE,OAAO,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAC3D,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAE5C,qBAAa,uBAAwB,SAAQ,kBAAkB;IAIjD,OAAO,CAAC,QAAQ,CAAC,MAAM;IAHnC,OAAO,CAAC,SAAS,CAAkB;IACnC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;gBAEH,MAAM,EAAE,sBAAsB;IA+BrD,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAI9B,OAAO,CAAC,YAAY;IAIpB,OAAO,CAAC,YAAY;IAId,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;IAmBhD,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAoBrF,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAK3C,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAKxC,UAAU,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAc/B,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;IAyBpD,cAAc,IAAI,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;IAgCzC,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;CAQpD"}
@@ -0,0 +1,149 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AzureBlobStorageAdapter = void 0;
4
+ const storage_blob_1 = require("@azure/storage-blob");
5
+ const identity_1 = require("@azure/identity");
6
+ const adapters_1 = require("../../core/adapters");
7
+ class AzureBlobStorageAdapter extends adapters_1.HashStorageAdapter {
8
+ config;
9
+ container;
10
+ prefix;
11
+ constructor(config) {
12
+ super();
13
+ this.config = config;
14
+ const { endpoint, container, credentials, pathPrefix } = this.config;
15
+ this.prefix = pathPrefix ? pathPrefix.replace(/\/$/, '') : '';
16
+ let blobServiceClient;
17
+ if (credentials.accountKey && credentials.accountName) {
18
+ const credential = new storage_blob_1.StorageSharedKeyCredential(credentials.accountName, credentials.accountKey);
19
+ blobServiceClient = new storage_blob_1.BlobServiceClient(endpoint, credential);
20
+ }
21
+ else if (credentials.sasToken) {
22
+ const sasUrl = endpoint.includes('?') || credentials.sasToken.startsWith('?')
23
+ ? `${endpoint}${credentials.sasToken}`
24
+ : `${endpoint}?${credentials.sasToken}`;
25
+ blobServiceClient = new storage_blob_1.BlobServiceClient(sasUrl);
26
+ }
27
+ else {
28
+ const credential = new identity_1.DefaultAzureCredential();
29
+ blobServiceClient = new storage_blob_1.BlobServiceClient(endpoint, credential);
30
+ }
31
+ this.container = blobServiceClient.getContainerClient(container);
32
+ }
33
+ async dispose() {
34
+ return;
35
+ }
36
+ getChunkPath(hash) {
37
+ return this.prefix ? `${this.prefix}/chunks/${hash}` : `chunks/${hash}`;
38
+ }
39
+ getIndexPath() {
40
+ return this.prefix ? `${this.prefix}/rd-index.json` : 'rd-index.json';
41
+ }
42
+ async getChunk(hash) {
43
+ try {
44
+ const blob = this.container.getBlobClient(this.getChunkPath(hash));
45
+ if (!(await blob.exists())) {
46
+ return null;
47
+ }
48
+ const download = await blob.download();
49
+ return download.readableStreamBody;
50
+ }
51
+ catch (error) {
52
+ if (error instanceof storage_blob_1.RestError && error.statusCode === 404) {
53
+ return null;
54
+ }
55
+ throw error;
56
+ }
57
+ }
58
+ async putChunk(hash, data, opts) {
59
+ try {
60
+ const blob = this.container.getBlockBlobClient(this.getChunkPath(hash));
61
+ if (!opts?.overwrite) {
62
+ const exists = await blob.exists();
63
+ if (exists) {
64
+ return;
65
+ }
66
+ }
67
+ await blob.uploadStream(data, 4 * 1024 * 1024, 5, {
68
+ blobHTTPHeaders: { blobContentType: 'application/octet-stream' },
69
+ });
70
+ }
71
+ catch (error) {
72
+ throw error;
73
+ }
74
+ }
75
+ async chunkExists(hash) {
76
+ const blob = this.container.getBlobClient(this.getChunkPath(hash));
77
+ return blob.exists();
78
+ }
79
+ async deleteChunk(hash) {
80
+ const blob = this.container.getBlobClient(this.getChunkPath(hash));
81
+ await blob.deleteIfExists();
82
+ }
83
+ async listChunks() {
84
+ const hashes = [];
85
+ const chunksPath = this.prefix ? `${this.prefix}/chunks/` : 'chunks/';
86
+ for await (const blob of this.container.listBlobsFlat({ prefix: chunksPath })) {
87
+ const name = blob.name.startsWith(chunksPath)
88
+ ? blob.name.slice(chunksPath.length)
89
+ : blob.name;
90
+ hashes.push(name);
91
+ }
92
+ return hashes;
93
+ }
94
+ async getChunkInfo(hash) {
95
+ try {
96
+ const blob = this.container.getBlobClient(this.getChunkPath(hash));
97
+ if (!(await blob.exists())) {
98
+ return null;
99
+ }
100
+ const props = await blob.getProperties();
101
+ return {
102
+ hash,
103
+ size: props.contentLength ?? 0,
104
+ modified: props.lastModified ?? undefined,
105
+ metadata: props.metadata ?? undefined,
106
+ };
107
+ }
108
+ catch (error) {
109
+ if (error instanceof storage_blob_1.RestError && error.statusCode === 404) {
110
+ return null;
111
+ }
112
+ throw error;
113
+ }
114
+ }
115
+ async getRemoteIndex() {
116
+ try {
117
+ const blob = this.container.getBlobClient(this.getIndexPath());
118
+ const exists = await blob.exists();
119
+ if (!exists) {
120
+ return null;
121
+ }
122
+ const download = await blob.download();
123
+ const chunks = [];
124
+ const stream = download.readableStreamBody;
125
+ if (!stream) {
126
+ return null;
127
+ }
128
+ for await (const chunk of stream) {
129
+ chunks.push(typeof chunk === 'string' ? Buffer.from(chunk, 'utf-8') : chunk);
130
+ }
131
+ const data = Buffer.concat(chunks).toString('utf-8');
132
+ return JSON.parse(data);
133
+ }
134
+ catch (error) {
135
+ if (error instanceof storage_blob_1.RestError && error.statusCode === 404) {
136
+ return null;
137
+ }
138
+ throw error;
139
+ }
140
+ }
141
+ async putRemoteIndex(index) {
142
+ const blob = this.container.getBlockBlobClient(this.getIndexPath());
143
+ const contents = JSON.stringify(index, null, 2);
144
+ await blob.upload(contents, Buffer.byteLength(contents), {
145
+ blobHTTPHeaders: { blobContentType: 'application/json' },
146
+ });
147
+ }
148
+ }
149
+ exports.AzureBlobStorageAdapter = AzureBlobStorageAdapter;
@@ -0,0 +1,20 @@
1
+ import { Readable } from 'stream';
2
+ import { BlobInfo, HashStorageAdapter } from '../../core/adapters';
3
+ import { GCSStorageConfig } from '../../core/config';
4
+ import { RDIndex } from '../../core/models';
5
+ export declare class GCSStorageAdapter extends HashStorageAdapter {
6
+ private readonly config;
7
+ private storage;
8
+ constructor(config: GCSStorageConfig);
9
+ dispose(): Promise<void>;
10
+ private getPath;
11
+ getChunk(hash: string): Promise<Readable | null>;
12
+ putChunk(hash: string, data: Readable): Promise<void>;
13
+ chunkExists(hash: string): Promise<boolean>;
14
+ deleteChunk(hash: string): Promise<void>;
15
+ listChunks(): Promise<string[]>;
16
+ getChunkInfo(hash: string): Promise<BlobInfo | null>;
17
+ getRemoteIndex(): Promise<RDIndex | null>;
18
+ putRemoteIndex(index: RDIndex): Promise<void>;
19
+ }
20
+ //# sourceMappingURL=gcs-storage-adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gcs-storage-adapter.d.ts","sourceRoot":"","sources":["../../../src/infrastructure/adapters/gcs-storage-adapter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAGlC,OAAO,EAAE,QAAQ,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AACnE,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAE5C,qBAAa,iBAAkB,SAAQ,kBAAkB;IAG3C,OAAO,CAAC,QAAQ,CAAC,MAAM;IAFnC,OAAO,CAAC,OAAO,CAAU;gBAEI,MAAM,EAAE,gBAAgB;IAa/C,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAI9B,OAAO,CAAC,OAAO;IAIT,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;IAWhD,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAUrD,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAQ3C,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAKxC,UAAU,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAU/B,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;IAwBpD,cAAc,IAAI,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;IAkBzC,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;CAepD"}
@@ -0,0 +1,101 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.GCSStorageAdapter = void 0;
4
+ const storage_1 = require("@google-cloud/storage");
5
+ const adapters_1 = require("../../core/adapters");
6
+ class GCSStorageAdapter extends adapters_1.HashStorageAdapter {
7
+ config;
8
+ storage;
9
+ constructor(config) {
10
+ super();
11
+ this.config = config;
12
+ this.storage = new storage_1.Storage({
13
+ projectId: config.credentials.projectId,
14
+ apiEndpoint: config.apiEndpoint,
15
+ credentials: {
16
+ client_email: config.credentials.clientEmail,
17
+ private_key: config.credentials.privateKey,
18
+ },
19
+ });
20
+ }
21
+ async dispose() {
22
+ return;
23
+ }
24
+ getPath(hash) {
25
+ return this.config.pathPrefix ? `${this.config.pathPrefix}/chunks/${hash}` : hash;
26
+ }
27
+ async getChunk(hash) {
28
+ const file = this.storage.bucket(this.config.bucket).file(this.getPath(hash));
29
+ const [exists] = await file.exists();
30
+ if (!exists) {
31
+ return null;
32
+ }
33
+ return file.createReadStream();
34
+ }
35
+ async putChunk(hash, data) {
36
+ const file = this.storage.bucket(this.config.bucket).file(this.getPath(hash));
37
+ const writeStream = file.createWriteStream({ resumable: false });
38
+ await new Promise((resolve, reject) => {
39
+ data.pipe(writeStream).on('finish', resolve).on('error', reject);
40
+ });
41
+ }
42
+ async chunkExists(hash) {
43
+ const file = this.storage.bucket(this.config.bucket).file(this.getPath(hash));
44
+ const [exists] = await file.exists();
45
+ return exists;
46
+ }
47
+ async deleteChunk(hash) {
48
+ const file = this.storage.bucket(this.config.bucket).file(this.getPath(hash));
49
+ await file.delete({ ignoreNotFound: true });
50
+ }
51
+ async listChunks() {
52
+ const chunksPath = this.config.pathPrefix ? `${this.config.pathPrefix}/chunks` : '';
53
+ const [files] = await this.storage.bucket(this.config.bucket).getFiles({
54
+ prefix: chunksPath,
55
+ });
56
+ return files.map((file) => file.name.replace(`${this.config.pathPrefix}/chunks/`, ''));
57
+ }
58
+ async getChunkInfo(hash) {
59
+ const file = this.storage.bucket(this.config.bucket).file(this.getPath(hash));
60
+ const [exists] = await file.exists();
61
+ if (!exists) {
62
+ return null;
63
+ }
64
+ const [metadata] = await file.getMetadata();
65
+ const meta = metadata.metadata
66
+ ? Object.fromEntries(Object.entries(metadata.metadata).map(([key, value]) => [key, JSON.stringify(value)]))
67
+ : {};
68
+ return {
69
+ hash,
70
+ size: Number(metadata.size),
71
+ modified: metadata.updated ? new Date(metadata.updated) : undefined,
72
+ metadata: meta,
73
+ };
74
+ }
75
+ async getRemoteIndex() {
76
+ const indexPath = this.config.pathPrefix
77
+ ? `${this.config.pathPrefix}/rd-index.json`
78
+ : 'rd-index.json';
79
+ const file = this.storage.bucket(this.config.bucket).file(indexPath);
80
+ const [exists] = await file.exists();
81
+ if (!exists) {
82
+ return null;
83
+ }
84
+ const [contents] = await file.download();
85
+ const data = contents.toString('utf-8');
86
+ return JSON.parse(data);
87
+ }
88
+ async putRemoteIndex(index) {
89
+ const indexPath = this.config.pathPrefix
90
+ ? `${this.config.pathPrefix}/rd-index.json`
91
+ : 'rd-index.json';
92
+ const bucket = this.storage.bucket(this.config.bucket);
93
+ const file = bucket.file(indexPath);
94
+ const contents = JSON.stringify(index, null, 2);
95
+ await file.save(contents, {
96
+ contentType: 'application/json',
97
+ resumable: false,
98
+ });
99
+ }
100
+ }
101
+ exports.GCSStorageAdapter = GCSStorageAdapter;
@@ -0,0 +1,23 @@
1
+ import { Readable } from 'stream';
2
+ import { BlobInfo, HashStorageAdapter } from '../../core/adapters';
3
+ import { HTTPStorageConfig } from '../../core/config';
4
+ import { RDIndex } from '../../core/models';
5
+ export declare class HTTPStorageAdapter extends HashStorageAdapter {
6
+ private readonly config;
7
+ private readonly baseUrl;
8
+ private readonly token?;
9
+ private readonly apiKey?;
10
+ constructor(config: HTTPStorageConfig);
11
+ dispose(): Promise<void>;
12
+ private buildUrl;
13
+ private buildIndexUrl;
14
+ private headers;
15
+ getChunk(hash: string): Promise<Readable | null>;
16
+ putChunk(hash: string, data: Readable): Promise<void>;
17
+ chunkExists(hash: string): Promise<boolean>;
18
+ deleteChunk(hash: string): Promise<void>;
19
+ getChunkInfo(hash: string): Promise<BlobInfo | null>;
20
+ getRemoteIndex(): Promise<RDIndex | null>;
21
+ putRemoteIndex(index: RDIndex): Promise<void>;
22
+ }
23
+ //# sourceMappingURL=http-storage-adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http-storage-adapter.d.ts","sourceRoot":"","sources":["../../../src/infrastructure/adapters/http-storage-adapter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAElC,OAAO,EAAE,QAAQ,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAEnE,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAU5C,qBAAa,kBAAmB,SAAQ,kBAAkB;IAK5C,OAAO,CAAC,QAAQ,CAAC,MAAM;IAJnC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAkB;IACzC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAkB;gBAEb,MAAM,EAAE,iBAAiB;IAUhD,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAI9B,OAAO,CAAC,QAAQ;IAQhB,OAAO,CAAC,aAAa;IAUrB,OAAO,CAAC,OAAO;IAcT,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;IAqBhD,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAcrD,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAmB3C,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAiBxC,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;IAgCpD,cAAc,IAAI,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;IAsBzC,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;CAepD"}
@@ -0,0 +1,154 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.HTTPStorageAdapter = void 0;
4
+ const stream_1 = require("stream");
5
+ const adapters_1 = require("../../core/adapters");
6
+ const exceptions_1 = require("../../core/exceptions");
7
+ class HTTPStorageAdapter extends adapters_1.HashStorageAdapter {
8
+ config;
9
+ baseUrl;
10
+ token;
11
+ apiKey;
12
+ constructor(config) {
13
+ super();
14
+ this.config = config;
15
+ const { endpoint, credentials } = config;
16
+ this.baseUrl = endpoint.replace(/\/+$/, '');
17
+ this.token = credentials?.bearerToken;
18
+ this.apiKey = credentials?.apiKey;
19
+ }
20
+ async dispose() {
21
+ return;
22
+ }
23
+ buildUrl(hash) {
24
+ const prefix = this.config.pathPrefix
25
+ ? `/${this.config.pathPrefix.replace(/^\/+|\/+$/g, '')}`
26
+ : '';
27
+ return `${this.baseUrl}${prefix}/${encodeURIComponent(hash)}`;
28
+ }
29
+ buildIndexUrl() {
30
+ const prefix = this.config.pathPrefix
31
+ ? `/${this.config.pathPrefix.replace(/^\/+|\/+$/g, '')}`
32
+ : '';
33
+ const indexFile = this.config.indexFilePath ?? 'rd-index.json';
34
+ return `${this.baseUrl}${prefix ? prefix + '/' : '/'}${indexFile}`;
35
+ }
36
+ headers(extra) {
37
+ const headers = { ...(extra || {}) };
38
+ if (this.token) {
39
+ headers['Authorization'] = `Bearer ${this.token}`;
40
+ }
41
+ if (this.apiKey) {
42
+ headers['x-api-key'] = this.apiKey;
43
+ }
44
+ return headers;
45
+ }
46
+ async getChunk(hash) {
47
+ const url = this.buildUrl(hash);
48
+ const res = await fetch(url, {
49
+ method: 'GET',
50
+ headers: this.headers(),
51
+ });
52
+ if (res.status === 404) {
53
+ return null;
54
+ }
55
+ if (!res.ok) {
56
+ throw new exceptions_1.GetChunkException(`${res.status} ${res.statusText}`);
57
+ }
58
+ // Convert web ReadableStream to Node.js Readable
59
+ const nodeStream = stream_1.Readable.fromWeb(res.body);
60
+ return nodeStream;
61
+ }
62
+ async putChunk(hash, data) {
63
+ const url = this.buildUrl(hash);
64
+ const res = await fetch(url, {
65
+ method: 'PUT',
66
+ headers: this.headers({ 'Content-Type': 'application/octet-stream' }),
67
+ body: data,
68
+ });
69
+ if (!res.ok) {
70
+ throw new exceptions_1.PutChunkException(`${res.status} ${res.statusText}`);
71
+ }
72
+ }
73
+ async chunkExists(hash) {
74
+ const url = this.buildUrl(hash);
75
+ const res = await fetch(url, {
76
+ method: 'HEAD',
77
+ headers: this.headers(),
78
+ });
79
+ if (res.status === 404) {
80
+ return false;
81
+ }
82
+ if (!res.ok && res.status !== 200) {
83
+ throw new exceptions_1.HeadChunkException(`${res.status} ${res.statusText}`);
84
+ }
85
+ return res.ok;
86
+ }
87
+ async deleteChunk(hash) {
88
+ const url = this.buildUrl(hash);
89
+ const res = await fetch(url, {
90
+ method: 'DELETE',
91
+ headers: this.headers(),
92
+ });
93
+ if (res.status === 404) {
94
+ return;
95
+ }
96
+ if (!res.ok) {
97
+ throw new exceptions_1.DeleteChunkException(`${res.status} ${res.statusText}`);
98
+ }
99
+ }
100
+ async getChunkInfo(hash) {
101
+ const url = this.buildUrl(hash);
102
+ const res = await fetch(url, {
103
+ method: 'HEAD',
104
+ headers: this.headers(),
105
+ });
106
+ if (res.status === 404) {
107
+ return null;
108
+ }
109
+ if (!res.ok) {
110
+ throw new exceptions_1.HeadChunkException(`${res.status} ${res.statusText}`);
111
+ }
112
+ const size = Number(res.headers.get('content-length')) || 0;
113
+ const modified = res.headers.get('last-modified')
114
+ ? new Date(res.headers.get('last-modified'))
115
+ : undefined;
116
+ const metadata = {};
117
+ for (const [key, value] of res.headers.entries()) {
118
+ if (key.startsWith('x-meta-')) {
119
+ metadata[key.substring(7)] = value;
120
+ }
121
+ }
122
+ return { hash, size, modified, metadata };
123
+ }
124
+ async getRemoteIndex() {
125
+ const url = this.buildIndexUrl();
126
+ const res = await fetch(url, {
127
+ method: 'GET',
128
+ headers: this.headers(),
129
+ });
130
+ if (res.status === 404) {
131
+ return null;
132
+ }
133
+ if (!res.ok) {
134
+ throw new exceptions_1.GetRemoteIndexException(`${res.status} ${res.statusText}`);
135
+ }
136
+ const buffer = Buffer.from(await res.arrayBuffer());
137
+ const data = buffer.toString('utf-8');
138
+ return JSON.parse(data);
139
+ }
140
+ async putRemoteIndex(index) {
141
+ const url = this.buildIndexUrl();
142
+ const res = await fetch(url, {
143
+ method: 'PUT',
144
+ headers: this.headers({
145
+ 'Content-Type': 'application/json',
146
+ }),
147
+ body: JSON.stringify(index, null, 2),
148
+ });
149
+ if (!res.ok) {
150
+ throw new exceptions_1.PutRemoteIndexException(`${res.status} ${res.statusText}`);
151
+ }
152
+ }
153
+ }
154
+ exports.HTTPStorageAdapter = HTTPStorageAdapter;