@secondlayer/sdk 6.39.0 → 6.40.1
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/dist/index.d.ts +69 -3
- package/dist/index.js +69 -37
- package/dist/index.js.map +7 -7
- package/dist/streams/index.d.ts +69 -3
- package/dist/streams/index.js +67 -36
- package/dist/streams/index.js.map +6 -6
- package/dist/subgraphs/index.d.ts +69 -3
- package/dist/subgraphs/index.js +69 -37
- package/dist/subgraphs/index.js.map +6 -6
- package/package.json +4 -2
package/dist/streams/index.d.ts
CHANGED
|
@@ -230,6 +230,12 @@ type StreamsEventBase = {
|
|
|
230
230
|
* Optional for back-compat; the API always sets it on Streams responses.
|
|
231
231
|
*/
|
|
232
232
|
finalized?: boolean
|
|
233
|
+
/**
|
|
234
|
+
* Labels whose filter group this event satisfied, present only when the
|
|
235
|
+
* request used a labelled `filters` map. The SDK dispatches on it for you
|
|
236
|
+
* (`on.<label>`), so handlers rarely read it directly.
|
|
237
|
+
*/
|
|
238
|
+
matched?: string[]
|
|
233
239
|
};
|
|
234
240
|
type StreamsEventOf<
|
|
235
241
|
T extends StreamsEventType,
|
|
@@ -299,6 +305,34 @@ type StreamsReorgsListEnvelope = {
|
|
|
299
305
|
};
|
|
300
306
|
/** A filter that matches a single value or any value in a list. */
|
|
301
307
|
type StreamsFilterValue = string | readonly string[];
|
|
308
|
+
/**
|
|
309
|
+
* One labelled filter group. Fields inside a group AND together; groups in a
|
|
310
|
+
* map OR together server-side.
|
|
311
|
+
*/
|
|
312
|
+
type StreamsLabelledFilter = {
|
|
313
|
+
types?: readonly StreamsEventType[]
|
|
314
|
+
contractId?: StreamsFilterValue
|
|
315
|
+
sender?: StreamsFilterValue
|
|
316
|
+
recipient?: StreamsFilterValue
|
|
317
|
+
assetIdentifier?: string
|
|
318
|
+
};
|
|
319
|
+
/** A map of label → filter group. Labels are yours; the server echoes them. */
|
|
320
|
+
type StreamsFilterMap = Record<string, StreamsLabelledFilter>;
|
|
321
|
+
/**
|
|
322
|
+
* The events one label can yield. A group that declares `types` narrows to
|
|
323
|
+
* exactly those variants, so a per-label handler needs no `event_type` guard;
|
|
324
|
+
* a group without `types` keeps the full union.
|
|
325
|
+
*/
|
|
326
|
+
type StreamsEventForFilter<
|
|
327
|
+
F,
|
|
328
|
+
D extends boolean = false
|
|
329
|
+
> = F extends {
|
|
330
|
+
types: readonly (infer T extends StreamsEventType)[]
|
|
331
|
+
} ? D extends true ? Extract<IndexEvent, {
|
|
332
|
+
event_type: T
|
|
333
|
+
}> : Extract<StreamsEvent, {
|
|
334
|
+
event_type: T
|
|
335
|
+
}> : D extends true ? IndexEvent : StreamsEvent;
|
|
302
336
|
type StreamsEventsListParams = {
|
|
303
337
|
cursor?: string | null
|
|
304
338
|
fromHeight?: number
|
|
@@ -310,6 +344,12 @@ type StreamsEventsListParams = {
|
|
|
310
344
|
sender?: StreamsFilterValue
|
|
311
345
|
recipient?: StreamsFilterValue
|
|
312
346
|
assetIdentifier?: string
|
|
347
|
+
/**
|
|
348
|
+
* Labelled filter groups. The groups OR together in one scan and each
|
|
349
|
+
* returned event carries the labels it matched (`event.matched`) — two
|
|
350
|
+
* unrelated concerns share one page, one cursor, one checkpoint.
|
|
351
|
+
*/
|
|
352
|
+
filters?: StreamsFilterMap
|
|
313
353
|
limit?: number
|
|
314
354
|
};
|
|
315
355
|
type StreamsEventsStreamParams = {
|
|
@@ -320,6 +360,8 @@ type StreamsEventsStreamParams = {
|
|
|
320
360
|
sender?: StreamsFilterValue
|
|
321
361
|
recipient?: StreamsFilterValue
|
|
322
362
|
assetIdentifier?: string
|
|
363
|
+
/** Labelled filter groups; see {@link StreamsEventsListParams.filters}. */
|
|
364
|
+
filters?: StreamsFilterMap
|
|
323
365
|
batchSize?: number
|
|
324
366
|
emptyBackoffMs?: number
|
|
325
367
|
maxPages?: number
|
|
@@ -335,6 +377,8 @@ type StreamsEventsSubscribeParams = {
|
|
|
335
377
|
sender?: StreamsFilterValue
|
|
336
378
|
recipient?: StreamsFilterValue
|
|
337
379
|
assetIdentifier?: string
|
|
380
|
+
/** Labelled filter groups; see {@link StreamsEventsListParams.filters}. */
|
|
381
|
+
filters?: StreamsFilterMap
|
|
338
382
|
/** Abort to unsubscribe (the returned function does the same). */
|
|
339
383
|
signal?: AbortSignal
|
|
340
384
|
/** Called for each pushed event, in order. */
|
|
@@ -386,7 +430,8 @@ type StreamsReorgContext = {
|
|
|
386
430
|
};
|
|
387
431
|
type StreamsEventsConsumeParams<
|
|
388
432
|
TTx = never,
|
|
389
|
-
D extends boolean = false
|
|
433
|
+
D extends boolean = false,
|
|
434
|
+
F extends StreamsFilterMap = Record<never, never>
|
|
390
435
|
> = {
|
|
391
436
|
fromCursor?: string | null
|
|
392
437
|
/**
|
|
@@ -420,13 +465,33 @@ type StreamsEventsConsumeParams<
|
|
|
420
465
|
sender?: StreamsFilterValue
|
|
421
466
|
recipient?: StreamsFilterValue
|
|
422
467
|
assetIdentifier?: string
|
|
468
|
+
/**
|
|
469
|
+
* Labelled filter groups. The groups OR together in ONE server-side scan,
|
|
470
|
+
* so two unrelated concerns share one page, one cursor, and one checkpoint
|
|
471
|
+
* instead of two consume loops. Pair with `on` to handle each label.
|
|
472
|
+
*/
|
|
473
|
+
filters?: F
|
|
474
|
+
/**
|
|
475
|
+
* One handler per label in `filters`. Every label must be handled, so
|
|
476
|
+
* adding a label is a compile error until its handler exists.
|
|
477
|
+
*
|
|
478
|
+
* A label's declared `types` narrows its handler's events, so `payload` is
|
|
479
|
+
* typed without an `event_type` guard. Labels are dispatched in declaration
|
|
480
|
+
* order: a label's own events stay in cursor order, but events of different
|
|
481
|
+
* labels do not interleave within a page — add `onBatch` when you need
|
|
482
|
+
* strict global order across labels.
|
|
483
|
+
*/
|
|
484
|
+
on?: { [K in keyof F] : (events: StreamsEventForFilter<F[K], D>[], ctx: StreamsBatchContext & WithSinkTx<TTx>) => void | Promise<void> }
|
|
423
485
|
batchSize?: number
|
|
424
486
|
/**
|
|
425
487
|
* Apply a page of canonical events. Persist `ctx.cursor` in the same
|
|
426
488
|
* transaction as your writes. Returning a cursor overrides `ctx.cursor` as
|
|
427
489
|
* the resume point (advanced manual control); returning nothing uses it.
|
|
490
|
+
*
|
|
491
|
+
* Optional only when `on` handles the page instead; a consume call with
|
|
492
|
+
* neither throws.
|
|
428
493
|
*/
|
|
429
|
-
onBatch
|
|
494
|
+
onBatch?: (events: D extends true ? IndexEvent[] : StreamsEvent[], envelope: StreamsEventsEnvelope, ctx: StreamsBatchContext & WithSinkTx<TTx>) => void | string | null | undefined | Promise<void> | Promise<string | null | undefined>
|
|
430
495
|
/**
|
|
431
496
|
* Roll your projection back to `reorg.fork_point_height`, persisting
|
|
432
497
|
* `ctx.cursor` in the same transaction. Called once per *new* reorg
|
|
@@ -585,9 +650,10 @@ type StreamsClient = {
|
|
|
585
650
|
* stops it.
|
|
586
651
|
*/
|
|
587
652
|
consume<
|
|
653
|
+
const F extends StreamsFilterMap = Record<never, never>,
|
|
588
654
|
TTx = never,
|
|
589
655
|
D extends boolean = false
|
|
590
|
-
>(params: StreamsEventsConsumeParams<TTx, D> & {
|
|
656
|
+
>(params: StreamsEventsConsumeParams<TTx, D, F> & {
|
|
591
657
|
sink?: ConsumerSink<TTx>
|
|
592
658
|
}): Promise<StreamsEventsConsumeResult>
|
|
593
659
|
/**
|
package/dist/streams/index.js
CHANGED
|
@@ -399,7 +399,8 @@ async function consumeStreamsEvents(opts) {
|
|
|
399
399
|
const emptyBackoffMs = opts.emptyBackoffMs ?? 500;
|
|
400
400
|
const maxPages = opts.maxPages ?? Number.POSITIVE_INFINITY;
|
|
401
401
|
const maxEmptyPolls = opts.maxEmptyPolls ?? Number.POSITIVE_INFINITY;
|
|
402
|
-
|
|
402
|
+
const committedCursor = await opts.sink?.loadCursor() ?? null;
|
|
403
|
+
let cursor = opts.fromCursor ?? committedCursor;
|
|
403
404
|
const handledReorgs = new Set;
|
|
404
405
|
let pages = 0;
|
|
405
406
|
let emptyPolls = 0;
|
|
@@ -413,7 +414,8 @@ async function consumeStreamsEvents(opts) {
|
|
|
413
414
|
contractId: opts.contractId,
|
|
414
415
|
sender: opts.sender,
|
|
415
416
|
recipient: opts.recipient,
|
|
416
|
-
assetIdentifier: opts.assetIdentifier
|
|
417
|
+
assetIdentifier: opts.assetIdentifier,
|
|
418
|
+
filters: opts.filters
|
|
417
419
|
}), {
|
|
418
420
|
retryCount: opts.retryCount,
|
|
419
421
|
retryDelay: opts.retryDelay,
|
|
@@ -490,7 +492,8 @@ async function* iterateStreamsBatches(opts) {
|
|
|
490
492
|
contractId: opts.contractId,
|
|
491
493
|
sender: opts.sender,
|
|
492
494
|
recipient: opts.recipient,
|
|
493
|
-
assetIdentifier: opts.assetIdentifier
|
|
495
|
+
assetIdentifier: opts.assetIdentifier,
|
|
496
|
+
filters: opts.filters
|
|
494
497
|
});
|
|
495
498
|
const checkpoint = envelope.next_cursor ?? cursor;
|
|
496
499
|
if (envelope.events.length > 0 || envelope.reorgs.length > 0) {
|
|
@@ -527,7 +530,8 @@ async function* streamStreamsEvents(opts) {
|
|
|
527
530
|
contractId: opts.contractId,
|
|
528
531
|
sender: opts.sender,
|
|
529
532
|
recipient: opts.recipient,
|
|
530
|
-
assetIdentifier: opts.assetIdentifier
|
|
533
|
+
assetIdentifier: opts.assetIdentifier,
|
|
534
|
+
filters: opts.filters
|
|
531
535
|
});
|
|
532
536
|
pages++;
|
|
533
537
|
for (const event of envelope.events) {
|
|
@@ -802,7 +806,8 @@ function subscribeStreamsEvents(opts) {
|
|
|
802
806
|
contract_id: params.contractId,
|
|
803
807
|
sender: params.sender,
|
|
804
808
|
recipient: params.recipient,
|
|
805
|
-
asset_identifier: params.assetIdentifier
|
|
809
|
+
asset_identifier: params.assetIdentifier,
|
|
810
|
+
filters: params.filters ? JSON.stringify(params.filters) : undefined
|
|
806
811
|
})}`;
|
|
807
812
|
const res = await opts.fetchImpl(url, {
|
|
808
813
|
headers: {
|
|
@@ -1046,7 +1051,8 @@ function createStreamsClient(options) {
|
|
|
1046
1051
|
contractId,
|
|
1047
1052
|
sender,
|
|
1048
1053
|
recipient,
|
|
1049
|
-
assetIdentifier
|
|
1054
|
+
assetIdentifier,
|
|
1055
|
+
filters
|
|
1050
1056
|
}) => {
|
|
1051
1057
|
return listEvents({
|
|
1052
1058
|
cursor,
|
|
@@ -1056,9 +1062,13 @@ function createStreamsClient(options) {
|
|
|
1056
1062
|
contractId,
|
|
1057
1063
|
sender,
|
|
1058
1064
|
recipient,
|
|
1059
|
-
assetIdentifier
|
|
1065
|
+
assetIdentifier,
|
|
1066
|
+
filters
|
|
1060
1067
|
});
|
|
1061
1068
|
};
|
|
1069
|
+
function encodeFilters(filters) {
|
|
1070
|
+
return filters ? JSON.stringify(filters) : undefined;
|
|
1071
|
+
}
|
|
1062
1072
|
async function listEvents(params = {}) {
|
|
1063
1073
|
return request(`/v1/streams/events${buildQuery({
|
|
1064
1074
|
cursor: params.cursor,
|
|
@@ -1070,9 +1080,56 @@ function createStreamsClient(options) {
|
|
|
1070
1080
|
recipient: params.recipient,
|
|
1071
1081
|
asset_identifier: params.assetIdentifier,
|
|
1072
1082
|
types: params.types,
|
|
1073
|
-
not_types: params.notTypes
|
|
1083
|
+
not_types: params.notTypes,
|
|
1084
|
+
filters: encodeFilters(params.filters)
|
|
1074
1085
|
})}`);
|
|
1075
1086
|
}
|
|
1087
|
+
function consumeEvents(params) {
|
|
1088
|
+
const labels = params.filters ? Object.keys(params.filters) : [];
|
|
1089
|
+
if (labels.length === 0 && !params.onBatch) {
|
|
1090
|
+
throw new ValidationError("consume requires onBatch, or filters + on handlers.", 400);
|
|
1091
|
+
}
|
|
1092
|
+
if (labels.length > 0 && !params.on && !params.onBatch) {
|
|
1093
|
+
throw new ValidationError("consume with filters requires on handlers (or onBatch).", 400);
|
|
1094
|
+
}
|
|
1095
|
+
const dispatch = params.on;
|
|
1096
|
+
const project = (events) => params.decoded ? events.map(decode) : events;
|
|
1097
|
+
const onBatch = async (events, envelope, ctx) => {
|
|
1098
|
+
for (const label of labels) {
|
|
1099
|
+
const forLabel = events.filter((event) => event.matched?.includes(label));
|
|
1100
|
+
if (forLabel.length === 0)
|
|
1101
|
+
continue;
|
|
1102
|
+
await dispatch?.[label]?.(project(forLabel), ctx);
|
|
1103
|
+
}
|
|
1104
|
+
const userOnBatch = params.onBatch;
|
|
1105
|
+
return await userOnBatch?.(project(events), envelope, ctx);
|
|
1106
|
+
};
|
|
1107
|
+
return consumeStreamsEvents({
|
|
1108
|
+
fromCursor: params.fromCursor,
|
|
1109
|
+
sink: params.sink,
|
|
1110
|
+
onProgress: params.onProgress,
|
|
1111
|
+
mode: params.mode,
|
|
1112
|
+
finalizedOnly: params.finalizedOnly,
|
|
1113
|
+
types: params.types,
|
|
1114
|
+
notTypes: params.notTypes,
|
|
1115
|
+
contractId: params.contractId,
|
|
1116
|
+
sender: params.sender,
|
|
1117
|
+
recipient: params.recipient,
|
|
1118
|
+
assetIdentifier: params.assetIdentifier,
|
|
1119
|
+
filters: params.filters,
|
|
1120
|
+
batchSize: params.batchSize ?? 100,
|
|
1121
|
+
fetchEvents,
|
|
1122
|
+
onBatch,
|
|
1123
|
+
onReorg: params.onReorg,
|
|
1124
|
+
emptyBackoffMs: params.emptyBackoffMs,
|
|
1125
|
+
maxPages: params.maxPages,
|
|
1126
|
+
maxEmptyPolls: params.maxEmptyPolls,
|
|
1127
|
+
signal: params.signal,
|
|
1128
|
+
retryCount: params.retryCount,
|
|
1129
|
+
retryDelay: params.retryDelay,
|
|
1130
|
+
onError: params.onError
|
|
1131
|
+
});
|
|
1132
|
+
}
|
|
1076
1133
|
return {
|
|
1077
1134
|
consume(params = {}) {
|
|
1078
1135
|
return iterateStreamsBatches({
|
|
@@ -1094,33 +1151,7 @@ function createStreamsClient(options) {
|
|
|
1094
1151
|
byTxId(txId) {
|
|
1095
1152
|
return request(`/v1/streams/events/${encodeURIComponent(txId)}`);
|
|
1096
1153
|
},
|
|
1097
|
-
consume
|
|
1098
|
-
const onBatch = params.decoded ? (events, envelope, ctx) => params.onBatch(events.map(decode), envelope, ctx) : params.onBatch;
|
|
1099
|
-
return consumeStreamsEvents({
|
|
1100
|
-
fromCursor: params.fromCursor,
|
|
1101
|
-
sink: params.sink,
|
|
1102
|
-
onProgress: params.onProgress,
|
|
1103
|
-
mode: params.mode,
|
|
1104
|
-
finalizedOnly: params.finalizedOnly,
|
|
1105
|
-
types: params.types,
|
|
1106
|
-
notTypes: params.notTypes,
|
|
1107
|
-
contractId: params.contractId,
|
|
1108
|
-
sender: params.sender,
|
|
1109
|
-
recipient: params.recipient,
|
|
1110
|
-
assetIdentifier: params.assetIdentifier,
|
|
1111
|
-
batchSize: params.batchSize ?? 100,
|
|
1112
|
-
fetchEvents,
|
|
1113
|
-
onBatch,
|
|
1114
|
-
onReorg: params.onReorg,
|
|
1115
|
-
emptyBackoffMs: params.emptyBackoffMs,
|
|
1116
|
-
maxPages: params.maxPages,
|
|
1117
|
-
maxEmptyPolls: params.maxEmptyPolls,
|
|
1118
|
-
signal: params.signal,
|
|
1119
|
-
retryCount: params.retryCount,
|
|
1120
|
-
retryDelay: params.retryDelay,
|
|
1121
|
-
onError: params.onError
|
|
1122
|
-
});
|
|
1123
|
-
},
|
|
1154
|
+
consume: consumeEvents,
|
|
1124
1155
|
stream(params = {}) {
|
|
1125
1156
|
return streamStreamsEvents({
|
|
1126
1157
|
fromCursor: params.fromCursor,
|
|
@@ -1453,5 +1484,5 @@ export {
|
|
|
1453
1484
|
AuthError
|
|
1454
1485
|
};
|
|
1455
1486
|
|
|
1456
|
-
//# debugId=
|
|
1487
|
+
//# debugId=93D7CDA8BB38740964756E2164756E21
|
|
1457
1488
|
//# sourceMappingURL=index.js.map
|