@fizzyflow/endless-vector 0.0.4 → 0.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/EndlessVector.js CHANGED
@@ -95,7 +95,7 @@ export default class EndlessVector {
95
95
  * @param {SuiClient} params.suiClient - Sui client instance for blockchain interactions
96
96
  * @param {string} params.packageId - ID of the Move package containing the EndlessVector module
97
97
  * @param {CustomSignAndExecuteTransactionFunction} params.signAndExecuteTransaction - Function to sign and execute transactions
98
- * @param {?Uint8Array} [params.array] - Optional Uint8Array to initialize the vector with as the first item to get with .at(0)
98
+ * @param {?Uint8Array|Uint8Array[]} [params.array] - Optional Uint8Array to initialize the vector with as the first item to get with .at(0)
99
99
  * @param {?Object} [params.gasCoin] - Optional gas coin object reference {objectId: string, digest: string, version: string} to use for transaction payment
100
100
  * @param {?Object} [params.options] - Optional transaction parameters
101
101
  * @param {?Number} [params.options.timeout] - Transaction confirmation timeout in ms, default 30000
@@ -131,13 +131,30 @@ export default class EndlessVector {
131
131
  }
132
132
 
133
133
  if (array && array.length) {
134
- const vectorInput = await EndlessVector.getCreateTransactionAndReturnVectorInput({
135
- packageId: normalizedPackageId,
136
- }, array, tx);
137
- tx.moveCall({
138
- target: `${normalizedPackageId}::endless_vector::transfer_to_sender`,
139
- arguments: [vectorInput],
140
- });
134
+ if ((array instanceof Uint8Array)) {
135
+ // single chunk
136
+ const vectorInput = await EndlessVector.getCreateTransactionAndReturnVectorInput({
137
+ packageId: normalizedPackageId,
138
+ }, array, tx);
139
+ tx.moveCall({
140
+ target: `${normalizedPackageId}::endless_vector::transfer_to_sender`,
141
+ arguments: [vectorInput],
142
+ });
143
+ } else if (array[0] && (array[0] instanceof Uint8Array)) {
144
+ // multiple chunks
145
+ const vectorInput = await EndlessVector.getCreateTransactionAndReturnVectorInput({
146
+ packageId: normalizedPackageId,
147
+ }, null, tx);
148
+ for (let i = 0; i < array.length; i++) {
149
+ EndlessVector.composePushTransaction(normalizedPackageId, vectorInput, array[i], tx);
150
+ }
151
+ tx.moveCall({
152
+ target: `${normalizedPackageId}::endless_vector::transfer_to_sender`,
153
+ arguments: [vectorInput],
154
+ });
155
+ } else {
156
+ throw new Error('.array must be Uint8Array or array of Uint8Array');
157
+ }
141
158
  } else {
142
159
  tx.moveCall({
143
160
  target: `${normalizedPackageId}::endless_vector::empty_entry`,
@@ -306,7 +323,7 @@ export default class EndlessVector {
306
323
  * Creates a transaction to push new byte arrays to the EndlessVector.
307
324
  * Note: this method only creates the transaction, it does not sign or execute it.
308
325
 
309
- * @param {Uint8Array} arr - Uint8Array to push
326
+ * @param {Uint8Array|Uint8Array[]} arr - Uint8Array to push
310
327
  * @returns {Transaction} The transaction object to be signed and executed
311
328
  */
312
329
  getPushTransaction(arr, txToAppendTo = null) {
@@ -319,7 +336,15 @@ export default class EndlessVector {
319
336
  tx = new Transaction();
320
337
  }
321
338
 
322
- EndlessVector.composePushTransaction(this._packageId, tx.object(this.id), arr, tx);
339
+ if (arr instanceof Uint8Array) {
340
+ EndlessVector.composePushTransaction(this._packageId, tx.object(this.id), arr, tx);
341
+ } else if (Array.isArray(arr) && arr[0] && (arr[0] instanceof Uint8Array)) {
342
+ for (let i = 0; i < arr.length; i++) {
343
+ EndlessVector.composePushTransaction(this._packageId, tx.object(this.id), arr[i], tx);
344
+ }
345
+ } else {
346
+ throw new Error('.array must be Uint8Array or array of Uint8Array');
347
+ }
323
348
 
324
349
  return tx;
325
350
  }
@@ -330,7 +355,7 @@ export default class EndlessVector {
330
355
  * Requires the instance to be writable (packageId and signAndExecuteTransaction must be provided).
331
356
  * @throws {Error} If the instance is not writable or if the transaction fails
332
357
  *
333
- * @param {Uint8Array} arr - Byte array to push
358
+ * @param {Uint8Array|Uint8Array[]} arr - Byte array or array of byte arrays to push
334
359
  * @param {?Object} params - Configuration parameters
335
360
  * @param {?Number} [params.timeout] - wait for transaction confirmation timeout in ms, default 30000
336
361
  * @param {?Number} [params.pollIntervalMs] - wait for transaction confirmation poll interval in ms, default 1000
package/README.md CHANGED
@@ -33,6 +33,7 @@ const vectorWithData = await EndlessVector.create({
33
33
  suiClient: client,
34
34
  packageId: 'testnet', // or 'mainnet' or '0xYOUR_PACKAGE_ID'
35
35
  array: new Uint8Array([1, 2, 3]), // [0] to append to EndlessVector
36
+ //array: [new Uint8Array([1, 2, 3]), new Uint8Array([5, 6, 7])], // or [0] and [1] to append to EndlessVector
36
37
  signAndExecuteTransaction: async (tx) => {
37
38
  const result = await wallet.signAndExecuteTransaction({ transaction: tx });
38
39
  return result.digest;
@@ -69,7 +70,7 @@ Creates a new EndlessVector on the blockchain.
69
70
  - `suiClient` (SuiClient) - Sui client instance for blockchain interactions
70
71
  - `packageId` (string) - 'testnet', 'mainnet', or ID of the Move package containing the EndlessVector module
71
72
  - `signAndExecuteTransaction` (function) - Function to sign and execute transactions
72
- - `array` (Uint8Array, optional) - Optional first vector<u8> to push back to the new vector
73
+ - `array` (Uint8Array or Uint8Array[], optional) - Optional first vector<u8>(s) to push back to the new vector
73
74
  - `gasCoin` (Object, optional) - Gas coin object reference `{objectId: string, digest: string, version: string}` for transaction payment
74
75
  - `options` (Object, optional) - Additional options:
75
76
  - `timeout` (number) - Transaction confirmation timeout in ms (default: 30000)
@@ -142,7 +143,7 @@ await vector.reInitialize();
142
143
 
143
144
  #### push(arr, params)
144
145
 
145
- Pushes a new byte array to the vector. Requires writable mode. Maximum size per item: ~200KB.
146
+ Pushes a Uint8Array or few Uint8Array(Uint8Array[]) to the vector. Requires writable mode. Maximum size per push: ~120KB.
146
147
 
147
148
  ```javascript
148
149
  const data = new Uint8Array([1, 2, 3, 4, 5]);
@@ -150,7 +151,7 @@ await vector.push(data);
150
151
  ```
151
152
 
152
153
  **Parameters:**
153
- - `arr` (Uint8Array) - Data to push
154
+ - `arr` (Uint8Array or Uint8Array[]) - Data to push
154
155
  - `params` (Object, optional) - Additional parameters
155
156
 
156
157
  #### getPushTransaction(arr, tx)
@@ -170,7 +171,7 @@ await signAndExecuteTransaction(tx);
170
171
  ```
171
172
 
172
173
  **Parameters:**
173
- - `arr` (Uint8Array) - Data to push
174
+ - `arr` (Uint8Array or Uint8Array[]) - Data to push
174
175
  - `tx` (Transaction, optional) - Existing transaction to append to
175
176
 
176
177
  **Returns:** Transaction
package/index.d.ts ADDED
@@ -0,0 +1,347 @@
1
+ import type { SuiClient, GetObjectParams, GetDynamicFieldsParams } from '@mysten/sui/client';
2
+ import type { Transaction, TransactionResult, TransactionObjectArgument } from '@mysten/sui/transactions';
3
+
4
+ /**
5
+ * Custom function to sign and execute transactions
6
+ */
7
+ export type CustomSignAndExecuteTransactionFunction = (tx: Transaction) => Promise<string>;
8
+
9
+ /**
10
+ * Configuration parameters for creating an EndlessVector instance
11
+ */
12
+ export interface EndlessVectorConstructorParams {
13
+ /** Sui client instance for blockchain interactions */
14
+ suiClient?: SuiClient;
15
+ /** ID or address of the EndlessVector on the Sui blockchain */
16
+ id?: string;
17
+ /** Adds write capability if provided, ID of the Move package containing the EndlessVector module or 'mainnet', 'testnet' to use known IDs */
18
+ packageId?: string | null;
19
+ /** Adds write capability if provided, function should accept Sui transaction, sign and submit it to the blockchain and return its digest */
20
+ signAndExecuteTransaction?: CustomSignAndExecuteTransactionFunction | null;
21
+ }
22
+
23
+ /**
24
+ * Configuration parameters for creating a new EndlessVector via static create method
25
+ */
26
+ export interface EndlessVectorCreateParams {
27
+ /** Sui client instance for blockchain interactions */
28
+ suiClient: SuiClient;
29
+ /** ID of the Move package containing the EndlessVector module */
30
+ packageId: string;
31
+ /** Function to sign and execute transactions */
32
+ signAndExecuteTransaction: CustomSignAndExecuteTransactionFunction;
33
+ /** Optional Uint8Array or array of Uint8Arrays to initialize the vector with */
34
+ array?: Uint8Array | Uint8Array[] | null;
35
+ /** Optional gas coin object reference {objectId: string, digest: string, version: string} to use for transaction payment */
36
+ gasCoin?: { objectId: string; digest: string; version: string } | null;
37
+ /** Optional transaction parameters */
38
+ options?: {
39
+ /** Transaction confirmation timeout in ms, default 30000 */
40
+ timeout?: number;
41
+ /** Poll interval in ms, default 1000 */
42
+ pollIntervalMs?: number;
43
+ };
44
+ }
45
+
46
+ /**
47
+ * Configuration parameters for getCreateTransactionAndReturnVectorInput
48
+ */
49
+ export interface GetCreateTransactionParams {
50
+ /** The package ID ('mainnet', 'testnet', or explicit package ID) */
51
+ packageId: string;
52
+ }
53
+
54
+ /**
55
+ * Configuration parameters for push and concat operations
56
+ */
57
+ export interface TransactionOptions {
58
+ /** wait for transaction confirmation timeout in ms, default 30000 */
59
+ timeout?: number;
60
+ /** wait for transaction confirmation poll interval in ms, default 1000 */
61
+ pollIntervalMs?: number;
62
+ }
63
+
64
+ /**
65
+ * Configuration parameters for creating an EndlessVectorHistory instance
66
+ */
67
+ export interface EndlessVectorHistoryConstructorParams {
68
+ /** Sui client instance for blockchain interactions */
69
+ suiClient?: SuiClient;
70
+ /** Unique identifier for this history item */
71
+ id?: string;
72
+ /** Index position of this history item in the sequence */
73
+ index?: number;
74
+ /** Raw field data from the blockchain object */
75
+ fields?: any | null;
76
+ /** Reference to the parent EndlessVector instance */
77
+ endlessVector?: EndlessVector;
78
+ /** Reference to the parent EndlessVectorArchive instance */
79
+ endlessVectorArchive?: EndlessVectorArchive | null;
80
+ }
81
+
82
+ /**
83
+ * Configuration parameters for creating an EndlessVectorArchive instance
84
+ */
85
+ export interface EndlessVectorArchiveConstructorParams {
86
+ /** Sui client instance for blockchain interactions */
87
+ suiClient?: SuiClient;
88
+ /** ID or address of the EndlessVectorArchive on the Sui blockchain */
89
+ id?: string;
90
+ /** Index position of this archive item in the sequence */
91
+ index?: number;
92
+ /** Reference to the parent EndlessVector instance */
93
+ endlessVector?: EndlessVector;
94
+ /** Raw field data from the blockchain object */
95
+ fields?: any;
96
+ }
97
+
98
+ /**
99
+ * Represents a history item in an EndlessVector, managing a segment of the vector's data.
100
+ * Each history item stores a portion of the vector's elements and maintains metadata
101
+ * about its position and relationships with adjacent history items.
102
+ */
103
+ export declare class EndlessVectorHistory {
104
+ suiClient: SuiClient;
105
+ id: string;
106
+ index: number;
107
+
108
+ constructor(params?: EndlessVectorHistoryConstructorParams);
109
+
110
+ /**
111
+ * Sets the fields data for this history item. Called by loader of EndlessVector.
112
+ */
113
+ setFields(fields: any): void;
114
+
115
+ /**
116
+ * Checks if this history item has been initialized and is ready for use.
117
+ */
118
+ isReady(): boolean;
119
+
120
+ /**
121
+ * Initializes this history item by loading its data from the blockchain.
122
+ * Uses promise-based synchronization to prevent multiple concurrent initializations.
123
+ */
124
+ initialize(): Promise<boolean>;
125
+
126
+ /**
127
+ * Gets the last index position that this history item covers.
128
+ */
129
+ get endsAt(): number | undefined;
130
+
131
+ /**
132
+ * Indicates whether the first item in this history contains suffix bytes that should be
133
+ * added to the last item from the previous history segment.
134
+ */
135
+ get firstItemIsFromPreviousHistory(): boolean;
136
+
137
+ /**
138
+ * Gets the first index position that this history item covers.
139
+ */
140
+ get startsAt(): number;
141
+
142
+ /**
143
+ * Gets the number of bytes from the next history item that should be appended
144
+ * to the last item in this history segment.
145
+ */
146
+ get followedByNextBytes(): number;
147
+
148
+ /**
149
+ * Retrieves the byte array at the specified index within this history segment.
150
+ */
151
+ at(i: number): Promise<Uint8Array>;
152
+
153
+ /**
154
+ * Gets the suffix bytes stored in this history item that should be appended
155
+ * to the last item of the previous history segment.
156
+ */
157
+ getSuffixStoredBytes(): Uint8Array;
158
+ }
159
+
160
+ /**
161
+ * Represents an archive item in an EndlessVector
162
+ */
163
+ export declare class EndlessVectorArchive {
164
+ suiClient: SuiClient;
165
+ id: string;
166
+ index: number;
167
+ historyTableId: string | null;
168
+ historyItemsCount: number;
169
+
170
+ constructor(params?: EndlessVectorArchiveConstructorParams);
171
+
172
+ /**
173
+ * Sets the fields data for this archive item. Called by loader of EndlessVector.
174
+ */
175
+ setFields(fields: any): void;
176
+
177
+ /**
178
+ * Checks if this archive item has been initialized and is ready for use.
179
+ */
180
+ isReady(): boolean;
181
+
182
+ /**
183
+ * Gets the total number of items stored in this archive.
184
+ */
185
+ get length(): number;
186
+
187
+ /**
188
+ * Gets the first index position that this archive covers.
189
+ */
190
+ get startsAt(): number;
191
+
192
+ /**
193
+ * Gets the last index position that this archive covers.
194
+ */
195
+ get endsAt(): number | undefined;
196
+
197
+ /**
198
+ * Initializes this archive item by loading its data from the blockchain.
199
+ */
200
+ initialize(): Promise<boolean>;
201
+
202
+ /**
203
+ * Gets a history item within this archive by its index.
204
+ */
205
+ getHistory(historyIndex: number | string): Promise<EndlessVectorHistory>;
206
+
207
+ /**
208
+ * Retrieves the byte array at the specified index within this archive.
209
+ */
210
+ at(i: number): Promise<Uint8Array>;
211
+
212
+ /**
213
+ * Gets suffix bytes from a history item at the specified index within this archive.
214
+ */
215
+ getSuffixFromHistoryItemOfIndex(i: number): Promise<Uint8Array>;
216
+ }
217
+
218
+ /**
219
+ * Represents an endless vector data structure that can grow beyond Sui object size limits
220
+ * by storing overflow data in history items. Provides seamless access to all elements regardless
221
+ * of whether they're stored in the current object or historical segments.
222
+ */
223
+ export declare class EndlessVector {
224
+ suiClient: SuiClient;
225
+ id: string;
226
+ binaryLength: number;
227
+ length: number;
228
+ historyItemsCount: number;
229
+ historyTableId: string | null;
230
+ firstItemIsFromPreviousHistory: boolean;
231
+ archiveTableId: string | null;
232
+ archiveItemsCount: number;
233
+ archivedAtLength: number;
234
+ archivedFromLength: number;
235
+ burnedArchiveCount: number;
236
+
237
+ constructor(params?: EndlessVectorConstructorParams);
238
+
239
+ /**
240
+ * Static factory method to create a new empty EndlessVector on the blockchain.
241
+ */
242
+ static create(params: EndlessVectorCreateParams): Promise<EndlessVector>;
243
+
244
+ /**
245
+ * Creates an empty EndlessVector and returns the vector input reference.
246
+ */
247
+ static getCreateTransactionAndReturnVectorInput(
248
+ params: GetCreateTransactionParams,
249
+ arr?: Uint8Array | null,
250
+ txToAppendTo?: Transaction | null
251
+ ): Promise<TransactionResult>;
252
+
253
+ /**
254
+ * Attach move calls to transaction, to push item into endlessvector, handling large arrays by chunking them.
255
+ */
256
+ static composePushTransaction(
257
+ packageId: string,
258
+ vectorInput: TransactionObjectArgument,
259
+ arr: Uint8Array,
260
+ tx: Transaction
261
+ ): Transaction;
262
+
263
+ /**
264
+ * Check if the EndlessVector instance is writable
265
+ */
266
+ get isWritable(): boolean;
267
+
268
+ /**
269
+ * Gets the first index that is stored in the current EndlessVector object (not in history items).
270
+ */
271
+ get firstNotHistoryIndex(): number;
272
+
273
+ /**
274
+ * Forces re-initialization of the EndlessVector to reload data from the blockchain.
275
+ */
276
+ reInitialize(): void;
277
+
278
+ /**
279
+ * Initializes the EndlessVector by loading data from the Sui blockchain.
280
+ */
281
+ initialize(): Promise<void>;
282
+
283
+ /**
284
+ * Gets a history item by its index, loading it from the blockchain if needed.
285
+ */
286
+ getHistory(historyIndex: number | string): Promise<EndlessVectorHistory>;
287
+
288
+ /**
289
+ * Gets an archive item by its index, loading it from the blockchain if needed.
290
+ */
291
+ getArchive(archiveIndex: number | string): Promise<EndlessVectorArchive>;
292
+
293
+ /**
294
+ * Loads multiple history items in a single batch request for efficiency.
295
+ */
296
+ loadHistoryItemsBunch(historyItems: EndlessVectorHistory[]): Promise<void>;
297
+
298
+ /**
299
+ * Loads a single history item, batching requests for efficiency.
300
+ */
301
+ loadHistoryItem(historyItem: EndlessVectorHistory): Promise<EndlessVectorHistory>;
302
+
303
+ /**
304
+ * Loads multiple archive items in a single batch request for efficiency.
305
+ */
306
+ loadArchiveItemsBunch(archiveItems: EndlessVectorArchive[]): Promise<void>;
307
+
308
+ /**
309
+ * Loads a single archive item, batching requests for efficiency.
310
+ */
311
+ loadArchiveItem(archiveItem: EndlessVectorArchive): Promise<EndlessVectorArchive>;
312
+
313
+ /**
314
+ * Retrieves the byte array at the specified index from either current items or history.
315
+ */
316
+ at(i: number): Promise<Uint8Array>;
317
+
318
+ /**
319
+ * Gets suffix bytes from a history item at the specified index.
320
+ */
321
+ getSuffixFromHistoryItemOfIndex(i: number): Promise<Uint8Array | undefined>;
322
+
323
+ /**
324
+ * Creates a transaction to push new byte arrays to the EndlessVector.
325
+ */
326
+ getPushTransaction(arr: Uint8Array | Uint8Array[], txToAppendTo?: Transaction | null): Transaction;
327
+
328
+ /**
329
+ * Pushes new byte array to the EndlessVector, creating and executing the necessary transaction.
330
+ */
331
+ push(arr: Uint8Array | Uint8Array[], params?: TransactionOptions): Promise<boolean>;
332
+
333
+ /**
334
+ * Creates a transaction to concatenate EndlessVector(s) into this one.
335
+ */
336
+ getConcatTransaction(
337
+ other: string | EndlessVector | Array<string | EndlessVector>,
338
+ txToAppendTo?: Transaction | null
339
+ ): Transaction;
340
+
341
+ /**
342
+ * Concatenates EndlessVector(s) into this one, creating and executing the necessary transaction.
343
+ */
344
+ concat(other: string | EndlessVector | Array<string | EndlessVector>, params?: TransactionOptions): Promise<boolean>;
345
+ }
346
+
347
+ export { EndlessVector as default };
package/package.json CHANGED
@@ -1,9 +1,10 @@
1
1
  {
2
2
  "name": "@fizzyflow/endless-vector",
3
- "version": "0.0.4",
3
+ "version": "0.0.5",
4
4
  "description": "",
5
5
  "type": "module",
6
6
  "main": "./index.js",
7
+ "types": "./index.d.ts",
7
8
  "keywords": [
8
9
  "sui",
9
10
  "vector",
package/test/base.test.js CHANGED
@@ -117,6 +117,32 @@ test('test raw create transaction', async t => {
117
117
  });
118
118
 
119
119
 
120
+ test('make a test EndlessVector with few chunks in a single tx', async t => {
121
+ const data = [
122
+ randomBytesOfLength(1 * 1024),
123
+ randomBytesOfLength(2 * 1024),
124
+ randomBytesOfLength(3 * 1024),
125
+ ];
126
+
127
+ const testEndlessVector = await EndlessVector.create({
128
+ array: data,
129
+ suiClient: suiMaster.client, // instance of Sui SDK SuiClient
130
+ packageId: contract.id, // provide packageId and signAndExecuteTransaction to make EndlessVector writable
131
+ signAndExecuteTransaction: signAndExecuteTransaction,
132
+ });
133
+
134
+ const getBack0 = await testEndlessVector.at(0);
135
+ const getBack1 = await testEndlessVector.at(1);
136
+ const getBack2 = await testEndlessVector.at(2);
137
+
138
+ t.ok(equalUint8Arrays(getBack0, data[0]));
139
+ t.ok(equalUint8Arrays(getBack1, data[1]));
140
+ t.ok(equalUint8Arrays(getBack2, data[2]));
141
+
142
+ t.ok(testEndlessVector.length === 3);
143
+ t.ok(testEndlessVector.binaryLength === 6 * 1024);
144
+ });
145
+
120
146
  test('make a test EndlessVector and push single Uint8Array to it', async t => {
121
147
  endlessVector = await EndlessVector.create({
122
148
  suiClient: suiMaster.client, // instance of Sui SDK SuiClient