@ardrive/turbo-sdk 1.26.0 → 1.27.0-alpha.1

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.
@@ -34,3 +34,4 @@ __exportStar(require("./upload.js"), exports);
34
34
  __exportStar(require("./signer.js"), exports);
35
35
  __exportStar(require("../common/index.js"), exports);
36
36
  __exportStar(require("../types.js"), exports);
37
+ __exportStar(require("../common/events.js"), exports);
@@ -1,6 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.TurboWebArweaveSigner = exports.HexSolanaSigner = exports.EthereumSigner = exports.ArweaveSigner = exports.ArconnectSigner = void 0;
3
+ exports.readableStreamToAsyncIterable = exports.TurboWebArweaveSigner = exports.HexSolanaSigner = exports.EthereumSigner = exports.ArweaveSigner = exports.ArconnectSigner = void 0;
4
+ exports.streamSignerReadableStream = streamSignerReadableStream;
5
+ exports.isAsyncIterable = isAsyncIterable;
4
6
  /**
5
7
  * Copyright (C) 2022-2024 Permanent Data Solutions, Inc.
6
8
  *
@@ -46,61 +48,21 @@ class TurboWebArweaveSigner extends signer_js_1.TurboDataItemAbstractSigner {
46
48
  await this.setPublicKey();
47
49
  // Create signing emitter if events are provided
48
50
  const fileSize = fileSizeFactory();
49
- try {
50
- const fileStream = fileStreamFactory();
51
- // start with 0 progress
52
- emitter?.emit('signing-progress', {
53
- processedBytes: 0,
54
- totalBytes: fileSize,
55
- });
56
- // TODO: implement streamReadableStreamSigner that incrementally signs the stream with events instead of converting to a buffer
57
- const buffer = fileStream instanceof Buffer
58
- ? fileStream
59
- : await (0, readableStream_js_1.readableStreamToBuffer)({
60
- stream: fileStream,
61
- size: fileSize,
62
- });
63
- // TODO: replace this with streamSigner that uses a ReadableStream with events
64
- emitter?.emit('signing-progress', {
65
- processedBytes: Math.floor(fileSize / 2),
66
- totalBytes: fileSize,
67
- });
68
- let signedDataItem;
69
- this.logger.debug('Signing data item...');
70
- if (this.signer instanceof arbundles_1.ArconnectSigner) {
71
- this.logger.debug('Arconnect signer detected, signing with Arconnect signData Item API...');
72
- const sign = Buffer.from(await this.signer['signer'].signDataItem({
73
- data: Uint8Array.from(buffer),
74
- tags: dataItemOpts?.tags,
75
- target: dataItemOpts?.target,
76
- anchor: dataItemOpts?.anchor,
77
- }));
78
- signedDataItem = new arbundles_1.DataItem(sign);
79
- }
80
- else {
81
- signedDataItem = (0, arbundles_1.createData)(Uint8Array.from(buffer), this.signer, dataItemOpts);
82
- await signedDataItem.sign(this.signer);
83
- }
84
- // emit last progress event (100%)
85
- emitter?.emit('signing-progress', {
86
- processedBytes: fileSize,
87
- totalBytes: fileSize,
88
- });
89
- // emit completion event
90
- emitter?.emit('signing-success');
91
- this.logger.debug('Successfully signed data item...');
92
- return {
93
- // while this returns a Buffer - it needs to match our return type for uploading
94
- dataItemStreamFactory: () => signedDataItem.getRaw(),
95
- dataItemSizeFactory: () => signedDataItem.getRaw().length,
96
- };
97
- }
98
- catch (error) {
99
- // If we have a signing emitter, emit error
100
- // TODO: create a SigningError class and throw that instead of the generic Error
101
- emitter?.emit('signing-error', error);
102
- throw error;
103
- }
51
+ this.logger.debug('Signing data item...');
52
+ const { signedDataItemFactory, signedDataItemSize } = await streamSignerReadableStream({
53
+ streamFactory: (0, readableStream_js_1.createUint8ArrayReadableStreamFactory)({
54
+ data: fileStreamFactory(),
55
+ }),
56
+ signer: this.signer,
57
+ dataItemOpts,
58
+ fileSize,
59
+ emitter,
60
+ });
61
+ this.logger.debug('Successfully signed data item...');
62
+ return {
63
+ dataItemStreamFactory: signedDataItemFactory,
64
+ dataItemSizeFactory: () => signedDataItemSize,
65
+ };
104
66
  }
105
67
  async generateSignedRequestHeaders() {
106
68
  await this.setPublicKey();
@@ -112,3 +74,113 @@ class TurboWebArweaveSigner extends signer_js_1.TurboDataItemAbstractSigner {
112
74
  }
113
75
  }
114
76
  exports.TurboWebArweaveSigner = TurboWebArweaveSigner;
77
+ const readableStreamToAsyncIterable = (stream) => ({
78
+ async *[Symbol.asyncIterator]() {
79
+ const reader = stream.getReader();
80
+ try {
81
+ while (true) {
82
+ const { done, value } = await reader.read();
83
+ if (done)
84
+ break;
85
+ if (value !== undefined)
86
+ yield Buffer.from(value);
87
+ }
88
+ }
89
+ finally {
90
+ reader.releaseLock();
91
+ }
92
+ },
93
+ });
94
+ exports.readableStreamToAsyncIterable = readableStreamToAsyncIterable;
95
+ async function streamSignerReadableStream({ streamFactory, signer, dataItemOpts, fileSize, emitter, }) {
96
+ try {
97
+ const header = (0, arbundles_1.createData)('', signer, dataItemOpts);
98
+ const headerSize = header.getRaw().byteLength;
99
+ const totalDataItemSizeWithHeader = fileSize + headerSize;
100
+ const [stream1, stream2] = streamFactory().tee();
101
+ const reader1 = stream1.getReader();
102
+ let bytesProcessed = 0;
103
+ const eventingStream = new ReadableStream({
104
+ start() {
105
+ // technically this should be emitted after each DeepHashChunk be we cannot access that stage, so we emit it here instead
106
+ bytesProcessed = headerSize;
107
+ emitter?.emit('signing-progress', {
108
+ processedBytes: bytesProcessed,
109
+ totalBytes: totalDataItemSizeWithHeader,
110
+ });
111
+ },
112
+ async pull(controller) {
113
+ const { done, value } = await reader1.read();
114
+ if (done) {
115
+ controller.close();
116
+ return;
117
+ }
118
+ bytesProcessed += value.byteLength;
119
+ controller.enqueue(value);
120
+ emitter?.emit('signing-progress', {
121
+ processedBytes: bytesProcessed,
122
+ totalBytes: totalDataItemSizeWithHeader,
123
+ });
124
+ },
125
+ cancel() {
126
+ reader1.cancel();
127
+ },
128
+ });
129
+ // create a readable that emits signing events as bytes are pulled through using the first stream from .tee()
130
+ const asyncIterableReadableStream = (0, exports.readableStreamToAsyncIterable)(eventingStream);
131
+ // provide that ReadableStream with events to deep hash, so as it pulls bytes through events get emitted
132
+ const parts = [
133
+ (0, arbundles_1.stringToBuffer)('dataitem'),
134
+ (0, arbundles_1.stringToBuffer)('1'),
135
+ (0, arbundles_1.stringToBuffer)(header.signatureType.toString()),
136
+ Uint8Array.from(header.rawOwner),
137
+ Uint8Array.from(header.rawTarget),
138
+ Uint8Array.from(header.rawAnchor),
139
+ Uint8Array.from(header.rawTags),
140
+ asyncIterableReadableStream,
141
+ ];
142
+ const hash = await (0, arbundles_1.deepHash)(parts);
143
+ const sigBytes = Buffer.from(await signer.sign(hash));
144
+ emitter?.emit('signing-success');
145
+ header.setSignature(sigBytes);
146
+ const headerBytes = header.getRaw();
147
+ const signedDataItemFactory = () => {
148
+ const reader = stream2.getReader();
149
+ return new ReadableStream({
150
+ start(controller) {
151
+ controller.enqueue(Uint8Array.from(headerBytes));
152
+ bytesProcessed += headerBytes.byteLength;
153
+ },
154
+ async pull(controller) {
155
+ try {
156
+ const { done, value } = await reader.read();
157
+ if (done) {
158
+ controller.close();
159
+ return;
160
+ }
161
+ controller.enqueue(value);
162
+ }
163
+ catch (error) {
164
+ controller.error(error);
165
+ }
166
+ },
167
+ cancel() {
168
+ reader.cancel();
169
+ },
170
+ });
171
+ };
172
+ return {
173
+ signedDataItemSize: totalDataItemSizeWithHeader,
174
+ signedDataItemFactory,
175
+ };
176
+ }
177
+ catch (error) {
178
+ emitter?.emit('signing-error', error);
179
+ throw error;
180
+ }
181
+ }
182
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
183
+ function isAsyncIterable(data) {
184
+ return (typeof data[Symbol.asyncIterator] ===
185
+ 'function');
186
+ }
@@ -40,7 +40,7 @@ function createReadableStreamWithEvents({ data, dataSize, emitter, eventNamesMap
40
40
  ? data
41
41
  : new ReadableStream({
42
42
  start: (controller) => {
43
- controller.enqueue(data);
43
+ controller.enqueue(new Uint8Array(data.buffer, data.byteOffset, data.byteLength));
44
44
  controller.close();
45
45
  },
46
46
  });
@@ -58,12 +58,12 @@ function createReadableStreamWithEvents({ data, dataSize, emitter, eventNamesMap
58
58
  controller.close();
59
59
  return;
60
60
  }
61
- processedBytes += value.length;
61
+ processedBytes += value.byteLength;
62
62
  emitter.emit(eventNamesMap['on-progress'], {
63
63
  processedBytes,
64
64
  totalBytes: dataSize,
65
65
  });
66
- controller.enqueue(value);
66
+ controller.enqueue(new Uint8Array(value.buffer, value.byteOffset, value.byteLength));
67
67
  }
68
68
  catch (error) {
69
69
  emitter.emit(eventNamesMap['on-error'], error);
@@ -119,7 +119,7 @@ function createReadableWithEvents({ data, dataSize, emitter, eventNamesMap, }) {
119
119
  let processedBytes = 0;
120
120
  existingStream.on('data', (chunk) => {
121
121
  eventingStream.write(chunk);
122
- processedBytes += chunk.length;
122
+ processedBytes += chunk.byteLength;
123
123
  emitter.emit(eventNamesMap['on-progress'], {
124
124
  processedBytes,
125
125
  totalBytes: dataSize,
@@ -41,19 +41,19 @@ export class TurboUnauthenticatedUploadService {
41
41
  this.retryConfig = retryConfig;
42
42
  }
43
43
  async uploadSignedDataItem({ dataItemStreamFactory, dataItemSizeFactory, dataItemOpts, signal, events = {}, }) {
44
- const fileSize = dataItemSizeFactory();
44
+ const dataItemSize = dataItemSizeFactory();
45
45
  this.logger.debug('Uploading signed data item...');
46
46
  // create the tapped stream with events
47
47
  const emitter = new TurboEventEmitter(events);
48
48
  // create the stream with upload events
49
49
  const { stream: streamWithUploadEvents, resume } = createStreamWithUploadEvents({
50
50
  data: dataItemStreamFactory(),
51
- dataSize: fileSize,
51
+ dataSize: dataItemSize,
52
52
  emitter,
53
53
  });
54
54
  const headers = {
55
55
  'content-type': 'application/octet-stream',
56
- 'content-length': `${fileSize}`,
56
+ 'content-length': `${dataItemSize}`,
57
57
  };
58
58
  if (dataItemOpts !== undefined && dataItemOpts.paidBy !== undefined) {
59
59
  const paidBy = Array.isArray(dataItemOpts.paidBy)
@@ -136,11 +136,10 @@ export class TurboAuthenticatedBaseUploadService extends TurboUnauthenticatedUpl
136
136
  if (signal?.aborted) {
137
137
  throw new CanceledError();
138
138
  }
139
+ // Now that we have the signed data item, we can upload it using the uploadSignedDataItem method
140
+ // which will create a new emitter with upload events. We await
141
+ // this result due to the wrapped retry logic of this method.
139
142
  try {
140
- this.logger.debug('Uploading signed data item...');
141
- // Now that we have the signed data item, we can upload it using the uploadSignedDataItem method
142
- // which will create a new emitter with upload events. We await
143
- // this result due to the wrapped retry logic of this method.
144
143
  const response = await this.uploadSignedDataItem({
145
144
  dataItemStreamFactory,
146
145
  dataItemSizeFactory,
@@ -246,6 +245,7 @@ export class TurboAuthenticatedBaseUploadService extends TurboUnauthenticatedUpl
246
245
  };
247
246
  try {
248
247
  const result = await this.uploadFile({
248
+ // TODO: can fix this type by passing a class generic and specifying in the node/web abstracts which stream type to use
249
249
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
250
250
  fileStreamFactory: () => this.getFileStreamForFile(file),
251
251
  fileSizeFactory: () => this.getFileSize(file),
@@ -290,6 +290,7 @@ export class TurboAuthenticatedBaseUploadService extends TurboUnauthenticatedUpl
290
290
  ];
291
291
  const manifestBuffer = Buffer.from(JSON.stringify(manifest));
292
292
  const manifestResponse = await this.uploadFile({
293
+ // TODO: can fix this type by passing a class generic and specifying in the node/web abstracts which stream type to use
293
294
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
294
295
  fileStreamFactory: () => this.createManifestStream(manifestBuffer),
295
296
  fileSizeFactory: () => manifestBuffer.byteLength,
@@ -13,6 +13,7 @@
13
13
  * See the License for the specific language governing permissions and
14
14
  * limitations under the License.
15
15
  */
16
+ export const DEFAULT_STREAM_CHUNK_SIZE = 20 * 1024 * 1024; // 20mb
16
17
  export async function readableStreamToBuffer({ stream, size, }) {
17
18
  const reader = stream.getReader();
18
19
  const buffer = Buffer.alloc(size);
@@ -28,3 +29,97 @@ export async function readableStreamToBuffer({ stream, size, }) {
28
29
  }
29
30
  return buffer;
30
31
  }
32
+ export function ensureChunkedStream(input, maxChunkSize = DEFAULT_STREAM_CHUNK_SIZE) {
33
+ const reader = input.getReader();
34
+ let leftover = null;
35
+ return new ReadableStream({
36
+ async pull(controller) {
37
+ // If we have leftover from a previous large chunk, continue slicing it
38
+ if (leftover) {
39
+ const chunk = leftover.subarray(0, maxChunkSize);
40
+ leftover = leftover.subarray(chunk.length);
41
+ if (leftover.length === 0)
42
+ leftover = null;
43
+ controller.enqueue(chunk);
44
+ return;
45
+ }
46
+ const { value, done } = await reader.read();
47
+ if (done) {
48
+ controller.close();
49
+ return;
50
+ }
51
+ // Runtime check because ReadableStream defaults to <any> and can be abused
52
+ if (!(value instanceof Uint8Array)) {
53
+ throw new TypeError('Expected Uint8Array from source stream');
54
+ }
55
+ if (value.byteLength <= maxChunkSize) {
56
+ controller.enqueue(value);
57
+ }
58
+ else {
59
+ // Slice and enqueue one piece now, keep the rest
60
+ // subarray is the new view with the same buffer (not copy)
61
+ controller.enqueue(value.subarray(0, maxChunkSize));
62
+ leftover = value.subarray(maxChunkSize);
63
+ }
64
+ },
65
+ });
66
+ }
67
+ export function createUint8ArrayReadableStreamFactory({ data, maxChunkSize = DEFAULT_STREAM_CHUNK_SIZE, }) {
68
+ // Blob streams are already ReadableStream<Uint8Array>
69
+ if (data instanceof Blob) {
70
+ return () => ensureChunkedStream(data.stream());
71
+ }
72
+ // We need to handle the case where the data is a ReadableStream that is not a Uint8Array
73
+ // This is to ensure downstream code can handle the data as a Uint8Array
74
+ if (data instanceof ReadableStream) {
75
+ return () => {
76
+ const reader = data.getReader();
77
+ const stream = new ReadableStream({
78
+ async pull(controller) {
79
+ const { value, done } = await reader.read();
80
+ if (done) {
81
+ controller.close();
82
+ return;
83
+ }
84
+ if (ArrayBuffer.isView(value)) {
85
+ // specifying offset and length is required to ensure chunks remain within their slice of the buffer
86
+ controller.enqueue(new Uint8Array(value.buffer, value.byteOffset, value.byteLength));
87
+ }
88
+ else if (value instanceof ArrayBuffer ||
89
+ value instanceof SharedArrayBuffer) {
90
+ controller.enqueue(new Uint8Array(value));
91
+ }
92
+ else {
93
+ throw new TypeError('Unsupported chunk type in ReadableStream');
94
+ }
95
+ },
96
+ });
97
+ return ensureChunkedStream(stream, maxChunkSize);
98
+ };
99
+ }
100
+ return () => {
101
+ let uint8;
102
+ if (typeof data === 'string') {
103
+ uint8 = new TextEncoder().encode(data);
104
+ }
105
+ else if (ArrayBuffer.isView(data)) {
106
+ // In theory we could use the view directly, but that might allow other typed arrays like BigInt64Array to be used which could behave unexpectedly downstream
107
+ // specifying offset and length is required to ensure chunks remain within their slice of the buffer
108
+ uint8 = new Uint8Array(data.buffer, data.byteOffset, data.byteLength);
109
+ }
110
+ else if (data instanceof ArrayBuffer ||
111
+ data instanceof SharedArrayBuffer) {
112
+ uint8 = new Uint8Array(data);
113
+ }
114
+ else {
115
+ throw new TypeError('Unsupported input type for stream');
116
+ }
117
+ const stream = new ReadableStream({
118
+ start(controller) {
119
+ controller.enqueue(uint8);
120
+ controller.close();
121
+ },
122
+ });
123
+ return ensureChunkedStream(stream, maxChunkSize);
124
+ };
125
+ }
@@ -14,4 +14,4 @@
14
14
  * limitations under the License.
15
15
  */
16
16
  // AUTOMATICALLY GENERATED FILE - DO NOT TOUCH
17
- export const version = '1.26.0';
17
+ export const version = '1.27.0-alpha.1';
@@ -18,3 +18,4 @@ export * from './upload.js';
18
18
  export * from './signer.js';
19
19
  export * from '../common/index.js';
20
20
  export * from '../types.js';
21
+ export * from '../common/events.js';
@@ -13,9 +13,9 @@
13
13
  * See the License for the specific language governing permissions and
14
14
  * limitations under the License.
15
15
  */
16
- import { ArconnectSigner, ArweaveSigner, DataItem, EthereumSigner, HexSolanaSigner, InjectedEthereumSigner, createData, } from '@dha-team/arbundles';
16
+ import { ArconnectSigner, ArweaveSigner, EthereumSigner, HexSolanaSigner, InjectedEthereumSigner, createData, deepHash, stringToBuffer, } from '@dha-team/arbundles';
17
17
  import { TurboDataItemAbstractSigner } from '../common/signer.js';
18
- import { readableStreamToBuffer } from '../utils/readableStream.js';
18
+ import { createUint8ArrayReadableStreamFactory } from '../utils/readableStream.js';
19
19
  /**
20
20
  * Utility exports to avoid clients having to install arbundles
21
21
  */
@@ -43,61 +43,21 @@ export class TurboWebArweaveSigner extends TurboDataItemAbstractSigner {
43
43
  await this.setPublicKey();
44
44
  // Create signing emitter if events are provided
45
45
  const fileSize = fileSizeFactory();
46
- try {
47
- const fileStream = fileStreamFactory();
48
- // start with 0 progress
49
- emitter?.emit('signing-progress', {
50
- processedBytes: 0,
51
- totalBytes: fileSize,
52
- });
53
- // TODO: implement streamReadableStreamSigner that incrementally signs the stream with events instead of converting to a buffer
54
- const buffer = fileStream instanceof Buffer
55
- ? fileStream
56
- : await readableStreamToBuffer({
57
- stream: fileStream,
58
- size: fileSize,
59
- });
60
- // TODO: replace this with streamSigner that uses a ReadableStream with events
61
- emitter?.emit('signing-progress', {
62
- processedBytes: Math.floor(fileSize / 2),
63
- totalBytes: fileSize,
64
- });
65
- let signedDataItem;
66
- this.logger.debug('Signing data item...');
67
- if (this.signer instanceof ArconnectSigner) {
68
- this.logger.debug('Arconnect signer detected, signing with Arconnect signData Item API...');
69
- const sign = Buffer.from(await this.signer['signer'].signDataItem({
70
- data: Uint8Array.from(buffer),
71
- tags: dataItemOpts?.tags,
72
- target: dataItemOpts?.target,
73
- anchor: dataItemOpts?.anchor,
74
- }));
75
- signedDataItem = new DataItem(sign);
76
- }
77
- else {
78
- signedDataItem = createData(Uint8Array.from(buffer), this.signer, dataItemOpts);
79
- await signedDataItem.sign(this.signer);
80
- }
81
- // emit last progress event (100%)
82
- emitter?.emit('signing-progress', {
83
- processedBytes: fileSize,
84
- totalBytes: fileSize,
85
- });
86
- // emit completion event
87
- emitter?.emit('signing-success');
88
- this.logger.debug('Successfully signed data item...');
89
- return {
90
- // while this returns a Buffer - it needs to match our return type for uploading
91
- dataItemStreamFactory: () => signedDataItem.getRaw(),
92
- dataItemSizeFactory: () => signedDataItem.getRaw().length,
93
- };
94
- }
95
- catch (error) {
96
- // If we have a signing emitter, emit error
97
- // TODO: create a SigningError class and throw that instead of the generic Error
98
- emitter?.emit('signing-error', error);
99
- throw error;
100
- }
46
+ this.logger.debug('Signing data item...');
47
+ const { signedDataItemFactory, signedDataItemSize } = await streamSignerReadableStream({
48
+ streamFactory: createUint8ArrayReadableStreamFactory({
49
+ data: fileStreamFactory(),
50
+ }),
51
+ signer: this.signer,
52
+ dataItemOpts,
53
+ fileSize,
54
+ emitter,
55
+ });
56
+ this.logger.debug('Successfully signed data item...');
57
+ return {
58
+ dataItemStreamFactory: signedDataItemFactory,
59
+ dataItemSizeFactory: () => signedDataItemSize,
60
+ };
101
61
  }
102
62
  async generateSignedRequestHeaders() {
103
63
  await this.setPublicKey();
@@ -108,3 +68,112 @@ export class TurboWebArweaveSigner extends TurboDataItemAbstractSigner {
108
68
  return super.signData(dataToSign);
109
69
  }
110
70
  }
71
+ export const readableStreamToAsyncIterable = (stream) => ({
72
+ async *[Symbol.asyncIterator]() {
73
+ const reader = stream.getReader();
74
+ try {
75
+ while (true) {
76
+ const { done, value } = await reader.read();
77
+ if (done)
78
+ break;
79
+ if (value !== undefined)
80
+ yield Buffer.from(value);
81
+ }
82
+ }
83
+ finally {
84
+ reader.releaseLock();
85
+ }
86
+ },
87
+ });
88
+ export async function streamSignerReadableStream({ streamFactory, signer, dataItemOpts, fileSize, emitter, }) {
89
+ try {
90
+ const header = createData('', signer, dataItemOpts);
91
+ const headerSize = header.getRaw().byteLength;
92
+ const totalDataItemSizeWithHeader = fileSize + headerSize;
93
+ const [stream1, stream2] = streamFactory().tee();
94
+ const reader1 = stream1.getReader();
95
+ let bytesProcessed = 0;
96
+ const eventingStream = new ReadableStream({
97
+ start() {
98
+ // technically this should be emitted after each DeepHashChunk be we cannot access that stage, so we emit it here instead
99
+ bytesProcessed = headerSize;
100
+ emitter?.emit('signing-progress', {
101
+ processedBytes: bytesProcessed,
102
+ totalBytes: totalDataItemSizeWithHeader,
103
+ });
104
+ },
105
+ async pull(controller) {
106
+ const { done, value } = await reader1.read();
107
+ if (done) {
108
+ controller.close();
109
+ return;
110
+ }
111
+ bytesProcessed += value.byteLength;
112
+ controller.enqueue(value);
113
+ emitter?.emit('signing-progress', {
114
+ processedBytes: bytesProcessed,
115
+ totalBytes: totalDataItemSizeWithHeader,
116
+ });
117
+ },
118
+ cancel() {
119
+ reader1.cancel();
120
+ },
121
+ });
122
+ // create a readable that emits signing events as bytes are pulled through using the first stream from .tee()
123
+ const asyncIterableReadableStream = readableStreamToAsyncIterable(eventingStream);
124
+ // provide that ReadableStream with events to deep hash, so as it pulls bytes through events get emitted
125
+ const parts = [
126
+ stringToBuffer('dataitem'),
127
+ stringToBuffer('1'),
128
+ stringToBuffer(header.signatureType.toString()),
129
+ Uint8Array.from(header.rawOwner),
130
+ Uint8Array.from(header.rawTarget),
131
+ Uint8Array.from(header.rawAnchor),
132
+ Uint8Array.from(header.rawTags),
133
+ asyncIterableReadableStream,
134
+ ];
135
+ const hash = await deepHash(parts);
136
+ const sigBytes = Buffer.from(await signer.sign(hash));
137
+ emitter?.emit('signing-success');
138
+ header.setSignature(sigBytes);
139
+ const headerBytes = header.getRaw();
140
+ const signedDataItemFactory = () => {
141
+ const reader = stream2.getReader();
142
+ return new ReadableStream({
143
+ start(controller) {
144
+ controller.enqueue(Uint8Array.from(headerBytes));
145
+ bytesProcessed += headerBytes.byteLength;
146
+ },
147
+ async pull(controller) {
148
+ try {
149
+ const { done, value } = await reader.read();
150
+ if (done) {
151
+ controller.close();
152
+ return;
153
+ }
154
+ controller.enqueue(value);
155
+ }
156
+ catch (error) {
157
+ controller.error(error);
158
+ }
159
+ },
160
+ cancel() {
161
+ reader.cancel();
162
+ },
163
+ });
164
+ };
165
+ return {
166
+ signedDataItemSize: totalDataItemSizeWithHeader,
167
+ signedDataItemFactory,
168
+ };
169
+ }
170
+ catch (error) {
171
+ emitter?.emit('signing-error', error);
172
+ throw error;
173
+ }
174
+ }
175
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
176
+ export function isAsyncIterable(data) {
177
+ return (typeof data[Symbol.asyncIterator] ===
178
+ 'function');
179
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../../src/common/events.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAe,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAE/C,OAAO,EACL,4BAA4B,EAC5B,6BAA6B,EAC7B,0BAA0B,EAC1B,2BAA2B,EAC3B,2BAA2B,EAC3B,4BAA4B,EAC7B,MAAM,aAAa,CAAC;AAwLrB;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,EACrC,IAAI,EACJ,QAAQ,EACR,OAAO,EACP,aAAa,GACd,EAAE;IACD,IAAI,EAAE,QAAQ,GAAG,MAAM,GAAG,cAAc,CAAC;IACzC,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,iBAAiB,CAAC;IAC3B,aAAa,EAAE;QACb,aAAa,EACT,MAAM,4BAA4B,GAClC,MAAM,6BAA6B,GACnC,MAAM,2BAA2B,CAAC;QACtC,UAAU,EACN,MAAM,4BAA4B,GAClC,MAAM,6BAA6B,GACnC,MAAM,2BAA2B,CAAC;QACtC,QAAQ,EACJ,MAAM,4BAA4B,GAClC,MAAM,6BAA6B,GACnC,MAAM,2BAA2B,CAAC;KACvC,CAAC;CACH,GAAG;IAAE,MAAM,EAAE,QAAQ,GAAG,cAAc,CAAC;IAAC,MAAM,EAAE,MAAM,IAAI,CAAA;CAAE,CAuB5D;AAED,MAAM,MAAM,uBAAuB,GAAG,4BAA4B,GAChE,6BAA6B,GAC7B,2BAA2B,CAAC;AAC9B,MAAM,MAAM,0BAA0B,GAAG,2BAA2B,GAClE,4BAA4B,GAC5B,0BAA0B,CAAC;AAE7B,qBAAa,iBAAkB,SAAQ,YAAY,CAAC,uBAAuB,CAAC;gBAC9D,EACV,UAAU,EACV,OAAO,EACP,SAAS,EACT,gBAAgB,EAChB,aAAa,EACb,eAAe,EACf,iBAAiB,EACjB,cAAc,EACd,gBAAgB,GACjB,GAAE,0BAA+B;CA2DnC;AAED,wBAAgB,4BAA4B,CAAC,EAC3C,IAAI,EACJ,QAAQ,EACR,OAAiC,GAClC,EAAE;IACD,IAAI,EAAE,QAAQ,GAAG,MAAM,GAAG,cAAc,CAAC;IACzC,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,iBAAiB,CAAC;CAC7B,GAAG;IAAE,MAAM,EAAE,QAAQ,GAAG,cAAc,CAAC;IAAC,MAAM,EAAE,MAAM,IAAI,CAAA;CAAE,CAW5D;AAED,wBAAgB,6BAA6B,CAAC,EAC5C,IAAI,EACJ,QAAQ,EACR,OAAiC,GAClC,EAAE;IACD,IAAI,EAAE,QAAQ,GAAG,MAAM,GAAG,cAAc,CAAC;IACzC,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,iBAAiB,CAAC;CAC7B,GAAG;IAAE,MAAM,EAAE,QAAQ,GAAG,cAAc,CAAC;IAAC,MAAM,EAAE,MAAM,IAAI,CAAA;CAAE,CAW5D"}
1
+ {"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../../src/common/events.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAe,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAE/C,OAAO,EACL,4BAA4B,EAC5B,6BAA6B,EAC7B,0BAA0B,EAC1B,2BAA2B,EAC3B,2BAA2B,EAC3B,4BAA4B,EAC7B,MAAM,aAAa,CAAC;AA4LrB;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,EACrC,IAAI,EACJ,QAAQ,EACR,OAAO,EACP,aAAa,GACd,EAAE;IACD,IAAI,EAAE,QAAQ,GAAG,MAAM,GAAG,cAAc,CAAC;IACzC,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,iBAAiB,CAAC;IAC3B,aAAa,EAAE;QACb,aAAa,EACT,MAAM,4BAA4B,GAClC,MAAM,6BAA6B,GACnC,MAAM,2BAA2B,CAAC;QACtC,UAAU,EACN,MAAM,4BAA4B,GAClC,MAAM,6BAA6B,GACnC,MAAM,2BAA2B,CAAC;QACtC,QAAQ,EACJ,MAAM,4BAA4B,GAClC,MAAM,6BAA6B,GACnC,MAAM,2BAA2B,CAAC;KACvC,CAAC;CACH,GAAG;IAAE,MAAM,EAAE,QAAQ,GAAG,cAAc,CAAC;IAAC,MAAM,EAAE,MAAM,IAAI,CAAA;CAAE,CAuB5D;AAED,MAAM,MAAM,uBAAuB,GAAG,4BAA4B,GAChE,6BAA6B,GAC7B,2BAA2B,CAAC;AAC9B,MAAM,MAAM,0BAA0B,GAAG,2BAA2B,GAClE,4BAA4B,GAC5B,0BAA0B,CAAC;AAE7B,qBAAa,iBAAkB,SAAQ,YAAY,CAAC,uBAAuB,CAAC;gBAC9D,EACV,UAAU,EACV,OAAO,EACP,SAAS,EACT,gBAAgB,EAChB,aAAa,EACb,eAAe,EACf,iBAAiB,EACjB,cAAc,EACd,gBAAgB,GACjB,GAAE,0BAA+B;CA2DnC;AAED,wBAAgB,4BAA4B,CAAC,EAC3C,IAAI,EACJ,QAAQ,EACR,OAAiC,GAClC,EAAE;IACD,IAAI,EAAE,QAAQ,GAAG,MAAM,GAAG,cAAc,CAAC;IACzC,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,iBAAiB,CAAC;CAC7B,GAAG;IAAE,MAAM,EAAE,QAAQ,GAAG,cAAc,CAAC;IAAC,MAAM,EAAE,MAAM,IAAI,CAAA;CAAE,CAW5D;AAED,wBAAgB,6BAA6B,CAAC,EAC5C,IAAI,EACJ,QAAQ,EACR,OAAiC,GAClC,EAAE;IACD,IAAI,EAAE,QAAQ,GAAG,MAAM,GAAG,cAAc,CAAC;IACzC,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,iBAAiB,CAAC;CAC7B,GAAG;IAAE,MAAM,EAAE,QAAQ,GAAG,cAAc,CAAC;IAAC,MAAM,EAAE,MAAM,IAAI,CAAA;CAAE,CAW5D"}
@@ -1 +1 @@
1
- {"version":3,"file":"upload.d.ts","sourceRoot":"","sources":["../../../src/common/upload.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"upload.d.ts","sourceRoot":"","sources":["../../../src/common/upload.ts"],"names":[],"mappings":"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"}
@@ -13,8 +13,14 @@
13
13
  * See the License for the specific language governing permissions and
14
14
  * limitations under the License.
15
15
  */
16
+ export declare const DEFAULT_STREAM_CHUNK_SIZE: number;
16
17
  export declare function readableStreamToBuffer({ stream, size, }: {
17
18
  stream: ReadableStream;
18
19
  size: number;
19
20
  }): Promise<Buffer>;
21
+ export declare function ensureChunkedStream(input: ReadableStream<Uint8Array>, maxChunkSize?: number): ReadableStream<Uint8Array>;
22
+ export declare function createUint8ArrayReadableStreamFactory({ data, maxChunkSize, }: {
23
+ data: string | Uint8Array | ArrayBuffer | Buffer | SharedArrayBuffer | Blob | ReadableStream;
24
+ maxChunkSize?: number;
25
+ }): () => ReadableStream<Uint8Array>;
20
26
  //# sourceMappingURL=readableStream.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"readableStream.d.ts","sourceRoot":"","sources":["../../../src/utils/readableStream.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,sBAAsB,CAAC,EAC3C,MAAM,EACN,IAAI,GACL,EAAE;IACD,MAAM,EAAE,cAAc,CAAC;IACvB,IAAI,EAAE,MAAM,CAAC;CACd,GAAG,OAAO,CAAC,MAAM,CAAC,CAelB"}
1
+ {"version":3,"file":"readableStream.d.ts","sourceRoot":"","sources":["../../../src/utils/readableStream.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,eAAO,MAAM,yBAAyB,QAAmB,CAAC;AAE1D,wBAAsB,sBAAsB,CAAC,EAC3C,MAAM,EACN,IAAI,GACL,EAAE;IACD,MAAM,EAAE,cAAc,CAAC;IACvB,IAAI,EAAE,MAAM,CAAC;CACd,GAAG,OAAO,CAAC,MAAM,CAAC,CAelB;AAED,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,cAAc,CAAC,UAAU,CAAC,EACjC,YAAY,SAA4B,GACvC,cAAc,CAAC,UAAU,CAAC,CAoC5B;AAED,wBAAgB,qCAAqC,CAAC,EACpD,IAAI,EACJ,YAAwC,GACzC,EAAE;IACD,IAAI,EACA,MAAM,GACN,UAAU,GACV,WAAW,GACX,MAAM,GACN,iBAAiB,GACjB,IAAI,GACJ,cAAc,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,GAAG,MAAM,cAAc,CAAC,UAAU,CAAC,CA6DnC"}