@ariadng/sheets 0.1.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.
- package/LICENSE +21 -0
- package/README.md +439 -0
- package/dist/advanced/index.d.ts +5 -0
- package/dist/advanced/index.d.ts.map +1 -0
- package/dist/advanced/index.js +1063 -0
- package/dist/advanced/index.mjs +1005 -0
- package/dist/advanced/metrics.d.ts +50 -0
- package/dist/advanced/metrics.d.ts.map +1 -0
- package/dist/advanced/rate-limit.d.ts +27 -0
- package/dist/advanced/rate-limit.d.ts.map +1 -0
- package/dist/core/auth.d.ts +32 -0
- package/dist/core/auth.d.ts.map +1 -0
- package/dist/core/client.d.ts +35 -0
- package/dist/core/client.d.ts.map +1 -0
- package/dist/core/errors.d.ts +11 -0
- package/dist/core/errors.d.ts.map +1 -0
- package/dist/core/index.d.ts +6 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +315 -0
- package/dist/core/index.mjs +271 -0
- package/dist/plus/batch.d.ts +25 -0
- package/dist/plus/batch.d.ts.map +1 -0
- package/dist/plus/cache.d.ts +19 -0
- package/dist/plus/cache.d.ts.map +1 -0
- package/dist/plus/index.d.ts +7 -0
- package/dist/plus/index.d.ts.map +1 -0
- package/dist/plus/index.js +742 -0
- package/dist/plus/index.mjs +691 -0
- package/dist/plus/types.d.ts +39 -0
- package/dist/plus/types.d.ts.map +1 -0
- package/package.json +81 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 ariadng
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,439 @@
|
|
|
1
|
+
# Sheets
|
|
2
|
+
|
|
3
|
+
A pragmatic TypeScript client for Google Sheets API v4 with stellar performance, that provides essential features without over-engineering. Start simple and add complexity only when needed.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Progressive Enhancement** - Start with core features, add more as needed
|
|
8
|
+
- **Modular Packages** - Core (~3KB), Plus (~5KB), Advanced (~2KB)
|
|
9
|
+
- **Smart Retry Logic** - Exponential backoff with jitter
|
|
10
|
+
- **Optional Caching** - Reduce API calls with configurable TTL
|
|
11
|
+
- **Type Safety** - Full TypeScript support with type utilities
|
|
12
|
+
- **Rate Limiting** - Adaptive or token bucket strategies
|
|
13
|
+
- **Metrics Collection** - Track performance and errors
|
|
14
|
+
- **Batch Operations** - Efficient bulk reads/writes
|
|
15
|
+
|
|
16
|
+
## Installation
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
# Core package only
|
|
20
|
+
npm install @ariadng/sheets
|
|
21
|
+
|
|
22
|
+
# With specific packages
|
|
23
|
+
npm install @ariadng/sheets
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Quick Start
|
|
27
|
+
|
|
28
|
+
### Basic Usage
|
|
29
|
+
|
|
30
|
+
```typescript
|
|
31
|
+
import { GoogleSheetsCore, createServiceAccountAuth } from '@ariadng/sheets/core';
|
|
32
|
+
|
|
33
|
+
// Setup with service account
|
|
34
|
+
const auth = await createServiceAccountAuth('./service-account-key.json');
|
|
35
|
+
const sheets = new GoogleSheetsCore({ auth });
|
|
36
|
+
|
|
37
|
+
// Simple read
|
|
38
|
+
const data = await sheets.read('spreadsheetId', 'Sheet1!A1:B10');
|
|
39
|
+
console.log(data); // [[value1, value2], [value3, value4], ...]
|
|
40
|
+
|
|
41
|
+
// Simple write
|
|
42
|
+
await sheets.write('spreadsheetId', 'Sheet1!A1:B2', [
|
|
43
|
+
['Name', 'Score'],
|
|
44
|
+
['Alice', 100]
|
|
45
|
+
]);
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### With Caching
|
|
49
|
+
|
|
50
|
+
```typescript
|
|
51
|
+
import { withCache } from '@ariadng/sheets/plus';
|
|
52
|
+
|
|
53
|
+
const cachedSheets = withCache(sheets, {
|
|
54
|
+
ttlSeconds: 300 // 5-minute cache
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
// First read hits API
|
|
58
|
+
const data1 = await cachedSheets.read(id, 'A1:B10');
|
|
59
|
+
|
|
60
|
+
// Second read uses cache (within 5 minutes)
|
|
61
|
+
const data2 = await cachedSheets.read(id, 'A1:B10'); // Much faster!
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### With Rate Limiting
|
|
65
|
+
|
|
66
|
+
```typescript
|
|
67
|
+
import { withAdaptiveRateLimit } from '@ariadng/sheets/advanced';
|
|
68
|
+
|
|
69
|
+
const rateLimitedSheets = withAdaptiveRateLimit(sheets);
|
|
70
|
+
|
|
71
|
+
// Automatically handles rate limits
|
|
72
|
+
for (let i = 0; i < 1000; i++) {
|
|
73
|
+
await rateLimitedSheets.read(id, `A${i}`);
|
|
74
|
+
// Automatically slows down if hitting limits
|
|
75
|
+
}
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## Authentication
|
|
79
|
+
|
|
80
|
+
### Service Account
|
|
81
|
+
|
|
82
|
+
```typescript
|
|
83
|
+
import { createServiceAccountAuth } from '@ariadng/sheets/core';
|
|
84
|
+
|
|
85
|
+
// From file
|
|
86
|
+
const auth = await createServiceAccountAuth('./service-account.json');
|
|
87
|
+
|
|
88
|
+
// From object
|
|
89
|
+
const auth = await createServiceAccountAuth({
|
|
90
|
+
client_email: 'your-service-account@project.iam.gserviceaccount.com',
|
|
91
|
+
private_key: '-----BEGIN PRIVATE KEY-----...',
|
|
92
|
+
// ... other fields
|
|
93
|
+
});
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### OAuth2
|
|
97
|
+
|
|
98
|
+
```typescript
|
|
99
|
+
import { createOAuth2Client, generateAuthUrl, getTokenFromCode } from '@ariadng/sheets/core';
|
|
100
|
+
|
|
101
|
+
const client = await createOAuth2Client({
|
|
102
|
+
client_id: 'your-client-id',
|
|
103
|
+
client_secret: 'your-client-secret',
|
|
104
|
+
redirect_uris: ['http://localhost:3000/callback']
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
// Generate auth URL
|
|
108
|
+
const authUrl = generateAuthUrl(client);
|
|
109
|
+
console.log('Visit:', authUrl);
|
|
110
|
+
|
|
111
|
+
// After user authorizes, exchange code for token
|
|
112
|
+
const tokens = await getTokenFromCode(client, authorizationCode);
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
## Core Features
|
|
116
|
+
|
|
117
|
+
### CRUD Operations
|
|
118
|
+
|
|
119
|
+
```typescript
|
|
120
|
+
// Read
|
|
121
|
+
const values = await sheets.read(spreadsheetId, 'Sheet1!A1:C10');
|
|
122
|
+
|
|
123
|
+
// Write (replaces existing data)
|
|
124
|
+
await sheets.write(spreadsheetId, 'Sheet1!A1:C3', [
|
|
125
|
+
['Header1', 'Header2', 'Header3'],
|
|
126
|
+
['Value1', 'Value2', 'Value3']
|
|
127
|
+
]);
|
|
128
|
+
|
|
129
|
+
// Append (adds to end)
|
|
130
|
+
await sheets.append(spreadsheetId, 'Sheet1!A:C', [
|
|
131
|
+
['New1', 'New2', 'New3']
|
|
132
|
+
]);
|
|
133
|
+
|
|
134
|
+
// Clear
|
|
135
|
+
await sheets.clear(spreadsheetId, 'Sheet1!A1:C10');
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
### Batch Operations
|
|
139
|
+
|
|
140
|
+
```typescript
|
|
141
|
+
// Batch read multiple ranges
|
|
142
|
+
const results = await sheets.batchRead(spreadsheetId, [
|
|
143
|
+
'Sheet1!A1:B10',
|
|
144
|
+
'Sheet2!C1:D5'
|
|
145
|
+
]);
|
|
146
|
+
|
|
147
|
+
// Batch write multiple ranges
|
|
148
|
+
await sheets.batchWrite(spreadsheetId, [
|
|
149
|
+
{ range: 'Sheet1!A1:B2', values: [['A', 'B'], ['C', 'D']] },
|
|
150
|
+
{ range: 'Sheet2!A1:B2', values: [['E', 'F'], ['G', 'H']] }
|
|
151
|
+
]);
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
## Plus Package Features
|
|
155
|
+
|
|
156
|
+
### Type Utilities
|
|
157
|
+
|
|
158
|
+
```typescript
|
|
159
|
+
import { A1, TypedSheets, Parsers, Serializers } from '@ariadng/sheets/plus';
|
|
160
|
+
|
|
161
|
+
// A1 notation utilities
|
|
162
|
+
const col = A1.columnToIndex('C'); // 2
|
|
163
|
+
const letter = A1.indexToColumn(2); // 'C'
|
|
164
|
+
const range = A1.build('Sheet1', 'A', 1, 'C', 10); // 'Sheet1!A1:C10'
|
|
165
|
+
|
|
166
|
+
// Type-safe operations
|
|
167
|
+
interface User {
|
|
168
|
+
name: string;
|
|
169
|
+
email: string;
|
|
170
|
+
age: number;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
const typed = new TypedSheets<User[]>(sheets);
|
|
174
|
+
const users = await typed.read(
|
|
175
|
+
spreadsheetId,
|
|
176
|
+
'Users!A1:C100',
|
|
177
|
+
Parsers.rowsToObjects<User>
|
|
178
|
+
);
|
|
179
|
+
|
|
180
|
+
// Data transformation
|
|
181
|
+
const objects = [
|
|
182
|
+
{ name: 'Alice', age: 30 },
|
|
183
|
+
{ name: 'Bob', age: 25 }
|
|
184
|
+
];
|
|
185
|
+
const rows = Serializers.objectsToRows(objects);
|
|
186
|
+
// [['name', 'age'], ['Alice', 30], ['Bob', 25]]
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
### Batch Operations Manager
|
|
190
|
+
|
|
191
|
+
```typescript
|
|
192
|
+
import { BatchOperations } from '@ariadng/sheets/plus';
|
|
193
|
+
|
|
194
|
+
const batchOps = new BatchOperations(sheets);
|
|
195
|
+
|
|
196
|
+
// Automatically chunks large batches
|
|
197
|
+
const operations = Array.from({ length: 500 }, (_, i) => ({
|
|
198
|
+
range: `Sheet1!A${i}:B${i}`,
|
|
199
|
+
values: [[`Row${i}`, `Value${i}`]]
|
|
200
|
+
}));
|
|
201
|
+
|
|
202
|
+
await batchOps.batchWrite(spreadsheetId, operations); // Handles chunking
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
### Simple Cache
|
|
206
|
+
|
|
207
|
+
```typescript
|
|
208
|
+
import { SimpleCache } from '@ariadng/sheets/plus';
|
|
209
|
+
|
|
210
|
+
const cache = new SimpleCache({
|
|
211
|
+
ttlSeconds: 60,
|
|
212
|
+
maxEntries: 100
|
|
213
|
+
});
|
|
214
|
+
|
|
215
|
+
cache.set('key', data);
|
|
216
|
+
const cached = cache.get('key');
|
|
217
|
+
cache.invalidate('pattern*'); // Wildcard invalidation
|
|
218
|
+
cache.clear(); // Clear all
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
## Advanced Package Features
|
|
222
|
+
|
|
223
|
+
### Adaptive Rate Limiting
|
|
224
|
+
|
|
225
|
+
```typescript
|
|
226
|
+
import { AdaptiveRateLimiter } from '@ariadng/sheets/advanced';
|
|
227
|
+
|
|
228
|
+
const limiter = new AdaptiveRateLimiter();
|
|
229
|
+
|
|
230
|
+
// Automatically adjusts delay based on success/failure
|
|
231
|
+
await limiter.execute(async () => {
|
|
232
|
+
return sheets.read(id, range);
|
|
233
|
+
});
|
|
234
|
+
|
|
235
|
+
// Get current stats
|
|
236
|
+
const stats = limiter.getStats();
|
|
237
|
+
console.log(stats); // { requestsInWindow: 45, successRate: 0.98, baseDelay: 0 }
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
### Metrics Collection
|
|
241
|
+
|
|
242
|
+
```typescript
|
|
243
|
+
import { withMetrics } from '@ariadng/sheets/advanced';
|
|
244
|
+
|
|
245
|
+
const metricsSheets = withMetrics(sheets);
|
|
246
|
+
|
|
247
|
+
// Use normally
|
|
248
|
+
await metricsSheets.read(id, range);
|
|
249
|
+
await metricsSheets.write(id, range, values);
|
|
250
|
+
|
|
251
|
+
// Get metrics
|
|
252
|
+
const metrics = metricsSheets.metrics.getMetrics();
|
|
253
|
+
console.log(metrics);
|
|
254
|
+
// {
|
|
255
|
+
// totalRequests: 150,
|
|
256
|
+
// successfulRequests: 148,
|
|
257
|
+
// failedRequests: 2,
|
|
258
|
+
// averageLatency: 123.5,
|
|
259
|
+
// rateLimitHits: 1,
|
|
260
|
+
// errorsByCode: Map { 429 => 1, 500 => 1 }
|
|
261
|
+
// }
|
|
262
|
+
|
|
263
|
+
const summary = metricsSheets.metrics.getSummary();
|
|
264
|
+
console.log(summary);
|
|
265
|
+
// {
|
|
266
|
+
// successRate: 0.987,
|
|
267
|
+
// requestsPerSecond: 2.5,
|
|
268
|
+
// uptimeSeconds: 60
|
|
269
|
+
// }
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
## Error Handling
|
|
273
|
+
|
|
274
|
+
```typescript
|
|
275
|
+
import { GoogleSheetsError } from '@ariadng/sheets/core';
|
|
276
|
+
|
|
277
|
+
try {
|
|
278
|
+
await sheets.read(spreadsheetId, range);
|
|
279
|
+
} catch (error) {
|
|
280
|
+
if (error instanceof GoogleSheetsError) {
|
|
281
|
+
console.error(`API Error ${error.code}: ${error.message}`);
|
|
282
|
+
|
|
283
|
+
if (error.isRetryable) {
|
|
284
|
+
console.log('This error is retryable');
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
if (error.isPermissionError()) {
|
|
288
|
+
console.log('Share the sheet with service account');
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
if (error.isRateLimitError()) {
|
|
292
|
+
console.log('Hit rate limit, slow down');
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
// User-friendly message
|
|
296
|
+
console.log(error.getUserMessage());
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
## Common Patterns
|
|
302
|
+
|
|
303
|
+
### Progressive Enhancement
|
|
304
|
+
|
|
305
|
+
```typescript
|
|
306
|
+
import { GoogleSheetsCore } from '@ariadng/sheets/core';
|
|
307
|
+
import { withCache } from '@ariadng/sheets/plus';
|
|
308
|
+
import { withAdaptiveRateLimit, withMetrics } from '@ariadng/sheets/advanced';
|
|
309
|
+
|
|
310
|
+
// Start simple
|
|
311
|
+
let sheets = new GoogleSheetsCore({ auth });
|
|
312
|
+
|
|
313
|
+
// Add features as needed
|
|
314
|
+
sheets = withCache(sheets, { ttlSeconds: 300 });
|
|
315
|
+
sheets = withAdaptiveRateLimit(sheets);
|
|
316
|
+
sheets = withMetrics(sheets);
|
|
317
|
+
|
|
318
|
+
// Now have all features!
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
### Data Processing Pipeline
|
|
322
|
+
|
|
323
|
+
```typescript
|
|
324
|
+
import { Parsers, Serializers } from '@ariadng/sheets/plus';
|
|
325
|
+
|
|
326
|
+
// Read raw data
|
|
327
|
+
const raw = await sheets.read(id, 'Data!A1:Z1000');
|
|
328
|
+
|
|
329
|
+
// Parse to objects
|
|
330
|
+
const records = Parsers.rowsToObjects(raw);
|
|
331
|
+
|
|
332
|
+
// Process data
|
|
333
|
+
const processed = records
|
|
334
|
+
.filter(r => r.status === 'active')
|
|
335
|
+
.map(r => ({ ...r, processed: true }));
|
|
336
|
+
|
|
337
|
+
// Convert back to rows
|
|
338
|
+
const rows = Serializers.objectsToRows(processed);
|
|
339
|
+
|
|
340
|
+
// Write back
|
|
341
|
+
await sheets.write(id, 'Processed!A1', rows);
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
### Efficient Batch Processing
|
|
345
|
+
|
|
346
|
+
```typescript
|
|
347
|
+
import { BatchOperations } from '@ariadng/sheets/plus';
|
|
348
|
+
|
|
349
|
+
const batch = new BatchOperations(sheets);
|
|
350
|
+
|
|
351
|
+
// Mixed operations
|
|
352
|
+
const results = await batch.executeBatch(spreadsheetId, {
|
|
353
|
+
reads: ['Summary!A1:Z1', 'Config!A1:B10'],
|
|
354
|
+
writes: [
|
|
355
|
+
{ range: 'Output!A1:B100', values: outputData }
|
|
356
|
+
],
|
|
357
|
+
clears: ['Temp!A:Z']
|
|
358
|
+
});
|
|
359
|
+
|
|
360
|
+
// All executed efficiently in parallel when possible
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
## API Reference
|
|
364
|
+
|
|
365
|
+
### Core Package
|
|
366
|
+
|
|
367
|
+
#### GoogleSheetsCore
|
|
368
|
+
|
|
369
|
+
- `constructor(config: GoogleSheetsConfig)`
|
|
370
|
+
- `read(spreadsheetId: string, range: string): Promise<any[][]>`
|
|
371
|
+
- `write(spreadsheetId: string, range: string, values: any[][]): Promise<UpdateValuesResponse>`
|
|
372
|
+
- `append(spreadsheetId: string, range: string, values: any[][]): Promise<AppendValuesResponse>`
|
|
373
|
+
- `clear(spreadsheetId: string, range: string): Promise<ClearValuesResponse>`
|
|
374
|
+
- `batchRead(spreadsheetId: string, ranges: string[]): Promise<ValueRange[]>`
|
|
375
|
+
- `batchWrite(spreadsheetId: string, data: BatchWriteData[]): Promise<BatchUpdateValuesResponse>`
|
|
376
|
+
- `getSpreadsheet(spreadsheetId: string): Promise<Spreadsheet>`
|
|
377
|
+
- `getApi(): sheets_v4.Sheets`
|
|
378
|
+
|
|
379
|
+
### Plus Package
|
|
380
|
+
|
|
381
|
+
#### A1 Utilities
|
|
382
|
+
|
|
383
|
+
- `A1.columnToIndex(column: string): number`
|
|
384
|
+
- `A1.indexToColumn(index: number): string`
|
|
385
|
+
- `A1.parse(notation: string): A1Components`
|
|
386
|
+
- `A1.build(sheet?, startCol, startRow, endCol?, endRow?): string`
|
|
387
|
+
- `A1.getDimensions(notation: string): { rows: number, columns: number }`
|
|
388
|
+
- `A1.offset(notation: string, rowOffset: number, colOffset: number): string`
|
|
389
|
+
|
|
390
|
+
#### Parsers
|
|
391
|
+
|
|
392
|
+
- `Parsers.rowsToObjects<T>(data: any[][]): T[]`
|
|
393
|
+
- `Parsers.asNumbers(data: any[][]): number[][]`
|
|
394
|
+
- `Parsers.asStrings(data: any[][]): string[][]`
|
|
395
|
+
- `Parsers.asMap<V>(data: any[][]): Map<string, V>`
|
|
396
|
+
- `Parsers.column<T>(data: any[][], columnIndex: number): T[]`
|
|
397
|
+
|
|
398
|
+
#### Serializers
|
|
399
|
+
|
|
400
|
+
- `Serializers.objectsToRows<T>(objects: T[], headers?: string[]): any[][]`
|
|
401
|
+
- `Serializers.mapToRows<K,V>(map: Map<K,V>): any[][]`
|
|
402
|
+
- `Serializers.arrayToColumn<T>(array: T[]): any[][]`
|
|
403
|
+
- `Serializers.transpose(data: any[][]): any[][]`
|
|
404
|
+
|
|
405
|
+
## Performance
|
|
406
|
+
|
|
407
|
+
| Operation | Base Latency | With Cache | With Rate Limit |
|
|
408
|
+
|-----------|-------------|------------|-----------------|
|
|
409
|
+
| Single Read | 100-200ms | 0-1ms (hit) | +0-50ms |
|
|
410
|
+
| Batch Read (10) | 150-250ms | 0-1ms (hit) | +0-50ms |
|
|
411
|
+
| Single Write | 150-300ms | N/A | +0-50ms |
|
|
412
|
+
| Batch Write (100) | 300-500ms | N/A | +0-100ms |
|
|
413
|
+
|
|
414
|
+
## Best Practices
|
|
415
|
+
|
|
416
|
+
1. **Use batch operations** when reading/writing multiple ranges
|
|
417
|
+
2. **Enable caching** for frequently read, rarely changed data
|
|
418
|
+
3. **Add rate limiting** for bulk operations or scripts
|
|
419
|
+
4. **Use type utilities** for better type safety and code clarity
|
|
420
|
+
5. **Handle errors gracefully** with proper retry logic
|
|
421
|
+
6. **Monitor with metrics** in production environments
|
|
422
|
+
|
|
423
|
+
## Requirements
|
|
424
|
+
|
|
425
|
+
- Node.js 14+
|
|
426
|
+
- Google Sheets API enabled in Google Cloud Console
|
|
427
|
+
- Service account or OAuth2 credentials
|
|
428
|
+
|
|
429
|
+
## License
|
|
430
|
+
|
|
431
|
+
MIT
|
|
432
|
+
|
|
433
|
+
## Contributing
|
|
434
|
+
|
|
435
|
+
Contributions are welcome! Please read our contributing guidelines before submitting PRs.
|
|
436
|
+
|
|
437
|
+
## Support
|
|
438
|
+
|
|
439
|
+
For issues and feature requests, please use the [GitHub issues page](https://github.com/ariadng/sheets/issues).
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { AdaptiveRateLimiter, TokenBucketRateLimiter, withAdaptiveRateLimit, withTokenBucketRateLimit, } from './rate-limit';
|
|
2
|
+
export { MetricsCollector, PerformanceMonitor, withMetrics, } from './metrics';
|
|
3
|
+
export type { Metrics } from './metrics';
|
|
4
|
+
export * from '../plus';
|
|
5
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/advanced/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,mBAAmB,EACnB,sBAAsB,EACtB,qBAAqB,EACrB,wBAAwB,GACxB,MAAM,cAAc,CAAC;AAEtB,OAAO,EACN,gBAAgB,EAChB,kBAAkB,EAClB,WAAW,GACX,MAAM,WAAW,CAAC;AACnB,YAAY,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGzC,cAAc,SAAS,CAAC"}
|