@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/index.d.ts
CHANGED
|
@@ -509,6 +509,12 @@ type StreamsEventBase = {
|
|
|
509
509
|
* Optional for back-compat; the API always sets it on Streams responses.
|
|
510
510
|
*/
|
|
511
511
|
finalized?: boolean
|
|
512
|
+
/**
|
|
513
|
+
* Labels whose filter group this event satisfied, present only when the
|
|
514
|
+
* request used a labelled `filters` map. The SDK dispatches on it for you
|
|
515
|
+
* (`on.<label>`), so handlers rarely read it directly.
|
|
516
|
+
*/
|
|
517
|
+
matched?: string[]
|
|
512
518
|
};
|
|
513
519
|
type StreamsEventOf<
|
|
514
520
|
T extends StreamsEventType,
|
|
@@ -578,6 +584,34 @@ type StreamsReorgsListEnvelope = {
|
|
|
578
584
|
};
|
|
579
585
|
/** A filter that matches a single value or any value in a list. */
|
|
580
586
|
type StreamsFilterValue = string | readonly string[];
|
|
587
|
+
/**
|
|
588
|
+
* One labelled filter group. Fields inside a group AND together; groups in a
|
|
589
|
+
* map OR together server-side.
|
|
590
|
+
*/
|
|
591
|
+
type StreamsLabelledFilter = {
|
|
592
|
+
types?: readonly StreamsEventType[]
|
|
593
|
+
contractId?: StreamsFilterValue
|
|
594
|
+
sender?: StreamsFilterValue
|
|
595
|
+
recipient?: StreamsFilterValue
|
|
596
|
+
assetIdentifier?: string
|
|
597
|
+
};
|
|
598
|
+
/** A map of label → filter group. Labels are yours; the server echoes them. */
|
|
599
|
+
type StreamsFilterMap = Record<string, StreamsLabelledFilter>;
|
|
600
|
+
/**
|
|
601
|
+
* The events one label can yield. A group that declares `types` narrows to
|
|
602
|
+
* exactly those variants, so a per-label handler needs no `event_type` guard;
|
|
603
|
+
* a group without `types` keeps the full union.
|
|
604
|
+
*/
|
|
605
|
+
type StreamsEventForFilter<
|
|
606
|
+
F,
|
|
607
|
+
D extends boolean = false
|
|
608
|
+
> = F extends {
|
|
609
|
+
types: readonly (infer T extends StreamsEventType)[]
|
|
610
|
+
} ? D extends true ? Extract<IndexEvent, {
|
|
611
|
+
event_type: T
|
|
612
|
+
}> : Extract<StreamsEvent, {
|
|
613
|
+
event_type: T
|
|
614
|
+
}> : D extends true ? IndexEvent : StreamsEvent;
|
|
581
615
|
type StreamsEventsListParams = {
|
|
582
616
|
cursor?: string | null
|
|
583
617
|
fromHeight?: number
|
|
@@ -589,6 +623,12 @@ type StreamsEventsListParams = {
|
|
|
589
623
|
sender?: StreamsFilterValue
|
|
590
624
|
recipient?: StreamsFilterValue
|
|
591
625
|
assetIdentifier?: string
|
|
626
|
+
/**
|
|
627
|
+
* Labelled filter groups. The groups OR together in one scan and each
|
|
628
|
+
* returned event carries the labels it matched (`event.matched`) — two
|
|
629
|
+
* unrelated concerns share one page, one cursor, one checkpoint.
|
|
630
|
+
*/
|
|
631
|
+
filters?: StreamsFilterMap
|
|
592
632
|
limit?: number
|
|
593
633
|
};
|
|
594
634
|
type StreamsEventsStreamParams = {
|
|
@@ -599,6 +639,8 @@ type StreamsEventsStreamParams = {
|
|
|
599
639
|
sender?: StreamsFilterValue
|
|
600
640
|
recipient?: StreamsFilterValue
|
|
601
641
|
assetIdentifier?: string
|
|
642
|
+
/** Labelled filter groups; see {@link StreamsEventsListParams.filters}. */
|
|
643
|
+
filters?: StreamsFilterMap
|
|
602
644
|
batchSize?: number
|
|
603
645
|
emptyBackoffMs?: number
|
|
604
646
|
maxPages?: number
|
|
@@ -614,6 +656,8 @@ type StreamsEventsSubscribeParams = {
|
|
|
614
656
|
sender?: StreamsFilterValue
|
|
615
657
|
recipient?: StreamsFilterValue
|
|
616
658
|
assetIdentifier?: string
|
|
659
|
+
/** Labelled filter groups; see {@link StreamsEventsListParams.filters}. */
|
|
660
|
+
filters?: StreamsFilterMap
|
|
617
661
|
/** Abort to unsubscribe (the returned function does the same). */
|
|
618
662
|
signal?: AbortSignal
|
|
619
663
|
/** Called for each pushed event, in order. */
|
|
@@ -665,7 +709,8 @@ type StreamsReorgContext = {
|
|
|
665
709
|
};
|
|
666
710
|
type StreamsEventsConsumeParams<
|
|
667
711
|
TTx = never,
|
|
668
|
-
D extends boolean = false
|
|
712
|
+
D extends boolean = false,
|
|
713
|
+
F extends StreamsFilterMap = Record<never, never>
|
|
669
714
|
> = {
|
|
670
715
|
fromCursor?: string | null
|
|
671
716
|
/**
|
|
@@ -699,13 +744,33 @@ type StreamsEventsConsumeParams<
|
|
|
699
744
|
sender?: StreamsFilterValue
|
|
700
745
|
recipient?: StreamsFilterValue
|
|
701
746
|
assetIdentifier?: string
|
|
747
|
+
/**
|
|
748
|
+
* Labelled filter groups. The groups OR together in ONE server-side scan,
|
|
749
|
+
* so two unrelated concerns share one page, one cursor, and one checkpoint
|
|
750
|
+
* instead of two consume loops. Pair with `on` to handle each label.
|
|
751
|
+
*/
|
|
752
|
+
filters?: F
|
|
753
|
+
/**
|
|
754
|
+
* One handler per label in `filters`. Every label must be handled, so
|
|
755
|
+
* adding a label is a compile error until its handler exists.
|
|
756
|
+
*
|
|
757
|
+
* A label's declared `types` narrows its handler's events, so `payload` is
|
|
758
|
+
* typed without an `event_type` guard. Labels are dispatched in declaration
|
|
759
|
+
* order: a label's own events stay in cursor order, but events of different
|
|
760
|
+
* labels do not interleave within a page — add `onBatch` when you need
|
|
761
|
+
* strict global order across labels.
|
|
762
|
+
*/
|
|
763
|
+
on?: { [K in keyof F] : (events: StreamsEventForFilter<F[K], D>[], ctx: StreamsBatchContext & WithSinkTx<TTx>) => void | Promise<void> }
|
|
702
764
|
batchSize?: number
|
|
703
765
|
/**
|
|
704
766
|
* Apply a page of canonical events. Persist `ctx.cursor` in the same
|
|
705
767
|
* transaction as your writes. Returning a cursor overrides `ctx.cursor` as
|
|
706
768
|
* the resume point (advanced manual control); returning nothing uses it.
|
|
769
|
+
*
|
|
770
|
+
* Optional only when `on` handles the page instead; a consume call with
|
|
771
|
+
* neither throws.
|
|
707
772
|
*/
|
|
708
|
-
onBatch
|
|
773
|
+
onBatch?: (events: D extends true ? IndexEvent[] : StreamsEvent[], envelope: StreamsEventsEnvelope, ctx: StreamsBatchContext & WithSinkTx<TTx>) => void | string | null | undefined | Promise<void> | Promise<string | null | undefined>
|
|
709
774
|
/**
|
|
710
775
|
* Roll your projection back to `reorg.fork_point_height`, persisting
|
|
711
776
|
* `ctx.cursor` in the same transaction. Called once per *new* reorg
|
|
@@ -864,9 +929,10 @@ type StreamsClient = {
|
|
|
864
929
|
* stops it.
|
|
865
930
|
*/
|
|
866
931
|
consume<
|
|
932
|
+
const F extends StreamsFilterMap = Record<never, never>,
|
|
867
933
|
TTx = never,
|
|
868
934
|
D extends boolean = false
|
|
869
|
-
>(params: StreamsEventsConsumeParams<TTx, D> & {
|
|
935
|
+
>(params: StreamsEventsConsumeParams<TTx, D, F> & {
|
|
870
936
|
sink?: ConsumerSink<TTx>
|
|
871
937
|
}): Promise<StreamsEventsConsumeResult>
|
|
872
938
|
/**
|
package/dist/index.js
CHANGED
|
@@ -655,7 +655,8 @@ async function consumeStreamsEvents(opts) {
|
|
|
655
655
|
const emptyBackoffMs = opts.emptyBackoffMs ?? 500;
|
|
656
656
|
const maxPages = opts.maxPages ?? Number.POSITIVE_INFINITY;
|
|
657
657
|
const maxEmptyPolls = opts.maxEmptyPolls ?? Number.POSITIVE_INFINITY;
|
|
658
|
-
|
|
658
|
+
const committedCursor = await opts.sink?.loadCursor() ?? null;
|
|
659
|
+
let cursor = opts.fromCursor ?? committedCursor;
|
|
659
660
|
const handledReorgs = new Set;
|
|
660
661
|
let pages = 0;
|
|
661
662
|
let emptyPolls = 0;
|
|
@@ -669,7 +670,8 @@ async function consumeStreamsEvents(opts) {
|
|
|
669
670
|
contractId: opts.contractId,
|
|
670
671
|
sender: opts.sender,
|
|
671
672
|
recipient: opts.recipient,
|
|
672
|
-
assetIdentifier: opts.assetIdentifier
|
|
673
|
+
assetIdentifier: opts.assetIdentifier,
|
|
674
|
+
filters: opts.filters
|
|
673
675
|
}), {
|
|
674
676
|
retryCount: opts.retryCount,
|
|
675
677
|
retryDelay: opts.retryDelay,
|
|
@@ -746,7 +748,8 @@ async function* iterateStreamsBatches(opts) {
|
|
|
746
748
|
contractId: opts.contractId,
|
|
747
749
|
sender: opts.sender,
|
|
748
750
|
recipient: opts.recipient,
|
|
749
|
-
assetIdentifier: opts.assetIdentifier
|
|
751
|
+
assetIdentifier: opts.assetIdentifier,
|
|
752
|
+
filters: opts.filters
|
|
750
753
|
});
|
|
751
754
|
const checkpoint = envelope.next_cursor ?? cursor;
|
|
752
755
|
if (envelope.events.length > 0 || envelope.reorgs.length > 0) {
|
|
@@ -783,7 +786,8 @@ async function* streamStreamsEvents(opts) {
|
|
|
783
786
|
contractId: opts.contractId,
|
|
784
787
|
sender: opts.sender,
|
|
785
788
|
recipient: opts.recipient,
|
|
786
|
-
assetIdentifier: opts.assetIdentifier
|
|
789
|
+
assetIdentifier: opts.assetIdentifier,
|
|
790
|
+
filters: opts.filters
|
|
787
791
|
});
|
|
788
792
|
pages++;
|
|
789
793
|
for (const event of envelope.events) {
|
|
@@ -817,7 +821,8 @@ async function consumeIndexFeed(opts) {
|
|
|
817
821
|
const emptyBackoffMs = opts.emptyBackoffMs ?? 500;
|
|
818
822
|
const maxPages = opts.maxPages ?? Number.POSITIVE_INFINITY;
|
|
819
823
|
const maxEmptyPolls = opts.maxEmptyPolls ?? Number.POSITIVE_INFINITY;
|
|
820
|
-
|
|
824
|
+
const committedCursor = await opts.sink?.loadCursor() ?? null;
|
|
825
|
+
let cursor = opts.fromCursor ?? committedCursor;
|
|
821
826
|
const handledReorgs = new Set;
|
|
822
827
|
let pages = 0;
|
|
823
828
|
let emptyPolls = 0;
|
|
@@ -1598,7 +1603,8 @@ function subscribeStreamsEvents(opts) {
|
|
|
1598
1603
|
contract_id: params.contractId,
|
|
1599
1604
|
sender: params.sender,
|
|
1600
1605
|
recipient: params.recipient,
|
|
1601
|
-
asset_identifier: params.assetIdentifier
|
|
1606
|
+
asset_identifier: params.assetIdentifier,
|
|
1607
|
+
filters: params.filters ? JSON.stringify(params.filters) : undefined
|
|
1602
1608
|
})}`;
|
|
1603
1609
|
const res = await opts.fetchImpl(url, {
|
|
1604
1610
|
headers: {
|
|
@@ -1842,7 +1848,8 @@ function createStreamsClient(options) {
|
|
|
1842
1848
|
contractId,
|
|
1843
1849
|
sender,
|
|
1844
1850
|
recipient,
|
|
1845
|
-
assetIdentifier
|
|
1851
|
+
assetIdentifier,
|
|
1852
|
+
filters
|
|
1846
1853
|
}) => {
|
|
1847
1854
|
return listEvents({
|
|
1848
1855
|
cursor,
|
|
@@ -1852,9 +1859,13 @@ function createStreamsClient(options) {
|
|
|
1852
1859
|
contractId,
|
|
1853
1860
|
sender,
|
|
1854
1861
|
recipient,
|
|
1855
|
-
assetIdentifier
|
|
1862
|
+
assetIdentifier,
|
|
1863
|
+
filters
|
|
1856
1864
|
});
|
|
1857
1865
|
};
|
|
1866
|
+
function encodeFilters(filters) {
|
|
1867
|
+
return filters ? JSON.stringify(filters) : undefined;
|
|
1868
|
+
}
|
|
1858
1869
|
async function listEvents(params = {}) {
|
|
1859
1870
|
return request(`/v1/streams/events${buildQuery({
|
|
1860
1871
|
cursor: params.cursor,
|
|
@@ -1866,9 +1877,56 @@ function createStreamsClient(options) {
|
|
|
1866
1877
|
recipient: params.recipient,
|
|
1867
1878
|
asset_identifier: params.assetIdentifier,
|
|
1868
1879
|
types: params.types,
|
|
1869
|
-
not_types: params.notTypes
|
|
1880
|
+
not_types: params.notTypes,
|
|
1881
|
+
filters: encodeFilters(params.filters)
|
|
1870
1882
|
})}`);
|
|
1871
1883
|
}
|
|
1884
|
+
function consumeEvents(params) {
|
|
1885
|
+
const labels = params.filters ? Object.keys(params.filters) : [];
|
|
1886
|
+
if (labels.length === 0 && !params.onBatch) {
|
|
1887
|
+
throw new ValidationError("consume requires onBatch, or filters + on handlers.", 400);
|
|
1888
|
+
}
|
|
1889
|
+
if (labels.length > 0 && !params.on && !params.onBatch) {
|
|
1890
|
+
throw new ValidationError("consume with filters requires on handlers (or onBatch).", 400);
|
|
1891
|
+
}
|
|
1892
|
+
const dispatch = params.on;
|
|
1893
|
+
const project = (events) => params.decoded ? events.map(decode) : events;
|
|
1894
|
+
const onBatch = async (events, envelope, ctx) => {
|
|
1895
|
+
for (const label of labels) {
|
|
1896
|
+
const forLabel = events.filter((event) => event.matched?.includes(label));
|
|
1897
|
+
if (forLabel.length === 0)
|
|
1898
|
+
continue;
|
|
1899
|
+
await dispatch?.[label]?.(project(forLabel), ctx);
|
|
1900
|
+
}
|
|
1901
|
+
const userOnBatch = params.onBatch;
|
|
1902
|
+
return await userOnBatch?.(project(events), envelope, ctx);
|
|
1903
|
+
};
|
|
1904
|
+
return consumeStreamsEvents({
|
|
1905
|
+
fromCursor: params.fromCursor,
|
|
1906
|
+
sink: params.sink,
|
|
1907
|
+
onProgress: params.onProgress,
|
|
1908
|
+
mode: params.mode,
|
|
1909
|
+
finalizedOnly: params.finalizedOnly,
|
|
1910
|
+
types: params.types,
|
|
1911
|
+
notTypes: params.notTypes,
|
|
1912
|
+
contractId: params.contractId,
|
|
1913
|
+
sender: params.sender,
|
|
1914
|
+
recipient: params.recipient,
|
|
1915
|
+
assetIdentifier: params.assetIdentifier,
|
|
1916
|
+
filters: params.filters,
|
|
1917
|
+
batchSize: params.batchSize ?? 100,
|
|
1918
|
+
fetchEvents,
|
|
1919
|
+
onBatch,
|
|
1920
|
+
onReorg: params.onReorg,
|
|
1921
|
+
emptyBackoffMs: params.emptyBackoffMs,
|
|
1922
|
+
maxPages: params.maxPages,
|
|
1923
|
+
maxEmptyPolls: params.maxEmptyPolls,
|
|
1924
|
+
signal: params.signal,
|
|
1925
|
+
retryCount: params.retryCount,
|
|
1926
|
+
retryDelay: params.retryDelay,
|
|
1927
|
+
onError: params.onError
|
|
1928
|
+
});
|
|
1929
|
+
}
|
|
1872
1930
|
return {
|
|
1873
1931
|
consume(params = {}) {
|
|
1874
1932
|
return iterateStreamsBatches({
|
|
@@ -1890,33 +1948,7 @@ function createStreamsClient(options) {
|
|
|
1890
1948
|
byTxId(txId) {
|
|
1891
1949
|
return request(`/v1/streams/events/${encodeURIComponent(txId)}`);
|
|
1892
1950
|
},
|
|
1893
|
-
consume
|
|
1894
|
-
const onBatch = params.decoded ? (events, envelope, ctx) => params.onBatch(events.map(decode), envelope, ctx) : params.onBatch;
|
|
1895
|
-
return consumeStreamsEvents({
|
|
1896
|
-
fromCursor: params.fromCursor,
|
|
1897
|
-
sink: params.sink,
|
|
1898
|
-
onProgress: params.onProgress,
|
|
1899
|
-
mode: params.mode,
|
|
1900
|
-
finalizedOnly: params.finalizedOnly,
|
|
1901
|
-
types: params.types,
|
|
1902
|
-
notTypes: params.notTypes,
|
|
1903
|
-
contractId: params.contractId,
|
|
1904
|
-
sender: params.sender,
|
|
1905
|
-
recipient: params.recipient,
|
|
1906
|
-
assetIdentifier: params.assetIdentifier,
|
|
1907
|
-
batchSize: params.batchSize ?? 100,
|
|
1908
|
-
fetchEvents,
|
|
1909
|
-
onBatch,
|
|
1910
|
-
onReorg: params.onReorg,
|
|
1911
|
-
emptyBackoffMs: params.emptyBackoffMs,
|
|
1912
|
-
maxPages: params.maxPages,
|
|
1913
|
-
maxEmptyPolls: params.maxEmptyPolls,
|
|
1914
|
-
signal: params.signal,
|
|
1915
|
-
retryCount: params.retryCount,
|
|
1916
|
-
retryDelay: params.retryDelay,
|
|
1917
|
-
onError: params.onError
|
|
1918
|
-
});
|
|
1919
|
-
},
|
|
1951
|
+
consume: consumeEvents,
|
|
1920
1952
|
stream(params = {}) {
|
|
1921
1953
|
return streamStreamsEvents({
|
|
1922
1954
|
fromCursor: params.fromCursor,
|
|
@@ -2845,5 +2877,5 @@ export {
|
|
|
2845
2877
|
ApiError
|
|
2846
2878
|
};
|
|
2847
2879
|
|
|
2848
|
-
//# debugId=
|
|
2880
|
+
//# debugId=E4A30787B92D2A4C64756E2164756E21
|
|
2849
2881
|
//# sourceMappingURL=index.js.map
|