Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Dec 11, 2025

The Proxy-based DbRecord system doesn't serialize through Comlink for web worker scenarios. Replaced with plain objects using xRec property for change tracking.

This is a breaking change release (v2.0.0) with complete removal of the deprecated DbRecord API.

Changes

Record Structure

  • Records are now plain objects with non-enumerable xRec property storing original database values
  • __tableName tracks table association (non-enumerable)
  • Fully serializable via JSON, structuredClone, and Comlink without transfer handlers

API Changes

  • Added db.save(record) - determines INSERT vs UPDATE by checking xRec.system_id
  • Added db.deleteRecord(record) - deletes record using primary key
  • Removed .save() and .delete() methods from records themselves
  • HLC timestamps now applied during db.save(), not on property mutation

Change Detection

  • _getChangedFields() compares current values against xRec
  • Only modified fields included in UPDATE statements
  • LWW columns automatically get __hlc timestamps when values change

Streaming & Queries

  • StreamingQuery<T> returns T[] instead of (T & DbRecord<T>)[]
  • All query methods return plain objects with xRec tracking

Deprecated Code Removal (v2.0.0)

  • Removed DbRecord class and entire Proxy-based implementation
  • Removed comlink-transfer module including all serialization helpers:
    • registerDbRecordTransferHandler()
    • serializeDbRecord(), deserializeDbRecord()
    • serializeDbRecords(), deserializeDbRecords()
    • isDbRecord(), isSerializableDbRecord()
  • Removed /src/records directory entirely
  • Updated package version from 1.16.0 to 2.0.0
  • Reduced bundle size by ~7KB

Example

// Query returns plain objects
const users = await db.query('users', { 
  where: 'age >= ?', 
  whereArgs: [21] 
});

// Modify and save
users[0].age = 32;
await db.save(users[0]); // Only updates changed fields

// xRec tracks original state
console.log(users[0].xRec.age); // 31 (original value)

// Works through Comlink automatically
const cloned = structuredClone(users); // Just works

Breaking Changes (v2.0.0)

Before (v1.x - REMOVED):

const user = db.createRecord('users');
user.name = 'Alice';
await user.save();
await user.delete();

// Comlink serialization helpers
registerDbRecordTransferHandler(transferHandlers);
const serialized = serializeDbRecord(user);

After (v2.0.0 - Current API):

const user = db.createRecord('users');
user.name = 'Alice';
await db.save(user);
await db.deleteRecord(user);

// No Comlink helpers needed - plain objects work automatically
const cloned = structuredClone(user); // Just works

Removed APIs

  • DbRecord class
  • record.save() and record.delete() methods on records
  • All Comlink transfer handlers and serialization helpers
  • Query return types changed from DbRecord<T>[] to T[] (plain objects with xRec)

Migration Guide

All code using the old DbRecord API must be updated to use database methods:

  • Replace record.save() with db.save(record)
  • Replace record.delete() with db.deleteRecord(record)
  • Remove any Comlink transfer handler registrations
  • Remove any manual serialization calls
Original prompt

This entire DbRecord design is giving me a headache with comlink. Can you redesign the way the developer interacts with the database and records? Probably best to just keep it simple with a copy of each column in a "xRec" property object for simple comparison of what has changed when we call db.save(rec), that way we can handle HLC timestamping and comparison correctly. we don't get the timestamp from when the property was set, but rather the timestamp from when the record was "saved", but that's fine I guess.

In reality then, we should have a simple stream for a query that returns pure objects and all the logic is contained in the database when calling save and the other functions. We still need the bulkLoad for when we load fresh data from the API, as it checks against HLC timestamps and doesn't overwrite fresher data from local vs server.

[Chronological Review: The conversation began with the user reporting an error related to the "opfs" not being available in a web worker when initializing the database. The user then expressed a desire not to preemptively dismiss a storage backend requested by developers. Following this, the user discussed issues with the serialization of WorkerDbRecord instances through Comlink, proposing a solution to avoid using queryRecords in the main thread and suggesting alternative hooks. The user then inquired about enabling DbRecord to work across Comlink. The conversation shifted towards redesigning the DbRecord interaction with the database, emphasizing simplicity and proper handling of HLC timestamps and comparisons. The user suggested a new approach to manage records and queries more effectively.]

[Intent Mapping:

  1. "i am getting an error stating that opfs is not available in this environment when i initialize the db in a web worker" - User seeks help with a specific error.
  2. "we should not premetively test and dismiss a storage backend requested by the developer" - User wants to ensure flexibility in backend storage options.
  3. "The issue is that queryRecords returns WorkerDbRecord instances which can't be serialized through Comlink." - User identifies a technical limitation and proposes a workaround.
  4. "Do we have a way to enable DbRecord to work across comlink?" - User is looking for a solution to a serialization issue.
  5. "This entire DbRecord design is giving me a headache with comlink." - User expresses frustration and requests a redesign for simplicity and better functionality.]

[Technical Inventory:

  • Technologies: Web Workers, Comlink, SQLite, HLC (Hybrid Logical Clock)
  • Concepts: Serialization of objects, database record management, hooks for data querying and manipulation.
  • Decisions: Avoiding the use of DbRecord instances in worker-based databases, proposing simpler hooks for data operations.]

[Code Archaeology:

  • File: hooks.ts
    • Lines 255 to 285: Discussion on disabling useDbRecords hook due to serialization issues.
    • Proposed changes to other DbRecord-related hooks to ensure compatibility with worker-based databases.
    • Suggested new hooks: useQuery, useInsert, useUpdate, useDelete for simpler data operations.]

[Progress Assessment:

  • Completed: Identification of issues with DbRecord serialization and proposed solutions for using simpler hooks.
  • Pending: Implementation of the new design for DbRecord interactions and further exploration of enabling DbRecord across Comlink.]

[Context Validation: All critical information for continuation is captured, including user frustrations, proposed solutions, and the need for a redesign.]

[Recent Commands Analysis:

  • Last Agent Commands: User requested to delegate to a cloud agent for further assistance.
  • Tool Results Summary: No specific tool results were provided in the recent commands.
  • Pre-Summary State: The agent was actively discussing the redesign of the DbRecord interaction with the database when the token budget was exceeded.
  • Operation Context: The user is seeking a more efficient and simpler way to manage database records and interactions, particularly in the context of using Comlink and web workers.]
1. Conversation Overview: - Primary Objectives: - "i am getting an error stating that opfs is not available in this environment when i initialize the db in a web worker" - User seeks help with a specific error. - "we should not premetively test and dismiss a storage backend requested by the developer" - User wants to ensure flexibility in backend storage options. - "This entire DbRecord design is giving me a headache with comlink." - User expresses frustration and requests a redesign for simplicity and better functionality. - Session Context: The conversation flowed from error reporting to discussing technical limitations and proposing a redesign for better database interaction. - User Intent Evolution: The user transitioned from seeking immediate help with an error to expressing broader concerns about the design and usability of the databas...

Created from VS Code via the GitHub Pull Request extension.


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Copilot AI and others added 2 commits December 11, 2025 14:27
Co-authored-by: graknol <1364029+graknol@users.noreply.github.com>
Co-authored-by: graknol <1364029+graknol@users.noreply.github.com>
Copilot AI changed the title [WIP] Redesign developer interaction with database records Replace Proxy-based DbRecord with plain objects for Comlink compatibility Dec 11, 2025
Copilot AI requested a review from graknol December 11, 2025 14:32
@graknol
Copy link
Owner

graknol commented Dec 11, 2025

@copilot remove all deprecated code. We only want current api in the package, also update the package version to 2.0.0

Co-authored-by: graknol <1364029+graknol@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Dec 11, 2025

@copilot remove all deprecated code. We only want current api in the package, also update the package version to 2.0.0

Done! Removed all deprecated code and updated version to 2.0.0 in commit e24566b.

Changes:

  • Removed DbRecord class and Proxy-based implementation
  • Removed comlink-transfer module and all serialization helpers
  • Removed entire /src/records directory
  • Updated package version from 1.16.0 to 2.0.0
  • Updated VERSION constant in index.ts to 2.0.0
  • All 70 tests passing
  • Bundle size reduced by ~7KB

Copilot AI changed the title Replace Proxy-based DbRecord with plain objects for Comlink compatibility Replace Proxy-based DbRecord with plain objects for Comlink compatibility (v2.0.0) Dec 11, 2025
@graknol graknol marked this pull request as ready for review December 11, 2025 14:42
@graknol graknol merged commit 80a367b into main Dec 11, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants