Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Adds support for working the V2 records API using fancy records aka "items" aka records from the @flatfile/records package.
Instead of bringing in the records package as a dependency, I just copied over the
FlatfileRecordimplementation, and made some small changes to how "dirtiness" works to simplify creating new records.More context there:
FlatfileRecordhas a concept of dirty which means the record object has changes which need to be synced to the server with a write. For new records which you intend to create, they are dirty by definition since they don't exist on the server at all yet, so they need to be written. In the existing implementation, you would need to pass a special flag to the constructor (new FlatfileRecord(data, true)) so it would be marked as a new/dirty record.I simplified this so the absence of a
__kid parameter is used to signify a new record.Don't take it from me, here's what amp has to say:
Add FlatfileRecord-based v2 Records API with Rich Object Interface
Overview
This PR introduces a new v2 Records API that provides a rich object-oriented interface for working with Flatfile records through the
FlatfileRecordclass. This complements the existing raw JSONL API with a more developer-friendly approach that includes automatic type casting, validation message handling, and intelligent change tracking.Key Features
New API Methods
get()andgetStreaming(): Fetch records asFlatfileRecordobjects instead of raw JSONLwrite()andwriteStreaming(): WriteFlatfileRecordobjects with automatic changeset detectiongetRaw(),getRawStreaming(),writeRaw(),writeRawStreaming()Detailed Method Documentation
get(sheetId, options?, requestOptions?)Fetches records from a sheet and returns them as
FlatfileRecordobjects with rich manipulation capabilities.Parameters:
sheetId: Flatfile.SheetId- Target sheet identifieroptions?: GetRecordsRequestOptions- Query options (filters, pagination, etc.)requestOptions?: RequestOptions- HTTP request configurationReturns:
Promise<FlatfileRecord[]>Key Features:
Example:
getStreaming(sheetId, options?, requestOptions?)Streams records as
FlatfileRecordobjects for memory-efficient processing of large datasets.Parameters:
get()methodReturns:
AsyncGenerator<FlatfileRecord, void, unknown>Key Features:
Example:
write(records, options?, requestOptions?)Writes an array of
FlatfileRecordobjects to Flatfile with intelligent changeset detection.Parameters:
records: FlatfileRecord[]- Array of records to writeoptions?: WriteRecordsRequestOptions- Write configurationrequestOptions?: RequestOptions- HTTP request configurationReturns:
Promise<WriteRecordsResponse>Write Modes:
Changeset Mode (Default)
isDirty()returnstrue__k)__k)Truncate Mode
TEMP_*IDs)Changeset Logic Examples:
Error Handling:
Post-Write Behavior:
commit()called)writeStreaming(recordsStream, options?, requestOptions?)Streams
FlatfileRecordobjects directly to Flatfile using HTTP body streaming for memory-efficient writes.Parameters:
recordsStream: AsyncIterable<FlatfileRecord>- Async generator/iterator of recordsoptions?: WriteStreamingOptions- Write configurationrequestOptions?: RequestOptions- HTTP request configurationReturns:
Promise<WriteRecordsResponse>Key Features:
write()Example:
Advanced Streaming Pattern:
Method Comparison
get()getStreaming()write()writeStreaming()FlatfileRecord[]AsyncGeneratorWriteRecordsResponseWriteRecordsResponseFlatfileRecord Class Features
str(),num(),bool(),date()with automatic castingerr(),warn(),info()for managing field-level messageshas(),isEmpty(),flag(),unflag(),delete(), and moreImplementation Details
Browser Compatibility
The
FlatfileRecordclass has been adapted from an existing implementation to be fully browser-compatible:util,crypto.randomUUID)asString,asBool,asNumber,asDate)JsonlRecord Type Integration
Enhanced the
JsonlRecordinterface to support link metadata:This allows the
getLinks()method to filter by link type without complex union types.Smart Dirty State Management
Implemented sophisticated dirty state tracking that ensures semantic alignment between
isDirty()andchangeset():Original Issue
The initial implementation had a critical flaw where new records (without
__k) would always returntruefromisDirty(), even after being committed. This meant:Solution
Added a
_committedflag to track commit state:isDirty()returnstrueuntilcommit()is calledisDirty()returnsfalsefor clean records_committed = falseMethods that affect dirty state:
set()- field changeserr(),warn(),info()- validation messagesdelete()- record deletionsetDirty()- manual dirty markingChangeset Logic
The
changeset()method provides intelligent diff detection:__k): Returns all data fieldsManual Dirty Marking
Added
setDirty()method for edge cases:Useful when you suspect external modifications or need to force a full record write.
Usage Examples
Basic Usage
Streaming
Write Modes
Changeset Mode (Default)
Truncate Mode
Technical Implementation Details
Method Architecture
All four new methods are built on top of the existing raw JSONL methods, providing a rich wrapper layer:
Streaming Implementation
The streaming methods use modern web APIs with graceful fallbacks:
Error Handling Strategy
Each method implements comprehensive error handling:
Performance Optimizations
Memory Management
Network Efficiency
Data Processing
API Design Decisions
Why separate methods instead of options?
get()vsgetRaw()makes the return type obviousgetRaw()methods unchangedWhy smart changeset detection?
Why streaming methods?
Why auto-commit after write?
Why manual dirty marking (
setDirty())?Breaking Changes
None. This is purely additive - all existing APIs remain unchanged.
Testing
Files Changed
src/v2/records/FlatfileRecord.ts- Core record class implementationsrc/v2/records/index.ts- New v2 API methodssrc/v2/records/types.ts- Enhanced JsonlRecord interfacesrc/v2/records/utils.ts- Browser-compatible utilitiessrc/v2/index.ts- V2 namespace exportssrc/index.ts- Main export updatestests/bun/records.test.ts- Comprehensive test coverageexamples/v2-records-usage.ts- Usage examples and documentationMigration Path
Developers can adopt the new API incrementally:
getRaw()/writeRaw()methodsget()for read-only operationswrite()for change tracking benefitsThis provides a smooth transition path while unlocking powerful new capabilities for record manipulation.