@secondlayer/sdk 9.0.1 → 10.0.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/AGENTS.md +78 -17
- package/README.md +98 -31
- package/dist/index.d.ts +234 -113
- package/dist/index.js +782 -445
- package/dist/index.js.map +19 -19
- package/dist/sinks/bun-sqlite.d.ts +4 -1
- package/dist/sinks/bun-sqlite.js +18 -19
- package/dist/sinks/bun-sqlite.js.map +5 -5
- package/dist/sinks/core.d.ts +8 -1
- package/dist/sinks/core.js +15 -19
- package/dist/sinks/core.js.map +4 -4
- package/dist/sinks/drizzle.d.ts +4 -1
- package/dist/sinks/drizzle.js +19 -20
- package/dist/sinks/drizzle.js.map +5 -5
- package/dist/sinks/kysely.d.ts +4 -1
- package/dist/sinks/kysely.js +20 -20
- package/dist/sinks/kysely.js.map +5 -5
- package/dist/sinks/testing.d.ts +4 -1
- package/dist/sinks/testing.js +14 -1
- package/dist/sinks/testing.js.map +3 -3
- package/dist/streams/index.d.ts +94 -24
- package/dist/streams/index.js +411 -194
- package/dist/streams/index.js.map +13 -13
- package/dist/subgraphs/index.d.ts +198 -92
- package/dist/subgraphs/index.js +778 -443
- package/dist/subgraphs/index.js.map +17 -17
- package/package.json +4 -4
package/dist/streams/index.d.ts
CHANGED
|
@@ -115,8 +115,11 @@ interface ConsumerSink<Tx = unknown> {
|
|
|
115
115
|
* same `rewindCursor` (the lowest fork point) but its own
|
|
116
116
|
* `forkPointHeight` — scope the undo by `forkPointHeight` only (contract
|
|
117
117
|
* invariant #11), and expect re-application after a crash (#10).
|
|
118
|
+
*
|
|
119
|
+
* `rewindCursor` is `null` only for a fork at genesis: clear the
|
|
120
|
+
* checkpoint so the next run starts from the first event.
|
|
118
121
|
*/
|
|
119
|
-
rollback(forkPointHeight: number, rewindCursor: string): Promise<void>;
|
|
122
|
+
rollback(forkPointHeight: number, rewindCursor: string | null): Promise<void>;
|
|
120
123
|
}
|
|
121
124
|
/** `ctx` gains `tx` exactly when a sink is attached; without one the shape
|
|
122
125
|
* is unchanged (an intersection with `unknown` is an identity, so
|
|
@@ -356,11 +359,41 @@ type StreamsEventsSubscribeParams = {
|
|
|
356
359
|
filters?: StreamsFilterMap;
|
|
357
360
|
/** Abort to unsubscribe (the returned function does the same). */
|
|
358
361
|
signal?: AbortSignal;
|
|
359
|
-
/**
|
|
362
|
+
/**
|
|
363
|
+
* Called for each pushed event, in order. The resume cursor advances only
|
|
364
|
+
* after this resolves, so a handler that throws sees the same event again
|
|
365
|
+
* on reconnect (at-least-once). Key durable writes by `cursor`.
|
|
366
|
+
*/
|
|
360
367
|
onEvent: (event: StreamsEvent) => void | Promise<void>;
|
|
361
|
-
/**
|
|
362
|
-
*
|
|
368
|
+
/**
|
|
369
|
+
* Called on every failure. Transport errors (dropped socket, 5xx, 429, a
|
|
370
|
+
* stale connection, a throwing handler) reconnect from the last handled
|
|
371
|
+
* cursor with exponential backoff. Errors that a retry cannot fix (401,
|
|
372
|
+
* 4xx, a bad signature) end the subscription and reject its `done`.
|
|
373
|
+
*/
|
|
363
374
|
onError?: (err: unknown) => void;
|
|
375
|
+
/**
|
|
376
|
+
* First reconnect pause in ms (default 1000). Doubles per consecutive
|
|
377
|
+
* failure up to 30 s with jitter, resets once a frame arrives, and never
|
|
378
|
+
* undercuts a `Retry-After`.
|
|
379
|
+
*/
|
|
380
|
+
reconnectDelayMs?: number;
|
|
381
|
+
/**
|
|
382
|
+
* Reconnect when no frame (pings included) arrives for this long (default
|
|
383
|
+
* 60000, three server heartbeats). Catches a half-open socket that never
|
|
384
|
+
* errors; set it above your instance's heartbeat interval.
|
|
385
|
+
*/
|
|
386
|
+
staleAfterMs?: number;
|
|
387
|
+
};
|
|
388
|
+
/**
|
|
389
|
+
* Handle for a live subscription: call it to unsubscribe. `done` resolves
|
|
390
|
+
* after unsubscribe (or the signal aborting) and rejects with the error that
|
|
391
|
+
* ended the loop when a retry could not fix it, so a worker can `await`
|
|
392
|
+
* it instead of polling for silence.
|
|
393
|
+
*/
|
|
394
|
+
type StreamsSubscription = {
|
|
395
|
+
(): void;
|
|
396
|
+
done: Promise<void>;
|
|
364
397
|
};
|
|
365
398
|
/**
|
|
366
399
|
* The checkpoint the SDK computes for a batch. Persist `cursor` inside the same
|
|
@@ -425,8 +458,11 @@ type StreamsBatchContext = ConsumerBatchContext;
|
|
|
425
458
|
* The checkpoint for a reorg rollback. Persist `cursor` (the rewind position)
|
|
426
459
|
* inside the same transaction as your rollback so the two commit atomically.
|
|
427
460
|
*/
|
|
461
|
+
/** `cursor` is the rewind position the loop resumes from after `onReorg`:
|
|
462
|
+
* the foot of the fork point, or `null` for a fork at genesis. Persist it
|
|
463
|
+
* in the same transaction as the rollback. */
|
|
428
464
|
type StreamsReorgContext = {
|
|
429
|
-
cursor: string;
|
|
465
|
+
cursor: string | null;
|
|
430
466
|
};
|
|
431
467
|
type StreamsEventsConsumeParams<
|
|
432
468
|
TTx = never,
|
|
@@ -494,12 +530,23 @@ type StreamsEventsConsumeParams<
|
|
|
494
530
|
onBatch?: (events: D extends true ? IndexEvent[] : StreamsEvent[], envelope: StreamsEventsEnvelope, ctx: StreamsBatchContext & WithSinkTx<TTx>) => void | string | null | undefined | Promise<void> | Promise<string | null | undefined>;
|
|
495
531
|
/**
|
|
496
532
|
* Roll your projection back to `reorg.fork_point_height`, persisting
|
|
497
|
-
* `ctx.cursor` in the same transaction. Called once per *new* reorg
|
|
498
|
-
* (deduped in-memory, fork-ascending) before the SDK
|
|
499
|
-
* now-canonical events.
|
|
500
|
-
*
|
|
533
|
+
* `ctx.cursor` in the same transaction. Called once per *new* reorg at or
|
|
534
|
+
* below the checkpoint (deduped in-memory, fork-ascending) before the SDK
|
|
535
|
+
* rewinds and re-reads the now-canonical events. A reorg whose fork sits
|
|
536
|
+
* above the checkpoint is not a rollback (nothing past it was written) and
|
|
537
|
+
* is skipped. Omit it to ignore reorgs (events stay canonical, but stale
|
|
538
|
+
* rows from an orphaned fork are left in place).
|
|
539
|
+
*
|
|
540
|
+
* With `onReorg` or a `sink` attached, every empty page also polls
|
|
541
|
+
* `reorgs.list` (one extra request per idle poll) so a fork that lands
|
|
542
|
+
* while the consumer idles at the tip is rolled back too.
|
|
501
543
|
*/
|
|
502
544
|
onReorg?: (reorg: StreamsReorg, ctx: StreamsReorgContext) => Promise<void> | void;
|
|
545
|
+
/** Deepest rewind one reorg may make below the checkpoint before the loop
|
|
546
|
+
* refuses with `ValidationError`. Default 1000 blocks. The fork point is
|
|
547
|
+
* server supplied and drives a delete on every declared table, so raise
|
|
548
|
+
* this only for a source you trust. */
|
|
549
|
+
maxRollbackDepth?: number;
|
|
503
550
|
/** Page-fetch retries after the first failure (429/5xx/network only —
|
|
504
551
|
* 4xx and handler throws always propagate). Default 3; `0` disables. */
|
|
505
552
|
retryCount?: number;
|
|
@@ -562,8 +609,16 @@ type StreamsEventsReplayParams = {
|
|
|
562
609
|
* Called once per finalized dump file, in block order, before live tailing.
|
|
563
610
|
* Process the parquet with your own tooling (e.g. DuckDB) — the SDK does not
|
|
564
611
|
* decode parquet. Use `client.dumps.download(file)` to fetch + verify bytes.
|
|
612
|
+
*
|
|
613
|
+
* Delivery is file-granular and at-least-once: a file whose range straddles
|
|
614
|
+
* `from` is handed over whole. `ctx.from` is that cursor (`null` from
|
|
615
|
+
* genesis); skip rows at or below it, or key rows by `cursor` so a re-run
|
|
616
|
+
* is an idempotent no-op. Files ending at or below `from` are not handed
|
|
617
|
+
* over at all.
|
|
565
618
|
*/
|
|
566
|
-
onDumpFile: (file: StreamsDumpFile
|
|
619
|
+
onDumpFile: (file: StreamsDumpFile, ctx: {
|
|
620
|
+
from: string | null;
|
|
621
|
+
}) => Promise<void> | void;
|
|
567
622
|
/** Called per live page after the dump phase, like `consume`. */
|
|
568
623
|
onBatch: (events: StreamsEvent[], envelope: StreamsEventsEnvelope) => Promise<string | null | undefined> | string | null | undefined;
|
|
569
624
|
/**
|
|
@@ -699,9 +754,11 @@ type StreamsClient = {
|
|
|
699
754
|
* Subscribe to the real-time SSE push surface. Calls `onEvent` for each new
|
|
700
755
|
* canonical event as the server pushes it (chain cadence, not poll-bounded),
|
|
701
756
|
* and verifies each frame's inline ed25519 signature when the client was
|
|
702
|
-
* created with `verify`. Returns an unsubscribe function
|
|
757
|
+
* created with `verify`. Returns an unsubscribe function whose `done`
|
|
758
|
+
* settles when the loop ends. Not reorg-aware: an event delivered then
|
|
759
|
+
* orphaned is never retracted. Durable writers use `consume()`.
|
|
703
760
|
*/
|
|
704
|
-
subscribe(params: StreamsEventsSubscribeParams):
|
|
761
|
+
subscribe(params: StreamsEventsSubscribeParams): StreamsSubscription;
|
|
705
762
|
};
|
|
706
763
|
blocks: {
|
|
707
764
|
events(heightOrHash: number | string): Promise<StreamsEventsListEnvelope>;
|
|
@@ -717,6 +774,8 @@ type StreamsClient = {
|
|
|
717
774
|
type CreateStreamsClientOptions = {
|
|
718
775
|
apiKey?: string;
|
|
719
776
|
baseUrl?: string;
|
|
777
|
+
/** Deploy origin label sent as `x-sl-origin` (telemetry). Defaults to `cli`. */
|
|
778
|
+
origin?: "cli" | "mcp" | "session";
|
|
720
779
|
fetchImpl?: FetchLike2;
|
|
721
780
|
/**
|
|
722
781
|
* Public base URL for bulk parquet dumps (the R2/CDN bucket root). Required
|
|
@@ -844,26 +903,30 @@ declare class ApiError extends SecondLayerError {
|
|
|
844
903
|
body?: unknown;
|
|
845
904
|
constructor(status: number, message: string, body?: unknown, code?: string, options?: SecondLayerErrorOptions);
|
|
846
905
|
}
|
|
847
|
-
/** Thrown on a 401
|
|
906
|
+
/** Thrown on a 401 by both the instance clients and Streams. Carries the
|
|
907
|
+
* server's `{error, code}` envelope when it sent one, so a revoked token reads
|
|
908
|
+
* differently from a missing one. */
|
|
848
909
|
declare class AuthError extends ApiError {
|
|
849
910
|
readonly status: 401;
|
|
850
|
-
constructor(message?: string);
|
|
911
|
+
constructor(message?: string, body?: unknown, code?: string);
|
|
851
912
|
}
|
|
852
|
-
/** Thrown on a 429
|
|
913
|
+
/** Thrown on a 429 by both the instance clients and Streams. `retryable`,
|
|
853
914
|
* with `retryAfterSeconds` parsed from the `Retry-After` header when sent. */
|
|
854
915
|
declare class RateLimitError extends ApiError {
|
|
855
916
|
/** Raw `Retry-After` header value (seconds or HTTP-date). */
|
|
856
917
|
readonly retryAfter?: string | undefined;
|
|
857
918
|
readonly status: 429;
|
|
858
|
-
constructor(message?: string, retryAfter?: string | undefined);
|
|
919
|
+
constructor(message?: string, retryAfter?: string | undefined, body?: unknown, code?: string);
|
|
859
920
|
}
|
|
860
|
-
/** Thrown on a 4xx the caller can fix (bad cursor, bad params). Never retried.
|
|
921
|
+
/** Thrown on a 4xx the caller can fix (bad cursor, bad params). Never retried.
|
|
922
|
+
* `code` is the server's machine-readable code when the envelope carried one. */
|
|
861
923
|
declare class ValidationError extends ApiError {
|
|
862
|
-
constructor(message: string, status: number, body?: unknown);
|
|
924
|
+
constructor(message: string, status: number, body?: unknown, code?: string);
|
|
863
925
|
}
|
|
864
|
-
/** Thrown on a 5xx from the Streams API
|
|
926
|
+
/** Thrown on a 5xx from the Streams API, and on a failed signing-key fetch.
|
|
927
|
+
* `retryable`: the page retry policy tries again. */
|
|
865
928
|
declare class StreamsServerError extends ApiError {
|
|
866
|
-
constructor(message: string, status: number, body?: unknown);
|
|
929
|
+
constructor(message: string, status: number, body?: unknown, code?: string);
|
|
867
930
|
}
|
|
868
931
|
/** Thrown when response signature verification is enabled and fails. */
|
|
869
932
|
declare class StreamsSignatureError extends SecondLayerError {
|
|
@@ -875,7 +938,9 @@ import { DecodedEventColumns, DecodedEventRow, DecodedFtBurn, DecodedFtBurnPaylo
|
|
|
875
938
|
* Helpers for Streams cursors. A cursor is the opaque `<block>:<index>` string
|
|
876
939
|
* that marks a position in the event stream; treat the format as an
|
|
877
940
|
* implementation detail and go through these helpers instead of string-building
|
|
878
|
-
* it at call sites.
|
|
941
|
+
* it at call sites. Encode/decode and the rewind sentinel come from the
|
|
942
|
+
* canonical codec in `@secondlayer/shared` so the SDK cannot accept a spelling
|
|
943
|
+
* the server would 400, or rewind to a different foot than Index/Streams.
|
|
879
944
|
*/
|
|
880
945
|
declare const Cursor: {
|
|
881
946
|
/**
|
|
@@ -887,18 +952,23 @@ declare const Cursor: {
|
|
|
887
952
|
* is `height`: the new canonical block at `height` carries a fresh first
|
|
888
953
|
* event at `(height, 0)` that the consumer MUST re-read.
|
|
889
954
|
*
|
|
890
|
-
* Encoded as
|
|
955
|
+
* Encoded as `blockEndCursor(height - 1)` rather than the seemingly-natural
|
|
891
956
|
* `${height}:0` — that earlier form was an off-by-one: being exclusive, it
|
|
892
957
|
* skipped `(height, 0)`, silently dropping the fork block's first row on
|
|
893
958
|
* every reorg. The sentinel is int4 max (the `event_index`/`tx_index` column
|
|
894
959
|
* type), larger than any real index, so nothing at `height - 1` survives the
|
|
895
960
|
* keyset and the next returned row is exactly `(height, 0)`.
|
|
961
|
+
*
|
|
962
|
+
* `atHeight(0)` is `null`: the pre-genesis position both consume loops
|
|
963
|
+
* accept as "read everything from the first event". There is no string
|
|
964
|
+
* cursor below `0:0`, and `0:0` itself is exclusive, so returning it here
|
|
965
|
+
* skipped the genesis event.
|
|
896
966
|
*/
|
|
897
|
-
atHeight(height: number): string;
|
|
967
|
+
atHeight(height: number): string | null;
|
|
898
968
|
/** Parse a `<block>:<index>` cursor. Throws `ValidationError` if malformed. */
|
|
899
969
|
parse(cursor: string): {
|
|
900
970
|
blockHeight: number;
|
|
901
971
|
eventIndex: number;
|
|
902
972
|
};
|
|
903
973
|
};
|
|
904
|
-
export { isStxTransfer, isStxMint, isStxLock, isStxBurn, isPrint, isNftTransfer, isNftMint, isNftBurn, isFtTransfer, isFtMint, isFtBurn, decodeStxTransfer, decodeStxMint, decodeStxLock, decodeStxBurn, decodePrint, decodeNftTransfer, decodeNftMint, decodeNftBurn, decodeFtTransfer, decodeFtMint, decodeFtBurn, decode, createStreamsClient, ValidationError, StreamsTip, StreamsSignatureError, StreamsServerError, StreamsReorgsListParams, StreamsReorgsListEnvelope, StreamsReorgContext, StreamsReorg, StreamsEventsSubscribeParams, StreamsEventsStreamParams, StreamsEventsListParams, StreamsEventsListEnvelope, StreamsEventsEnvelope, StreamsEventsConsumeResult, StreamsEventsConsumeParams, StreamsEventType, StreamsEventPayload, StreamsEvent, StreamsDumpsManifest, StreamsDumps, StreamsDumpFile, StreamsConsumeParams, StreamsClient, StreamsCanonicalBlock, StreamsBatchContext, StreamsBatch, STREAMS_EVENT_TYPES, RateLimitError, NftTransferPayload2 as NftTransferPayload, NftTransferEvent, FtTransferPayload2 as FtTransferPayload, FtTransferEvent, FetchLike2 as FetchLike, DecodedStxTransferPayload, DecodedStxTransfer, DecodedStxMintPayload, DecodedStxMint, DecodedStxLockPayload, DecodedStxLock, DecodedStxBurnPayload, DecodedStxBurn, DecodedPrintValue, DecodedPrintPayload, DecodedPrint, DecodedNftTransferPayload, DecodedNftTransfer, DecodedNftMintPayload, DecodedNftMint, DecodedNftBurnPayload, DecodedNftBurn, DecodedFtTransferPayload, DecodedFtTransfer, DecodedFtMintPayload, DecodedFtMint, DecodedFtBurnPayload, DecodedFtBurn, DecodedEventRow, DecodedEventColumns, Cursor, ConsumerBatchContext, AuthError };
|
|
974
|
+
export { isStxTransfer, isStxMint, isStxLock, isStxBurn, isPrint, isNftTransfer, isNftMint, isNftBurn, isFtTransfer, isFtMint, isFtBurn, decodeStxTransfer, decodeStxMint, decodeStxLock, decodeStxBurn, decodePrint, decodeNftTransfer, decodeNftMint, decodeNftBurn, decodeFtTransfer, decodeFtMint, decodeFtBurn, decode, createStreamsClient, ValidationError, StreamsTip, StreamsSubscription, StreamsSignatureError, StreamsServerError, StreamsReorgsListParams, StreamsReorgsListEnvelope, StreamsReorgContext, StreamsReorg, StreamsEventsSubscribeParams, StreamsEventsStreamParams, StreamsEventsListParams, StreamsEventsListEnvelope, StreamsEventsEnvelope, StreamsEventsConsumeResult, StreamsEventsConsumeParams, StreamsEventType, StreamsEventPayload, StreamsEvent, StreamsDumpsManifest, StreamsDumps, StreamsDumpFile, StreamsConsumeParams, StreamsClient, StreamsCanonicalBlock, StreamsBatchContext, StreamsBatch, STREAMS_EVENT_TYPES, RateLimitError, NftTransferPayload2 as NftTransferPayload, NftTransferEvent, FtTransferPayload2 as FtTransferPayload, FtTransferEvent, FetchLike2 as FetchLike, DecodedStxTransferPayload, DecodedStxTransfer, DecodedStxMintPayload, DecodedStxMint, DecodedStxLockPayload, DecodedStxLock, DecodedStxBurnPayload, DecodedStxBurn, DecodedPrintValue, DecodedPrintPayload, DecodedPrint, DecodedNftTransferPayload, DecodedNftTransfer, DecodedNftMintPayload, DecodedNftMint, DecodedNftBurnPayload, DecodedNftBurn, DecodedFtTransferPayload, DecodedFtTransfer, DecodedFtMintPayload, DecodedFtMint, DecodedFtBurnPayload, DecodedFtBurn, DecodedEventRow, DecodedEventColumns, Cursor, ConsumerBatchContext, AuthError };
|