@revealui/sync 0.2.0 → 0.3.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.
Files changed (52) hide show
  1. package/README.md +82 -118
  2. package/dist/collab/agent-client-factory.d.ts.map +1 -1
  3. package/dist/collab/agent-client.d.ts +1 -0
  4. package/dist/collab/agent-client.d.ts.map +1 -1
  5. package/dist/collab/agent-client.js +16 -7
  6. package/dist/collab/index.d.ts +1 -0
  7. package/dist/collab/index.d.ts.map +1 -1
  8. package/dist/collab/index.js +1 -0
  9. package/dist/collab/protocol-constants.d.ts +5 -0
  10. package/dist/collab/protocol-constants.d.ts.map +1 -0
  11. package/dist/collab/protocol-constants.js +4 -0
  12. package/dist/collab/server-index.d.ts +1 -0
  13. package/dist/collab/server-index.d.ts.map +1 -1
  14. package/dist/collab/server-index.js +1 -0
  15. package/dist/collab/use-collab-document.d.ts +1 -1
  16. package/dist/collab/use-collab-document.d.ts.map +1 -1
  17. package/dist/collab/use-collab-document.js +7 -4
  18. package/dist/collab/use-collaboration.d.ts.map +1 -1
  19. package/dist/collab/yjs-websocket-provider.d.ts.map +1 -1
  20. package/dist/collab/yjs-websocket-provider.js +1 -2
  21. package/dist/fetch-with-timeout.d.ts +7 -0
  22. package/dist/fetch-with-timeout.d.ts.map +1 -0
  23. package/dist/fetch-with-timeout.js +27 -0
  24. package/dist/hooks/useAgentContexts.d.ts +29 -0
  25. package/dist/hooks/useAgentContexts.d.ts.map +1 -0
  26. package/dist/hooks/useAgentContexts.js +22 -0
  27. package/dist/hooks/useAgentMemory.d.ts +34 -0
  28. package/dist/hooks/useAgentMemory.d.ts.map +1 -0
  29. package/dist/hooks/useAgentMemory.js +37 -0
  30. package/dist/hooks/useConversations.d.ts +26 -6
  31. package/dist/hooks/useConversations.d.ts.map +1 -1
  32. package/dist/hooks/useConversations.js +13 -3
  33. package/dist/hooks/useCoordinationSessions.d.ts +35 -0
  34. package/dist/hooks/useCoordinationSessions.d.ts.map +1 -0
  35. package/dist/hooks/useCoordinationSessions.js +22 -0
  36. package/dist/hooks/useCoordinationWorkItems.d.ts +41 -0
  37. package/dist/hooks/useCoordinationWorkItems.d.ts.map +1 -0
  38. package/dist/hooks/useCoordinationWorkItems.js +22 -0
  39. package/dist/index.d.ts +22 -1
  40. package/dist/index.d.ts.map +1 -1
  41. package/dist/index.js +16 -1
  42. package/dist/mutations.d.ts +14 -0
  43. package/dist/mutations.d.ts.map +1 -0
  44. package/dist/mutations.js +53 -0
  45. package/dist/provider/index.d.ts +31 -3
  46. package/dist/provider/index.d.ts.map +1 -1
  47. package/dist/provider/index.js +27 -6
  48. package/dist/shape-utils.d.ts +11 -0
  49. package/dist/shape-utils.d.ts.map +1 -0
  50. package/dist/shape-utils.js +14 -0
  51. package/dist/test-setup.d.ts.map +1 -1
  52. package/package.json +8 -5
package/README.md CHANGED
@@ -1,19 +1,15 @@
1
1
  # @revealui/sync
2
2
 
3
- **Status:** 🟡 Active Development | ⚠️ NOT Production Ready
4
-
5
- See [Project Status](../../docs/PROJECT_STATUS.md) for framework readiness.
6
-
7
- ElectricSQL sync utilities for RevealUI - real-time data synchronization with local-first architecture.
3
+ ElectricSQL sync utilities for RevealUI real-time data synchronization with local-first architecture.
8
4
 
9
5
  ## Features
10
6
 
11
- - **ElectricSQL Integration**: Real-time sync with ElectricSQL
12
- - **React Hooks**: Use sync data in React components
7
+ - **ElectricSQL Integration**: Real-time sync via shape subscriptions
8
+ - **React Hooks**: Subscribe to synced data in React components
9
+ - **Mutations**: Create, update, and delete records via authenticated REST endpoints
13
10
  - **Type-safe**: Full TypeScript support with database types
14
- - **Local-first**: Works offline, syncs when online
15
11
  - **React Provider**: Easy setup with `ElectricProvider`
16
- - **Optimistic Updates**: Instant UI updates with server reconciliation
12
+ - **Yjs Collaboration**: CRDT-based real-time collaborative editing
17
13
 
18
14
  ## Installation
19
15
 
@@ -32,27 +28,29 @@ import { ElectricProvider } from '@revealui/sync/provider'
32
28
 
33
29
  export default function App() {
34
30
  return (
35
- <ElectricProvider>
31
+ <ElectricProvider proxyBaseUrl="https://cms.revealui.com">
36
32
  <YourComponents />
37
33
  </ElectricProvider>
38
34
  )
39
35
  }
40
36
  ```
41
37
 
42
- ### Use Synced Data
38
+ ### Read Synced Data
39
+
40
+ Hooks subscribe to ElectricSQL shapes via authenticated proxy routes. Data updates in real-time as the database changes.
43
41
 
44
42
  ```typescript
45
43
  import { useAgentContexts } from '@revealui/sync'
46
44
 
47
45
  function MyComponent() {
48
- const { data: contexts, isLoading } = useAgentContexts()
46
+ const { contexts, isLoading } = useAgentContexts()
49
47
 
50
48
  if (isLoading) return <div>Loading...</div>
51
49
 
52
50
  return (
53
51
  <ul>
54
52
  {contexts.map(context => (
55
- <li key={context.id}>{context.name}</li>
53
+ <li key={context.id}>{JSON.stringify(context.context)}</li>
56
54
  ))}
57
55
  </ul>
58
56
  )
@@ -61,18 +59,29 @@ function MyComponent() {
61
59
 
62
60
  ### Mutations
63
61
 
62
+ Each hook returns `create`, `update`, and `remove` functions. Mutations go through authenticated REST endpoints at `/api/sync/*`. ElectricSQL picks up the database changes and pushes updates to all subscribers automatically.
63
+
64
64
  ```typescript
65
65
  import { useAgentContexts } from '@revealui/sync'
66
66
 
67
67
  function CreateContext() {
68
- const { create } = useAgentContexts()
68
+ const { contexts, create, update, remove } = useAgentContexts()
69
69
 
70
70
  const handleCreate = async () => {
71
- await create({
72
- name: 'New Context',
73
- agent_id: 'agent-123',
74
- // ... other fields
71
+ const result = await create({
72
+ agent_id: 'assistant',
73
+ context: { theme: 'dark', language: 'en' },
74
+ priority: 0.8,
75
75
  })
76
+ if (!result.success) console.error(result.error)
77
+ }
78
+
79
+ const handleUpdate = async (id: string) => {
80
+ await update(id, { context: { theme: 'light' } })
81
+ }
82
+
83
+ const handleDelete = async (id: string) => {
84
+ await remove(id)
76
85
  }
77
86
 
78
87
  return <button onClick={handleCreate}>Create</button>
@@ -83,141 +92,96 @@ function CreateContext() {
83
92
 
84
93
  ### `useAgentContexts()`
85
94
 
86
- Sync agent contexts (task context, working memory, etc.)
95
+ Subscribe to agent contexts (task context, working memory).
87
96
 
88
97
  ```typescript
89
98
  const {
90
- data, // Agent contexts array
91
- isLoading, // Loading state
92
- error, // Error state
93
- create, // Create function
94
- update, // Update function
95
- remove // Delete function
99
+ contexts, // AgentContextRecord[]
100
+ isLoading, // boolean
101
+ error, // Error | null
102
+ create, // (data: CreateAgentContextInput) => Promise<MutationResult>
103
+ update, // (id: string, data: UpdateAgentContextInput) => Promise<MutationResult>
104
+ remove, // (id: string) => Promise<MutationResult>
96
105
  } = useAgentContexts()
97
106
  ```
98
107
 
99
- ### `useAgentMemory()`
108
+ ### `useAgentMemory(agentId)`
100
109
 
101
- Sync agent memory (episodic, semantic, working)
110
+ Subscribe to agent memory (episodic, semantic, working) filtered by agent ID.
102
111
 
103
112
  ```typescript
104
113
  const {
105
- data, // Memory entries array
106
- isLoading,
107
- error,
108
- create,
109
- update,
110
- remove
111
- } = useAgentMemory()
114
+ memories, // AgentMemoryRecord[]
115
+ isLoading, // boolean
116
+ error, // Error | null
117
+ create, // (data: CreateAgentMemoryInput) => Promise<MutationResult>
118
+ update, // (id: string, data: UpdateAgentMemoryInput) => Promise<MutationResult>
119
+ remove, // (id: string) => Promise<MutationResult>
120
+ } = useAgentMemory('assistant')
112
121
  ```
113
122
 
114
- ### `useConversations()`
123
+ ### `useConversations(userId)`
115
124
 
116
- Sync conversation history
125
+ Subscribe to conversation history. Server-side proxy enforces row-level filtering by session — the `userId` parameter is for API compatibility but filtering is handled server-side.
117
126
 
118
127
  ```typescript
119
128
  const {
120
- data, // Conversations array
121
- isLoading,
122
- error,
123
- create,
124
- update,
125
- remove
126
- } = useConversations()
129
+ conversations, // ConversationRecord[]
130
+ isLoading, // boolean
131
+ error, // Error | null
132
+ create, // (data: CreateConversationInput) => Promise<MutationResult>
133
+ update, // (id: string, data: UpdateConversationInput) => Promise<MutationResult>
134
+ remove, // (id: string) => Promise<MutationResult>
135
+ } = useConversations(userId)
127
136
  ```
128
137
 
129
138
  ## How It Works
130
139
 
131
- 1. **ElectricSQL Service**: Runs as a sync service between Postgres and clients
132
- 2. **Shape Subscriptions**: Subscribe to "shapes" of data (queries)
133
- 3. **Local Cache**: Data cached locally in browser
134
- 4. **Real-time Updates**: Changes propagate instantly to all connected clients
135
- 5. **Conflict Resolution**: CRDT-based conflict resolution for offline edits
140
+ 1. **Reads**: ElectricSQL shape subscriptions via authenticated CMS proxy (`/api/shapes/*`)
141
+ 2. **Writes**: REST mutations via CMS API (`/api/sync/*`) → Postgres → ElectricSQL replication
142
+ 3. **Real-time**: Database changes propagate to all shape subscribers automatically
143
+ 4. **Auth**: All endpoints require a valid session cookie
136
144
 
137
- ## Environment Variables
145
+ ## Collaboration (Yjs)
138
146
 
139
- ```env
140
- # ElectricSQL service URL
141
- NEXT_PUBLIC_ELECTRIC_SERVICE_URL=http://localhost:5133
147
+ The collab layer provides CRDT-based collaborative editing:
142
148
 
143
- # Optional: Server-side Electric URL (if different)
144
- ELECTRIC_SERVICE_URL=http://localhost:5133
149
+ ```typescript
150
+ import { useCollaboration } from '@revealui/sync'
151
+
152
+ function Editor() {
153
+ const { doc, synced, connectedUsers } = useCollaboration({
154
+ documentId: 'doc-uuid',
155
+ serverUrl: 'ws://localhost:4000',
156
+ })
157
+ // ...
158
+ }
145
159
  ```
146
160
 
147
- ## Development
161
+ Server-side agents can use `AgentCollabClient` from `@revealui/sync/collab/server`.
148
162
 
149
- ```bash
150
- # Build package
151
- pnpm --filter @revealui/sync build
163
+ ## Environment Variables
152
164
 
153
- # Watch mode
154
- pnpm --filter @revealui/sync dev
165
+ ```env
166
+ # ElectricSQL service URL (used by CMS proxy)
167
+ ELECTRIC_SERVICE_URL=http://localhost:5133
155
168
 
156
- # Run tests
157
- pnpm --filter @revealui/sync test
169
+ # Optional: Electric auth secret
170
+ ELECTRIC_SECRET=your-secret
158
171
 
159
- # Type check
160
- pnpm --filter @revealui/sync typecheck
172
+ # Client-side (stored in provider context)
173
+ NEXT_PUBLIC_ELECTRIC_SERVICE_URL=http://localhost:5133
161
174
  ```
162
175
 
163
- ## Testing
176
+ ## Development
164
177
 
165
178
  ```bash
166
- # Run all tests
167
- pnpm --filter @revealui/sync test
168
-
169
- # Watch mode
170
- pnpm --filter @revealui/sync test:watch
171
-
172
- # Coverage
173
- pnpm --filter @revealui/sync test:coverage
174
- ```
175
-
176
- ## Architecture
177
-
178
- ```
179
- ┌─────────────────┐
180
- │ React Component │
181
- │ (useAgentContexts) │
182
- └────────┬────────┘
183
-
184
-
185
- ┌─────────────────┐
186
- │ ElectricSQL │
187
- │ Shape Hook │
188
- └────────┬────────┘
189
-
190
-
191
- ┌─────────────────┐
192
- │ Electric Sync │
193
- │ Service │
194
- └────────┬────────┘
195
-
196
-
197
- ┌─────────────────┐
198
- │ PostgreSQL │
199
- │ Database │
200
- └─────────────────┘
179
+ pnpm --filter @revealui/sync build # Build
180
+ pnpm --filter @revealui/sync dev # Watch mode
181
+ pnpm --filter @revealui/sync test # Run tests
182
+ pnpm --filter @revealui/sync typecheck # Type check
201
183
  ```
202
184
 
203
- ## Limitations
204
-
205
- ⚠️ **CRITICAL**: ElectricSQL API endpoints need independent verification before production use.
206
-
207
- **Status:** ⚠️ NEEDS VERIFICATION
208
- - ElectricSQL integration exists but requires testing
209
- - API endpoints based on assumptions
210
- - No integration tests performed yet
211
- - Not recommended for production until verified
212
-
213
- See [Project Roadmap](../../docs/PROJECT_ROADMAP.md) and [Production Readiness](../../docs/PRODUCTION_READINESS.md) for details.
214
-
215
- ## Related Documentation
216
-
217
- - [ElectricSQL Documentation](https://electric-sql.com/docs) - Official ElectricSQL docs
218
- - [Architecture](../../docs/ARCHITECTURE.md) - System architecture overview
219
- - [Database Guide](../../docs/DATABASE.md) - Database setup
220
-
221
185
  ## License
222
186
 
223
187
  MIT
@@ -1 +1 @@
1
- {"version":3,"file":"agent-client-factory.d.ts","sourceRoot":"","sources":["../../src/collab/agent-client-factory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAsB,MAAM,mBAAmB,CAAA;AAIzE,MAAM,WAAW,wBAAwB;IACvC,SAAS,EAAE,MAAM,CAAA;IACjB,UAAU,EAAE,MAAM,CAAA;IAClB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,eAAe,CAAC,EAAE,MAAM,CAAA;CACzB;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,wBAAwB,GAAG,iBAAiB,CAgBtF;AAED,wBAAsB,2BAA2B,CAC/C,OAAO,EAAE,wBAAwB,GAAG;IAAE,aAAa,CAAC,EAAE,MAAM,CAAA;CAAE,GAC7D,OAAO,CAAC,iBAAiB,CAAC,CAK5B"}
1
+ {"version":3,"file":"agent-client-factory.d.ts","sourceRoot":"","sources":["../../src/collab/agent-client-factory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAsB,MAAM,mBAAmB,CAAC;AAI1E,MAAM,WAAW,wBAAwB;IACvC,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,wBAAwB,GAAG,iBAAiB,CAgBtF;AAED,wBAAsB,2BAA2B,CAC/C,OAAO,EAAE,wBAAwB,GAAG;IAAE,aAAa,CAAC,EAAE,MAAM,CAAA;CAAE,GAC7D,OAAO,CAAC,iBAAiB,CAAC,CAK5B"}
@@ -31,6 +31,7 @@ export declare class AgentCollabClient extends Observable<string> {
31
31
  private updateHandler;
32
32
  private awarenessUpdateHandler;
33
33
  private destroyed;
34
+ private pendingSyncAbort;
34
35
  constructor(options: AgentCollabClientOptions);
35
36
  connect(): void;
36
37
  disconnect(): void;
@@ -1 +1 @@
1
- {"version":3,"file":"agent-client.d.ts","sourceRoot":"","sources":["../../src/collab/agent-client.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAE5C,OAAO,KAAK,iBAAiB,MAAM,uBAAuB,CAAA;AAE1D,OAAO,KAAK,CAAC,MAAM,KAAK,CAAA;AAQxB,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,OAAO,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;CACd;AAED,MAAM,WAAW,wBAAwB;IACvC,SAAS,EAAE,MAAM,CAAA;IACjB,UAAU,EAAE,MAAM,CAAA;IAClB,QAAQ,EAAE,aAAa,CAAA;IACvB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,eAAe,CAAC,EAAE,MAAM,CAAA;CACzB;AAED,qBAAa,iBAAkB,SAAQ,UAAU,CAAC,MAAM,CAAC;IACvD,QAAQ,CAAC,GAAG,EAAE,CAAC,CAAC,GAAG,CAAA;IACnB,QAAQ,CAAC,SAAS,EAAE,iBAAiB,CAAC,SAAS,CAAA;IAC/C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAQ;IAClC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAQ;IACnC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAe;IACxC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAQ;IACnC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAQ;IAExC,OAAO,CAAC,EAAE,CAAyB;IACnC,OAAO,CAAC,MAAM,CAAQ;IACtB,OAAO,CAAC,iBAAiB,CAAI;IAC7B,OAAO,CAAC,cAAc,CAA6C;IACnE,OAAO,CAAC,aAAa,CAA+D;IACpF,OAAO,CAAC,sBAAsB,CAGrB;IACT,OAAO,CAAC,SAAS,CAAQ;gBAEb,OAAO,EAAE,wBAAwB;IA0B7C,OAAO,IAAI,IAAI;IAcf,UAAU,IAAI,IAAI;IAkBlB,WAAW,IAAI,CAAC,CAAC,GAAG;IAIpB,OAAO,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,CAAC,CAAC,IAAI;IAI9B,cAAc,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM;IAMrC,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI;IAI/D,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI;IAI9D,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI;IAQhD,QAAQ,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,UAAU,KAAK,IAAI,GAAG,MAAM,IAAI;IAU5D,iBAAiB,IAAI,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAUzD,WAAW,CAAC,SAAS,SAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAmB5C,OAAO,IAAI,IAAI;IASf,OAAO,CAAC,iBAAiB;IAazB,OAAO,CAAC,UAAU;IAoClB,OAAO,CAAC,aAAa;IA+BrB,OAAO,CAAC,WAAW;IAenB,OAAO,CAAC,WAAW;IAKnB,OAAO,CAAC,iBAAiB;IAezB,OAAO,CAAC,eAAe;CAOxB"}
1
+ {"version":3,"file":"agent-client.d.ts","sourceRoot":"","sources":["../../src/collab/agent-client.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAE7C,OAAO,KAAK,iBAAiB,MAAM,uBAAuB,CAAC;AAE3D,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AAOzB,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,OAAO,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,wBAAwB;IACvC,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,aAAa,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,qBAAa,iBAAkB,SAAQ,UAAU,CAAC,MAAM,CAAC;IACvD,QAAQ,CAAC,GAAG,EAAE,CAAC,CAAC,GAAG,CAAC;IACpB,QAAQ,CAAC,SAAS,EAAE,iBAAiB,CAAC,SAAS,CAAC;IAChD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAgB;IACzC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAU;IACxC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAS;IAEzC,OAAO,CAAC,EAAE,CAA0B;IACpC,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,iBAAiB,CAAK;IAC9B,OAAO,CAAC,cAAc,CAA8C;IACpE,OAAO,CAAC,aAAa,CAAgE;IACrF,OAAO,CAAC,sBAAsB,CAGpB;IACV,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,gBAAgB,CAA6B;gBAEzC,OAAO,EAAE,wBAAwB;IA0B7C,OAAO,IAAI,IAAI;IAcf,UAAU,IAAI,IAAI;IAkBlB,WAAW,IAAI,CAAC,CAAC,GAAG;IAIpB,OAAO,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,CAAC,CAAC,IAAI;IAI9B,cAAc,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM;IAIrC,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI;IAI/D,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI;IAI9D,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI;IAQhD,QAAQ,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,UAAU,KAAK,IAAI,GAAG,MAAM,IAAI;IAU5D,iBAAiB,IAAI,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAUzD,WAAW,CAAC,SAAS,SAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IA+B5C,OAAO,IAAI,IAAI;IAUf,OAAO,CAAC,iBAAiB;IAazB,OAAO,CAAC,UAAU;IAoClB,OAAO,CAAC,aAAa;IAoCrB,OAAO,CAAC,WAAW;IAenB,OAAO,CAAC,WAAW;IAKnB,OAAO,CAAC,iBAAiB;IAezB,OAAO,CAAC,eAAe;CAOxB"}
@@ -5,8 +5,7 @@ import WebSocket from 'ws';
5
5
  import * as awarenessProtocol from 'y-protocols/awareness';
6
6
  import * as syncProtocol from 'y-protocols/sync';
7
7
  import * as Y from 'yjs';
8
- const MESSAGE_SYNC = 0;
9
- const MESSAGE_AWARENESS = 1;
8
+ import { MESSAGE_AWARENESS, MESSAGE_SYNC } from './protocol-constants.js';
10
9
  const MAX_RECONNECT_ATTEMPTS = 5;
11
10
  const BASE_RECONNECT_DELAY = 1000;
12
11
  const RECONNECT_MULTIPLIER = 2;
@@ -26,6 +25,7 @@ export class AgentCollabClient extends Observable {
26
25
  updateHandler = null;
27
26
  awarenessUpdateHandler;
28
27
  destroyed = false;
28
+ pendingSyncAbort = null;
29
29
  constructor(options) {
30
30
  super();
31
31
  this.serverUrl = options.serverUrl;
@@ -83,8 +83,6 @@ export class AgentCollabClient extends Observable {
83
83
  return this.doc.getText(name ?? this.defaultTextName);
84
84
  }
85
85
  getTextContent(name) {
86
- // Y.Text.toString() returns the text content — ESLint doesn't recognize this
87
- // eslint-disable-next-line @typescript-eslint/no-base-to-string
88
86
  return this.getText(name).toString();
89
87
  }
90
88
  insertText(index, content, name) {
@@ -122,22 +120,33 @@ export class AgentCollabClient extends Observable {
122
120
  if (this.synced)
123
121
  return Promise.resolve();
124
122
  return new Promise((resolve, reject) => {
125
- const timeout = setTimeout(() => {
123
+ const cleanup = () => {
124
+ clearTimeout(timeout);
126
125
  this.off('sync', handler);
126
+ if (this.pendingSyncAbort === abort)
127
+ this.pendingSyncAbort = null;
128
+ };
129
+ const timeout = setTimeout(() => {
130
+ cleanup();
127
131
  reject(new Error(`Sync timeout after ${timeoutMs}ms`));
128
132
  }, timeoutMs);
129
133
  const handler = (isSynced) => {
130
134
  if (isSynced) {
131
- clearTimeout(timeout);
132
- this.off('sync', handler);
135
+ cleanup();
133
136
  resolve();
134
137
  }
135
138
  };
139
+ const abort = () => {
140
+ cleanup();
141
+ reject(new Error('Client destroyed while waiting for sync'));
142
+ };
143
+ this.pendingSyncAbort = abort;
136
144
  this.on('sync', handler);
137
145
  });
138
146
  }
139
147
  destroy() {
140
148
  this.destroyed = true;
149
+ this.pendingSyncAbort?.();
141
150
  this.awareness.off('update', this.awarenessUpdateHandler);
142
151
  this.disconnect();
143
152
  this.awareness.destroy();
@@ -1,3 +1,4 @@
1
+ export { MESSAGE_AWARENESS, MESSAGE_SYNC } from './protocol-constants.js';
1
2
  export type { CollabDocumentState } from './use-collab-document.js';
2
3
  export { useCollabDocument } from './use-collab-document.js';
3
4
  export type { CollaborationIdentity, UseCollaborationOptions, UseCollaborationResult, } from './use-collaboration.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/collab/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAA;AACnE,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAA;AAC5D,YAAY,EACV,qBAAqB,EACrB,uBAAuB,EACvB,sBAAsB,GACvB,MAAM,wBAAwB,CAAA;AAC/B,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAA;AACzD,YAAY,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAA;AAC/D,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/collab/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAC1E,YAAY,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AACpE,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,YAAY,EACV,qBAAqB,EACrB,uBAAuB,EACvB,sBAAsB,GACvB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,YAAY,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC"}
@@ -1,3 +1,4 @@
1
+ export { MESSAGE_AWARENESS, MESSAGE_SYNC } from './protocol-constants.js';
1
2
  export { useCollabDocument } from './use-collab-document.js';
2
3
  export { useCollaboration } from './use-collaboration.js';
3
4
  export { CollabProvider } from './yjs-websocket-provider.js';
@@ -0,0 +1,5 @@
1
+ /** Yjs sync protocol message type */
2
+ export declare const MESSAGE_SYNC = 0;
3
+ /** Yjs awareness protocol message type */
4
+ export declare const MESSAGE_AWARENESS = 1;
5
+ //# sourceMappingURL=protocol-constants.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"protocol-constants.d.ts","sourceRoot":"","sources":["../../src/collab/protocol-constants.ts"],"names":[],"mappings":"AAAA,qCAAqC;AACrC,eAAO,MAAM,YAAY,IAAI,CAAC;AAE9B,0CAA0C;AAC1C,eAAO,MAAM,iBAAiB,IAAI,CAAC"}
@@ -0,0 +1,4 @@
1
+ /** Yjs sync protocol message type */
2
+ export const MESSAGE_SYNC = 0;
3
+ /** Yjs awareness protocol message type */
4
+ export const MESSAGE_AWARENESS = 1;
@@ -2,4 +2,5 @@ export type { AgentCollabClientOptions, AgentIdentity } from './agent-client.js'
2
2
  export { AgentCollabClient } from './agent-client.js';
3
3
  export type { CreateAgentClientOptions } from './agent-client-factory.js';
4
4
  export { createAgentClient, createAndConnectAgentClient } from './agent-client-factory.js';
5
+ export { MESSAGE_AWARENESS, MESSAGE_SYNC } from './protocol-constants.js';
5
6
  //# sourceMappingURL=server-index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"server-index.d.ts","sourceRoot":"","sources":["../../src/collab/server-index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,wBAAwB,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AAChF,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAA;AACrD,YAAY,EAAE,wBAAwB,EAAE,MAAM,2BAA2B,CAAA;AACzE,OAAO,EAAE,iBAAiB,EAAE,2BAA2B,EAAE,MAAM,2BAA2B,CAAA"}
1
+ {"version":3,"file":"server-index.d.ts","sourceRoot":"","sources":["../../src/collab/server-index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,wBAAwB,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACjF,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtD,YAAY,EAAE,wBAAwB,EAAE,MAAM,2BAA2B,CAAC;AAC1E,OAAO,EAAE,iBAAiB,EAAE,2BAA2B,EAAE,MAAM,2BAA2B,CAAC;AAC3F,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC"}
@@ -1,2 +1,3 @@
1
1
  export { AgentCollabClient } from './agent-client.js';
2
2
  export { createAgentClient, createAndConnectAgentClient } from './agent-client-factory.js';
3
+ export { MESSAGE_AWARENESS, MESSAGE_SYNC } from './protocol-constants.js';
@@ -4,5 +4,5 @@ export interface CollabDocumentState {
4
4
  isLoading: boolean;
5
5
  error: Error | null;
6
6
  }
7
- export declare function useCollabDocument(documentId: string, electricUrl: string): CollabDocumentState;
7
+ export declare function useCollabDocument(documentId: string): CollabDocumentState;
8
8
  //# sourceMappingURL=use-collab-document.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"use-collab-document.d.ts","sourceRoot":"","sources":["../../src/collab/use-collab-document.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,mBAAmB;IAClC,YAAY,EAAE,UAAU,GAAG,IAAI,CAAA;IAC/B,gBAAgB,EAAE,MAAM,CAAA;IACxB,SAAS,EAAE,OAAO,CAAA;IAClB,KAAK,EAAE,KAAK,GAAG,IAAI,CAAA;CACpB;AAKD,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,mBAAmB,CA+C9F"}
1
+ {"version":3,"file":"use-collab-document.d.ts","sourceRoot":"","sources":["../../src/collab/use-collab-document.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,mBAAmB;IAClC,YAAY,EAAE,UAAU,GAAG,IAAI,CAAC;IAChC,gBAAgB,EAAE,MAAM,CAAC;IACzB,SAAS,EAAE,OAAO,CAAC;IACnB,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;CACrB;AAKD,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,mBAAmB,CAiDzE"}
@@ -1,18 +1,21 @@
1
1
  import { useShape } from '@electric-sql/react';
2
+ import { fetchWithTimeout } from '../fetch-with-timeout.js';
3
+ import { useElectricConfig } from '../provider/index.js';
2
4
  // UUID v4 pattern — only format accepted as a yjs_documents PK
3
5
  const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
4
- export function useCollabDocument(documentId, electricUrl) {
6
+ export function useCollabDocument(documentId) {
7
+ const { proxyBaseUrl } = useElectricConfig();
5
8
  // Validate before interpolating into the WHERE clause. yjs_documents PKs are
6
9
  // always UUIDs — reject anything else so no untrusted string enters the query.
7
10
  const isValidId = UUID_RE.test(documentId);
8
11
  // Hook must always be called (Rules of Hooks). Pass an impossible WHERE when
9
12
  // the ID is invalid so the shape returns no rows but the hook still runs.
10
13
  const { data, isLoading, error } = useShape({
11
- url: `${electricUrl}/v1/shape`,
14
+ url: `${proxyBaseUrl}/api/shapes/yjs-documents`,
12
15
  params: {
13
- table: 'yjs_documents',
14
- where: isValidId ? `id = '${documentId}'` : `id = 'invalid'`,
16
+ document_id: isValidId ? documentId : '__invalid__',
15
17
  },
18
+ fetchClient: fetchWithTimeout,
16
19
  });
17
20
  if (!isValidId) {
18
21
  return {
@@ -1 +1 @@
1
- {"version":3,"file":"use-collaboration.d.ts","sourceRoot":"","sources":["../../src/collab/use-collaboration.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,CAAC,MAAM,KAAK,CAAA;AACxB,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAA;AAC/D,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAA;AAE5D,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,OAAO,GAAG,OAAO,CAAA;IACxB,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB;AAED,MAAM,WAAW,uBAAuB;IACtC,UAAU,EAAE,MAAM,CAAA;IAClB,SAAS,EAAE,MAAM,CAAA;IACjB,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,YAAY,CAAC,EAAE,UAAU,GAAG,IAAI,CAAA;IAChC,QAAQ,CAAC,EAAE,qBAAqB,CAAA;CACjC;AAED,MAAM,WAAW,sBAAsB;IACrC,GAAG,EAAE,CAAC,CAAC,GAAG,GAAG,IAAI,CAAA;IACjB,QAAQ,EAAE,cAAc,GAAG,IAAI,CAAA;IAC/B,MAAM,EAAE,OAAO,CAAA;IACf,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,EAAE,KAAK,GAAG,IAAI,CAAA;IACnB,cAAc,EAAE,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,CAAA;CAC1C;AAED,wBAAgB,gBAAgB,CAAC,EAC/B,UAAU,EACV,SAAS,EACT,OAAc,EACd,YAAmB,EACnB,QAAQ,GACT,EAAE,uBAAuB,GAAG,sBAAsB,CAqElD"}
1
+ {"version":3,"file":"use-collaboration.d.ts","sourceRoot":"","sources":["../../src/collab/use-collaboration.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AACzB,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAE7D,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,uBAAuB;IACtC,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,YAAY,CAAC,EAAE,UAAU,GAAG,IAAI,CAAC;IACjC,QAAQ,CAAC,EAAE,qBAAqB,CAAC;CAClC;AAED,MAAM,WAAW,sBAAsB;IACrC,GAAG,EAAE,CAAC,CAAC,GAAG,GAAG,IAAI,CAAC;IAClB,QAAQ,EAAE,cAAc,GAAG,IAAI,CAAC;IAChC,MAAM,EAAE,OAAO,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IACpB,cAAc,EAAE,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;CAC3C;AAED,wBAAgB,gBAAgB,CAAC,EAC/B,UAAU,EACV,SAAS,EACT,OAAc,EACd,YAAmB,EACnB,QAAQ,GACT,EAAE,uBAAuB,GAAG,sBAAsB,CAqElD"}
@@ -1 +1 @@
1
- {"version":3,"file":"yjs-websocket-provider.d.ts","sourceRoot":"","sources":["../../src/collab/yjs-websocket-provider.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAC5C,OAAO,KAAK,iBAAiB,MAAM,uBAAuB,CAAA;AAE1D,OAAO,KAAK,CAAC,MAAM,KAAK,CAAA;AAQxB,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,OAAO,GAAG,OAAO,CAAA;IACvB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,MAAM,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAA;CAC3C;AAED,qBAAa,cAAe,SAAQ,UAAU,CAAC,MAAM,CAAC;IACpD,GAAG,EAAE,CAAC,CAAC,GAAG,CAAA;IACV,SAAS,EAAE,iBAAiB,CAAC,SAAS,CAAA;IACtC,OAAO,CAAC,SAAS,CAAQ;IACzB,OAAO,CAAC,UAAU,CAAQ;IAC1B,OAAO,CAAC,EAAE,CAAyB;IACnC,OAAO,CAAC,MAAM,CAAQ;IACtB,OAAO,CAAC,iBAAiB,CAAI;IAC7B,OAAO,CAAC,cAAc,CAA6C;IACnE,OAAO,CAAC,aAAa,CAA+D;IACpF,OAAO,CAAC,sBAAsB,CAGrB;gBAGP,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,GAAG,EAAE,CAAC,CAAC,GAAG,EACV,OAAO,CAAC,EAAE;QAAE,YAAY,CAAC,EAAE,UAAU,GAAG,IAAI,CAAA;KAAE;IA2BhD,gBAAgB,CAAC,QAAQ,EAAE,YAAY,GAAG,IAAI;IAI9C,iBAAiB,IAAI,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC;IAU9C,OAAO,IAAI,IAAI;IAuFf,UAAU,IAAI,IAAI;IAmBlB,OAAO,CAAC,iBAAiB;IAezB,OAAO,CAAC,eAAe;IAQvB,OAAO,IAAI,IAAI;CAMhB"}
1
+ {"version":3,"file":"yjs-websocket-provider.d.ts","sourceRoot":"","sources":["../../src/collab/yjs-websocket-provider.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,KAAK,iBAAiB,MAAM,uBAAuB,CAAC;AAE3D,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AAOzB,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;CAC5C;AAED,qBAAa,cAAe,SAAQ,UAAU,CAAC,MAAM,CAAC;IACpD,GAAG,EAAE,CAAC,CAAC,GAAG,CAAC;IACX,SAAS,EAAE,iBAAiB,CAAC,SAAS,CAAC;IACvC,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,EAAE,CAA0B;IACpC,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,iBAAiB,CAAK;IAC9B,OAAO,CAAC,cAAc,CAA8C;IACpE,OAAO,CAAC,aAAa,CAAgE;IACrF,OAAO,CAAC,sBAAsB,CAGpB;gBAGR,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,GAAG,EAAE,CAAC,CAAC,GAAG,EACV,OAAO,CAAC,EAAE;QAAE,YAAY,CAAC,EAAE,UAAU,GAAG,IAAI,CAAA;KAAE;IA2BhD,gBAAgB,CAAC,QAAQ,EAAE,YAAY,GAAG,IAAI;IAI9C,iBAAiB,IAAI,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC;IAU9C,OAAO,IAAI,IAAI;IAuFf,UAAU,IAAI,IAAI;IAmBlB,OAAO,CAAC,iBAAiB;IAezB,OAAO,CAAC,eAAe;IAQvB,OAAO,IAAI,IAAI;CAMhB"}
@@ -4,8 +4,7 @@ import { Observable } from 'lib0/observable';
4
4
  import * as awarenessProtocol from 'y-protocols/awareness';
5
5
  import * as syncProtocol from 'y-protocols/sync';
6
6
  import * as Y from 'yjs';
7
- const MESSAGE_SYNC = 0;
8
- const MESSAGE_AWARENESS = 1;
7
+ import { MESSAGE_AWARENESS, MESSAGE_SYNC } from './protocol-constants.js';
9
8
  const MAX_RECONNECT_ATTEMPTS = 10;
10
9
  const BASE_RECONNECT_DELAY = 1000;
11
10
  const RECONNECT_MULTIPLIER = 1.5;
@@ -0,0 +1,7 @@
1
+ /**
2
+ * A fetch wrapper that aborts requests after {@link SHAPE_FETCH_TIMEOUT_MS} (10 s).
3
+ * Passed as `fetchClient` to ElectricSQL `useShape` so that shape subscription
4
+ * requests to the CMS proxy do not hang indefinitely.
5
+ */
6
+ export declare function fetchWithTimeout(input: RequestInfo | URL, init?: RequestInit): Promise<Response>;
7
+ //# sourceMappingURL=fetch-with-timeout.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fetch-with-timeout.d.ts","sourceRoot":"","sources":["../src/fetch-with-timeout.ts"],"names":[],"mappings":"AAGA;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,WAAW,GAAG,GAAG,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,QAAQ,CAAC,CAoBhG"}
@@ -0,0 +1,27 @@
1
+ /** Default timeout for Electric shape proxy fetch requests (milliseconds). */
2
+ const SHAPE_FETCH_TIMEOUT_MS = 10_000;
3
+ /**
4
+ * A fetch wrapper that aborts requests after {@link SHAPE_FETCH_TIMEOUT_MS} (10 s).
5
+ * Passed as `fetchClient` to ElectricSQL `useShape` so that shape subscription
6
+ * requests to the CMS proxy do not hang indefinitely.
7
+ */
8
+ export function fetchWithTimeout(input, init) {
9
+ // If the caller already provides a signal, respect it and compose with our timeout.
10
+ const externalSignal = init?.signal;
11
+ const controller = new AbortController();
12
+ const timeout = setTimeout(() => controller.abort(), SHAPE_FETCH_TIMEOUT_MS);
13
+ // If the external signal aborts, forward to our controller.
14
+ if (externalSignal) {
15
+ if (externalSignal.aborted) {
16
+ controller.abort(externalSignal.reason);
17
+ }
18
+ else {
19
+ externalSignal.addEventListener('abort', () => controller.abort(externalSignal.reason), {
20
+ once: true,
21
+ });
22
+ }
23
+ }
24
+ return fetch(input, { ...init, signal: controller.signal }).finally(() => {
25
+ clearTimeout(timeout);
26
+ });
27
+ }
@@ -0,0 +1,29 @@
1
+ import type { MutationResult } from '../mutations.js';
2
+ export interface AgentContextRecord {
3
+ id: string;
4
+ session_id: string;
5
+ agent_id: string;
6
+ context: Record<string, unknown>;
7
+ priority: number;
8
+ created_at: string;
9
+ updated_at: string;
10
+ }
11
+ export interface CreateAgentContextInput {
12
+ agent_id: string;
13
+ context?: Record<string, unknown>;
14
+ priority?: number;
15
+ }
16
+ export interface UpdateAgentContextInput {
17
+ context?: Record<string, unknown>;
18
+ priority?: number;
19
+ }
20
+ export interface UseAgentContextsResult {
21
+ contexts: AgentContextRecord[];
22
+ isLoading: boolean;
23
+ error: Error | null;
24
+ create: (data: CreateAgentContextInput) => Promise<MutationResult<AgentContextRecord>>;
25
+ update: (id: string, data: UpdateAgentContextInput) => Promise<MutationResult<AgentContextRecord>>;
26
+ remove: (id: string) => Promise<MutationResult<void>>;
27
+ }
28
+ export declare function useAgentContexts(): UseAgentContextsResult;
29
+ //# sourceMappingURL=useAgentContexts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useAgentContexts.d.ts","sourceRoot":"","sources":["../../src/hooks/useAgentContexts.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAKtD,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,uBAAuB;IACtC,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,uBAAuB;IACtC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,sBAAsB;IACrC,QAAQ,EAAE,kBAAkB,EAAE,CAAC;IAC/B,SAAS,EAAE,OAAO,CAAC;IACnB,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IACpB,MAAM,EAAE,CAAC,IAAI,EAAE,uBAAuB,KAAK,OAAO,CAAC,cAAc,CAAC,kBAAkB,CAAC,CAAC,CAAC;IACvF,MAAM,EAAE,CACN,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,uBAAuB,KAC1B,OAAO,CAAC,cAAc,CAAC,kBAAkB,CAAC,CAAC,CAAC;IACjD,MAAM,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC;CACvD;AAED,wBAAgB,gBAAgB,IAAI,sBAAsB,CAqBzD"}
@@ -0,0 +1,22 @@
1
+ 'use client';
2
+ import { useShape } from '@electric-sql/react';
3
+ import { fetchWithTimeout } from '../fetch-with-timeout.js';
4
+ import { useSyncMutations } from '../mutations.js';
5
+ import { useElectricConfig } from '../provider/index.js';
6
+ import { toRecords } from '../shape-utils.js';
7
+ export function useAgentContexts() {
8
+ const { proxyBaseUrl } = useElectricConfig();
9
+ const { data, isLoading, error } = useShape({
10
+ url: `${proxyBaseUrl}/api/shapes/agent-contexts`,
11
+ fetchClient: fetchWithTimeout,
12
+ });
13
+ const { create, update, remove } = useSyncMutations('agent-contexts');
14
+ return {
15
+ contexts: toRecords(data),
16
+ isLoading,
17
+ error: error || null,
18
+ create,
19
+ update,
20
+ remove,
21
+ };
22
+ }
@@ -0,0 +1,34 @@
1
+ import type { MutationResult } from '../mutations.js';
2
+ export interface AgentMemoryRecord {
3
+ id: string;
4
+ agent_id: string;
5
+ content: string;
6
+ type: string;
7
+ metadata: Record<string, unknown>;
8
+ created_at: string;
9
+ expires_at: string | null;
10
+ }
11
+ export interface CreateAgentMemoryInput {
12
+ agent_id: string;
13
+ content: string;
14
+ type: string;
15
+ source: Record<string, unknown>;
16
+ metadata?: Record<string, unknown>;
17
+ expires_at?: string | null;
18
+ }
19
+ export interface UpdateAgentMemoryInput {
20
+ content?: string;
21
+ type?: string;
22
+ metadata?: Record<string, unknown>;
23
+ expires_at?: string | null;
24
+ }
25
+ export interface UseAgentMemoryResult {
26
+ memories: AgentMemoryRecord[];
27
+ isLoading: boolean;
28
+ error: Error | null;
29
+ create: (data: CreateAgentMemoryInput) => Promise<MutationResult<AgentMemoryRecord>>;
30
+ update: (id: string, data: UpdateAgentMemoryInput) => Promise<MutationResult<AgentMemoryRecord>>;
31
+ remove: (id: string) => Promise<MutationResult<void>>;
32
+ }
33
+ export declare function useAgentMemory(agentId: string): UseAgentMemoryResult;
34
+ //# sourceMappingURL=useAgentMemory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useAgentMemory.d.ts","sourceRoot":"","sources":["../../src/hooks/useAgentMemory.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAOtD,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED,MAAM,WAAW,sBAAsB;IACrC,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAED,MAAM,WAAW,sBAAsB;IACrC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,iBAAiB,EAAE,CAAC;IAC9B,SAAS,EAAE,OAAO,CAAC;IACnB,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IACpB,MAAM,EAAE,CAAC,IAAI,EAAE,sBAAsB,KAAK,OAAO,CAAC,cAAc,CAAC,iBAAiB,CAAC,CAAC,CAAC;IACrF,MAAM,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,sBAAsB,KAAK,OAAO,CAAC,cAAc,CAAC,iBAAiB,CAAC,CAAC,CAAC;IACjG,MAAM,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC;CACvD;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,oBAAoB,CAuCpE"}
@@ -0,0 +1,37 @@
1
+ 'use client';
2
+ import { useShape } from '@electric-sql/react';
3
+ import { fetchWithTimeout } from '../fetch-with-timeout.js';
4
+ import { useSyncMutations } from '../mutations.js';
5
+ import { useElectricConfig } from '../provider/index.js';
6
+ import { toRecords } from '../shape-utils.js';
7
+ const AGENT_ID_RE = /^[a-zA-Z0-9_-]+$/;
8
+ export function useAgentMemory(agentId) {
9
+ const { proxyBaseUrl } = useElectricConfig();
10
+ const isValid = agentId.length > 0 && AGENT_ID_RE.test(agentId);
11
+ // Hook must always be called (Rules of Hooks). Pass an impossible WHERE when
12
+ // the ID is invalid so the shape returns no rows but the hook still runs.
13
+ const { data, isLoading, error } = useShape({
14
+ url: `${proxyBaseUrl}/api/shapes/agent-memories`,
15
+ params: { agent_id: isValid ? agentId : '00000000-0000-0000-0000-000000000000' },
16
+ fetchClient: fetchWithTimeout,
17
+ });
18
+ const { create, update, remove } = useSyncMutations('agent-memories');
19
+ if (!isValid) {
20
+ return {
21
+ memories: [],
22
+ isLoading: false,
23
+ error: new Error('Invalid agentId: must be non-empty alphanumeric, hyphens, underscores only'),
24
+ create,
25
+ update,
26
+ remove,
27
+ };
28
+ }
29
+ return {
30
+ memories: toRecords(data),
31
+ isLoading,
32
+ error: error || null,
33
+ create,
34
+ update,
35
+ remove,
36
+ };
37
+ }
@@ -1,11 +1,31 @@
1
- type ConversationRecord = {
2
- id: string | number;
1
+ import type { MutationResult } from '../mutations.js';
2
+ export interface ConversationRecord {
3
+ id: string;
4
+ user_id: string;
5
+ agent_id: string;
3
6
  title?: string | null;
4
- };
5
- export declare function useConversations(_userId: string): {
7
+ status: string;
8
+ device_id?: string | null;
9
+ version: number;
10
+ created_at: string;
11
+ updated_at: string;
12
+ }
13
+ export interface CreateConversationInput {
14
+ agent_id: string;
15
+ title?: string;
16
+ device_id?: string;
17
+ }
18
+ export interface UpdateConversationInput {
19
+ title?: string;
20
+ status?: string;
21
+ }
22
+ export interface UseConversationsResult {
6
23
  conversations: ConversationRecord[];
7
24
  isLoading: boolean;
8
25
  error: Error | null;
9
- };
10
- export {};
26
+ create: (data: CreateConversationInput) => Promise<MutationResult<ConversationRecord>>;
27
+ update: (id: string, data: UpdateConversationInput) => Promise<MutationResult<ConversationRecord>>;
28
+ remove: (id: string) => Promise<MutationResult<void>>;
29
+ }
30
+ export declare function useConversations(_userId: string): UseConversationsResult;
11
31
  //# sourceMappingURL=useConversations.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"useConversations.d.ts","sourceRoot":"","sources":["../../src/hooks/useConversations.ts"],"names":[],"mappings":"AAIA,KAAK,kBAAkB,GAAG;IACxB,EAAE,EAAE,MAAM,GAAG,MAAM,CAAA;IACnB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CACtB,CAAA;AAID,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM;;;WAU5B,KAAK,GAAG,IAAI;EAE/B"}
1
+ {"version":3,"file":"useConversations.d.ts","sourceRoot":"","sources":["../../src/hooks/useConversations.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAKtD,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,uBAAuB;IACtC,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,uBAAuB;IACtC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,sBAAsB;IACrC,aAAa,EAAE,kBAAkB,EAAE,CAAC;IACpC,SAAS,EAAE,OAAO,CAAC;IACnB,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IACpB,MAAM,EAAE,CAAC,IAAI,EAAE,uBAAuB,KAAK,OAAO,CAAC,cAAc,CAAC,kBAAkB,CAAC,CAAC,CAAC;IACvF,MAAM,EAAE,CACN,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,uBAAuB,KAC1B,OAAO,CAAC,cAAc,CAAC,kBAAkB,CAAC,CAAC,CAAC;IACjD,MAAM,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC;CACvD;AAID,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,sBAAsB,CAuBxE"}
@@ -1,16 +1,26 @@
1
1
  'use client';
2
2
  import { useShape } from '@electric-sql/react';
3
+ import { fetchWithTimeout } from '../fetch-with-timeout.js';
4
+ import { useSyncMutations } from '../mutations.js';
5
+ import { useElectricConfig } from '../provider/index.js';
6
+ import { toRecords } from '../shape-utils.js';
3
7
  // _userId kept for API compatibility — filtering is enforced by the server-side
4
8
  // proxy at /api/shapes/conversations, which reads the session cookie directly.
5
9
  export function useConversations(_userId) {
10
+ const { proxyBaseUrl } = useElectricConfig();
6
11
  // The proxy validates the session and enforces row-level filtering server-side.
7
12
  // Client-provided params are not forwarded — the proxy overrides them.
8
13
  const { data, isLoading, error } = useShape({
9
- url: `/api/shapes/conversations`,
14
+ url: `${proxyBaseUrl}/api/shapes/conversations`,
15
+ fetchClient: fetchWithTimeout,
10
16
  });
17
+ const { create, update, remove } = useSyncMutations('conversations');
11
18
  return {
12
- conversations: Array.isArray(data) ? data : [],
19
+ conversations: toRecords(data),
13
20
  isLoading,
14
- error: error,
21
+ error: error || null,
22
+ create,
23
+ update,
24
+ remove,
15
25
  };
16
26
  }
@@ -0,0 +1,35 @@
1
+ import type { MutationResult } from '../mutations.js';
2
+ export interface CoordinationSessionRecord {
3
+ id: string;
4
+ agent_id: string;
5
+ started_at: string;
6
+ ended_at: string | null;
7
+ task: string;
8
+ status: string;
9
+ pid: number | null;
10
+ tools: Record<string, number> | null;
11
+ metadata: Record<string, unknown> | null;
12
+ }
13
+ export interface CreateCoordinationSessionInput {
14
+ agent_id: string;
15
+ task?: string;
16
+ pid?: number;
17
+ metadata?: Record<string, unknown>;
18
+ }
19
+ export interface UpdateCoordinationSessionInput {
20
+ task?: string;
21
+ status?: string;
22
+ ended_at?: string;
23
+ tools?: Record<string, number>;
24
+ metadata?: Record<string, unknown>;
25
+ }
26
+ export interface UseCoordinationSessionsResult {
27
+ sessions: CoordinationSessionRecord[];
28
+ isLoading: boolean;
29
+ error: Error | null;
30
+ create: (data: CreateCoordinationSessionInput) => Promise<MutationResult<CoordinationSessionRecord>>;
31
+ update: (id: string, data: UpdateCoordinationSessionInput) => Promise<MutationResult<CoordinationSessionRecord>>;
32
+ remove: (id: string) => Promise<MutationResult<void>>;
33
+ }
34
+ export declare function useCoordinationSessions(): UseCoordinationSessionsResult;
35
+ //# sourceMappingURL=useCoordinationSessions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useCoordinationSessions.d.ts","sourceRoot":"","sources":["../../src/hooks/useCoordinationSessions.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAKtD,MAAM,WAAW,yBAAyB;IACxC,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC;IACrC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;CAC1C;AAED,MAAM,WAAW,8BAA8B;IAC7C,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED,MAAM,WAAW,8BAA8B;IAC7C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED,MAAM,WAAW,6BAA6B;IAC5C,QAAQ,EAAE,yBAAyB,EAAE,CAAC;IACtC,SAAS,EAAE,OAAO,CAAC;IACnB,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IACpB,MAAM,EAAE,CACN,IAAI,EAAE,8BAA8B,KACjC,OAAO,CAAC,cAAc,CAAC,yBAAyB,CAAC,CAAC,CAAC;IACxD,MAAM,EAAE,CACN,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,8BAA8B,KACjC,OAAO,CAAC,cAAc,CAAC,yBAAyB,CAAC,CAAC,CAAC;IACxD,MAAM,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC;CACvD;AAED,wBAAgB,uBAAuB,IAAI,6BAA6B,CAqBvE"}
@@ -0,0 +1,22 @@
1
+ 'use client';
2
+ import { useShape } from '@electric-sql/react';
3
+ import { fetchWithTimeout } from '../fetch-with-timeout.js';
4
+ import { useSyncMutations } from '../mutations.js';
5
+ import { useElectricConfig } from '../provider/index.js';
6
+ import { toRecords } from '../shape-utils.js';
7
+ export function useCoordinationSessions() {
8
+ const { proxyBaseUrl } = useElectricConfig();
9
+ const { data, isLoading, error } = useShape({
10
+ url: `${proxyBaseUrl}/api/shapes/coordination-sessions`,
11
+ fetchClient: fetchWithTimeout,
12
+ });
13
+ const { create, update, remove } = useSyncMutations('coordination-sessions');
14
+ return {
15
+ sessions: toRecords(data),
16
+ isLoading,
17
+ error: error || null,
18
+ create,
19
+ update,
20
+ remove,
21
+ };
22
+ }
@@ -0,0 +1,41 @@
1
+ import type { MutationResult } from '../mutations.js';
2
+ export interface CoordinationWorkItemRecord {
3
+ id: string;
4
+ title: string;
5
+ description: string | null;
6
+ status: string;
7
+ priority: number;
8
+ owner_agent: string | null;
9
+ owner_session: string | null;
10
+ parent_id: string | null;
11
+ metadata: Record<string, unknown> | null;
12
+ created_at: string;
13
+ updated_at: string;
14
+ completed_at: string | null;
15
+ }
16
+ export interface CreateCoordinationWorkItemInput {
17
+ title: string;
18
+ description?: string;
19
+ priority?: number;
20
+ owner_agent?: string;
21
+ parent_id?: string;
22
+ metadata?: Record<string, unknown>;
23
+ }
24
+ export interface UpdateCoordinationWorkItemInput {
25
+ title?: string;
26
+ description?: string;
27
+ status?: string;
28
+ priority?: number;
29
+ owner_agent?: string;
30
+ metadata?: Record<string, unknown>;
31
+ }
32
+ export interface UseCoordinationWorkItemsResult {
33
+ workItems: CoordinationWorkItemRecord[];
34
+ isLoading: boolean;
35
+ error: Error | null;
36
+ create: (data: CreateCoordinationWorkItemInput) => Promise<MutationResult<CoordinationWorkItemRecord>>;
37
+ update: (id: string, data: UpdateCoordinationWorkItemInput) => Promise<MutationResult<CoordinationWorkItemRecord>>;
38
+ remove: (id: string) => Promise<MutationResult<void>>;
39
+ }
40
+ export declare function useCoordinationWorkItems(): UseCoordinationWorkItemsResult;
41
+ //# sourceMappingURL=useCoordinationWorkItems.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useCoordinationWorkItems.d.ts","sourceRoot":"","sources":["../../src/hooks/useCoordinationWorkItems.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAKtD,MAAM,WAAW,0BAA0B;IACzC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IACzC,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B;AAED,MAAM,WAAW,+BAA+B;IAC9C,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED,MAAM,WAAW,+BAA+B;IAC9C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED,MAAM,WAAW,8BAA8B;IAC7C,SAAS,EAAE,0BAA0B,EAAE,CAAC;IACxC,SAAS,EAAE,OAAO,CAAC;IACnB,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IACpB,MAAM,EAAE,CACN,IAAI,EAAE,+BAA+B,KAClC,OAAO,CAAC,cAAc,CAAC,0BAA0B,CAAC,CAAC,CAAC;IACzD,MAAM,EAAE,CACN,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,+BAA+B,KAClC,OAAO,CAAC,cAAc,CAAC,0BAA0B,CAAC,CAAC,CAAC;IACzD,MAAM,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC;CACvD;AAED,wBAAgB,wBAAwB,IAAI,8BAA8B,CAqBzE"}
@@ -0,0 +1,22 @@
1
+ 'use client';
2
+ import { useShape } from '@electric-sql/react';
3
+ import { fetchWithTimeout } from '../fetch-with-timeout.js';
4
+ import { useSyncMutations } from '../mutations.js';
5
+ import { useElectricConfig } from '../provider/index.js';
6
+ import { toRecords } from '../shape-utils.js';
7
+ export function useCoordinationWorkItems() {
8
+ const { proxyBaseUrl } = useElectricConfig();
9
+ const { data, isLoading, error } = useShape({
10
+ url: `${proxyBaseUrl}/api/shapes/coordination-work-items`,
11
+ fetchClient: fetchWithTimeout,
12
+ });
13
+ const { create, update, remove } = useSyncMutations('coordination-work-items');
14
+ return {
15
+ workItems: toRecords(data),
16
+ isLoading,
17
+ error: error || null,
18
+ create,
19
+ update,
20
+ remove,
21
+ };
22
+ }
package/dist/index.d.ts CHANGED
@@ -1,5 +1,26 @@
1
+ /**
2
+ * @revealui/sync — Real-time collaboration and sync primitives.
3
+ *
4
+ * The collab layer (Yjs-based) is fully functional.
5
+ * ElectricProvider provides proxyBaseUrl config to child hooks. All hooks route
6
+ * through the authenticated CMS proxy at /api/shapes/* — no direct Electric client.
7
+ *
8
+ * Reads use ElectricSQL shape subscriptions for real-time updates.
9
+ * Writes use REST mutations via /api/sync/* — changes propagate to all
10
+ * subscribers automatically through ElectricSQL replication.
11
+ */
1
12
  export type { CollabDocumentState, UseCollaborationOptions, UseCollaborationResult, } from './collab/index.js';
2
13
  export { CollabProvider, useCollabDocument, useCollaboration, } from './collab/index.js';
14
+ export type { AgentContextRecord, CreateAgentContextInput, UpdateAgentContextInput, UseAgentContextsResult, } from './hooks/useAgentContexts.js';
15
+ export { useAgentContexts } from './hooks/useAgentContexts.js';
16
+ export type { AgentMemoryRecord, CreateAgentMemoryInput, UpdateAgentMemoryInput, UseAgentMemoryResult, } from './hooks/useAgentMemory.js';
17
+ export { useAgentMemory } from './hooks/useAgentMemory.js';
18
+ export type { ConversationRecord, CreateConversationInput, UpdateConversationInput, UseConversationsResult, } from './hooks/useConversations.js';
3
19
  export { useConversations } from './hooks/useConversations.js';
4
- export { ElectricProvider } from './provider/index.js';
20
+ export type { CoordinationSessionRecord, CreateCoordinationSessionInput, UpdateCoordinationSessionInput, UseCoordinationSessionsResult, } from './hooks/useCoordinationSessions.js';
21
+ export { useCoordinationSessions } from './hooks/useCoordinationSessions.js';
22
+ export type { CoordinationWorkItemRecord, CreateCoordinationWorkItemInput, UpdateCoordinationWorkItemInput, UseCoordinationWorkItemsResult, } from './hooks/useCoordinationWorkItems.js';
23
+ export { useCoordinationWorkItems } from './hooks/useCoordinationWorkItems.js';
24
+ export type { MutationResult } from './mutations.js';
25
+ export { ElectricProvider, useElectricConfig } from './provider/index.js';
5
26
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,mBAAmB,EACnB,uBAAuB,EACvB,sBAAsB,GACvB,MAAM,mBAAmB,CAAA;AAC1B,OAAO,EACL,cAAc,EACd,iBAAiB,EACjB,gBAAgB,GACjB,MAAM,mBAAmB,CAAA;AAC1B,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAA;AAC9D,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,YAAY,EACV,mBAAmB,EACnB,uBAAuB,EACvB,sBAAsB,GACvB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,cAAc,EACd,iBAAiB,EACjB,gBAAgB,GACjB,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EACV,kBAAkB,EAClB,uBAAuB,EACvB,uBAAuB,EACvB,sBAAsB,GACvB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAC/D,YAAY,EACV,iBAAiB,EACjB,sBAAsB,EACtB,sBAAsB,EACtB,oBAAoB,GACrB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC3D,YAAY,EACV,kBAAkB,EAClB,uBAAuB,EACvB,uBAAuB,EACvB,sBAAsB,GACvB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAC/D,YAAY,EACV,yBAAyB,EACzB,8BAA8B,EAC9B,8BAA8B,EAC9B,6BAA6B,GAC9B,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EAAE,uBAAuB,EAAE,MAAM,oCAAoC,CAAC;AAC7E,YAAY,EACV,0BAA0B,EAC1B,+BAA+B,EAC/B,+BAA+B,EAC/B,8BAA8B,GAC/B,MAAM,qCAAqC,CAAC;AAC7C,OAAO,EAAE,wBAAwB,EAAE,MAAM,qCAAqC,CAAC;AAC/E,YAAY,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC"}
package/dist/index.js CHANGED
@@ -1,3 +1,18 @@
1
+ /**
2
+ * @revealui/sync — Real-time collaboration and sync primitives.
3
+ *
4
+ * The collab layer (Yjs-based) is fully functional.
5
+ * ElectricProvider provides proxyBaseUrl config to child hooks. All hooks route
6
+ * through the authenticated CMS proxy at /api/shapes/* — no direct Electric client.
7
+ *
8
+ * Reads use ElectricSQL shape subscriptions for real-time updates.
9
+ * Writes use REST mutations via /api/sync/* — changes propagate to all
10
+ * subscribers automatically through ElectricSQL replication.
11
+ */
1
12
  export { CollabProvider, useCollabDocument, useCollaboration, } from './collab/index.js';
13
+ export { useAgentContexts } from './hooks/useAgentContexts.js';
14
+ export { useAgentMemory } from './hooks/useAgentMemory.js';
2
15
  export { useConversations } from './hooks/useConversations.js';
3
- export { ElectricProvider } from './provider/index.js';
16
+ export { useCoordinationSessions } from './hooks/useCoordinationSessions.js';
17
+ export { useCoordinationWorkItems } from './hooks/useCoordinationWorkItems.js';
18
+ export { ElectricProvider, useElectricConfig } from './provider/index.js';
@@ -0,0 +1,14 @@
1
+ export interface MutationResult<T = unknown> {
2
+ success: boolean;
3
+ data?: T;
4
+ error?: string;
5
+ }
6
+ /**
7
+ * Hook that returns mutation functions for a given sync API endpoint.
8
+ */
9
+ export declare function useSyncMutations<TCreate, TUpdate, TRecord>(endpoint: string): {
10
+ create: (data: TCreate) => Promise<MutationResult<TRecord>>;
11
+ update: (id: string, data: TUpdate) => Promise<MutationResult<TRecord>>;
12
+ remove: (id: string) => Promise<MutationResult<void>>;
13
+ };
14
+ //# sourceMappingURL=mutations.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mutations.d.ts","sourceRoot":"","sources":["../src/mutations.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,cAAc,CAAC,CAAC,GAAG,OAAO;IACzC,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,CAAC,CAAC;IACT,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AA0CD;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM;mBAK3D,OAAO,KAAG,OAAO,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;iBAO5C,MAAM,QAAQ,OAAO,KAAG,OAAO,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;iBAOxD,MAAM,KAAG,OAAO,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;EAOpD"}
@@ -0,0 +1,53 @@
1
+ 'use client';
2
+ import { useCallback } from 'react';
3
+ import { useElectricConfig } from './provider/index.js';
4
+ /** Default timeout for mutation fetch requests (milliseconds). */
5
+ const MUTATION_FETCH_TIMEOUT_MS = 10_000;
6
+ /**
7
+ * Make an authenticated mutation request to the CMS API.
8
+ * Credentials are included so the session cookie is sent cross-origin.
9
+ * Requests are aborted after {@link MUTATION_FETCH_TIMEOUT_MS} (10 s).
10
+ */
11
+ async function mutationFetch(url, method, body) {
12
+ const controller = new AbortController();
13
+ const timeout = setTimeout(() => controller.abort(), MUTATION_FETCH_TIMEOUT_MS);
14
+ let response;
15
+ try {
16
+ response = await fetch(url, {
17
+ method,
18
+ credentials: 'include',
19
+ signal: controller.signal,
20
+ headers: body !== undefined ? { 'Content-Type': 'application/json' } : undefined,
21
+ body: body !== undefined ? JSON.stringify(body) : undefined,
22
+ });
23
+ }
24
+ finally {
25
+ clearTimeout(timeout);
26
+ }
27
+ if (!response.ok) {
28
+ const errorData = (await response.json().catch(() => null));
29
+ return {
30
+ success: false,
31
+ error: errorData?.error ?? `Request failed with status ${response.status}`,
32
+ };
33
+ }
34
+ const data = (await response.json());
35
+ return { success: true, data };
36
+ }
37
+ /**
38
+ * Hook that returns mutation functions for a given sync API endpoint.
39
+ */
40
+ export function useSyncMutations(endpoint) {
41
+ const { proxyBaseUrl } = useElectricConfig();
42
+ const baseUrl = `${proxyBaseUrl}/api/sync/${endpoint}`;
43
+ const create = useCallback(async (data) => {
44
+ return mutationFetch(baseUrl, 'POST', data);
45
+ }, [baseUrl]);
46
+ const update = useCallback(async (id, data) => {
47
+ return mutationFetch(`${baseUrl}/${encodeURIComponent(id)}`, 'PATCH', data);
48
+ }, [baseUrl]);
49
+ const remove = useCallback(async (id) => {
50
+ return mutationFetch(`${baseUrl}/${encodeURIComponent(id)}`, 'DELETE');
51
+ }, [baseUrl]);
52
+ return { create, update, remove };
53
+ }
@@ -1,7 +1,35 @@
1
- import type { ReactNode } from 'react';
2
- export declare function ElectricProvider({ children, }: {
1
+ import { type ReactNode } from 'react';
2
+ interface ElectricContextValue {
3
+ /**
4
+ * Direct Electric service URL (e.g. the Railway instance).
5
+ * Stored in context for future use — not consumed by the current proxy-based hooks.
6
+ * All hooks use proxyBaseUrl + /api/shapes/* instead.
7
+ */
8
+ serviceUrl: string | null;
9
+ /**
10
+ * Base URL prefix for authenticated CMS shape proxy routes.
11
+ * Default '' keeps all hook URLs relative (works for same-origin apps).
12
+ * Set to 'https://cms.revealui.com' when consuming from a different origin.
13
+ */
14
+ proxyBaseUrl: string;
15
+ debug: boolean;
16
+ }
17
+ /**
18
+ * Provides ElectricSQL configuration to child hooks (`useConversations`, `useCollabDocument`).
19
+ *
20
+ * Provides proxyBaseUrl (and optional serviceUrl/debug) to child hooks via context.
21
+ * All hooks use the CMS proxy pattern — no direct Electric connection is established here.
22
+ */
23
+ export declare function ElectricProvider(props: {
3
24
  children: ReactNode;
4
25
  serviceUrl?: string;
26
+ proxyBaseUrl?: string;
5
27
  debug?: boolean;
6
- }): import("react/jsx-runtime").JSX.Element;
28
+ }): ReactNode;
29
+ /**
30
+ * Access the ElectricSQL configuration provided by `ElectricProvider`.
31
+ * Returns `{ serviceUrl: null, debug: false }` if no provider is present.
32
+ */
33
+ export declare function useElectricConfig(): ElectricContextValue;
34
+ export {};
7
35
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/provider/index.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAGtC,wBAAgB,gBAAgB,CAAC,EAC/B,QAAQ,GACT,EAAE;IACD,QAAQ,EAAE,SAAS,CAAA;IACnB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,KAAK,CAAC,EAAE,OAAO,CAAA;CAChB,2CAIA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/provider/index.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAiB,KAAK,SAAS,EAAgB,MAAM,OAAO,CAAC;AAEpE,UAAU,oBAAoB;IAC5B;;;;OAIG;IACH,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B;;;;OAIG;IACH,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,OAAO,CAAC;CAChB;AAQD;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE;IACtC,QAAQ,EAAE,SAAS,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB,GAAG,SAAS,CAWZ;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,IAAI,oBAAoB,CAExD"}
@@ -1,8 +1,29 @@
1
1
  'use client';
2
- import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
3
- // ElectricProvider placeholder - useShape works with proxy API
4
- export function ElectricProvider({ children, }) {
5
- // For now, just pass through children
6
- // useShape hooks work directly with proxy API endpoints
7
- return _jsx(_Fragment, { children: children });
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import { createContext, use, useMemo } from 'react';
4
+ const ElectricContext = createContext({
5
+ serviceUrl: null,
6
+ proxyBaseUrl: '',
7
+ debug: false,
8
+ });
9
+ /**
10
+ * Provides ElectricSQL configuration to child hooks (`useConversations`, `useCollabDocument`).
11
+ *
12
+ * Provides proxyBaseUrl (and optional serviceUrl/debug) to child hooks via context.
13
+ * All hooks use the CMS proxy pattern — no direct Electric connection is established here.
14
+ */
15
+ export function ElectricProvider(props) {
16
+ const value = useMemo(() => ({
17
+ serviceUrl: props.serviceUrl ?? null,
18
+ proxyBaseUrl: props.proxyBaseUrl ?? '',
19
+ debug: props.debug ?? false,
20
+ }), [props.serviceUrl, props.proxyBaseUrl, props.debug]);
21
+ return _jsx(ElectricContext, { value: value, children: props.children });
22
+ }
23
+ /**
24
+ * Access the ElectricSQL configuration provided by `ElectricProvider`.
25
+ * Returns `{ serviceUrl: null, debug: false }` if no provider is present.
26
+ */
27
+ export function useElectricConfig() {
28
+ return use(ElectricContext);
8
29
  }
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Cast ElectricSQL shape data to a typed record array.
3
+ *
4
+ * ElectricSQL's `useShape` returns `Row[]` (i.e. `Record<string, Value>[]`).
5
+ * Our record interfaces describe the exact same shape but lack the index
6
+ * signature that `Row` carries, so TypeScript rejects a direct assignment.
7
+ * This helper encapsulates the boundary cast in one place and returns an
8
+ * empty array when data is falsy.
9
+ */
10
+ export declare function toRecords<T>(data: unknown[] | undefined): T[];
11
+ //# sourceMappingURL=shape-utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shape-utils.d.ts","sourceRoot":"","sources":["../src/shape-utils.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,wBAAgB,SAAS,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,SAAS,GAAG,CAAC,EAAE,CAG7D"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Cast ElectricSQL shape data to a typed record array.
3
+ *
4
+ * ElectricSQL's `useShape` returns `Row[]` (i.e. `Record<string, Value>[]`).
5
+ * Our record interfaces describe the exact same shape but lack the index
6
+ * signature that `Row` carries, so TypeScript rejects a direct assignment.
7
+ * This helper encapsulates the boundary cast in one place and returns an
8
+ * empty array when data is falsy.
9
+ */
10
+ export function toRecords(data) {
11
+ if (!Array.isArray(data))
12
+ return [];
13
+ return data;
14
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"test-setup.d.ts","sourceRoot":"","sources":["../src/test-setup.ts"],"names":[],"mappings":"AAAA,OAAO,kCAAkC,CAAA"}
1
+ {"version":3,"file":"test-setup.d.ts","sourceRoot":"","sources":["../src/test-setup.ts"],"names":[],"mappings":"AAAA,OAAO,kCAAkC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,7 @@
1
1
  {
2
2
  "name": "@revealui/sync",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
+ "experimental": true,
4
5
  "license": "MIT",
5
6
  "files": [
6
7
  "dist"
@@ -12,8 +13,8 @@
12
13
  "ws": "^8.18.0",
13
14
  "y-protocols": "^1.0.7",
14
15
  "yjs": "^13.6.29",
15
- "@revealui/contracts": "1.0.0",
16
- "@revealui/db": "0.2.0"
16
+ "@revealui/db": "0.3.0",
17
+ "@revealui/contracts": "1.2.0"
17
18
  },
18
19
  "devDependencies": {
19
20
  "@testing-library/jest-dom": "^6.6.4",
@@ -28,6 +29,9 @@
28
29
  "vitest": "^4.0.18",
29
30
  "dev": "0.0.1"
30
31
  },
32
+ "engines": {
33
+ "node": ">=24.13.0"
34
+ },
31
35
  "exports": {
32
36
  ".": {
33
37
  "types": "./dist/index.d.ts",
@@ -58,9 +62,8 @@
58
62
  "clean": "rm -rf dist",
59
63
  "dev": "tsc --watch",
60
64
  "lint": "biome check .",
61
- "lint:eslint": "eslint .",
62
65
  "test": "vitest run",
63
- "test:coverage": "vitest run --coverage",
66
+ "test:coverage": "vitest run --coverage --coverage.reporter=json-summary --coverage.reporter=html --coverage.reporter=text",
64
67
  "test:watch": "vitest",
65
68
  "typecheck": "tsc --noEmit"
66
69
  }