swarm-deploy 0.0.0 → 0.2.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 (148) hide show
  1. package/CHANGELOG.md +76 -0
  2. package/LICENSE.md +201 -0
  3. package/NOTICE.md +13 -0
  4. package/README.md +1283 -0
  5. package/RELEASING.md +71 -0
  6. package/SECURITY.md +40 -0
  7. package/dist/abort.d.ts +16 -0
  8. package/dist/abort.js +52 -0
  9. package/dist/abort.js.map +1 -0
  10. package/dist/allowlist.d.ts +2 -0
  11. package/dist/allowlist.js +21 -0
  12. package/dist/allowlist.js.map +1 -0
  13. package/dist/bin/swarm-deploy.d.ts +2 -0
  14. package/dist/bin/swarm-deploy.js +41 -0
  15. package/dist/bin/swarm-deploy.js.map +1 -0
  16. package/dist/cli.d.ts +27 -0
  17. package/dist/cli.js +751 -0
  18. package/dist/cli.js.map +1 -0
  19. package/dist/client.d.ts +111 -0
  20. package/dist/client.js +276 -0
  21. package/dist/client.js.map +1 -0
  22. package/dist/direct-dht.d.ts +81 -0
  23. package/dist/direct-dht.js +254 -0
  24. package/dist/direct-dht.js.map +1 -0
  25. package/dist/error-code.d.ts +15 -0
  26. package/dist/error-code.js +30 -0
  27. package/dist/error-code.js.map +1 -0
  28. package/dist/errors.d.ts +31 -0
  29. package/dist/errors.js +37 -0
  30. package/dist/errors.js.map +1 -0
  31. package/dist/events-node.d.ts +2 -0
  32. package/dist/events-node.js +7 -0
  33. package/dist/events-node.js.map +1 -0
  34. package/dist/files.d.ts +32 -0
  35. package/dist/files.js +85 -0
  36. package/dist/files.js.map +1 -0
  37. package/dist/fs-node.d.ts +2 -0
  38. package/dist/fs-node.js +7 -0
  39. package/dist/fs-node.js.map +1 -0
  40. package/dist/hooks-module.d.ts +9 -0
  41. package/dist/hooks-module.js +118 -0
  42. package/dist/hooks-module.js.map +1 -0
  43. package/dist/hooks.d.ts +69 -0
  44. package/dist/hooks.js +88 -0
  45. package/dist/hooks.js.map +1 -0
  46. package/dist/identity.d.ts +7 -0
  47. package/dist/identity.js +50 -0
  48. package/dist/identity.js.map +1 -0
  49. package/dist/index.d.ts +12 -0
  50. package/dist/index.js +21 -0
  51. package/dist/index.js.map +1 -0
  52. package/dist/os-node.d.ts +2 -0
  53. package/dist/os-node.js +7 -0
  54. package/dist/os-node.js.map +1 -0
  55. package/dist/path-node.d.ts +2 -0
  56. package/dist/path-node.js +7 -0
  57. package/dist/path-node.js.map +1 -0
  58. package/dist/process-node.d.ts +2 -0
  59. package/dist/process-node.js +7 -0
  60. package/dist/process-node.js.map +1 -0
  61. package/dist/release.d.ts +26 -0
  62. package/dist/release.js +419 -0
  63. package/dist/release.js.map +1 -0
  64. package/dist/server.d.ts +239 -0
  65. package/dist/server.js +928 -0
  66. package/dist/server.js.map +1 -0
  67. package/dist/storage/atomic-file.d.ts +15 -0
  68. package/dist/storage/atomic-file.js +172 -0
  69. package/dist/storage/atomic-file.js.map +1 -0
  70. package/dist/storage/commit-journal.d.ts +120 -0
  71. package/dist/storage/commit-journal.js +417 -0
  72. package/dist/storage/commit-journal.js.map +1 -0
  73. package/dist/storage/commit-store.d.ts +307 -0
  74. package/dist/storage/commit-store.js +1691 -0
  75. package/dist/storage/commit-store.js.map +1 -0
  76. package/dist/storage/layout.d.ts +16 -0
  77. package/dist/storage/layout.js +409 -0
  78. package/dist/storage/layout.js.map +1 -0
  79. package/dist/storage/link-store.d.ts +70 -0
  80. package/dist/storage/link-store.js +363 -0
  81. package/dist/storage/link-store.js.map +1 -0
  82. package/dist/storage/recovery.d.ts +100 -0
  83. package/dist/storage/recovery.js +260 -0
  84. package/dist/storage/recovery.js.map +1 -0
  85. package/dist/storage/retention.d.ts +183 -0
  86. package/dist/storage/retention.js +619 -0
  87. package/dist/storage/retention.js.map +1 -0
  88. package/dist/storage/root-coordinator.d.ts +7 -0
  89. package/dist/storage/root-coordinator.js +27 -0
  90. package/dist/storage/root-coordinator.js.map +1 -0
  91. package/dist/storage/session-store.d.ts +2 -0
  92. package/dist/storage/session-store.js +7 -0
  93. package/dist/storage/session-store.js.map +1 -0
  94. package/dist/storage/tar-session-store.d.ts +147 -0
  95. package/dist/storage/tar-session-store.js +1044 -0
  96. package/dist/storage/tar-session-store.js.map +1 -0
  97. package/dist/storage/tree-fs.d.ts +44 -0
  98. package/dist/storage/tree-fs.js +580 -0
  99. package/dist/storage/tree-fs.js.map +1 -0
  100. package/dist/storage/tree-staging.d.ts +9 -0
  101. package/dist/storage/tree-staging.js +64 -0
  102. package/dist/storage/tree-staging.js.map +1 -0
  103. package/dist/storage/types.d.ts +77 -0
  104. package/dist/storage/types.js +3 -0
  105. package/dist/storage/types.js.map +1 -0
  106. package/dist/symlinks.d.ts +36 -0
  107. package/dist/symlinks.js +128 -0
  108. package/dist/symlinks.js.map +1 -0
  109. package/dist/tar-protocol/controls.d.ts +73 -0
  110. package/dist/tar-protocol/controls.js +291 -0
  111. package/dist/tar-protocol/controls.js.map +1 -0
  112. package/dist/tar-protocol/direct-wire.d.ts +43 -0
  113. package/dist/tar-protocol/direct-wire.js +194 -0
  114. package/dist/tar-protocol/direct-wire.js.map +1 -0
  115. package/dist/tar-protocol/extract.d.ts +18 -0
  116. package/dist/tar-protocol/extract.js +124 -0
  117. package/dist/tar-protocol/extract.js.map +1 -0
  118. package/dist/tar-protocol/hash.d.ts +10 -0
  119. package/dist/tar-protocol/hash.js +44 -0
  120. package/dist/tar-protocol/hash.js.map +1 -0
  121. package/dist/tar-protocol/lifecycle.d.ts +13 -0
  122. package/dist/tar-protocol/lifecycle.js +90 -0
  123. package/dist/tar-protocol/lifecycle.js.map +1 -0
  124. package/dist/tar-protocol/manifest.d.ts +58 -0
  125. package/dist/tar-protocol/manifest.js +312 -0
  126. package/dist/tar-protocol/manifest.js.map +1 -0
  127. package/dist/tar-protocol/tree-extract.d.ts +37 -0
  128. package/dist/tar-protocol/tree-extract.js +240 -0
  129. package/dist/tar-protocol/tree-extract.js.map +1 -0
  130. package/dist/tar-protocol/tree-manifest.d.ts +45 -0
  131. package/dist/tar-protocol/tree-manifest.js +277 -0
  132. package/dist/tar-protocol/tree-manifest.js.map +1 -0
  133. package/dist/tar-protocol/tree-path.d.ts +15 -0
  134. package/dist/tar-protocol/tree-path.js +68 -0
  135. package/dist/tar-protocol/tree-path.js.map +1 -0
  136. package/dist/tar-protocol/tree.d.ts +68 -0
  137. package/dist/tar-protocol/tree.js +269 -0
  138. package/dist/tar-protocol/tree.js.map +1 -0
  139. package/dist/tar-protocol/ustar.d.ts +36 -0
  140. package/dist/tar-protocol/ustar.js +167 -0
  141. package/dist/tar-protocol/ustar.js.map +1 -0
  142. package/dist/types.d.ts +61 -0
  143. package/dist/types.js +3 -0
  144. package/dist/types.js.map +1 -0
  145. package/dist/validation.d.ts +4 -0
  146. package/dist/validation.js +26 -0
  147. package/dist/validation.js.map +1 -0
  148. package/package.json +103 -1
@@ -0,0 +1,291 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.MAX_CONTROL_RECORD_BYTES = exports.CONTROL_VERSION = void 0;
7
+ exports.isTreeMetadata = isTreeMetadata;
8
+ exports.assertSourceParent = assertSourceParent;
9
+ exports.encodeMetadataRecord = encodeMetadataRecord;
10
+ exports.decodeMetadataRecord = decodeMetadataRecord;
11
+ exports.encodeTreeMetadataRecord = encodeTreeMetadataRecord;
12
+ exports.decodeTreeMetadataRecord = decodeTreeMetadataRecord;
13
+ exports.encodeAnyMetadataRecord = encodeAnyMetadataRecord;
14
+ exports.decodeAnyMetadataRecord = decodeAnyMetadataRecord;
15
+ exports.encodeAdmissionRecord = encodeAdmissionRecord;
16
+ exports.decodeAdmissionRecord = decodeAdmissionRecord;
17
+ exports.encodeFinalRecord = encodeFinalRecord;
18
+ exports.decodeFinalRecord = decodeFinalRecord;
19
+ exports.encodeControlFrame = encodeControlFrame;
20
+ const b4a_1 = __importDefault(require("b4a"));
21
+ const errors_js_1 = require("../errors.js");
22
+ const tree_path_js_1 = require("./tree-path.js");
23
+ const ustar_js_1 = require("./ustar.js");
24
+ exports.CONTROL_VERSION = 1;
25
+ exports.MAX_CONTROL_RECORD_BYTES = 4 * 1024;
26
+ const HEX_32 = /^[0-9a-f]{64}$/;
27
+ const SAFE_NAME = /^[A-Za-z0-9][A-Za-z0-9._-]{0,199}$/;
28
+ const SAFE_SOURCE_PARENT = /^[A-Za-z0-9][A-Za-z0-9._+-]{0,199}$/;
29
+ const HISTORY_PREFIX = 'history-';
30
+ const STABLE_CODES = new Set(Object.values(errors_js_1.ERRORS));
31
+ function isTreeMetadata(value) {
32
+ return value.kind === 'directory';
33
+ }
34
+ function invalid(message, cause = null) {
35
+ return new errors_js_1.SwarmDeployError(errors_js_1.ERRORS.PROTOCOL_INVALID, message, cause);
36
+ }
37
+ function isRecord(value) {
38
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
39
+ }
40
+ function exactKeys(value, expected) {
41
+ const actual = Object.keys(value).sort();
42
+ const wanted = [...expected].sort();
43
+ if (actual.length !== wanted.length || actual.some((key, index) => key !== wanted[index])) {
44
+ throw invalid('Unexpected control record fields');
45
+ }
46
+ }
47
+ function assertVersion(value) {
48
+ if (value !== exports.CONTROL_VERSION)
49
+ throw invalid('Unsupported control record version');
50
+ }
51
+ function assertSafeUint(value, name) {
52
+ if (typeof value !== 'number' || !Number.isSafeInteger(value) || value < 0) {
53
+ throw invalid(`Invalid ${name}`);
54
+ }
55
+ }
56
+ function assertHex32(value, name) {
57
+ if (typeof value !== 'string' || !HEX_32.test(value))
58
+ throw invalid(`Invalid ${name}`);
59
+ }
60
+ function assertName(value) {
61
+ if (typeof value !== 'string' ||
62
+ !SAFE_NAME.test(value) ||
63
+ value.startsWith(HISTORY_PREFIX) ||
64
+ b4a_1.default.from(value).byteLength > 100) {
65
+ throw new errors_js_1.SwarmDeployError(errors_js_1.ERRORS.INVALID_FILENAME, 'Invalid TAR filename');
66
+ }
67
+ }
68
+ function assertSourceParent(value) {
69
+ if (typeof value !== 'string' ||
70
+ !SAFE_SOURCE_PARENT.test(value) ||
71
+ b4a_1.default.from(value).byteLength > 100) {
72
+ throw new errors_js_1.SwarmDeployError(errors_js_1.ERRORS.INVALID_FILENAME, 'Invalid source parent');
73
+ }
74
+ }
75
+ function assertStableCode(value) {
76
+ if (typeof value !== 'string' || !STABLE_CODES.has(value))
77
+ throw invalid('Invalid error code');
78
+ }
79
+ function parseRecord(bytes) {
80
+ if (!b4a_1.default.isBuffer(bytes) || bytes.byteLength === 0)
81
+ throw invalid('Invalid control record');
82
+ if (bytes.byteLength > exports.MAX_CONTROL_RECORD_BYTES)
83
+ throw invalid('Control record too large');
84
+ let value;
85
+ try {
86
+ value = JSON.parse(b4a_1.default.toString(bytes, 'utf8'));
87
+ }
88
+ catch (error) {
89
+ throw invalid('Malformed control record', error);
90
+ }
91
+ if (!isRecord(value))
92
+ throw invalid('Control record must be an object');
93
+ return value;
94
+ }
95
+ function encodeRecord(value, validate) {
96
+ const checked = validate(value);
97
+ const encoded = b4a_1.default.from(JSON.stringify(checked));
98
+ if (encoded.byteLength > exports.MAX_CONTROL_RECORD_BYTES)
99
+ throw invalid('Control record too large');
100
+ return encoded;
101
+ }
102
+ function validateMetadata(value) {
103
+ if (!isRecord(value))
104
+ throw invalid('Metadata record must be an object');
105
+ const expected = [
106
+ 'v',
107
+ 'name',
108
+ 'fileSize',
109
+ 'fileSha256',
110
+ 'tarSize',
111
+ 'tarSha256',
112
+ 'transferId',
113
+ 'reset'
114
+ ];
115
+ if (Object.prototype.hasOwnProperty.call(value, 'sourceParent')) {
116
+ expected.push('sourceParent');
117
+ }
118
+ exactKeys(value, expected);
119
+ assertVersion(value.v);
120
+ assertName(value.name);
121
+ if (Object.prototype.hasOwnProperty.call(value, 'sourceParent')) {
122
+ assertSourceParent(value.sourceParent);
123
+ }
124
+ assertSafeUint(value.fileSize, 'file size');
125
+ assertHex32(value.fileSha256, 'file digest');
126
+ assertSafeUint(value.tarSize, 'TAR size');
127
+ if (value.tarSize !== (0, ustar_js_1.deterministicTarSize)(value.fileSize))
128
+ throw invalid('Noncanonical TAR size');
129
+ assertHex32(value.tarSha256, 'TAR digest');
130
+ assertHex32(value.transferId, 'transfer ID');
131
+ if (typeof value.reset !== 'boolean')
132
+ throw invalid('Invalid reset flag');
133
+ return value;
134
+ }
135
+ const TAR_END_BLOCKS = 2 * ustar_js_1.TAR_BLOCK_BYTES;
136
+ /**
137
+ * The exact set of TAR sizes a canonical generator can produce for these counts.
138
+ *
139
+ * Every entry owns one header block and the archive ends with two zero blocks. Only files carry
140
+ * payload, and each non-empty file pads to a block boundary with at most 511 bytes. At least one
141
+ * file exists when there is any payload, so the unpadded total is `minimum`, and at most
142
+ * `min(entryCount, payloadBytes)` files can each hold a padded tail. Real archives are whole blocks,
143
+ * so the window is the whole-block sizes from `minimum` rounded up to `maximum` rounded down.
144
+ */
145
+ function assertTreeTarSize(entryCount, payloadBytes, tarSize) {
146
+ if (payloadBytes > entryCount * ustar_js_1.MAX_USTAR_FILE_BYTES)
147
+ throw invalid('Invalid tree payload size');
148
+ if (payloadBytes > 0 && entryCount === 0)
149
+ throw invalid('Invalid tree payload size');
150
+ const base = TAR_END_BLOCKS + ustar_js_1.TAR_BLOCK_BYTES * entryCount;
151
+ const minimum = base + payloadBytes;
152
+ const maximum = minimum + (ustar_js_1.TAR_BLOCK_BYTES - 1) * Math.min(entryCount, payloadBytes);
153
+ const lowest = Math.ceil(minimum / ustar_js_1.TAR_BLOCK_BYTES) * ustar_js_1.TAR_BLOCK_BYTES;
154
+ const highest = Math.floor(maximum / ustar_js_1.TAR_BLOCK_BYTES) * ustar_js_1.TAR_BLOCK_BYTES;
155
+ if (tarSize % ustar_js_1.TAR_BLOCK_BYTES !== 0 || tarSize < lowest || tarSize > highest) {
156
+ throw invalid('Noncanonical TAR size');
157
+ }
158
+ }
159
+ function validateTreeMetadata(value) {
160
+ if (!isRecord(value))
161
+ throw invalid('Metadata record must be an object');
162
+ const expected = [
163
+ 'v',
164
+ 'kind',
165
+ 'name',
166
+ 'entryCount',
167
+ 'payloadBytes',
168
+ 'treeSha256',
169
+ 'tarSize',
170
+ 'tarSha256',
171
+ 'transferId',
172
+ 'reset'
173
+ ];
174
+ if (Object.prototype.hasOwnProperty.call(value, 'sourceParent'))
175
+ expected.push('sourceParent');
176
+ exactKeys(value, expected);
177
+ assertVersion(value.v);
178
+ if (value.kind !== 'directory')
179
+ throw invalid('Invalid artifact kind');
180
+ assertName(value.name);
181
+ if (Object.prototype.hasOwnProperty.call(value, 'sourceParent')) {
182
+ assertSourceParent(value.sourceParent);
183
+ }
184
+ assertSafeUint(value.entryCount, 'tree entry count');
185
+ if (value.entryCount > tree_path_js_1.MAX_TREE_ENTRIES)
186
+ throw invalid('Invalid tree entry count');
187
+ assertSafeUint(value.payloadBytes, 'tree payload size');
188
+ assertHex32(value.treeSha256, 'tree digest');
189
+ assertSafeUint(value.tarSize, 'TAR size');
190
+ assertHex32(value.tarSha256, 'TAR digest');
191
+ assertHex32(value.transferId, 'transfer ID');
192
+ if (typeof value.reset !== 'boolean')
193
+ throw invalid('Invalid reset flag');
194
+ assertTreeTarSize(value.entryCount, value.payloadBytes, value.tarSize);
195
+ return value;
196
+ }
197
+ function validateAnyMetadata(value) {
198
+ if (!isRecord(value))
199
+ throw invalid('Metadata record must be an object');
200
+ return Object.prototype.hasOwnProperty.call(value, 'kind')
201
+ ? validateTreeMetadata(value)
202
+ : validateMetadata(value);
203
+ }
204
+ function validateAdmission(value) {
205
+ if (!isRecord(value))
206
+ throw invalid('Admission record must be an object');
207
+ assertVersion(value.v);
208
+ if (value.status === 'ACCEPT') {
209
+ exactKeys(value, ['v', 'status', 'offset']);
210
+ if (value.offset !== 0)
211
+ throw invalid('Invalid ACCEPT offset');
212
+ }
213
+ else if (value.status === 'RESUME') {
214
+ exactKeys(value, ['v', 'status', 'offset', 'prefixSha256']);
215
+ assertSafeUint(value.offset, 'resume offset');
216
+ if (value.offset === 0)
217
+ throw invalid('Invalid resume offset');
218
+ assertHex32(value.prefixSha256, 'prefix digest');
219
+ }
220
+ else if (value.status === 'VERIFIED' || value.status === 'ALREADY_COMMITTED') {
221
+ exactKeys(value, ['v', 'status']);
222
+ }
223
+ else if (value.status === 'REJECTED') {
224
+ exactKeys(value, ['v', 'status', 'code']);
225
+ assertStableCode(value.code);
226
+ }
227
+ else {
228
+ throw invalid('Invalid admission status');
229
+ }
230
+ return value;
231
+ }
232
+ function validateFinal(value) {
233
+ if (!isRecord(value))
234
+ throw invalid('Final record must be an object');
235
+ assertVersion(value.v);
236
+ if (value.status === 'COMMITTED') {
237
+ exactKeys(value, ['v', 'status']);
238
+ }
239
+ else if (value.status === 'FAILED') {
240
+ exactKeys(value, ['v', 'status', 'code']);
241
+ assertStableCode(value.code);
242
+ }
243
+ else {
244
+ throw invalid('Invalid final status');
245
+ }
246
+ return value;
247
+ }
248
+ function encodeMetadataRecord(value) {
249
+ return encodeRecord(value, validateMetadata);
250
+ }
251
+ function decodeMetadataRecord(bytes) {
252
+ return validateMetadata(parseRecord(bytes));
253
+ }
254
+ function encodeTreeMetadataRecord(value) {
255
+ return encodeRecord(value, validateTreeMetadata);
256
+ }
257
+ function decodeTreeMetadataRecord(bytes) {
258
+ return validateTreeMetadata(parseRecord(bytes));
259
+ }
260
+ function encodeAnyMetadataRecord(value) {
261
+ return encodeRecord(value, validateAnyMetadata);
262
+ }
263
+ function decodeAnyMetadataRecord(bytes) {
264
+ return validateAnyMetadata(parseRecord(bytes));
265
+ }
266
+ function encodeAdmissionRecord(value) {
267
+ return encodeRecord(value, validateAdmission);
268
+ }
269
+ function decodeAdmissionRecord(bytes) {
270
+ return validateAdmission(parseRecord(bytes));
271
+ }
272
+ function encodeFinalRecord(value) {
273
+ return encodeRecord(value, validateFinal);
274
+ }
275
+ function decodeFinalRecord(bytes) {
276
+ return validateFinal(parseRecord(bytes));
277
+ }
278
+ function encodeControlFrame(record) {
279
+ if (!b4a_1.default.isBuffer(record) || record.byteLength === 0)
280
+ throw invalid('Invalid control record');
281
+ if (record.byteLength > exports.MAX_CONTROL_RECORD_BYTES)
282
+ throw invalid('Control record too large');
283
+ const frame = b4a_1.default.alloc(4 + record.byteLength);
284
+ frame[0] = (record.byteLength >>> 24) & 0xff;
285
+ frame[1] = (record.byteLength >>> 16) & 0xff;
286
+ frame[2] = (record.byteLength >>> 8) & 0xff;
287
+ frame[3] = record.byteLength & 0xff;
288
+ frame.set(record, 4);
289
+ return frame;
290
+ }
291
+ //# sourceMappingURL=controls.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"controls.js","sourceRoot":"","sources":["../../src/tar-protocol/controls.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,43 @@
1
+ import { type AbortSignalLike } from '../abort.js';
2
+ import type { DirectDhtSocket } from '../direct-dht.js';
3
+ import { decodeAdmissionRecord, decodeAnyMetadataRecord, decodeFinalRecord, type AdmissionRecord, type AnyMetadataRecord, type FinalRecord } from './controls.js';
4
+ import { type ProtocolWriteOptions } from './lifecycle.js';
5
+ /** Exact, bounded, phase-aware reader for a half-closed direct stream. */
6
+ export declare class DirectWireReader {
7
+ private readonly socket;
8
+ private readonly chunks;
9
+ private available;
10
+ private ended;
11
+ private failure;
12
+ private wake;
13
+ private readonly data;
14
+ private readonly end;
15
+ private readonly close;
16
+ private readonly error;
17
+ constructor(socket: DirectDhtSocket);
18
+ private notify;
19
+ /** Resolves on the next socket event: data, end, close, or error. */
20
+ private awaitEvent;
21
+ /**
22
+ * Returns only once at least one byte is buffered.
23
+ *
24
+ * The terminal checks are re-evaluated after every wake, not just on entry: a
25
+ * peer that half-closes mid-phase wakes this with no data, and resolving
26
+ * there would hand the caller an empty `chunks` array to dereference.
27
+ */
28
+ private wait;
29
+ exact(bytes: number, signal: AbortSignalLike | null | undefined, timeout: number): Promise<Buffer>;
30
+ control<T>(decode: (bytes: Uint8Array) => T, signal: AbortSignalLike | null | undefined, timeout: number): Promise<T>;
31
+ tar(length: number, write: (bytes: Buffer) => Promise<void>, signal: AbortSignalLike | null | undefined, timeout: number): Promise<void>;
32
+ /** The sender's write-half close is the deterministic no-trailing boundary. */
33
+ requireEnd(signal: AbortSignalLike | null | undefined, timeout: number): Promise<void>;
34
+ closeReader(): void;
35
+ }
36
+ export declare function endWrite(socket: DirectDhtSocket): void;
37
+ export declare function writeMetadata(socket: DirectDhtSocket, metadata: AnyMetadataRecord, options?: ProtocolWriteOptions): Promise<void>;
38
+ export declare function writeAdmission(socket: DirectDhtSocket, value: AdmissionRecord, options?: ProtocolWriteOptions): Promise<void>;
39
+ export declare function writeFinal(socket: DirectDhtSocket, value: FinalRecord, options?: ProtocolWriteOptions): Promise<void>;
40
+ export declare function writeTar(socket: DirectDhtSocket, value: Uint8Array, options?: ProtocolWriteOptions): Promise<void>;
41
+ export declare const decodeDirectMetadata: typeof decodeAnyMetadataRecord;
42
+ export declare const decodeDirectAdmission: typeof decodeAdmissionRecord;
43
+ export declare const decodeDirectFinal: typeof decodeFinalRecord;
@@ -0,0 +1,194 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.decodeDirectFinal = exports.decodeDirectAdmission = exports.decodeDirectMetadata = exports.DirectWireReader = void 0;
7
+ exports.endWrite = endWrite;
8
+ exports.writeMetadata = writeMetadata;
9
+ exports.writeAdmission = writeAdmission;
10
+ exports.writeFinal = writeFinal;
11
+ exports.writeTar = writeTar;
12
+ const b4a_1 = __importDefault(require("b4a"));
13
+ const abort_js_1 = require("../abort.js");
14
+ const errors_js_1 = require("../errors.js");
15
+ const controls_js_1 = require("./controls.js");
16
+ const lifecycle_js_1 = require("./lifecycle.js");
17
+ function invalid(message, cause = null) {
18
+ return new errors_js_1.SwarmDeployError(errors_js_1.ERRORS.PROTOCOL_INVALID, message, cause);
19
+ }
20
+ /** Exact, bounded, phase-aware reader for a half-closed direct stream. */
21
+ class DirectWireReader {
22
+ socket;
23
+ chunks = [];
24
+ available = 0;
25
+ ended = false;
26
+ failure = null;
27
+ wake = null;
28
+ data = (value) => {
29
+ if (!b4a_1.default.isBuffer(value) || value.byteLength === 0)
30
+ return;
31
+ this.chunks.push(b4a_1.default.from(value));
32
+ this.available += value.byteLength;
33
+ this.socket.pause?.();
34
+ this.notify();
35
+ };
36
+ end = () => {
37
+ this.ended = true;
38
+ this.notify();
39
+ };
40
+ close = () => {
41
+ if (!this.ended)
42
+ this.failure = invalid('Direct DHT stream closed without protocol completion');
43
+ this.notify();
44
+ };
45
+ error = (error) => {
46
+ this.failure = error;
47
+ this.notify();
48
+ };
49
+ constructor(socket) {
50
+ this.socket = socket;
51
+ this.socket.on('data', this.data);
52
+ this.socket.on('end', this.end);
53
+ this.socket.on('close', this.close);
54
+ this.socket.on('error', this.error);
55
+ this.socket.pause?.();
56
+ }
57
+ notify() {
58
+ const wake = this.wake;
59
+ this.wake = null;
60
+ wake?.();
61
+ }
62
+ /** Resolves on the next socket event: data, end, close, or error. */
63
+ awaitEvent(signal, timeout) {
64
+ return new Promise((resolve, reject) => {
65
+ let remove = () => { };
66
+ const timer = setTimeout(() => finish(new errors_js_1.SwarmDeployError(errors_js_1.ERRORS.UPLOAD_IDLE_TIMEOUT, 'Direct protocol read timed out')), timeout);
67
+ const finish = (error = null) => {
68
+ clearTimeout(timer);
69
+ remove();
70
+ this.wake = null;
71
+ if (error)
72
+ reject(error);
73
+ else
74
+ resolve();
75
+ };
76
+ remove = (0, abort_js_1.onAbort)(signal, () => finish((0, abort_js_1.abortError)()));
77
+ this.wake = () => finish(this.failure);
78
+ this.socket.resume?.();
79
+ });
80
+ }
81
+ /**
82
+ * Returns only once at least one byte is buffered.
83
+ *
84
+ * The terminal checks are re-evaluated after every wake, not just on entry: a
85
+ * peer that half-closes mid-phase wakes this with no data, and resolving
86
+ * there would hand the caller an empty `chunks` array to dereference.
87
+ */
88
+ async wait(signal, timeout) {
89
+ while (this.available === 0) {
90
+ if (this.failure)
91
+ throw this.failure;
92
+ if (this.ended)
93
+ throw invalid('Truncated direct protocol phase');
94
+ if (signal?.aborted)
95
+ throw (0, abort_js_1.abortError)();
96
+ await this.awaitEvent(signal, timeout);
97
+ }
98
+ }
99
+ async exact(bytes, signal, timeout) {
100
+ if (!Number.isSafeInteger(bytes) || bytes < 0)
101
+ throw invalid('Invalid direct stream length');
102
+ const result = b4a_1.default.alloc(bytes);
103
+ let offset = 0;
104
+ while (offset < bytes) {
105
+ await this.wait(signal, timeout);
106
+ const chunk = this.chunks[0];
107
+ const take = Math.min(bytes - offset, chunk.byteLength);
108
+ result.set(chunk.subarray(0, take), offset);
109
+ offset += take;
110
+ this.available -= take;
111
+ if (take === chunk.byteLength)
112
+ this.chunks.shift();
113
+ else
114
+ this.chunks[0] = chunk.subarray(take);
115
+ }
116
+ return result;
117
+ }
118
+ async control(decode, signal, timeout) {
119
+ const prefix = await this.exact(4, signal, timeout);
120
+ const length = prefix[0] * 0x1000000 + prefix[1] * 0x10000 + prefix[2] * 0x100 + prefix[3];
121
+ if (length <= 0 || length > controls_js_1.MAX_CONTROL_RECORD_BYTES) {
122
+ throw invalid('Invalid control frame length');
123
+ }
124
+ return decode(await this.exact(length, signal, timeout));
125
+ }
126
+ async tar(length, write, signal, timeout) {
127
+ let remaining = length;
128
+ while (remaining > 0) {
129
+ await this.wait(signal, timeout);
130
+ const chunk = this.chunks[0];
131
+ const take = Math.min(remaining, chunk.byteLength);
132
+ const part = chunk.subarray(0, take);
133
+ this.available -= take;
134
+ remaining -= take;
135
+ if (take === chunk.byteLength)
136
+ this.chunks.shift();
137
+ else
138
+ this.chunks[0] = chunk.subarray(take);
139
+ await write(part);
140
+ }
141
+ }
142
+ /** The sender's write-half close is the deterministic no-trailing boundary. */
143
+ async requireEnd(signal, timeout) {
144
+ if (this.available !== 0)
145
+ throw invalid('Trailing bytes after exact TAR payload');
146
+ while (!this.ended && !this.failure) {
147
+ if (signal?.aborted)
148
+ throw (0, abort_js_1.abortError)();
149
+ // Waits on the raw event here: reaching end-of-stream is the success
150
+ // condition for this phase, not a truncation.
151
+ await this.awaitEvent(signal, timeout);
152
+ if (this.available !== 0)
153
+ throw invalid('Trailing bytes after exact TAR payload');
154
+ }
155
+ if (this.failure)
156
+ throw this.failure;
157
+ }
158
+ closeReader() {
159
+ for (const event of ['data', 'end', 'close', 'error']) {
160
+ const listener = event === 'data'
161
+ ? this.data
162
+ : event === 'end'
163
+ ? this.end
164
+ : event === 'close'
165
+ ? this.close
166
+ : this.error;
167
+ this.socket.removeListener(event, listener);
168
+ }
169
+ this.socket.resume?.();
170
+ }
171
+ }
172
+ exports.DirectWireReader = DirectWireReader;
173
+ function endWrite(socket) {
174
+ const stream = socket;
175
+ if (typeof stream.end !== 'function')
176
+ throw invalid('Direct DHT socket cannot close write half');
177
+ stream.end();
178
+ }
179
+ function writeMetadata(socket, metadata, options = {}) {
180
+ return (0, lifecycle_js_1.writeFramedProtocolRecord)(socket, (0, controls_js_1.encodeAnyMetadataRecord)(metadata), options);
181
+ }
182
+ function writeAdmission(socket, value, options = {}) {
183
+ return (0, lifecycle_js_1.writeFramedProtocolRecord)(socket, (0, controls_js_1.encodeAdmissionRecord)(value), options);
184
+ }
185
+ function writeFinal(socket, value, options = {}) {
186
+ return (0, lifecycle_js_1.writeFramedProtocolRecord)(socket, (0, controls_js_1.encodeFinalRecord)(value), options);
187
+ }
188
+ function writeTar(socket, value, options = {}) {
189
+ return (0, lifecycle_js_1.writeProtocolBytes)(socket, value, options);
190
+ }
191
+ exports.decodeDirectMetadata = controls_js_1.decodeAnyMetadataRecord;
192
+ exports.decodeDirectAdmission = controls_js_1.decodeAdmissionRecord;
193
+ exports.decodeDirectFinal = controls_js_1.decodeFinalRecord;
194
+ //# sourceMappingURL=direct-wire.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"direct-wire.js","sourceRoot":"","sources":["../../src/tar-protocol/direct-wire.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ import { type AbortSignalLike } from '../abort.js';
2
+ import { type MetadataRecord } from './controls.js';
3
+ export interface TarExtractionStaging {
4
+ writeTar(chunk: Uint8Array): void | Promise<void>;
5
+ writeFile(chunk: Uint8Array): void | Promise<void>;
6
+ complete(): void | Promise<void>;
7
+ abort(error: unknown): void | Promise<void>;
8
+ }
9
+ export interface TarExtractionOptions {
10
+ signal?: AbortSignalLike | null;
11
+ }
12
+ export interface TarExtractionResult {
13
+ fileSize: number;
14
+ fileSha256: Buffer;
15
+ tarSize: number;
16
+ tarSha256: Buffer;
17
+ }
18
+ export declare function validateAndExtractTar(source: Iterable<Uint8Array> | AsyncIterable<Uint8Array>, offeredMetadata: MetadataRecord, staging: TarExtractionStaging, { signal }?: TarExtractionOptions): Promise<TarExtractionResult>;