@company-semantics/contracts 0.60.2 → 0.61.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/chat/index.ts +19 -2
- package/src/chat/types.ts +176 -12
package/package.json
CHANGED
package/src/chat/index.ts
CHANGED
|
@@ -24,8 +24,25 @@ export type {
|
|
|
24
24
|
ChatSummaryExtended,
|
|
25
25
|
TitleGenerationRequest,
|
|
26
26
|
TitleGenerationResponse,
|
|
27
|
+
// Event system types
|
|
28
|
+
BaseEvent,
|
|
29
|
+
InvalidationReason,
|
|
30
|
+
ChatChangedField,
|
|
31
|
+
// Domain events (carry full state)
|
|
32
|
+
ChatCreatedEvent,
|
|
33
|
+
ChatUpdatedEvent,
|
|
34
|
+
ChatDeletedEvent,
|
|
35
|
+
ChatDomainEvent,
|
|
36
|
+
// Invalidation events (staleness signals)
|
|
37
|
+
InvalidateChatEvent,
|
|
38
|
+
InvalidateChatListEvent,
|
|
39
|
+
ChatInvalidationEvent,
|
|
40
|
+
// SSE event unions
|
|
27
41
|
ChatSseEvent,
|
|
28
42
|
ChatUpdateEvent,
|
|
29
|
-
//
|
|
30
|
-
|
|
43
|
+
// Legacy types (deprecated, for migration)
|
|
44
|
+
LegacyChatCreatedEvent,
|
|
45
|
+
LegacyChatInvalidatedEvent,
|
|
46
|
+
LegacyChatListInvalidatedEvent,
|
|
47
|
+
LegacyChatSseEvent,
|
|
31
48
|
} from './types'
|
package/src/chat/types.ts
CHANGED
|
@@ -169,14 +169,44 @@ export interface TitleGenerationResponse {
|
|
|
169
169
|
isAutoGenerated: boolean
|
|
170
170
|
}
|
|
171
171
|
|
|
172
|
+
// =============================================================================
|
|
173
|
+
// Event System Types
|
|
174
|
+
// =============================================================================
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Base envelope for all SSE events.
|
|
178
|
+
*
|
|
179
|
+
* INV-EVENT-ORDER-1: Domain events for a given entity are emitted in commit order.
|
|
180
|
+
* Clients may assume monotonic updatedAt.
|
|
181
|
+
* INV-EVENT-IDEMPOTENT: Clients must treat events as idempotent. Full payload
|
|
182
|
+
* replacement handles duplicate events naturally.
|
|
183
|
+
* INV-EVENT-CONVERGENCE: Clients must assume events may be missed during SSE
|
|
184
|
+
* disconnects. Invalidation events ensure convergence.
|
|
185
|
+
*/
|
|
186
|
+
export interface BaseEvent {
|
|
187
|
+
/** Protocol version for forward compatibility */
|
|
188
|
+
v: 1
|
|
189
|
+
/** ISO 8601 timestamp when event was created */
|
|
190
|
+
timestamp: string
|
|
191
|
+
/** Optional event ID for telemetry/debugging (not for deduplication logic) */
|
|
192
|
+
eventId?: string
|
|
193
|
+
}
|
|
194
|
+
|
|
172
195
|
/**
|
|
173
|
-
*
|
|
174
|
-
*
|
|
196
|
+
* Reason for cache invalidation.
|
|
197
|
+
* INV-REASON-TELEMETRY: This is for telemetry only. UI behavior must be
|
|
198
|
+
* identical regardless of reason. Do not branch on this.
|
|
175
199
|
*/
|
|
176
|
-
export type
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
200
|
+
export type InvalidationReason = 'external-mutation' | 'bulk-operation' | 'sync-required'
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* Fields that can change on a chat, used in changed[] array.
|
|
204
|
+
*/
|
|
205
|
+
export type ChatChangedField = 'title' | 'titleSource' | 'status' | 'pinnedAt'
|
|
206
|
+
|
|
207
|
+
// =============================================================================
|
|
208
|
+
// Domain Events (past-tense facts, carry full state)
|
|
209
|
+
// =============================================================================
|
|
180
210
|
|
|
181
211
|
/**
|
|
182
212
|
* Emitted exactly once after a chat is successfully persisted.
|
|
@@ -185,18 +215,152 @@ export type ChatSseEvent =
|
|
|
185
215
|
* INV-EVENT-1: This event is emitted exactly once per successful stream.
|
|
186
216
|
* INV-PERSIST-1: Chat record + messages are committed atomically before this event.
|
|
187
217
|
*/
|
|
188
|
-
export interface ChatCreatedEvent {
|
|
218
|
+
export interface ChatCreatedEvent extends BaseEvent {
|
|
219
|
+
type: 'chat.created'
|
|
220
|
+
data: {
|
|
221
|
+
/** Canonical server-generated UUID - use this for URLs */
|
|
222
|
+
chatId: string
|
|
223
|
+
/** Client-provided ID for correlation (optional) */
|
|
224
|
+
interactionId?: string
|
|
225
|
+
/** Chat title */
|
|
226
|
+
title: string
|
|
227
|
+
/** How the title was set */
|
|
228
|
+
titleSource: TitleSource
|
|
229
|
+
/** Chat status */
|
|
230
|
+
status: ChatStatus
|
|
231
|
+
/** When pinned (null if not pinned) */
|
|
232
|
+
pinnedAt: string | null
|
|
233
|
+
/** Message count */
|
|
234
|
+
messageCount: number
|
|
235
|
+
/** ISO timestamp */
|
|
236
|
+
createdAt: string
|
|
237
|
+
/** ISO timestamp */
|
|
238
|
+
updatedAt: string
|
|
239
|
+
/** Whether chat is shared */
|
|
240
|
+
isShared: boolean
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* Emitted when chat metadata changes (title, pin, archive, etc.)
|
|
246
|
+
* Carries full current state - clients should replace local state entirely.
|
|
247
|
+
*/
|
|
248
|
+
export interface ChatUpdatedEvent extends BaseEvent {
|
|
249
|
+
type: 'chat.updated'
|
|
250
|
+
data: {
|
|
251
|
+
chatId: string
|
|
252
|
+
title: string
|
|
253
|
+
titleSource: TitleSource | null
|
|
254
|
+
titleGeneratedAt: string | null
|
|
255
|
+
status: ChatStatus
|
|
256
|
+
pinnedAt: string | null
|
|
257
|
+
messageCount: number
|
|
258
|
+
createdAt: string
|
|
259
|
+
updatedAt: string
|
|
260
|
+
isShared: boolean
|
|
261
|
+
}
|
|
262
|
+
/** What fields changed - for UI optimization only */
|
|
263
|
+
changed: ChatChangedField[]
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
/**
|
|
267
|
+
* Emitted when a chat is deleted.
|
|
268
|
+
*/
|
|
269
|
+
export interface ChatDeletedEvent extends BaseEvent {
|
|
270
|
+
type: 'chat.deleted'
|
|
271
|
+
data: {
|
|
272
|
+
chatId: string
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
// =============================================================================
|
|
277
|
+
// Invalidation Events (staleness signals)
|
|
278
|
+
// =============================================================================
|
|
279
|
+
|
|
280
|
+
/**
|
|
281
|
+
* Single-entity staleness signal.
|
|
282
|
+
* Emitted when a specific chat may be out of sync (e.g., external mutation).
|
|
283
|
+
*/
|
|
284
|
+
export interface InvalidateChatEvent extends BaseEvent {
|
|
285
|
+
type: 'invalidate.chat'
|
|
286
|
+
chatId: string
|
|
287
|
+
reason: InvalidationReason
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
/**
|
|
291
|
+
* Collection staleness signal.
|
|
292
|
+
* Emitted when chat list ordering/filtering may be stale.
|
|
293
|
+
*/
|
|
294
|
+
export interface InvalidateChatListEvent extends BaseEvent {
|
|
295
|
+
type: 'invalidate.chat-list'
|
|
296
|
+
reason: InvalidationReason
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
// =============================================================================
|
|
300
|
+
// SSE Event Union
|
|
301
|
+
// =============================================================================
|
|
302
|
+
|
|
303
|
+
/**
|
|
304
|
+
* All domain events that carry full state.
|
|
305
|
+
*/
|
|
306
|
+
export type ChatDomainEvent = ChatCreatedEvent | ChatUpdatedEvent | ChatDeletedEvent
|
|
307
|
+
|
|
308
|
+
/**
|
|
309
|
+
* All invalidation events that signal staleness.
|
|
310
|
+
*/
|
|
311
|
+
export type ChatInvalidationEvent = InvalidateChatEvent | InvalidateChatListEvent
|
|
312
|
+
|
|
313
|
+
/**
|
|
314
|
+
* SSE event types for chat updates.
|
|
315
|
+
* Client receives these via SSE and handles accordingly.
|
|
316
|
+
*/
|
|
317
|
+
export type ChatSseEvent = ChatDomainEvent | ChatInvalidationEvent
|
|
318
|
+
|
|
319
|
+
/**
|
|
320
|
+
* Convenience alias for backwards compat.
|
|
321
|
+
*/
|
|
322
|
+
export type ChatUpdateEvent = ChatSseEvent
|
|
323
|
+
|
|
324
|
+
// =============================================================================
|
|
325
|
+
// Legacy Event Types (deprecated, for migration period only)
|
|
326
|
+
// =============================================================================
|
|
327
|
+
|
|
328
|
+
/**
|
|
329
|
+
* @deprecated Use ChatCreatedEvent with v:1 instead.
|
|
330
|
+
* Legacy event shape without v field or data wrapper.
|
|
331
|
+
*/
|
|
332
|
+
export interface LegacyChatCreatedEvent {
|
|
189
333
|
type: 'chat.created'
|
|
190
|
-
/** Canonical server-generated UUID - use this for URLs */
|
|
191
334
|
chatId: string
|
|
192
|
-
/** Client-provided ID for correlation (optional) */
|
|
193
335
|
interactionId?: string
|
|
194
|
-
/** Auto-generated title from first message */
|
|
195
336
|
title?: string
|
|
196
337
|
timestamp: string
|
|
197
338
|
}
|
|
198
339
|
|
|
199
340
|
/**
|
|
200
|
-
*
|
|
341
|
+
* @deprecated Use InvalidateChatEvent instead.
|
|
342
|
+
* Legacy invalidation event without v field.
|
|
201
343
|
*/
|
|
202
|
-
export
|
|
344
|
+
export interface LegacyChatInvalidatedEvent {
|
|
345
|
+
type: 'chat.invalidated'
|
|
346
|
+
chatId: string
|
|
347
|
+
timestamp: string
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
/**
|
|
351
|
+
* @deprecated Use InvalidateChatListEvent instead.
|
|
352
|
+
* Legacy list invalidation event without v field.
|
|
353
|
+
*/
|
|
354
|
+
export interface LegacyChatListInvalidatedEvent {
|
|
355
|
+
type: 'chat.list.invalidated'
|
|
356
|
+
timestamp: string
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
/**
|
|
360
|
+
* @deprecated Use ChatSseEvent instead.
|
|
361
|
+
* Legacy SSE event union for migration period.
|
|
362
|
+
*/
|
|
363
|
+
export type LegacyChatSseEvent =
|
|
364
|
+
| LegacyChatInvalidatedEvent
|
|
365
|
+
| LegacyChatListInvalidatedEvent
|
|
366
|
+
| LegacyChatCreatedEvent
|