@candidstartup/infinisheet-types 0.10.0 → 0.12.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/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { Ok as Ok$1, Err as Err$1 } from 'neverthrow';
1
+ import { Ok as Ok$1, Err as Err$1, ResultAsync as ResultAsync$1 } from 'neverthrow';
2
2
 
3
3
  /**
4
4
  * An `Ok` instance is the *successful* variant of the {@link Result} type,
@@ -111,6 +111,205 @@ declare function err<T = never, E extends string = string>(err: E): Err<T, E>;
111
111
  declare function err<T = never, E = unknown>(err: E): Err<T, E>;
112
112
  declare function err<T = never, _E extends void = void>(err: void): Err<T, void>;
113
113
 
114
+ /**
115
+ * `ResultAsync` allows you to work with asynchronous Results in a type safe way
116
+ *
117
+ * `ResultAsync<T,E>` is a wrapper around `Promise<Result<T,E>>` which provides the same methods for chaining different
118
+ * `Result` and `ResultAsync` together as {@link Result}, while also chaining the asynchronous operations together using
119
+ * `Promise.then`.
120
+ *
121
+ * `ResultAsync` is *thenable* (implements `PromiseLike<T>`) so can be used in most places that a `Promise` can, including with `await`.
122
+ *
123
+ * Compatible with [`neverthrow`](https://github.com/supermacro/neverthrow)
124
+ *
125
+ * @typeParam T - The type of the value contained in the `ResultAsync` for the success case
126
+ * @typeParam E - The type of the error contained in the `ResultAsync` for the failure case
127
+ */
128
+ declare class ResultAsync<T, E> extends ResultAsync$1<T, E> {
129
+ }
130
+ /**
131
+ * Create an instance of `ResultAsync` containing an {@link Ok} variant of {@link Result}
132
+ *
133
+ * Equivalent to `new ResultAsync(Promise.resolve(new Ok(value)))`
134
+ *
135
+ * @typeParam T - The type of the value contained in the `ResultAsync` for the success case
136
+ * @typeParam E - The type of the error contained in the `ResultAsync` for the failure case
137
+ * @param value - The value to wrap in a `Result.Ok`.
138
+ */
139
+ declare function okAsync<T, E = never>(value: T): ResultAsync<T, E>;
140
+ declare function okAsync<_T extends void = void, E = never>(value: void): ResultAsync<void, E>;
141
+ /**
142
+ * Create an instance of `ResultAsync` containing an {@link Err} variant of {@link Result}
143
+ *
144
+ * Equivalent to `new ResultAsync(Promise.resolve(new Err(err)))`
145
+ *
146
+ * @typeParam T - The type of the value contained in the `Result` for the success case
147
+ * @typeParam E - The type of the error contained in the `Result` for the failure case
148
+ * @param err - The value to wrap in a `Result.Err`.
149
+ */
150
+ declare function errAsync<T = never, E = unknown>(err: E): ResultAsync<T, E>;
151
+ declare function errAsync<T = never, _E extends void = void>(err: void): ResultAsync<T, void>;
152
+
153
+ /** Common properties for Infinisheet errors */
154
+ interface InfinisheetError {
155
+ /** Discriminated union tag */
156
+ type: string;
157
+ /** End user message describing the problem */
158
+ message: string;
159
+ }
160
+ /**
161
+ * Attempt to access data that is outside the available range
162
+ *
163
+ */
164
+ interface InfinisheetRangeError extends InfinisheetError {
165
+ /** Discriminated union tag */
166
+ type: 'InfinisheetRangeError';
167
+ }
168
+ /** Convenience method that creates an {@link InfinisheetRangeError} */
169
+ declare function infinisheetRangeError(message: string): InfinisheetRangeError;
170
+ /** Type that represents an error when validating data passed to an API */
171
+ interface ValidationError extends InfinisheetError {
172
+ /** Discriminated union tag */
173
+ type: 'ValidationError';
174
+ }
175
+ /** Convenience method that creates a {@link ValidationError} */
176
+ declare function validationError(message: string): ValidationError;
177
+ /** Type that represents an error when accessing data in persistent storage */
178
+ interface StorageError extends InfinisheetError {
179
+ /** Discriminated union tag */
180
+ type: 'StorageError';
181
+ /** HTTP style status code
182
+ *
183
+ * Describes the type of problem encountered. Expected to be a 4XX or 5XX code.
184
+ */
185
+ statusCode?: number | undefined;
186
+ }
187
+ /** Convenience method that creates a {@link StorageError} */
188
+ declare function storageError(message: string, statusCode?: number): StorageError;
189
+
190
+ /** Identifier for a blob of data in a blob store */
191
+ type BlobId = string;
192
+ /** Identifier for a workflow triggered writing to {@link LogMetadata.pending} */
193
+ type WorkflowId = string;
194
+ /**
195
+ * Identifier for an entry in an {@link EventLog}.
196
+ *
197
+ * Incrementing integer.
198
+ */
199
+ type SequenceId = bigint;
200
+ /**
201
+ * Metadata stored in an {@link EventLog} entry
202
+ */
203
+ interface LogMetadata {
204
+ /** Stores a reference to a snapshot of the complete log up to and including this entry */
205
+ snapshot?: BlobId | undefined;
206
+ /** Stores a reference to an external history of the event log up to and including the previous entry */
207
+ history?: BlobId | undefined;
208
+ /** Indicates that a background workflow is pending */
209
+ pending?: WorkflowId | undefined;
210
+ }
211
+ /**
212
+ * Type that represents an entry in an {@link EventLog}
213
+ *
214
+ * Base interface that clients will typically implement multiple times.
215
+ * Each concrete implementation will define its own data properties that
216
+ * need to be serialized into the event log.
217
+ *
218
+ * Properties defined here are common metadata which require special handling
219
+ * by any `EventLog` implementation.
220
+ *
221
+ * All data properties are immutable once an entry has been added to the log. Metadata
222
+ * properties (apart from `type`) may change over time.
223
+ */
224
+ interface LogEntry extends LogMetadata {
225
+ /** Used as a discriminated union tag by implementations */
226
+ type: string;
227
+ }
228
+ /**
229
+ * Type that represents a consistency conflict when adding a {@link LogEntry} to an {@link EventLog}
230
+ *
231
+ * Occurs when an attempt is made to add an entry with a sequence id that is not
232
+ * the next available in the log.
233
+ *
234
+ * Typically happens when another client makes a change since you last read the log.
235
+ * Sync with the additional log entries and then try again.
236
+ */
237
+ interface ConflictError extends InfinisheetError {
238
+ /** Discriminated union tag */
239
+ type: 'ConflictError';
240
+ /** Next available sequence id */
241
+ nextSequenceId: SequenceId;
242
+ }
243
+ /** Convenience method that creates a {@link ConflictError} */
244
+ declare function conflictError(message: string, nextSequenceId: SequenceId): ConflictError;
245
+ /** Errors that can be returned by {@link EventLog} `addEntry` method */
246
+ type AddEntryError = ConflictError | StorageError;
247
+ /** Errors that can be returned by {@link EventLog} `query` method */
248
+ type QueryError = InfinisheetRangeError | StorageError;
249
+ /** Errors that can be returned by {@link EventLog} `truncate` method */
250
+ type TruncateError = InfinisheetRangeError | StorageError;
251
+ /** Errors that can be returned by {@link EventLog} `setMetadata` method */
252
+ type MetadataError = InfinisheetRangeError | StorageError;
253
+ /** A range of {@link LogEntry} values returned by querying an {@link EventLog} */
254
+ interface QueryValue<T extends LogEntry> {
255
+ /** Sequence id corresponding to the first entry in `entries`
256
+ *
257
+ * All other entries have consecutive ascending sequence ids
258
+ */
259
+ startSequenceId: SequenceId;
260
+ /**
261
+ * Sequence id after the final entry in `entries`
262
+ *
263
+ * If query was up to the `end` sequence id AND
264
+ * `isComplete` is true, this is the next available
265
+ * sequence id for `addEntry`.
266
+ */
267
+ endSequenceId: SequenceId;
268
+ /** True if all the requested entries have been returned
269
+ *
270
+ * Queries may return fewer entries than requested. If
271
+ * `isComplete` is `false`, repeat the query starting
272
+ * from `nextSequenceId`.
273
+ */
274
+ isComplete: boolean;
275
+ /** The {@link LogEntry} records returned by the query */
276
+ entries: T[];
277
+ }
278
+ /** Abstract interface representing an event log
279
+ *
280
+ *
281
+ */
282
+ interface EventLog<T extends LogEntry> {
283
+ /**
284
+ * Add an entry to the log with the given sequence id
285
+ *
286
+ * The `sequenceId` must be the next available sequence id in the log. This is returned as `endSequenceId` when
287
+ * making a query for the `last` entry in the log. Returns a {@link ConflictError} if not the next available id.
288
+ * Any other problem with serializing the entry will return a {@link StorageError}.
289
+ */
290
+ addEntry(entry: T, sequenceId: SequenceId): ResultAsync<void, AddEntryError>;
291
+ /**
292
+ * Set some or all of a log entry's metadata fields
293
+ *
294
+ * Changes are atomic. Either all of the specified fields are updated or none are.
295
+ */
296
+ setMetadata(sequenceId: SequenceId, metaData: LogMetadata): ResultAsync<void, MetadataError>;
297
+ /** Return a range of entries from `first` to `last` inclusive
298
+ *
299
+ * The event log may return fewer entries than requested. If so, repeat the query starting from `nextSequenceId`.
300
+ *
301
+ * @param start - `SequenceId` of first entry to return.
302
+ * Use `'start'` to query from the first entry in the log.
303
+ * Use `'snapshot'` to query from the most recent entry with a snapshot, or the first if no snapshot is defined.
304
+ *
305
+ * @param end - `SequenceId` one after the last entry to return.
306
+ * Use `'end'` to query everything to the end of the log.
307
+ */
308
+ query(start: SequenceId | 'snapshot' | 'start', end: SequenceId | 'end'): ResultAsync<QueryValue<T>, QueryError>;
309
+ /** All entries prior to `start` are removed from the log. */
310
+ truncate(start: SequenceId): ResultAsync<void, TruncateError>;
311
+ }
312
+
114
313
  /**
115
314
  * Interface used to determine the size and positioning offset for items in a single dimension.
116
315
  */
@@ -132,7 +331,6 @@ interface ItemOffsetMapping {
132
331
  * Implementation of {@link ItemOffsetMapping} for use when all items have a fixed size
133
332
  */
134
333
  declare class FixedSizeItemOffsetMapping implements ItemOffsetMapping {
135
- #private;
136
334
  /**
137
335
  * @param itemSize - Size to use for all items
138
336
  */
@@ -140,13 +338,13 @@ declare class FixedSizeItemOffsetMapping implements ItemOffsetMapping {
140
338
  itemSize(_itemIndex: number): number;
141
339
  itemOffset(itemIndex: number): number;
142
340
  offsetToItem(offset: number): [itemIndex: number, startOffset: number];
341
+ private fixedItemSize;
143
342
  }
144
343
 
145
344
  /**
146
345
  * Implementation of {@link ItemOffsetMapping} for use when initial items have variable sizes.
147
346
  */
148
347
  declare class VariableSizeItemOffsetMapping implements ItemOffsetMapping {
149
- #private;
150
348
  /**
151
349
  * @param defaultItemSize - Size to use for all other items
152
350
  * @param sizes - Array of sizes to use for the initial items, one size per item
@@ -155,6 +353,8 @@ declare class VariableSizeItemOffsetMapping implements ItemOffsetMapping {
155
353
  itemSize(itemIndex: number): number;
156
354
  itemOffset(itemIndex: number): number;
157
355
  offsetToItem(offset: number): [itemIndex: number, startOffset: number];
356
+ private defaultItemSize;
357
+ private sizes;
158
358
  }
159
359
 
160
360
  /** Possible spreadsheet error values
@@ -183,29 +383,6 @@ interface CellError {
183
383
  * explicitly marked as empty.
184
384
  */
185
385
  type CellValue = string | number | boolean | null | undefined | CellError;
186
- /** Type that represents an error when validating data to be stored in a cell */
187
- interface ValidationError {
188
- /** Discriminated union tag */
189
- type: 'ValidationError';
190
- /** End user message describing the problem */
191
- message: string;
192
- }
193
- /** Convenience method that creates a {@link ValidationError} */
194
- declare function validationError(message: string): ValidationError;
195
- /** Type that represents an error when storing data in a cell */
196
- interface StorageError {
197
- /** Discriminated union tag */
198
- type: 'StorageError';
199
- /** End user message describing the problem */
200
- message: string;
201
- /** HTTP style status code
202
- *
203
- * Describes the type of problem encountered. Expected to be a 4XX or 5XX code.
204
- */
205
- statusCode?: number | undefined;
206
- }
207
- /** Convenience method that creates a {@link StorageError} */
208
- declare function storageError(message: string, statusCode?: number): StorageError;
209
386
  /** Types of error that can be returned by {@link SpreadsheetData} methods */
210
387
  type SpreadsheetDataError = ValidationError | StorageError;
211
388
  /**
@@ -223,6 +400,13 @@ interface SpreadsheetData<Snapshot> {
223
400
  subscribe(onDataChange: () => void): () => void;
224
401
  /** Return a snapshot to use when accessing values at a consistent point in time */
225
402
  getSnapshot(): Snapshot;
403
+ /**
404
+ * Return load status at the time the snapshot was created
405
+ *
406
+ * On Success returns true if load has completed, false if still in progress
407
+ * On Err returns most recent error reported by the storage system
408
+ */
409
+ getLoadStatus(snapshot: Snapshot): Result<boolean, StorageError>;
226
410
  /** Number of rows in the spreadsheet */
227
411
  getRowCount(snapshot: Snapshot): number;
228
412
  /** {@link ItemOffsetMapping} which describes sizes and offsets to start of rows */
@@ -239,7 +423,7 @@ interface SpreadsheetData<Snapshot> {
239
423
  *
240
424
  * @returns `Ok` if the change was successfully applied
241
425
  */
242
- setCellValueAndFormat(row: number, column: number, value: CellValue, format: string | undefined): Result<void, SpreadsheetDataError>;
426
+ setCellValueAndFormat(row: number, column: number, value: CellValue, format: string | undefined): ResultAsync<void, SpreadsheetDataError>;
243
427
  /** Check whether value and format are valid to set for specified cell
244
428
  *
245
429
  * @returns `Ok` if the value and format are valid
@@ -249,13 +433,14 @@ interface SpreadsheetData<Snapshot> {
249
433
  declare class EmptySpreadsheetData implements SpreadsheetData<number> {
250
434
  subscribe(_onDataChange: () => void): () => void;
251
435
  getSnapshot(): number;
436
+ getLoadStatus(_snapshot: number): Result<boolean, StorageError>;
252
437
  getRowCount(_snapshot: number): number;
253
438
  getRowItemOffsetMapping(_snapshot: number): ItemOffsetMapping;
254
439
  getColumnCount(_snapshot: number): number;
255
440
  getColumnItemOffsetMapping(_snapshot: number): ItemOffsetMapping;
256
441
  getCellValue(_snapshot: number, _row: number, _column: number): CellValue;
257
442
  getCellFormat(_snapshot: number, _row: number, _column: number): string | undefined;
258
- setCellValueAndFormat(_row: number, _column: number, _value: CellValue, _format: string | undefined): Result<void, SpreadsheetDataError>;
443
+ setCellValueAndFormat(_row: number, _column: number, _value: CellValue, _format: string | undefined): ResultAsync<void, SpreadsheetDataError>;
259
444
  isValidCellValueAndFormat(_row: number, _column: number, _value: CellValue, _format: string | undefined): Result<void, ValidationError>;
260
445
  }
261
446
 
@@ -276,4 +461,5 @@ declare function rowColRefToCoords(ref: RowColRef): RowColCoords;
276
461
  /** Converts {@link RowColCoords} to a {@link RowColRef} */
277
462
  declare function rowColCoordsToRef(row: number | undefined, col: number | undefined): RowColRef;
278
463
 
279
- export { type CellError, type CellErrorValue, type CellValue, type ColRef, EmptySpreadsheetData, type Err, FixedSizeItemOffsetMapping, type ItemOffsetMapping, type Ok, type Result, type RowColCoords, type RowColRef, type SpreadsheetData, type SpreadsheetDataError, type StorageError, type ValidationError, VariableSizeItemOffsetMapping, colRefToIndex, err, indexToColRef, ok, rowColCoordsToRef, rowColRefToCoords, splitRowColRef, storageError, validationError };
464
+ export { EmptySpreadsheetData, FixedSizeItemOffsetMapping, ResultAsync, VariableSizeItemOffsetMapping, colRefToIndex, conflictError, err, errAsync, indexToColRef, infinisheetRangeError, ok, okAsync, rowColCoordsToRef, rowColRefToCoords, splitRowColRef, storageError, validationError };
465
+ export type { AddEntryError, BlobId, CellError, CellErrorValue, CellValue, ColRef, ConflictError, Err, EventLog, InfinisheetError, InfinisheetRangeError, ItemOffsetMapping, LogEntry, LogMetadata, MetadataError, Ok, QueryError, QueryValue, Result, RowColCoords, RowColRef, SequenceId, SpreadsheetData, SpreadsheetDataError, StorageError, TruncateError, ValidationError, WorkflowId };
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { ok as ok$1, err as err$1 } from 'neverthrow';
1
+ import { ok as ok$1, err as err$1, ResultAsync as ResultAsync$1, okAsync as okAsync$1, errAsync as errAsync$1 } from 'neverthrow';
2
2
 
3
3
  function ok(value) {
4
4
  return ok$1(value);
@@ -7,6 +7,47 @@ function err(err) {
7
7
  return err$1(err);
8
8
  }
9
9
 
10
+ /**
11
+ * `ResultAsync` allows you to work with asynchronous Results in a type safe way
12
+ *
13
+ * `ResultAsync<T,E>` is a wrapper around `Promise<Result<T,E>>` which provides the same methods for chaining different
14
+ * `Result` and `ResultAsync` together as {@link Result}, while also chaining the asynchronous operations together using
15
+ * `Promise.then`.
16
+ *
17
+ * `ResultAsync` is *thenable* (implements `PromiseLike<T>`) so can be used in most places that a `Promise` can, including with `await`.
18
+ *
19
+ * Compatible with [`neverthrow`](https://github.com/supermacro/neverthrow)
20
+ *
21
+ * @typeParam T - The type of the value contained in the `ResultAsync` for the success case
22
+ * @typeParam E - The type of the error contained in the `ResultAsync` for the failure case
23
+ */
24
+ class ResultAsync extends ResultAsync$1 {
25
+ }
26
+ function okAsync(value) {
27
+ return okAsync$1(value);
28
+ }
29
+ function errAsync(err) {
30
+ return errAsync$1(err);
31
+ }
32
+
33
+ /** Convenience method that creates an {@link InfinisheetRangeError} */
34
+ function infinisheetRangeError(message) {
35
+ return { type: 'InfinisheetRangeError', message };
36
+ }
37
+ /** Convenience method that creates a {@link ValidationError} */
38
+ function validationError(message) {
39
+ return { type: 'ValidationError', message };
40
+ }
41
+ /** Convenience method that creates a {@link StorageError} */
42
+ function storageError(message, statusCode) {
43
+ return { type: 'StorageError', message, statusCode };
44
+ }
45
+
46
+ /** Convenience method that creates a {@link ConflictError} */
47
+ function conflictError(message, nextSequenceId) {
48
+ return { type: 'ConflictError', message, nextSequenceId };
49
+ }
50
+
10
51
  /**
11
52
  * Implementation of {@link ItemOffsetMapping} for use when all items have a fixed size
12
53
  */
@@ -15,20 +56,20 @@ class FixedSizeItemOffsetMapping {
15
56
  * @param itemSize - Size to use for all items
16
57
  */
17
58
  constructor(itemSize) {
18
- this.#fixedItemSize = itemSize;
59
+ this.fixedItemSize = itemSize;
19
60
  }
20
61
  itemSize(_itemIndex) {
21
- return this.#fixedItemSize;
62
+ return this.fixedItemSize;
22
63
  }
23
64
  itemOffset(itemIndex) {
24
- return itemIndex * this.#fixedItemSize;
65
+ return itemIndex * this.fixedItemSize;
25
66
  }
26
67
  offsetToItem(offset) {
27
- const itemIndex = Math.floor(offset / this.#fixedItemSize);
28
- const startOffset = itemIndex * this.#fixedItemSize;
68
+ const itemIndex = Math.floor(offset / this.fixedItemSize);
69
+ const startOffset = itemIndex * this.fixedItemSize;
29
70
  return [itemIndex, startOffset];
30
71
  }
31
- #fixedItemSize;
72
+ fixedItemSize;
32
73
  }
33
74
 
34
75
  /**
@@ -40,64 +81,57 @@ class VariableSizeItemOffsetMapping {
40
81
  * @param sizes - Array of sizes to use for the initial items, one size per item
41
82
  */
42
83
  constructor(defaultItemSize, sizes) {
43
- this.#defaultItemSize = defaultItemSize;
44
- this.#sizes = sizes;
84
+ this.defaultItemSize = defaultItemSize;
85
+ this.sizes = sizes;
45
86
  }
46
87
  itemSize(itemIndex) {
47
- return (itemIndex < this.#sizes.length) ? this.#sizes[itemIndex] : this.#defaultItemSize;
88
+ return (itemIndex < this.sizes.length) ? this.sizes[itemIndex] : this.defaultItemSize;
48
89
  }
49
90
  itemOffset(itemIndex) {
50
91
  let offset = 0;
51
- let length = this.#sizes.length;
92
+ let length = this.sizes.length;
52
93
  if (itemIndex > length) {
53
94
  const numDefaultSize = itemIndex - length;
54
- offset = numDefaultSize * this.#defaultItemSize;
95
+ offset = numDefaultSize * this.defaultItemSize;
55
96
  }
56
97
  else {
57
98
  length = itemIndex;
58
99
  }
59
100
  for (let i = 0; i < length; i++) {
60
- offset += this.#sizes[i];
101
+ offset += this.sizes[i];
61
102
  }
62
103
  return offset;
63
104
  }
64
105
  offsetToItem(offset) {
65
106
  let startOffset = 0;
66
- for (const [i, size] of this.#sizes.entries()) {
107
+ for (const [i, size] of this.sizes.entries()) {
67
108
  if (startOffset + size > offset) {
68
109
  return [i, startOffset];
69
110
  }
70
111
  startOffset += size;
71
112
  }
72
- const itemIndex = Math.floor((offset - startOffset) / this.#defaultItemSize);
73
- startOffset += itemIndex * this.#defaultItemSize;
74
- const length = this.#sizes.length;
113
+ const itemIndex = Math.floor((offset - startOffset) / this.defaultItemSize);
114
+ startOffset += itemIndex * this.defaultItemSize;
115
+ const length = this.sizes.length;
75
116
  return [itemIndex + length, startOffset];
76
117
  }
77
- #defaultItemSize;
78
- #sizes;
118
+ defaultItemSize;
119
+ sizes;
79
120
  }
80
121
 
81
- /** Convenience method that creates a {@link ValidationError} */
82
- function validationError(message) {
83
- return { type: 'ValidationError', message };
84
- }
85
- /** Convenience method that creates a {@link StorageError} */
86
- function storageError(message, statusCode) {
87
- return { type: 'StorageError', message, statusCode };
88
- }
89
122
  const rowItemOffsetMapping = new FixedSizeItemOffsetMapping(30);
90
123
  const columnItemOffsetMapping = new FixedSizeItemOffsetMapping(100);
91
124
  class EmptySpreadsheetData {
92
125
  subscribe(_onDataChange) { return () => { }; }
93
126
  getSnapshot() { return 0; }
127
+ getLoadStatus(_snapshot) { return ok(true); }
94
128
  getRowCount(_snapshot) { return 0; }
95
129
  getRowItemOffsetMapping(_snapshot) { return rowItemOffsetMapping; }
96
130
  getColumnCount(_snapshot) { return 0; }
97
131
  getColumnItemOffsetMapping(_snapshot) { return columnItemOffsetMapping; }
98
132
  getCellValue(_snapshot, _row, _column) { return null; }
99
133
  getCellFormat(_snapshot, _row, _column) { return undefined; }
100
- setCellValueAndFormat(_row, _column, _value, _format) { return err(storageError("Not implemented", 501)); }
134
+ setCellValueAndFormat(_row, _column, _value, _format) { return errAsync(storageError("Not implemented", 501)); }
101
135
  isValidCellValueAndFormat(_row, _column, _value, _format) { return ok(); }
102
136
  }
103
137
 
@@ -156,5 +190,5 @@ function rowColCoordsToRef(row, col) {
156
190
  }
157
191
  }
158
192
 
159
- export { EmptySpreadsheetData, FixedSizeItemOffsetMapping, VariableSizeItemOffsetMapping, colRefToIndex, err, indexToColRef, ok, rowColCoordsToRef, rowColRefToCoords, splitRowColRef, storageError, validationError };
193
+ export { EmptySpreadsheetData, FixedSizeItemOffsetMapping, ResultAsync, VariableSizeItemOffsetMapping, colRefToIndex, conflictError, err, errAsync, indexToColRef, infinisheetRangeError, ok, okAsync, rowColCoordsToRef, rowColRefToCoords, splitRowColRef, storageError, validationError };
160
194
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../src/Result.ts","../src/FixedSizeItemOffsetMapping.ts","../src/VariableSizeItemOffsetMapping.ts","../src/SpreadsheetData.ts","../src/RowColRef.ts"],"sourcesContent":["import type { Ok as neverthrow_Ok, Err as neverthrow_Err } from \"neverthrow\";\nimport { err as neverthrow_err, ok as neverthrow_ok } from \"neverthrow\";\n\n/**\n * An `Ok` instance is the *successful* variant of the {@link Result} type, \n * representing a successful outcome from an operation which may fail.\n * \n * Implemented using [`neverthrow`](https://github.com/supermacro/neverthrow)\n * \n * @typeParam T - The type of the value contained in the `Result` for the success case\n * @typeParam E - The type of the error contained in the `Result` for the failure case\n */\nexport interface Ok<T,E> extends neverthrow_Ok<T,E> {}\n\n/**\n * An `Err` instance is the failure variant of the {@link Result} type, \n * representing a failure outcome from an operation which may fail.\n * \n * Implemented using [`neverthrow`](https://github.com/supermacro/neverthrow)\n * \n * @typeParam T - The type of the value contained in the `Result` for the success case\n * @typeParam E - The type of the error contained in the `Result` for the failure case\n */\nexport interface Err<T,E> extends neverthrow_Err<T,E> {}\n\n/**\n * A `Result` represents success ({@link Ok}) or failure ({@link Err}).\n * \n * Compatible with [`neverthrow`](https://github.com/supermacro/neverthrow)\n * \n * @typeParam T - The type of the value contained in the `Result` for the success case\n * @typeParam E - The type of the error contained in the `Result` for the failure case\n */\nexport type Result<T,E> = Ok<T,E> | Err<T,E>;\n\n/**\n * Create an instance of {@link Ok}.\n *\n * If you need to create an instance with a specific type (as you do whenever you\n * are not constructing immediately for a function return or as an argument to a\n * function), you can use a type parameter:\n *\n * ```ts\n * const yayNumber = ok<number, string>(12);\n * ```\n *\n * Note: passing nothing will produce a `Result<void, E>`, passing `undefined` will\n * produce a `Result<undefined, E>` which is compatible with `Result<void, E>`.\n *\n * ```ts\n * const normalResult = ok<number, string>(42);\n * const explicitUndefined = ok<undefined, string>(undefined);\n * const implicitVoid = ok<void, string>();\n * ```\n *\n * In the context of an immediate function return, or an arrow function with a\n * single expression value, you do not have to specify the types, so this can be\n * quite convenient.\n *\n * ```ts\n * const arrowValidate = (data: SomeData): Result<void, string> =>\n * isValid(data) ? ok() : err('something was wrong!');\n *\n * function fnValidate(data: someData): Result<void, string> {\n * return isValid(data) ? ok() : err('something was wrong');\n * }\n * ```\n *\n * @typeParam T - The type of the value contained in the `Result` for the success case\n * @typeParam E - The type of the error contained in the `Result` for the failure case\n * @param value - The value to wrap in a `Result.Ok`.\n */\nexport function ok<T, E = never>(value: T): Ok<T, E>\nexport function ok<_T extends void = void, E = never>(value: void): Ok<void, E>\nexport function ok<T, E = never>(value: T): Ok<T, E> {\n return neverthrow_ok<T,E>(value); \n}\n\n/**\n * Create an instance of {@link Err}.\n *\n * If you need to create an instance with a specific type (as you do whenever you\n * are not constructing immediately for a function return or as an argument to a\n * function), you can use a type parameter:\n *\n * ```ts\n * const notString = err<number, string>('something went wrong');\n * ```\n *\n * Note: passing nothing will produce a `Result<T, void>`, passing `undefined` will\n * produce a `Result<T, undefined>` which is compatible with `Result<T, void>`.\n *\n * ```ts\n * const normalResult = err<number, string>('oh no');\n * const explicitUndefined = err<number, undefined>(undefined);\n * const implicitVoid = err<number, void>();\n * ```\n *\n * In the context of an immediate function return, or an arrow function with a\n * single expression value, you do not have to specify the types, so this can be\n * quite convenient.\n *\n * ```ts\n * const arrowValidate = (data: SomeData): Result<number, string> =>\n * isValid(data) ? ok(42) : err('something went wrong');\n *\n * function fnValidate(data: someData): Result<number, string> {\n * return isValid(data) ? ok(42) : err('something went wrong');\n * }\n * ```\n *\n * @typeParam T - The type of the value contained in the `Result` for the success case\n * @typeParam E - The type of the error contained in the `Result` for the failure case\n * @param err - The value to wrap in a `Result.Err`.\n */\nexport function err<T = never, E extends string = string>(err: E): Err<T, E>\nexport function err<T = never, E = unknown>(err: E): Err<T, E>\nexport function err<T = never, _E extends void = void>(err: void): Err<T, void>\nexport function err<T = never, E = unknown>(err: E): Err<T, E> {\n return neverthrow_err<T,E>(err)\n}\n","import type { ItemOffsetMapping } from './ItemOffsetMapping';\n\n/**\n * Implementation of {@link ItemOffsetMapping} for use when all items have a fixed size\n */\nexport class FixedSizeItemOffsetMapping implements ItemOffsetMapping {\n /**\n * @param itemSize - Size to use for all items\n */\n constructor (itemSize: number) {\n this.#fixedItemSize = itemSize;\n }\n\n itemSize(_itemIndex: number): number {\n return this.#fixedItemSize;\n }\n\n itemOffset(itemIndex: number): number {\n return itemIndex * this.#fixedItemSize;\n }\n\n offsetToItem(offset: number): [itemIndex: number, startOffset: number] {\n const itemIndex = Math.floor(offset / this.#fixedItemSize);\n const startOffset = itemIndex * this.#fixedItemSize;\n\n return [itemIndex, startOffset];\n }\n\n #fixedItemSize: number;\n}\n\n","import type { ItemOffsetMapping } from './ItemOffsetMapping';\n\n/**\n * Implementation of {@link ItemOffsetMapping} for use when initial items have variable sizes.\n */\nexport class VariableSizeItemOffsetMapping implements ItemOffsetMapping {\n /**\n * @param defaultItemSize - Size to use for all other items\n * @param sizes - Array of sizes to use for the initial items, one size per item\n */\n constructor (defaultItemSize: number, sizes: number[]) {\n this.#defaultItemSize = defaultItemSize;\n this.#sizes = sizes;\n }\n\n itemSize(itemIndex: number): number {\n return (itemIndex < this.#sizes.length) ? this.#sizes[itemIndex]! : this.#defaultItemSize;\n }\n\n itemOffset(itemIndex: number): number {\n let offset = 0;\n let length = this.#sizes.length;\n if (itemIndex > length) {\n const numDefaultSize = itemIndex - length;\n offset = numDefaultSize * this.#defaultItemSize;\n } else {\n length = itemIndex;\n }\n \n for (let i = 0; i < length; i ++)\n {\n offset += this.#sizes[i]!;\n }\n\n return offset;\n }\n\n offsetToItem(offset: number): [itemIndex: number, startOffset: number] {\n let startOffset = 0;\n for (const [i,size] of this.#sizes.entries()) {\n if (startOffset + size > offset) {\n return [i, startOffset];\n }\n startOffset += size;\n }\n\n const itemIndex = Math.floor((offset - startOffset) / this.#defaultItemSize);\n startOffset += itemIndex * this.#defaultItemSize;\n\n const length = this.#sizes.length;\n return [itemIndex+length, startOffset];\n }\n\n #defaultItemSize: number;\n #sizes: number[];\n}\n","import type { ItemOffsetMapping } from \"./ItemOffsetMapping\";\nimport { FixedSizeItemOffsetMapping } from \"./FixedSizeItemOffsetMapping\";\nimport { Result, err, ok } from \"./Result\";\n\n/** Possible spreadsheet error values\n * \n * Includes those that can be returned by `ERROR.TYPE` and additional values\n * introduced by more recent versions of Excel.\n*/\nexport type CellErrorValue = '#NULL!' | \n '#DIV/0!' |\n '#VALUE!' |\n '#REF!' |\n '#NAME?' |\n '#NUM!' |\n '#N/A' |\n '#GETTING_DATA' |\n '#SPILL!' |\n '#UNKNOWN!' |\n '#FIELD!' |\n '#CALC!';\n\n/** Type that represents an error value stored in a cell\n * \n * Defined as a discriminated union so that additional cell value types\n * can be added in future.\n */\nexport interface CellError {\n /** Discriminated union tag */\n type: 'CellError',\n\n /** {@link CellErrorValue | Error Value} */\n value: CellErrorValue;\n};\n\n/** Possible types for a cell value \n * \n * The native JavaScript types string, number and boolean represent the *Text*, *Number* and *Logical*\n * spreadsheet data types. {@link CellError} represents an *Error Value*.\n * \n * Undefined is used to represent a cell with no defined value. Null represents a cell that has been\n * explicitly marked as empty. \n*/\nexport type CellValue = string | number | boolean | null | undefined | CellError;\n\n/** Type that represents an error when validating data to be stored in a cell */\nexport interface ValidationError {\n /** Discriminated union tag */\n type: 'ValidationError',\n\n /** End user message describing the problem */\n message: string,\n};\n\n/** Convenience method that creates a {@link ValidationError} */\nexport function validationError(message: string): ValidationError {\n return { type: 'ValidationError', message };\n}\n\n/** Type that represents an error when storing data in a cell */\nexport interface StorageError {\n /** Discriminated union tag */\n type: 'StorageError',\n\n /** End user message describing the problem */\n message: string,\n\n /** HTTP style status code\n * \n * Describes the type of problem encountered. Expected to be a 4XX or 5XX code.\n */\n statusCode?: number | undefined,\n};\n\n/** Convenience method that creates a {@link StorageError} */\nexport function storageError(message: string, statusCode?: number): StorageError {\n return { type: 'StorageError', message, statusCode };\n}\n\n/** Types of error that can be returned by {@link SpreadsheetData} methods */\nexport type SpreadsheetDataError = ValidationError | StorageError;\n\n/**\n * Interface used to access the data in a spreadsheet\n * \n * The data exposed through the interface may change over time outside of any changes made through the interface. The caller\n * can use the {@link subscribe} method to be notified when the data changes. When reading data, the caller must first request\n * a snapshot using {@link getSnapshot}. All values returned by gettors are relative to a specified snapshot. The values will be\n * consistent with each other as long as the same snapshot is used.\n * \n * @typeParam Snapshot - Type of snapshot. Implementations are free to use whatever type makes sense for them.\n */\nexport interface SpreadsheetData<Snapshot> {\n /** Subscribe to data changes */\n subscribe(onDataChange: () => void): () => void,\n\n /** Return a snapshot to use when accessing values at a consistent point in time */\n getSnapshot(): Snapshot,\n\n /** Number of rows in the spreadsheet */\n getRowCount(snapshot: Snapshot): number,\n\n /** {@link ItemOffsetMapping} which describes sizes and offsets to start of rows */\n getRowItemOffsetMapping(snapshot: Snapshot): ItemOffsetMapping,\n\n /** Number of columns in the spreadsheet */\n getColumnCount(snapshot: Snapshot): number,\n\n /** {@link ItemOffsetMapping} which describes sizes and offsets to start of columns */\n getColumnItemOffsetMapping(snapshot: Snapshot): ItemOffsetMapping,\n\n /** Value of specified cell using 0-based row and column indexes */\n getCellValue(snapshot: Snapshot, row: number, column: number): CellValue;\n\n /** Format of specified cell using 0-based row and column indexes */\n getCellFormat(snapshot: Snapshot, row: number, column: number): string | undefined;\n\n /** Set value and format of specified cell\n * \n * @returns `Ok` if the change was successfully applied\n */\n setCellValueAndFormat(row: number, column: number, value: CellValue, format: string | undefined): Result<void,SpreadsheetDataError>\n\n /** Check whether value and format are valid to set for specified cell\n * \n * @returns `Ok` if the value and format are valid\n */\n isValidCellValueAndFormat(row: number, column: number, value: CellValue, format: string | undefined): Result<void,ValidationError>\n}\n\nconst rowItemOffsetMapping = new FixedSizeItemOffsetMapping(30);\nconst columnItemOffsetMapping = new FixedSizeItemOffsetMapping(100);\n\nexport class EmptySpreadsheetData implements SpreadsheetData<number> {\n subscribe(_onDataChange: () => void) { return () => {}; }\n getSnapshot() { return 0; }\n \n getRowCount(_snapshot: number) { return 0; }\n getRowItemOffsetMapping(_snapshot: number): ItemOffsetMapping { return rowItemOffsetMapping; }\n getColumnCount(_snapshot: number) { return 0; }\n getColumnItemOffsetMapping(_snapshot: number): ItemOffsetMapping { return columnItemOffsetMapping; }\n getCellValue(_snapshot: number, _row: number, _column: number): CellValue { return null; }\n getCellFormat(_snapshot: number, _row: number, _column: number): string|undefined { return undefined; }\n setCellValueAndFormat(_row: number, _column: number, _value: CellValue, _format: string | undefined): Result<void,SpreadsheetDataError> \n { return err(storageError(\"Not implemented\", 501)); }\n isValidCellValueAndFormat(_row: number, _column: number, _value: CellValue, _format: string | undefined): Result<void,ValidationError> \n { return ok(); }\n}\n\n","/** Classic Spreadsheet reference to Column (e.g \"A\") */\nexport type ColRef = string;\n\n/** Classic Spreadsheet reference to Cell (e.g. \"A1\"), Row (e.g. \"1\") or Column (e.g \"A\") */\nexport type RowColRef = string;\n\n/** Equivalent to {@link RowColRef} as coordinate pair. \"A1\" has coords [0,0], \"1\" is [0,undefined] and \"A\" is [undefined,0] */\nexport type RowColCoords = [row: number|undefined, col: number|undefined];\n\n/** Converts a {@link ColRef} to the 0-based index of the column */\nexport function colRefToIndex(col: ColRef): number {\n let n = 0;\n for (let i = 0; i < col.length; i ++) {\n n = col.charCodeAt(i) - 64 + n * 26;\n }\n return n-1;\n}\n\n/** Converts a 0-based column index to a {@link ColRef} */\nexport function indexToColRef(index: number): ColRef {\n let ret = \"\";\n index ++;\n while (index > 0) {\n index --;\n const remainder = index % 26;\n index = Math.floor(index / 26);\n ret = String.fromCharCode(65+remainder) + ret;\n }\n return ret;\n}\n\n/** Splits a RowColRef into a 0-based row index and a {@link ColRef} */\nexport function splitRowColRef(ref: RowColRef): [row: number|undefined, col: ColRef|undefined] {\n const re = /^([A-Z]*)(\\d*)$/;\n const found = ref.match(re);\n if (!found)\n return [undefined,undefined];\n\n const col = found[1];\n const row = found[2] ? parseInt(found[2]) : 0;\n return [(row>0) ? row-1 : undefined, col ? col : undefined];\n}\n\n/** Converts a {@link RowColRef} to {@link RowColCoords} */\nexport function rowColRefToCoords(ref: RowColRef): RowColCoords {\n const [row,col] = splitRowColRef(ref);\n return [row, col ? colRefToIndex(col) : undefined];\n}\n\n/** Converts {@link RowColCoords} to a {@link RowColRef} */\nexport function rowColCoordsToRef(row: number|undefined, col: number|undefined): RowColRef {\n if (row !== undefined) {\n if (col !== undefined) {\n return indexToColRef(col) + (row+1);\n } else {\n return (row+1).toString();\n }\n } else {\n if (col !== undefined) {\n return indexToColRef(col);\n } else {\n return \"\";\n }\n }\n}"],"names":["neverthrow_ok","neverthrow_err"],"mappings":";;AA0EM,SAAU,EAAE,CAAe,KAAQ,EAAA;AACvC,IAAA,OAAOA,IAAa,CAAM,KAAK,CAAC;AAClC;AA0CM,SAAU,GAAG,CAAyB,GAAM,EAAA;AAChD,IAAA,OAAOC,KAAc,CAAM,GAAG,CAAC;AACjC;;ACtHA;;AAEG;MACU,0BAA0B,CAAA;AACrC;;AAEG;AACH,IAAA,WAAA,CAAa,QAAgB,EAAA;AAC3B,QAAA,IAAI,CAAC,cAAc,GAAG,QAAQ;;AAGhC,IAAA,QAAQ,CAAC,UAAkB,EAAA;QACzB,OAAO,IAAI,CAAC,cAAc;;AAG5B,IAAA,UAAU,CAAC,SAAiB,EAAA;AAC1B,QAAA,OAAO,SAAS,GAAG,IAAI,CAAC,cAAc;;AAGxC,IAAA,YAAY,CAAC,MAAc,EAAA;AACzB,QAAA,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,cAAc,CAAC;AAC1D,QAAA,MAAM,WAAW,GAAG,SAAS,GAAG,IAAI,CAAC,cAAc;AAEnD,QAAA,OAAO,CAAC,SAAS,EAAE,WAAW,CAAC;;AAGjC,IAAA,cAAc;AACf;;AC3BD;;AAEG;MACU,6BAA6B,CAAA;AACxC;;;AAGG;IACH,WAAa,CAAA,eAAuB,EAAE,KAAe,EAAA;AACnD,QAAA,IAAI,CAAC,gBAAgB,GAAG,eAAe;AACvC,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;;AAGrB,IAAA,QAAQ,CAAC,SAAiB,EAAA;QACxB,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,SAAS,CAAE,GAAG,IAAI,CAAC,gBAAgB;;AAG3F,IAAA,UAAU,CAAC,SAAiB,EAAA;QAC1B,IAAI,MAAM,GAAG,CAAC;AACd,QAAA,IAAI,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM;AAC/B,QAAA,IAAI,SAAS,GAAG,MAAM,EAAE;AACtB,YAAA,MAAM,cAAc,GAAG,SAAS,GAAG,MAAM;AACzC,YAAA,MAAM,GAAG,cAAc,GAAG,IAAI,CAAC,gBAAgB;;aAC1C;YACL,MAAM,GAAG,SAAS;;AAGpB,QAAA,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,EAAG,EAChC;AACE,YAAA,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,CAAE;;AAG3B,QAAA,OAAO,MAAM;;AAGf,IAAA,YAAY,CAAC,MAAc,EAAA;QACzB,IAAI,WAAW,GAAG,CAAC;AACnB,QAAA,KAAK,MAAM,CAAC,CAAC,EAAC,IAAI,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,EAAE;AAC5C,YAAA,IAAI,WAAW,GAAG,IAAI,GAAG,MAAM,EAAE;AAC/B,gBAAA,OAAO,CAAC,CAAC,EAAE,WAAW,CAAC;;YAEzB,WAAW,IAAI,IAAI;;AAGrB,QAAA,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,GAAG,WAAW,IAAI,IAAI,CAAC,gBAAgB,CAAC;AAC5E,QAAA,WAAW,IAAI,SAAS,GAAG,IAAI,CAAC,gBAAgB;AAEhD,QAAA,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM;AACjC,QAAA,OAAO,CAAC,SAAS,GAAC,MAAM,EAAE,WAAW,CAAC;;AAGxC,IAAA,gBAAgB;AAChB,IAAA,MAAM;AACP;;ACDD;AACM,SAAU,eAAe,CAAC,OAAe,EAAA;AAC7C,IAAA,OAAO,EAAE,IAAI,EAAE,iBAAiB,EAAE,OAAO,EAAE;AAC7C;AAiBA;AACgB,SAAA,YAAY,CAAC,OAAe,EAAE,UAAmB,EAAA;IAC/D,OAAO,EAAE,IAAI,EAAE,cAAc,EAAE,OAAO,EAAE,UAAU,EAAE;AACtD;AAqDA,MAAM,oBAAoB,GAAG,IAAI,0BAA0B,CAAC,EAAE,CAAC;AAC/D,MAAM,uBAAuB,GAAG,IAAI,0BAA0B,CAAC,GAAG,CAAC;MAEtD,oBAAoB,CAAA;IAC/B,SAAS,CAAC,aAAyB,EAAA,EAAI,OAAO,MAAO,GAAC,CAAC;AACvD,IAAA,WAAW,GAAK,EAAA,OAAO,CAAC,CAAC;AAEzB,IAAA,WAAW,CAAC,SAAiB,EAAA,EAAI,OAAO,CAAC,CAAC;AAC1C,IAAA,uBAAuB,CAAC,SAAiB,EAAA,EAAuB,OAAO,oBAAoB,CAAC;AAC5F,IAAA,cAAc,CAAC,SAAiB,EAAA,EAAI,OAAO,CAAC,CAAC;AAC7C,IAAA,0BAA0B,CAAC,SAAiB,EAAA,EAAuB,OAAO,uBAAuB,CAAC;IAClG,YAAY,CAAC,SAAiB,EAAE,IAAY,EAAE,OAAe,EAAA,EAAe,OAAO,IAAI,CAAC;IACxF,aAAa,CAAC,SAAiB,EAAE,IAAY,EAAE,OAAe,EAAA,EAAsB,OAAO,SAAS,CAAC;IACrG,qBAAqB,CAAC,IAAY,EAAE,OAAe,EAAE,MAAiB,EAAE,OAA2B,EACjG,EAAA,OAAO,GAAG,CAAC,YAAY,CAAC,iBAAiB,EAAE,GAAG,CAAC,CAAC,CAAC;AACnD,IAAA,yBAAyB,CAAC,IAAY,EAAE,OAAe,EAAE,MAAiB,EAAE,OAA2B,EAAA,EACrG,OAAO,EAAE,EAAE,CAAC;AACf;;AC1ID;AACM,SAAU,aAAa,CAAC,GAAW,EAAA;IACvC,IAAI,CAAC,GAAG,CAAC;AACT,IAAA,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,EAAG,EAAE;AACpC,QAAA,CAAC,GAAG,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE;;IAErC,OAAO,CAAC,GAAC,CAAC;AACZ;AAEA;AACM,SAAU,aAAa,CAAC,KAAa,EAAA;IACzC,IAAI,GAAG,GAAG,EAAE;AACZ,IAAA,KAAK,EAAG;AACR,IAAA,OAAO,KAAK,GAAG,CAAC,EAAE;AAChB,QAAA,KAAK,EAAG;AACR,QAAA,MAAM,SAAS,GAAG,KAAK,GAAG,EAAE;QAC5B,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,EAAE,CAAC;QAC9B,GAAG,GAAG,MAAM,CAAC,YAAY,CAAC,EAAE,GAAC,SAAS,CAAC,GAAG,GAAG;;AAE/C,IAAA,OAAO,GAAG;AACZ;AAEA;AACM,SAAU,cAAc,CAAC,GAAc,EAAA;IAC3C,MAAM,EAAE,GAAG,iBAAiB;IAC5B,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;AAC3B,IAAA,IAAI,CAAC,KAAK;AACR,QAAA,OAAO,CAAC,SAAS,EAAC,SAAS,CAAC;AAE9B,IAAA,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC;IACpB,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;IAC7C,OAAO,CAAC,CAAC,GAAG,GAAC,CAAC,IAAI,GAAG,GAAC,CAAC,GAAG,SAAS,EAAE,GAAG,GAAG,GAAG,GAAG,SAAS,CAAC;AAC7D;AAEA;AACM,SAAU,iBAAiB,CAAC,GAAc,EAAA;IAC9C,MAAM,CAAC,GAAG,EAAC,GAAG,CAAC,GAAG,cAAc,CAAC,GAAG,CAAC;AACrC,IAAA,OAAO,CAAC,GAAG,EAAE,GAAG,GAAG,aAAa,CAAC,GAAG,CAAC,GAAG,SAAS,CAAC;AACpD;AAEA;AACgB,SAAA,iBAAiB,CAAC,GAAqB,EAAE,GAAqB,EAAA;AAC5E,IAAA,IAAI,GAAG,KAAK,SAAS,EAAE;AACrB,QAAA,IAAI,GAAG,KAAK,SAAS,EAAE;YACrB,OAAO,aAAa,CAAC,GAAG,CAAC,IAAI,GAAG,GAAC,CAAC,CAAC;;aAC9B;YACL,OAAO,CAAC,GAAG,GAAC,CAAC,EAAE,QAAQ,EAAE;;;SAEtB;AACL,QAAA,IAAI,GAAG,KAAK,SAAS,EAAE;AACrB,YAAA,OAAO,aAAa,CAAC,GAAG,CAAC;;aACpB;AACL,YAAA,OAAO,EAAE;;;AAGf;;;;"}
1
+ {"version":3,"file":"index.js","sources":["../src/Result.ts","../src/ResultAsync.ts","../src/Error.ts","../src/EventLog.ts","../src/FixedSizeItemOffsetMapping.ts","../src/VariableSizeItemOffsetMapping.ts","../src/SpreadsheetData.ts","../src/RowColRef.ts"],"sourcesContent":["import type { Ok as neverthrow_Ok, Err as neverthrow_Err } from \"neverthrow\";\nimport { err as neverthrow_err, ok as neverthrow_ok } from \"neverthrow\";\n\n/**\n * An `Ok` instance is the *successful* variant of the {@link Result} type, \n * representing a successful outcome from an operation which may fail.\n * \n * Implemented using [`neverthrow`](https://github.com/supermacro/neverthrow)\n * \n * @typeParam T - The type of the value contained in the `Result` for the success case\n * @typeParam E - The type of the error contained in the `Result` for the failure case\n */\nexport interface Ok<T,E> extends neverthrow_Ok<T,E> {}\n\n/**\n * An `Err` instance is the failure variant of the {@link Result} type, \n * representing a failure outcome from an operation which may fail.\n * \n * Implemented using [`neverthrow`](https://github.com/supermacro/neverthrow)\n * \n * @typeParam T - The type of the value contained in the `Result` for the success case\n * @typeParam E - The type of the error contained in the `Result` for the failure case\n */\nexport interface Err<T,E> extends neverthrow_Err<T,E> {}\n\n/**\n * A `Result` represents success ({@link Ok}) or failure ({@link Err}).\n * \n * Compatible with [`neverthrow`](https://github.com/supermacro/neverthrow)\n * \n * @typeParam T - The type of the value contained in the `Result` for the success case\n * @typeParam E - The type of the error contained in the `Result` for the failure case\n */\nexport type Result<T,E> = Ok<T,E> | Err<T,E>;\n\n/**\n * Create an instance of {@link Ok}.\n *\n * If you need to create an instance with a specific type (as you do whenever you\n * are not constructing immediately for a function return or as an argument to a\n * function), you can use a type parameter:\n *\n * ```ts\n * const yayNumber = ok<number, string>(12);\n * ```\n *\n * Note: passing nothing will produce a `Result<void, E>`, passing `undefined` will\n * produce a `Result<undefined, E>` which is compatible with `Result<void, E>`.\n *\n * ```ts\n * const normalResult = ok<number, string>(42);\n * const explicitUndefined = ok<undefined, string>(undefined);\n * const implicitVoid = ok<void, string>();\n * ```\n *\n * In the context of an immediate function return, or an arrow function with a\n * single expression value, you do not have to specify the types, so this can be\n * quite convenient.\n *\n * ```ts\n * const arrowValidate = (data: SomeData): Result<void, string> =>\n * isValid(data) ? ok() : err('something was wrong!');\n *\n * function fnValidate(data: someData): Result<void, string> {\n * return isValid(data) ? ok() : err('something was wrong');\n * }\n * ```\n *\n * @typeParam T - The type of the value contained in the `Result` for the success case\n * @typeParam E - The type of the error contained in the `Result` for the failure case\n * @param value - The value to wrap in a `Result.Ok`.\n */\nexport function ok<T, E = never>(value: T): Ok<T, E>\nexport function ok<_T extends void = void, E = never>(value: void): Ok<void, E>\nexport function ok<T, E = never>(value: T): Ok<T, E> {\n return neverthrow_ok<T,E>(value); \n}\n\n/**\n * Create an instance of {@link Err}.\n *\n * If you need to create an instance with a specific type (as you do whenever you\n * are not constructing immediately for a function return or as an argument to a\n * function), you can use a type parameter:\n *\n * ```ts\n * const notString = err<number, string>('something went wrong');\n * ```\n *\n * Note: passing nothing will produce a `Result<T, void>`, passing `undefined` will\n * produce a `Result<T, undefined>` which is compatible with `Result<T, void>`.\n *\n * ```ts\n * const normalResult = err<number, string>('oh no');\n * const explicitUndefined = err<number, undefined>(undefined);\n * const implicitVoid = err<number, void>();\n * ```\n *\n * In the context of an immediate function return, or an arrow function with a\n * single expression value, you do not have to specify the types, so this can be\n * quite convenient.\n *\n * ```ts\n * const arrowValidate = (data: SomeData): Result<number, string> =>\n * isValid(data) ? ok(42) : err('something went wrong');\n *\n * function fnValidate(data: someData): Result<number, string> {\n * return isValid(data) ? ok(42) : err('something went wrong');\n * }\n * ```\n *\n * @typeParam T - The type of the value contained in the `Result` for the success case\n * @typeParam E - The type of the error contained in the `Result` for the failure case\n * @param err - The value to wrap in a `Result.Err`.\n */\nexport function err<T = never, E extends string = string>(err: E): Err<T, E>\nexport function err<T = never, E = unknown>(err: E): Err<T, E>\nexport function err<T = never, _E extends void = void>(err: void): Err<T, void>\nexport function err<T = never, E = unknown>(err: E): Err<T, E> {\n return neverthrow_err<T,E>(err)\n}\n","import { errAsync as neverthrow_errAsync, okAsync as neverthrow_okAsync, ResultAsync as neverthrow_ResultAsync } from \"neverthrow\";\n\n// Needed for Intellisense links\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nimport { Result, Ok, Err } from \"./Result\"\n\n/**\n * `ResultAsync` allows you to work with asynchronous Results in a type safe way\n * \n * `ResultAsync<T,E>` is a wrapper around `Promise<Result<T,E>>` which provides the same methods for chaining different\n * `Result` and `ResultAsync` together as {@link Result}, while also chaining the asynchronous operations together using\n * `Promise.then`.\n * \n * `ResultAsync` is *thenable* (implements `PromiseLike<T>`) so can be used in most places that a `Promise` can, including with `await`.\n * \n * Compatible with [`neverthrow`](https://github.com/supermacro/neverthrow)\n * \n * @typeParam T - The type of the value contained in the `ResultAsync` for the success case\n * @typeParam E - The type of the error contained in the `ResultAsync` for the failure case\n */\nexport class ResultAsync<T,E> extends neverthrow_ResultAsync<T,E> {}\n\n/**\n * Create an instance of `ResultAsync` containing an {@link Ok} variant of {@link Result}\n *\n * Equivalent to `new ResultAsync(Promise.resolve(new Ok(value)))`\n *\n * @typeParam T - The type of the value contained in the `ResultAsync` for the success case\n * @typeParam E - The type of the error contained in the `ResultAsync` for the failure case\n * @param value - The value to wrap in a `Result.Ok`.\n */\nexport function okAsync<T, E = never>(value: T): ResultAsync<T, E>\nexport function okAsync<_T extends void = void, E = never>(value: void): ResultAsync<void, E>\nexport function okAsync<T, E = never>(value: T): ResultAsync<T, E> {\n return neverthrow_okAsync(value);\n}\n\n/**\n * Create an instance of `ResultAsync` containing an {@link Err} variant of {@link Result}\n *\n * Equivalent to `new ResultAsync(Promise.resolve(new Err(err)))`\n *\n * @typeParam T - The type of the value contained in the `Result` for the success case\n * @typeParam E - The type of the error contained in the `Result` for the failure case\n * @param err - The value to wrap in a `Result.Err`.\n */\nexport function errAsync<T = never, E = unknown>(err: E): ResultAsync<T, E>\nexport function errAsync<T = never, _E extends void = void>(err: void): ResultAsync<T, void>\nexport function errAsync<T = never, E = unknown>(err: E): ResultAsync<T, E> {\n return neverthrow_errAsync<T,E>(err)\n}\n","/** Common properties for Infinisheet errors */\nexport interface InfinisheetError {\n /** Discriminated union tag */\n type: string,\n\n /** End user message describing the problem */\n message: string,\n}\n\n/** \n * Attempt to access data that is outside the available range\n * \n */\nexport interface InfinisheetRangeError extends InfinisheetError {\n /** Discriminated union tag */\n type: 'InfinisheetRangeError',\n\n};\n\n/** Convenience method that creates an {@link InfinisheetRangeError} */\nexport function infinisheetRangeError(message: string): InfinisheetRangeError {\n return { type: 'InfinisheetRangeError', message };\n}\n\n/** Type that represents an error when validating data passed to an API */\nexport interface ValidationError extends InfinisheetError {\n /** Discriminated union tag */\n type: 'ValidationError'\n};\n\n/** Convenience method that creates a {@link ValidationError} */\nexport function validationError(message: string): ValidationError {\n return { type: 'ValidationError', message };\n}\n\n/** Type that represents an error when accessing data in persistent storage */\nexport interface StorageError extends InfinisheetError {\n /** Discriminated union tag */\n type: 'StorageError',\n\n /** HTTP style status code\n * \n * Describes the type of problem encountered. Expected to be a 4XX or 5XX code.\n */\n statusCode?: number | undefined,\n};\n\n/** Convenience method that creates a {@link StorageError} */\nexport function storageError(message: string, statusCode?: number): StorageError {\n return { type: 'StorageError', message, statusCode };\n}","import { ResultAsync } from \"./ResultAsync\";\nimport { StorageError, InfinisheetError, InfinisheetRangeError } from \"./Error\"\n\n/** Identifier for a blob of data in a blob store */\nexport type BlobId = string;\n\n/** Identifier for a workflow triggered writing to {@link LogMetadata.pending} */\nexport type WorkflowId = string;\n\n/** \n * Identifier for an entry in an {@link EventLog}.\n * \n * Incrementing integer.\n*/\nexport type SequenceId = bigint;\n\n/**\n * Metadata stored in an {@link EventLog} entry\n */\nexport interface LogMetadata {\n /** Stores a reference to a snapshot of the complete log up to and including this entry */\n snapshot?: BlobId | undefined;\n\n /** Stores a reference to an external history of the event log up to and including the previous entry */\n history?: BlobId | undefined;\n\n /** Indicates that a background workflow is pending */\n pending?: WorkflowId | undefined;\n}\n\n/** \n * Type that represents an entry in an {@link EventLog}\n * \n * Base interface that clients will typically implement multiple times.\n * Each concrete implementation will define its own data properties that\n * need to be serialized into the event log.\n * \n * Properties defined here are common metadata which require special handling\n * by any `EventLog` implementation.\n * \n * All data properties are immutable once an entry has been added to the log. Metadata\n * properties (apart from `type`) may change over time.\n */\nexport interface LogEntry extends LogMetadata {\n /** Used as a discriminated union tag by implementations */\n type: string;\n};\n\n/** \n * Type that represents a consistency conflict when adding a {@link LogEntry} to an {@link EventLog}\n * \n * Occurs when an attempt is made to add an entry with a sequence id that is not\n * the next available in the log.\n * \n * Typically happens when another client makes a change since you last read the log.\n * Sync with the additional log entries and then try again.\n */\nexport interface ConflictError extends InfinisheetError {\n /** Discriminated union tag */\n type: 'ConflictError',\n\n /** Next available sequence id */\n nextSequenceId: SequenceId;\n};\n\n/** Convenience method that creates a {@link ConflictError} */\nexport function conflictError(message: string, nextSequenceId: SequenceId): ConflictError {\n return { type: 'ConflictError', message, nextSequenceId };\n}\n\n/** Errors that can be returned by {@link EventLog} `addEntry` method */\nexport type AddEntryError = ConflictError | StorageError;\n\n/** Errors that can be returned by {@link EventLog} `query` method */\nexport type QueryError = InfinisheetRangeError | StorageError;\n\n/** Errors that can be returned by {@link EventLog} `truncate` method */\nexport type TruncateError = InfinisheetRangeError | StorageError;\n\n/** Errors that can be returned by {@link EventLog} `setMetadata` method */\nexport type MetadataError = InfinisheetRangeError | StorageError;\n\n/** A range of {@link LogEntry} values returned by querying an {@link EventLog} */\nexport interface QueryValue<T extends LogEntry> {\n /** Sequence id corresponding to the first entry in `entries`\n * \n * All other entries have consecutive ascending sequence ids\n */\n startSequenceId: SequenceId;\n\n /** \n * Sequence id after the final entry in `entries`\n * \n * If query was up to the `end` sequence id AND\n * `isComplete` is true, this is the next available\n * sequence id for `addEntry`. \n */\n endSequenceId: SequenceId;\n\n /** True if all the requested entries have been returned\n * \n * Queries may return fewer entries than requested. If \n * `isComplete` is `false`, repeat the query starting\n * from `nextSequenceId`.\n */\n isComplete: boolean;\n\n /** The {@link LogEntry} records returned by the query */\n entries: T[];\n}\n\n/** Abstract interface representing an event log\n * \n * \n */\nexport interface EventLog<T extends LogEntry> {\n /** \n * Add an entry to the log with the given sequence id\n * \n * The `sequenceId` must be the next available sequence id in the log. This is returned as `endSequenceId` when\n * making a query for the `last` entry in the log. Returns a {@link ConflictError} if not the next available id.\n * Any other problem with serializing the entry will return a {@link StorageError}.\n */\n addEntry(entry: T, sequenceId: SequenceId): ResultAsync<void,AddEntryError>;\n\n /**\n * Set some or all of a log entry's metadata fields\n *\n * Changes are atomic. Either all of the specified fields are updated or none are.\n */\n setMetadata(sequenceId: SequenceId, metaData: LogMetadata): ResultAsync<void,MetadataError>;\n\n /** Return a range of entries from `first` to `last` inclusive \n * \n * The event log may return fewer entries than requested. If so, repeat the query starting from `nextSequenceId`.\n * \n * @param start - `SequenceId` of first entry to return. \n * Use `'start'` to query from the first entry in the log. \n * Use `'snapshot'` to query from the most recent entry with a snapshot, or the first if no snapshot is defined.\n * \n * @param end - `SequenceId` one after the last entry to return.\n * Use `'end'` to query everything to the end of the log.\n */\n query(start: SequenceId | 'snapshot' | 'start', end: SequenceId | 'end'): ResultAsync<QueryValue<T>,QueryError>;\n\n /** All entries prior to `start` are removed from the log. */\n truncate(start: SequenceId): ResultAsync<void,TruncateError>\n}","import type { ItemOffsetMapping } from './ItemOffsetMapping';\n\n/**\n * Implementation of {@link ItemOffsetMapping} for use when all items have a fixed size\n */\nexport class FixedSizeItemOffsetMapping implements ItemOffsetMapping {\n /**\n * @param itemSize - Size to use for all items\n */\n constructor (itemSize: number) {\n this.fixedItemSize = itemSize;\n }\n\n itemSize(_itemIndex: number): number {\n return this.fixedItemSize;\n }\n\n itemOffset(itemIndex: number): number {\n return itemIndex * this.fixedItemSize;\n }\n\n offsetToItem(offset: number): [itemIndex: number, startOffset: number] {\n const itemIndex = Math.floor(offset / this.fixedItemSize);\n const startOffset = itemIndex * this.fixedItemSize;\n\n return [itemIndex, startOffset];\n }\n\n private fixedItemSize: number;\n}\n\n","import type { ItemOffsetMapping } from './ItemOffsetMapping';\n\n/**\n * Implementation of {@link ItemOffsetMapping} for use when initial items have variable sizes.\n */\nexport class VariableSizeItemOffsetMapping implements ItemOffsetMapping {\n /**\n * @param defaultItemSize - Size to use for all other items\n * @param sizes - Array of sizes to use for the initial items, one size per item\n */\n constructor (defaultItemSize: number, sizes: number[]) {\n this.defaultItemSize = defaultItemSize;\n this.sizes = sizes;\n }\n\n itemSize(itemIndex: number): number {\n return (itemIndex < this.sizes.length) ? this.sizes[itemIndex]! : this.defaultItemSize;\n }\n\n itemOffset(itemIndex: number): number {\n let offset = 0;\n let length = this.sizes.length;\n if (itemIndex > length) {\n const numDefaultSize = itemIndex - length;\n offset = numDefaultSize * this.defaultItemSize;\n } else {\n length = itemIndex;\n }\n \n for (let i = 0; i < length; i ++)\n {\n offset += this.sizes[i]!;\n }\n\n return offset;\n }\n\n offsetToItem(offset: number): [itemIndex: number, startOffset: number] {\n let startOffset = 0;\n for (const [i,size] of this.sizes.entries()) {\n if (startOffset + size > offset) {\n return [i, startOffset];\n }\n startOffset += size;\n }\n\n const itemIndex = Math.floor((offset - startOffset) / this.defaultItemSize);\n startOffset += itemIndex * this.defaultItemSize;\n\n const length = this.sizes.length;\n return [itemIndex+length, startOffset];\n }\n\n private defaultItemSize: number;\n private sizes: number[];\n}\n","import type { ItemOffsetMapping } from \"./ItemOffsetMapping\";\nimport { FixedSizeItemOffsetMapping } from \"./FixedSizeItemOffsetMapping\";\nimport { Result, ok } from \"./Result\";\nimport { ResultAsync, errAsync } from \"./ResultAsync\";\nimport { ValidationError, StorageError, storageError } from \"./Error\";\n\n/** Possible spreadsheet error values\n * \n * Includes those that can be returned by `ERROR.TYPE` and additional values\n * introduced by more recent versions of Excel.\n*/\nexport type CellErrorValue = '#NULL!' | \n '#DIV/0!' |\n '#VALUE!' |\n '#REF!' |\n '#NAME?' |\n '#NUM!' |\n '#N/A' |\n '#GETTING_DATA' |\n '#SPILL!' |\n '#UNKNOWN!' |\n '#FIELD!' |\n '#CALC!';\n\n/** Type that represents an error value stored in a cell\n * \n * Defined as a discriminated union so that additional cell value types\n * can be added in future.\n */\nexport interface CellError {\n /** Discriminated union tag */\n type: 'CellError',\n\n /** {@link CellErrorValue | Error Value} */\n value: CellErrorValue;\n};\n\n/** Possible types for a cell value \n * \n * The native JavaScript types string, number and boolean represent the *Text*, *Number* and *Logical*\n * spreadsheet data types. {@link CellError} represents an *Error Value*.\n * \n * Undefined is used to represent a cell with no defined value. Null represents a cell that has been\n * explicitly marked as empty. \n*/\nexport type CellValue = string | number | boolean | null | undefined | CellError\n\n/** Types of error that can be returned by {@link SpreadsheetData} methods */\nexport type SpreadsheetDataError = ValidationError | StorageError;\n\n/**\n * Interface used to access the data in a spreadsheet\n * \n * The data exposed through the interface may change over time outside of any changes made through the interface. The caller\n * can use the {@link subscribe} method to be notified when the data changes. When reading data, the caller must first request\n * a snapshot using {@link getSnapshot}. All values returned by gettors are relative to a specified snapshot. The values will be\n * consistent with each other as long as the same snapshot is used.\n * \n * @typeParam Snapshot - Type of snapshot. Implementations are free to use whatever type makes sense for them.\n */\nexport interface SpreadsheetData<Snapshot> {\n /** Subscribe to data changes */\n subscribe(onDataChange: () => void): () => void,\n\n /** Return a snapshot to use when accessing values at a consistent point in time */\n getSnapshot(): Snapshot,\n\n /** \n * Return load status at the time the snapshot was created \n * \n * On Success returns true if load has completed, false if still in progress\n * On Err returns most recent error reported by the storage system\n */\n getLoadStatus(snapshot: Snapshot): Result<boolean,StorageError>,\n\n /** Number of rows in the spreadsheet */\n getRowCount(snapshot: Snapshot): number,\n\n /** {@link ItemOffsetMapping} which describes sizes and offsets to start of rows */\n getRowItemOffsetMapping(snapshot: Snapshot): ItemOffsetMapping,\n\n /** Number of columns in the spreadsheet */\n getColumnCount(snapshot: Snapshot): number,\n\n /** {@link ItemOffsetMapping} which describes sizes and offsets to start of columns */\n getColumnItemOffsetMapping(snapshot: Snapshot): ItemOffsetMapping,\n\n /** Value of specified cell using 0-based row and column indexes */\n getCellValue(snapshot: Snapshot, row: number, column: number): CellValue;\n\n /** Format of specified cell using 0-based row and column indexes */\n getCellFormat(snapshot: Snapshot, row: number, column: number): string | undefined;\n\n /** Set value and format of specified cell\n * \n * @returns `Ok` if the change was successfully applied\n */\n setCellValueAndFormat(row: number, column: number, value: CellValue, format: string | undefined): ResultAsync<void,SpreadsheetDataError>\n\n /** Check whether value and format are valid to set for specified cell\n * \n * @returns `Ok` if the value and format are valid\n */\n isValidCellValueAndFormat(row: number, column: number, value: CellValue, format: string | undefined): Result<void,ValidationError>\n}\n\nconst rowItemOffsetMapping = new FixedSizeItemOffsetMapping(30);\nconst columnItemOffsetMapping = new FixedSizeItemOffsetMapping(100);\n\nexport class EmptySpreadsheetData implements SpreadsheetData<number> {\n subscribe(_onDataChange: () => void) { return () => {}; }\n getSnapshot() { return 0; }\n \n getLoadStatus(_snapshot: number): Result<boolean,StorageError> { return ok(true); }\n getRowCount(_snapshot: number) { return 0; }\n getRowItemOffsetMapping(_snapshot: number): ItemOffsetMapping { return rowItemOffsetMapping; }\n getColumnCount(_snapshot: number) { return 0; }\n getColumnItemOffsetMapping(_snapshot: number): ItemOffsetMapping { return columnItemOffsetMapping; }\n getCellValue(_snapshot: number, _row: number, _column: number): CellValue { return null; }\n getCellFormat(_snapshot: number, _row: number, _column: number): string|undefined { return undefined; }\n setCellValueAndFormat(_row: number, _column: number, _value: CellValue, _format: string | undefined): ResultAsync<void,SpreadsheetDataError> \n { return errAsync(storageError(\"Not implemented\", 501)); }\n isValidCellValueAndFormat(_row: number, _column: number, _value: CellValue, _format: string | undefined): Result<void,ValidationError> \n { return ok(); }\n}\n\n","/** Classic Spreadsheet reference to Column (e.g \"A\") */\nexport type ColRef = string;\n\n/** Classic Spreadsheet reference to Cell (e.g. \"A1\"), Row (e.g. \"1\") or Column (e.g \"A\") */\nexport type RowColRef = string;\n\n/** Equivalent to {@link RowColRef} as coordinate pair. \"A1\" has coords [0,0], \"1\" is [0,undefined] and \"A\" is [undefined,0] */\nexport type RowColCoords = [row: number|undefined, col: number|undefined];\n\n/** Converts a {@link ColRef} to the 0-based index of the column */\nexport function colRefToIndex(col: ColRef): number {\n let n = 0;\n for (let i = 0; i < col.length; i ++) {\n n = col.charCodeAt(i) - 64 + n * 26;\n }\n return n-1;\n}\n\n/** Converts a 0-based column index to a {@link ColRef} */\nexport function indexToColRef(index: number): ColRef {\n let ret = \"\";\n index ++;\n while (index > 0) {\n index --;\n const remainder = index % 26;\n index = Math.floor(index / 26);\n ret = String.fromCharCode(65+remainder) + ret;\n }\n return ret;\n}\n\n/** Splits a RowColRef into a 0-based row index and a {@link ColRef} */\nexport function splitRowColRef(ref: RowColRef): [row: number|undefined, col: ColRef|undefined] {\n const re = /^([A-Z]*)(\\d*)$/;\n const found = ref.match(re);\n if (!found)\n return [undefined,undefined];\n\n const col = found[1];\n const row = found[2] ? parseInt(found[2]) : 0;\n return [(row>0) ? row-1 : undefined, col ? col : undefined];\n}\n\n/** Converts a {@link RowColRef} to {@link RowColCoords} */\nexport function rowColRefToCoords(ref: RowColRef): RowColCoords {\n const [row,col] = splitRowColRef(ref);\n return [row, col ? colRefToIndex(col) : undefined];\n}\n\n/** Converts {@link RowColCoords} to a {@link RowColRef} */\nexport function rowColCoordsToRef(row: number|undefined, col: number|undefined): RowColRef {\n if (row !== undefined) {\n if (col !== undefined) {\n return indexToColRef(col) + (row+1);\n } else {\n return (row+1).toString();\n }\n } else {\n if (col !== undefined) {\n return indexToColRef(col);\n } else {\n return \"\";\n }\n }\n}"],"names":["neverthrow_ok","neverthrow_err","neverthrow_ResultAsync","neverthrow_okAsync","neverthrow_errAsync"],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@candidstartup/infinisheet-types",
3
3
  "private": false,
4
- "version": "0.10.0",
4
+ "version": "0.12.0",
5
5
  "description": "Common types for the InfiniSheet packages",
6
6
  "author": "Tim Wiegand <tim.wiegand@thecandidstartup.org>",
7
7
  "license": "BSD-3-Clause",
@@ -52,5 +52,5 @@
52
52
  "dependencies": {
53
53
  "neverthrow": "^8.2.0"
54
54
  },
55
- "gitHead": "948f593793c217bd5b49aea712d3d700702ca120"
55
+ "gitHead": "03b639807d367f0c167dc5b6653b3935412cbde8"
56
56
  }