@ably/ai-transport 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.
- package/README.md +10 -19
- package/dist/ably-ai-transport.js +1790 -1091
- package/dist/ably-ai-transport.js.map +1 -1
- package/dist/ably-ai-transport.umd.cjs +1 -1
- package/dist/ably-ai-transport.umd.cjs.map +1 -1
- package/dist/constants.d.ts +2 -2
- package/dist/core/agent.d.ts +20 -5
- package/dist/core/channel-options.d.ts +57 -0
- package/dist/core/codec/codec-event.d.ts +9 -0
- package/dist/core/codec/decoder.d.ts +4 -1
- package/dist/core/codec/define-codec.d.ts +100 -0
- package/dist/core/codec/encoder.d.ts +2 -7
- package/dist/core/codec/field-bag.d.ts +85 -0
- package/dist/core/codec/fields.d.ts +141 -0
- package/dist/core/codec/index.d.ts +8 -1
- package/dist/core/codec/input-descriptor-decoder.d.ts +19 -0
- package/dist/core/codec/input-descriptor-encoder.d.ts +22 -0
- package/dist/core/codec/input-descriptors.d.ts +281 -0
- package/dist/core/codec/output-descriptor-decoder.d.ts +29 -0
- package/dist/core/codec/output-descriptor-encoder.d.ts +31 -0
- package/dist/core/codec/output-descriptors.d.ts +237 -0
- package/dist/core/codec/types.d.ts +95 -36
- package/dist/core/codec/well-known-inputs.d.ts +52 -0
- package/dist/core/transport/agent-view.d.ts +296 -0
- package/dist/core/transport/decode-fold.d.ts +40 -32
- package/dist/core/transport/headers.d.ts +30 -1
- package/dist/core/transport/index.d.ts +1 -1
- package/dist/core/transport/invocation.d.ts +1 -1
- package/dist/core/transport/load-history-pages.d.ts +71 -0
- package/dist/core/transport/load-history.d.ts +21 -16
- package/dist/core/transport/run-manager.d.ts +9 -11
- package/dist/core/transport/session-support.d.ts +55 -0
- package/dist/core/transport/tree.d.ts +165 -15
- package/dist/core/transport/types/agent.d.ts +120 -98
- package/dist/core/transport/types/client.d.ts +45 -12
- package/dist/core/transport/types/tree.d.ts +52 -10
- package/dist/core/transport/types/view.d.ts +55 -28
- package/dist/core/transport/view.d.ts +176 -58
- package/dist/core/transport/wire-log.d.ts +102 -0
- package/dist/errors.d.ts +10 -4
- package/dist/index.d.ts +6 -5
- package/dist/react/ably-ai-transport-react.js +784 -415
- package/dist/react/ably-ai-transport-react.js.map +1 -1
- package/dist/react/ably-ai-transport-react.umd.cjs +1 -1
- package/dist/react/ably-ai-transport-react.umd.cjs.map +1 -1
- package/dist/react/contexts/client-session-context.d.ts +2 -1
- package/dist/react/contexts/client-session-provider.d.ts +3 -0
- package/dist/react/index.d.ts +2 -1
- package/dist/react/internal/skipped-session.d.ts +8 -0
- package/dist/react/use-view.d.ts +3 -3
- package/dist/utils.d.ts +22 -54
- package/dist/vercel/ably-ai-transport-vercel.js +2297 -2026
- package/dist/vercel/ably-ai-transport-vercel.js.map +1 -1
- package/dist/vercel/ably-ai-transport-vercel.umd.cjs +1 -1
- package/dist/vercel/ably-ai-transport-vercel.umd.cjs.map +1 -1
- package/dist/vercel/codec/decode-lifecycle.d.ts +9 -0
- package/dist/vercel/codec/events.d.ts +1 -2
- package/dist/vercel/codec/fields.d.ts +44 -0
- package/dist/vercel/codec/fold-content.d.ts +16 -0
- package/dist/vercel/codec/fold-data.d.ts +16 -0
- package/dist/vercel/codec/fold-input.d.ts +67 -0
- package/dist/vercel/codec/fold-lifecycle.d.ts +16 -0
- package/dist/vercel/codec/fold-text.d.ts +16 -0
- package/dist/vercel/codec/fold-tool-input.d.ts +17 -0
- package/dist/vercel/codec/fold-tool-output.d.ts +16 -0
- package/dist/vercel/codec/index.d.ts +5 -30
- package/dist/vercel/codec/inputs.d.ts +11 -0
- package/dist/vercel/codec/outputs.d.ts +11 -0
- package/dist/vercel/codec/reducer-state.d.ts +121 -0
- package/dist/vercel/codec/reducer.d.ts +20 -102
- package/dist/vercel/codec/tool-transitions.d.ts +0 -6
- package/dist/vercel/codec/wire-data.d.ts +34 -0
- package/dist/vercel/index.d.ts +1 -0
- package/dist/vercel/react/ably-ai-transport-vercel-react.js +2013 -9500
- package/dist/vercel/react/ably-ai-transport-vercel-react.js.map +1 -1
- package/dist/vercel/react/ably-ai-transport-vercel-react.umd.cjs +1 -70
- package/dist/vercel/react/ably-ai-transport-vercel-react.umd.cjs.map +1 -1
- package/dist/vercel/react/contexts/chat-transport-context.d.ts +2 -1
- package/dist/vercel/run-end-reason.d.ts +66 -11
- package/dist/vercel/tool-part.d.ts +21 -0
- package/dist/vercel/transport/chat-transport.d.ts +0 -2
- package/dist/vercel/transport/index.d.ts +1 -1
- package/dist/vercel/transport/run-output-stream.d.ts +6 -8
- package/dist/version.d.ts +1 -1
- package/package.json +2 -2
- package/src/constants.ts +2 -2
- package/src/core/agent.ts +43 -19
- package/src/core/channel-options.ts +89 -0
- package/src/core/codec/codec-event.ts +27 -0
- package/src/core/codec/decoder.ts +145 -21
- package/src/core/codec/define-codec.ts +432 -0
- package/src/core/codec/encoder.ts +13 -54
- package/src/core/codec/field-bag.ts +142 -0
- package/src/core/codec/fields.ts +193 -0
- package/src/core/codec/index.ts +43 -0
- package/src/core/codec/input-descriptor-decoder.ts +97 -0
- package/src/core/codec/input-descriptor-encoder.ts +150 -0
- package/src/core/codec/input-descriptors.ts +373 -0
- package/src/core/codec/output-descriptor-decoder.ts +139 -0
- package/src/core/codec/output-descriptor-encoder.ts +101 -0
- package/src/core/codec/output-descriptors.ts +307 -0
- package/src/core/codec/types.ts +99 -36
- package/src/core/codec/well-known-inputs.ts +96 -0
- package/src/core/transport/agent-session.ts +330 -589
- package/src/core/transport/agent-view.ts +738 -0
- package/src/core/transport/client-session.ts +74 -69
- package/src/core/transport/decode-fold.ts +57 -47
- package/src/core/transport/headers.ts +57 -4
- package/src/core/transport/index.ts +2 -1
- package/src/core/transport/invocation.ts +1 -1
- package/src/core/transport/load-history-pages.ts +220 -0
- package/src/core/transport/load-history.ts +63 -61
- package/src/core/transport/pipe-stream.ts +10 -1
- package/src/core/transport/run-manager.ts +25 -31
- package/src/core/transport/session-support.ts +96 -0
- package/src/core/transport/tree.ts +414 -47
- package/src/core/transport/types/agent.ts +129 -102
- package/src/core/transport/types/client.ts +49 -13
- package/src/core/transport/types/tree.ts +61 -12
- package/src/core/transport/types/view.ts +57 -28
- package/src/core/transport/view.ts +520 -172
- package/src/core/transport/wire-log.ts +189 -0
- package/src/errors.ts +10 -3
- package/src/index.ts +44 -11
- package/src/react/contexts/client-session-context.ts +1 -1
- package/src/react/contexts/client-session-provider.tsx +38 -2
- package/src/react/index.ts +2 -1
- package/src/react/internal/skipped-session.ts +62 -0
- package/src/react/use-client-session.ts +7 -30
- package/src/react/use-view.ts +3 -3
- package/src/utils.ts +31 -97
- package/src/vercel/codec/decode-lifecycle.ts +70 -0
- package/src/vercel/codec/events.ts +1 -3
- package/src/vercel/codec/fields.ts +58 -0
- package/src/vercel/codec/fold-content.ts +54 -0
- package/src/vercel/codec/fold-data.ts +46 -0
- package/src/vercel/codec/fold-input.ts +255 -0
- package/src/vercel/codec/fold-lifecycle.ts +85 -0
- package/src/vercel/codec/fold-text.ts +55 -0
- package/src/vercel/codec/fold-tool-input.ts +86 -0
- package/src/vercel/codec/fold-tool-output.ts +79 -0
- package/src/vercel/codec/index.ts +23 -63
- package/src/vercel/codec/inputs.ts +116 -0
- package/src/vercel/codec/outputs.ts +207 -0
- package/src/vercel/codec/reducer-state.ts +169 -0
- package/src/vercel/codec/reducer.ts +52 -838
- package/src/vercel/codec/tool-transitions.ts +1 -12
- package/src/vercel/codec/wire-data.ts +64 -0
- package/src/vercel/index.ts +1 -0
- package/src/vercel/react/contexts/chat-transport-context.ts +1 -1
- package/src/vercel/react/use-chat-transport.ts +8 -28
- package/src/vercel/react/use-message-sync.ts +5 -10
- package/src/vercel/run-end-reason.ts +95 -16
- package/src/vercel/tool-part.ts +25 -0
- package/src/vercel/transport/chat-transport.ts +10 -22
- package/src/vercel/transport/index.ts +1 -1
- package/src/vercel/transport/run-output-stream.ts +7 -8
- package/src/version.ts +1 -1
- package/dist/core/transport/branch-chain.d.ts +0 -43
- package/dist/core/transport/load-conversation.d.ts +0 -128
- package/dist/vercel/codec/decoder.d.ts +0 -9
- package/dist/vercel/codec/encoder.d.ts +0 -11
- package/src/core/transport/branch-chain.ts +0 -58
- package/src/core/transport/load-conversation.ts +0 -355
- package/src/vercel/codec/decoder.ts +0 -696
- package/src/vercel/codec/encoder.ts +0 -548
|
@@ -3,7 +3,10 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Handles the Ably message action patterns (create, append, update, delete)
|
|
5
5
|
* and delegates to domain-specific hooks for event building and discrete
|
|
6
|
-
* event decoding.
|
|
6
|
+
* event decoding. Stream trackers are version-guarded: a delivery whose
|
|
7
|
+
* `Message.version.serial` the tracker has already incorporated decodes to
|
|
8
|
+
* nothing, so the same decoder instance can serve both the live
|
|
9
|
+
* subscription and history hydration without double-decoding.
|
|
7
10
|
*
|
|
8
11
|
* Domain decoders call `createDecoderCore(hooks, options)` and provide hooks
|
|
9
12
|
* for stream classification, event building, and discrete decoding. Hooks
|
|
@@ -102,7 +105,7 @@ class DefaultDecoderCore<TEvent> implements DecoderCore<TEvent> {
|
|
|
102
105
|
case 'message.create': {
|
|
103
106
|
const payload = this._toPayload(message);
|
|
104
107
|
return payload.transportHeaders?.[HEADER_STREAM] === 'true'
|
|
105
|
-
? this._decodeStreamedCreate(payload, message.serial)
|
|
108
|
+
? this._decodeStreamedCreate(payload, message.serial, message.version.serial)
|
|
106
109
|
: this._hooks.decodeDiscrete(payload);
|
|
107
110
|
}
|
|
108
111
|
|
|
@@ -169,13 +172,120 @@ class DefaultDecoderCore<TEvent> implements DecoderCore<TEvent> {
|
|
|
169
172
|
}
|
|
170
173
|
}
|
|
171
174
|
|
|
175
|
+
// -------------------------------------------------------------------------
|
|
176
|
+
// Private: version guard
|
|
177
|
+
// -------------------------------------------------------------------------
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Whether a delivery is already incorporated into (or out of contract for)
|
|
181
|
+
* an existing tracker, and so must decode to nothing. Covers two cases:
|
|
182
|
+
*
|
|
183
|
+
* - The delivery carries a `version.serial` at or below the tracker's —
|
|
184
|
+
* the mutation it describes is already incorporated (a history aggregate
|
|
185
|
+
* covered by live deltas, a resume retransmission, a whole-wire replay).
|
|
186
|
+
* - The tracker is closed — the stream has ended and its accumulated text
|
|
187
|
+
* has been dropped, so nothing further can fold into it. In-contract
|
|
188
|
+
* replays are already covered by the version check; this catches
|
|
189
|
+
* out-of-contract version-less deliveries for an ended stream.
|
|
190
|
+
*
|
|
191
|
+
* A version-bearing delivery that passes advances the tracker's version.
|
|
192
|
+
* @param method - Calling method name, for log messages.
|
|
193
|
+
* @param serial - The message serial (the tracker's key).
|
|
194
|
+
* @param tracker - The existing tracker for the serial.
|
|
195
|
+
* @param version - The delivery's `Message.version.serial`, if present.
|
|
196
|
+
* @returns True when the delivery must decode to nothing.
|
|
197
|
+
*/
|
|
198
|
+
private _alreadyIncorporated(
|
|
199
|
+
method: string,
|
|
200
|
+
serial: string,
|
|
201
|
+
tracker: StreamTrackerState,
|
|
202
|
+
version: string | undefined,
|
|
203
|
+
): boolean {
|
|
204
|
+
if (version !== undefined && version <= tracker.version) {
|
|
205
|
+
this._logger?.debug(`DefaultDecoderCore.${method}(); delivery already incorporated`, {
|
|
206
|
+
serial,
|
|
207
|
+
version,
|
|
208
|
+
trackerVersion: tracker.version,
|
|
209
|
+
});
|
|
210
|
+
return true;
|
|
211
|
+
}
|
|
212
|
+
if (tracker.closed) {
|
|
213
|
+
this._logger?.debug(`DefaultDecoderCore.${method}(); stream closed, dropping delivery`, { serial, version });
|
|
214
|
+
return true;
|
|
215
|
+
}
|
|
216
|
+
if (version !== undefined) tracker.version = version;
|
|
217
|
+
return false;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* Close a tracker, dropping its accumulated text. What remains is a
|
|
222
|
+
* `{version, closed}` tombstone: enough to recognise covered replays and
|
|
223
|
+
* out-of-contract post-close deliveries, without retaining the stream's
|
|
224
|
+
* full content for the decoder's lifetime.
|
|
225
|
+
* @param tracker - The tracker to close.
|
|
226
|
+
*/
|
|
227
|
+
private _closeTracker(tracker: StreamTrackerState): void {
|
|
228
|
+
tracker.closed = true;
|
|
229
|
+
tracker.accumulated = '';
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
// -------------------------------------------------------------------------
|
|
233
|
+
// Private: terminal-status transition
|
|
234
|
+
// -------------------------------------------------------------------------
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* Apply a stream's terminal status (complete / cancelled) to a tracker. On
|
|
238
|
+
* `complete` it emits end events (read before the tracker is closed) and
|
|
239
|
+
* then closes the tracker; on `cancelled` it closes silently. Both the
|
|
240
|
+
* append and prefix-match update paths funnel through here so they can't
|
|
241
|
+
* diverge. Covered replays and post-close deliveries are filtered upstream
|
|
242
|
+
* by `_alreadyIncorporated`, so no closed-once guard is needed here.
|
|
243
|
+
* Returns whether a terminal transition fired (so callers can log it).
|
|
244
|
+
* @param tracker - The stream tracker to close.
|
|
245
|
+
* @param status - The status header value from the message (may be undefined).
|
|
246
|
+
* @param closingCodecHeaders - Codec headers from the closing message, passed to buildEndEvents.
|
|
247
|
+
* @param outputs - The output array end events are pushed into.
|
|
248
|
+
* @returns True when this call closed the tracker; false otherwise.
|
|
249
|
+
*/
|
|
250
|
+
private _applyTerminalStatus(
|
|
251
|
+
tracker: StreamTrackerState,
|
|
252
|
+
status: string | undefined,
|
|
253
|
+
closingCodecHeaders: Record<string, string>,
|
|
254
|
+
outputs: TEvent[],
|
|
255
|
+
): boolean {
|
|
256
|
+
if (status === 'complete') {
|
|
257
|
+
outputs.push(...this._hooks.buildEndEvents(tracker, closingCodecHeaders));
|
|
258
|
+
this._closeTracker(tracker);
|
|
259
|
+
return true;
|
|
260
|
+
}
|
|
261
|
+
if (status === 'cancelled') {
|
|
262
|
+
this._closeTracker(tracker);
|
|
263
|
+
return true;
|
|
264
|
+
}
|
|
265
|
+
return false;
|
|
266
|
+
}
|
|
267
|
+
|
|
172
268
|
// -------------------------------------------------------------------------
|
|
173
269
|
// Private: streamed message create
|
|
174
270
|
// -------------------------------------------------------------------------
|
|
175
271
|
|
|
176
|
-
private _decodeStreamedCreate(
|
|
272
|
+
private _decodeStreamedCreate(
|
|
273
|
+
payload: MessagePayload,
|
|
274
|
+
serial: string | undefined,
|
|
275
|
+
version: string | undefined,
|
|
276
|
+
): TEvent[] {
|
|
177
277
|
if (!serial) return [];
|
|
178
278
|
|
|
279
|
+
const existing = this._serialState.get(serial);
|
|
280
|
+
if (existing) {
|
|
281
|
+
// A create is the message's first version, so a tracker for this serial
|
|
282
|
+
// has already incorporated it (resume retransmission, whole-wire replay).
|
|
283
|
+
this._logger?.debug('DefaultDecoderCore._decodeStreamedCreate(); duplicate create for tracked stream', {
|
|
284
|
+
serial,
|
|
285
|
+
});
|
|
286
|
+
return [];
|
|
287
|
+
}
|
|
288
|
+
|
|
179
289
|
const streamId = payload.transportHeaders?.[HEADER_STREAM_ID] ?? '';
|
|
180
290
|
|
|
181
291
|
const tracker: StreamTrackerState = {
|
|
@@ -184,6 +294,7 @@ class DefaultDecoderCore<TEvent> implements DecoderCore<TEvent> {
|
|
|
184
294
|
accumulated: '',
|
|
185
295
|
codecHeaders: { ...payload.codecHeaders },
|
|
186
296
|
transportHeaders: { ...payload.transportHeaders },
|
|
297
|
+
version: version ?? serial,
|
|
187
298
|
closed: false,
|
|
188
299
|
};
|
|
189
300
|
this._serialState.set(serial, tracker);
|
|
@@ -208,10 +319,18 @@ class DefaultDecoderCore<TEvent> implements DecoderCore<TEvent> {
|
|
|
208
319
|
|
|
209
320
|
const tracker = this._serialState.get(serial);
|
|
210
321
|
if (!tracker) {
|
|
211
|
-
//
|
|
322
|
+
// Out of contract: the platform converts the first post-attach append
|
|
323
|
+
// of an in-flight message into a full-contents update, so an append
|
|
324
|
+
// should never be a stream's first contact. Keep the first-contact
|
|
325
|
+
// heuristic as a defensive fallback.
|
|
326
|
+
this._logger?.warn('DefaultDecoderCore._decodeAppend(); append with no tracker, treating as first contact', {
|
|
327
|
+
serial,
|
|
328
|
+
});
|
|
212
329
|
return this._decodeUpdate(message);
|
|
213
330
|
}
|
|
214
331
|
|
|
332
|
+
if (this._alreadyIncorporated('_decodeAppend', serial, tracker, message.version.serial)) return [];
|
|
333
|
+
|
|
215
334
|
const transport = getTransportHeaders(message);
|
|
216
335
|
const closingCodec = getCodecHeaders(message);
|
|
217
336
|
const delta = typeof message.data === 'string' ? message.data : '';
|
|
@@ -223,13 +342,13 @@ class DefaultDecoderCore<TEvent> implements DecoderCore<TEvent> {
|
|
|
223
342
|
outputs.push(...this._hooks.buildDeltaEvents(tracker, delta));
|
|
224
343
|
}
|
|
225
344
|
|
|
226
|
-
if (status
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
345
|
+
if (this._applyTerminalStatus(tracker, status, closingCodec, outputs)) {
|
|
346
|
+
this._logger?.debug(
|
|
347
|
+
`DefaultDecoderCore._decodeAppend(); stream ${status === 'complete' ? 'complete' : 'cancelled'}`,
|
|
348
|
+
{
|
|
349
|
+
streamId: tracker.streamId,
|
|
350
|
+
},
|
|
351
|
+
);
|
|
233
352
|
}
|
|
234
353
|
|
|
235
354
|
return outputs;
|
|
@@ -253,9 +372,11 @@ class DefaultDecoderCore<TEvent> implements DecoderCore<TEvent> {
|
|
|
253
372
|
const tracker = this._serialState.get(serial);
|
|
254
373
|
|
|
255
374
|
if (!tracker) {
|
|
256
|
-
return this._decodeFirstContact(payload, isStreamed, status, serial);
|
|
375
|
+
return this._decodeFirstContact(payload, isStreamed, status, serial, message.version.serial);
|
|
257
376
|
}
|
|
258
377
|
|
|
378
|
+
if (this._alreadyIncorporated('_decodeUpdate', serial, tracker, message.version.serial)) return [];
|
|
379
|
+
|
|
259
380
|
// Updates to tracked streams use string data for prefix-match accumulation
|
|
260
381
|
const data = this._stringData(message);
|
|
261
382
|
|
|
@@ -269,12 +390,7 @@ class DefaultDecoderCore<TEvent> implements DecoderCore<TEvent> {
|
|
|
269
390
|
outputs.push(...this._hooks.buildDeltaEvents(tracker, delta));
|
|
270
391
|
}
|
|
271
392
|
|
|
272
|
-
|
|
273
|
-
tracker.closed = true;
|
|
274
|
-
outputs.push(...this._hooks.buildEndEvents(tracker, codec));
|
|
275
|
-
} else if (status === 'cancelled' && !tracker.closed) {
|
|
276
|
-
tracker.closed = true;
|
|
277
|
-
}
|
|
393
|
+
this._applyTerminalStatus(tracker, status, codec, outputs);
|
|
278
394
|
|
|
279
395
|
return outputs;
|
|
280
396
|
}
|
|
@@ -294,6 +410,7 @@ class DefaultDecoderCore<TEvent> implements DecoderCore<TEvent> {
|
|
|
294
410
|
isStreamed: boolean,
|
|
295
411
|
status: string | undefined,
|
|
296
412
|
serial: string,
|
|
413
|
+
version: string | undefined,
|
|
297
414
|
): TEvent[] {
|
|
298
415
|
// Non-streamed messages are discrete
|
|
299
416
|
if (!isStreamed) {
|
|
@@ -317,7 +434,8 @@ class DefaultDecoderCore<TEvent> implements DecoderCore<TEvent> {
|
|
|
317
434
|
accumulated: data,
|
|
318
435
|
codecHeaders: { ...codec },
|
|
319
436
|
transportHeaders: { ...payload.transportHeaders },
|
|
320
|
-
|
|
437
|
+
version: version ?? serial,
|
|
438
|
+
closed: false,
|
|
321
439
|
};
|
|
322
440
|
this._serialState.set(serial, newTracker);
|
|
323
441
|
|
|
@@ -332,6 +450,10 @@ class DefaultDecoderCore<TEvent> implements DecoderCore<TEvent> {
|
|
|
332
450
|
outputs.push(...this._hooks.buildEndEvents(newTracker, codec));
|
|
333
451
|
}
|
|
334
452
|
|
|
453
|
+
if (status === 'complete' || status === 'cancelled') {
|
|
454
|
+
this._closeTracker(newTracker);
|
|
455
|
+
}
|
|
456
|
+
|
|
335
457
|
return outputs;
|
|
336
458
|
}
|
|
337
459
|
|
|
@@ -349,8 +471,10 @@ class DefaultDecoderCore<TEvent> implements DecoderCore<TEvent> {
|
|
|
349
471
|
this._invokeOnStreamDelete(serial, tracker);
|
|
350
472
|
|
|
351
473
|
if (tracker) {
|
|
352
|
-
tracker
|
|
353
|
-
|
|
474
|
+
// No need to advance the tracker's version here: `_closeTracker` leaves a
|
|
475
|
+
// closed tombstone, and `_alreadyIncorporated`'s closed check drops every
|
|
476
|
+
// later delivery regardless of version.
|
|
477
|
+
this._closeTracker(tracker);
|
|
354
478
|
}
|
|
355
479
|
|
|
356
480
|
this._logger?.debug('DefaultDecoderCore._decodeDelete();', { serial });
|