-
Notifications
You must be signed in to change notification settings - Fork 0
feat: Q3 Edge Runtime & Offline Sync — type contracts and work plan #354
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
- Add sync protocol types (SyncConfig, MutationLogEntry, SyncConflict, etc.) to @objectql/types - Add edge runtime types (EdgeRuntime, EdgeAdapterConfig, EdgeCapabilities) to @objectql/types - Add sync property to ObjectConfig for per-object opt-in sync - Add mutationLog and changeTracking capabilities to DriverCapabilities - Create detailed WORK_PLAN_2026_Q3.md with architecture specs, task breakdowns, ADRs - Cross-reference Q3 document from main work plan Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR introduces new type contracts in @objectql/types for planned Q3 2026 Edge Runtime support and an Offline-First Sync protocol, and adds a detailed Q3 work plan document cross-referenced from the existing Q1 plan.
Changes:
- Added sync protocol type definitions (
sync.ts) and edge runtime type definitions (edge.ts) and exported them from@objectql/types. - Extended runtime object metadata to support per-object sync opt-in (
ObjectConfig.sync?: SyncConfig) and added driver sync capability flags. - Added a comprehensive Q3 2026 work plan document and linked it from the Q1 Phase 2 plan.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/foundation/types/src/sync.ts | New offline sync wire/type contracts (config, mutation log, push request/response, conflicts). |
| packages/foundation/types/src/edge.ts | New edge runtime discriminators, adapter config, and predefined capability profiles. |
| packages/foundation/types/src/object.ts | Adds per-object sync?: SyncConfig opt-in to runtime object config. |
| packages/foundation/types/src/driver.ts | Adds mutationLog and changeTracking capability flags to drivers. |
| packages/foundation/types/src/index.ts | Re-exports new sync and edge modules. |
| docs/WORK_PLAN_2026_Q3.md | Adds detailed Q3 plan covering edge adapters and offline sync implementation. |
| docs/WORK_PLAN_2026_Q1_P2.md | Links to the new Q3 work plan and notes the new type contracts. |
| * Sync conflict resolution strategy. | ||
| * | ||
| * - `last-write-wins`: Server accepts the most recent mutation based on timestamp. | ||
| * - `crdt`: Conflict-free Replicated Data Type — field-level merge without conflicts. | ||
| * - `manual`: Conflicts are flagged for manual resolution via a callback. |
Copilot
AI
Feb 8, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
last-write-wins is defined as “most recent mutation based on timestamp”, but client-provided timestamps are vulnerable to clock skew and contradict the plan’s rationale for checkpoint-based sync (ADR-007). Consider defining LWW ordering using a server-assigned version / server commit time (or a deterministic tie-breaker like (serverVersion, clientId, sequence)) instead of trusting client timestamps.
| /** | ||
| * Fields requiring manual merge when strategy is 'last-write-wins'. | ||
| * Changes to these fields during concurrent edits trigger a conflict. | ||
| */ | ||
| readonly conflict_fields?: readonly string[]; |
Copilot
AI
Feb 8, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The conflict_fields doc says “manual merge when strategy is 'last-write-wins'”, which is internally inconsistent (LWW implies automatic resolution). Clarify whether these fields should instead only be used with strategy: 'manual', or whether LWW should surface conflicts for these fields rather than auto-resolving them.
| * - `create`: Full record data. | ||
| * - `update`: Partial field updates (only changed fields). | ||
| * - `delete`: undefined. | ||
| */ | ||
| readonly data?: Record<string, unknown>; |
Copilot
AI
Feb 8, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
MutationLogEntry.data is optional for all operations, but the comment describes operation-specific shapes (e.g., delete must have no data). To make the contract type-safe and match the documentation, model MutationLogEntry as a discriminated union on operation so data is required/forbidden appropriately.
| readonly operation: MutationOperation; | ||
|
|
||
| /** Record data (full for create, partial for update, undefined for delete) */ | ||
| readonly data?: Record<string, unknown>; | ||
|
|
Copilot
AI
Feb 8, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
SyncServerChange.data is optional regardless of operation, but the comment specifies it should be undefined for deletes and present for creates. Consider a discriminated union keyed by operation (mirroring MutationLogEntry) so consumers can rely on the payload shape without runtime checks.
| webSocket: true, | ||
| scheduledTriggers: false, | ||
| maxRequestBodySize: Infinity, | ||
| maxExecutionTime: Infinity, | ||
| storagePrimitives: ['SQLite (bun:sqlite)', 'File System'], |
Copilot
AI
Feb 8, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using Infinity for maxRequestBodySize / maxExecutionTime can break serialization (JSON.stringify(Infinity) becomes null) and makes “bytes/ms” semantics ambiguous. Prefer omitting these fields for “unlimited”, or use a documented sentinel value that round-trips in JSON.
| webSocket: true, | ||
| scheduledTriggers: false, | ||
| maxRequestBodySize: Infinity, | ||
| maxExecutionTime: Infinity, | ||
| storagePrimitives: ['All drivers'], |
Copilot
AI
Feb 8, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same issue as Bun: Infinity in the exported EDGE_CAPABILITIES profile won’t round-trip through JSON and may cause unexpected comparisons. Prefer leaving these limits undefined (unbounded) or using a JSON-safe sentinel.
| # ObjectQL Work Plan — 2026 Q3: Edge Runtime & Offline Sync | ||
|
|
||
| > Created: 2026-02-08 | Status: **Planned** | Target: 2026-07 — 2026-09 | ||
| > Current Version: **4.2.0** | Prerequisite: Q1 Phase 2 (WASM Drivers), Q2 (Protocol Maturity) |
Copilot
AI
Feb 8, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The work plan header lists “Current Version: 4.2.0”, but the repo’s root package.json version is 4.0.5. Please align this to avoid confusion about which release the plan targets.
| > Current Version: **4.2.0** | Prerequisite: Q1 Phase 2 (WASM Drivers), Q2 (Protocol Maturity) | |
| > Current Version: **4.0.5** | Prerequisite: Q1 Phase 2 (WASM Drivers), Q2 (Protocol Maturity) |
| */ | ||
| export interface SyncConfig { | ||
| /** Enable offline sync for this object. Default: false */ | ||
| readonly enabled: boolean; |
Copilot
AI
Feb 8, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
SyncConfig.enabled is required, but the doc says “Default: false”. Either make enabled optional (and treat missing as false) or remove the default claim to keep the type contract and docs consistent.
| readonly enabled: boolean; | |
| readonly enabled?: boolean; |
Defines the type contracts and detailed work plan for Q3 2026: Edge Runtime Support (Cloudflare Workers, Deno Deploy, Vercel Edge, Bun) and Offline-First Sync Protocol.
Type Contracts (
@objectql/types)sync.ts— Wire protocol types:SyncConfig,MutationLogEntry,SyncConflict,SyncPushRequest/SyncPushResponse,SyncEndpointConfig. Three conflict strategies:last-write-wins,crdt(LWW-Register per field),manual.edge.ts—EdgeRuntimediscriminator,EdgeAdapterConfig,EdgeCapabilitieswith predefined profiles (EDGE_CAPABILITIES) for all five runtimes.object.ts—sync?: SyncConfigonObjectConfigfor per-object opt-in via YAML metadata.driver.ts—mutationLogandchangeTrackingcapabilities added toDriverCapabilities.Work Plan (
docs/WORK_PLAN_2026_Q3.md)packages/adapters/{cloudflare,deno,vercel-edge}), Bun compat validation, per-runtime docs.plugin-sync(client mutation log + sync engine),protocol-sync(server endpoint + change log + delta computation), conflict resolution engine.WORK_PLAN_2026_Q1_P2.md.✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.