@durable-streams/server 0.3.2 → 0.3.3
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.cjs +1297 -260
- package/dist/index.d.cts +236 -2
- package/dist/index.d.ts +236 -2
- package/dist/index.js +1344 -312
- package/package.json +3 -3
- package/src/crypto.ts +217 -0
- package/src/file-store.ts +187 -144
- package/src/glob.ts +70 -0
- package/src/index.ts +14 -0
- package/src/log.ts +56 -0
- package/src/server.ts +75 -26
- package/src/store.ts +59 -7
- package/src/subscription-manager.ts +882 -0
- package/src/subscription-routes.ts +504 -0
- package/src/subscription-types.ts +80 -0
- package/src/types.ts +8 -0
package/dist/index.d.cts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { IncomingMessage, ServerResponse } from "node:http";
|
|
2
|
+
|
|
1
3
|
//#region src/types.d.ts
|
|
2
4
|
/**
|
|
3
5
|
* Types for the in-memory durable streams test server.
|
|
@@ -5,6 +7,12 @@
|
|
|
5
7
|
/**
|
|
6
8
|
* A single message in a stream.
|
|
7
9
|
*/
|
|
10
|
+
/**
|
|
11
|
+
* Types for the in-memory durable streams test server.
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* A single message in a stream.
|
|
15
|
+
*/
|
|
8
16
|
interface StreamMessage {
|
|
9
17
|
/**
|
|
10
18
|
* The raw bytes of the message.
|
|
@@ -172,6 +180,13 @@ interface TestServerOptions {
|
|
|
172
180
|
* Default: October 9, 2024 00:00:00 UTC.
|
|
173
181
|
*/
|
|
174
182
|
cursorEpoch?: Date;
|
|
183
|
+
/**
|
|
184
|
+
* Enable webhook subscriptions.
|
|
185
|
+
* Pull-wake subscription routes are always mounted, but type=webhook creates
|
|
186
|
+
* are rejected unless this is true.
|
|
187
|
+
* Default: false.
|
|
188
|
+
*/
|
|
189
|
+
webhooks?: boolean;
|
|
175
190
|
}
|
|
176
191
|
/**
|
|
177
192
|
* Producer state for idempotent writes.
|
|
@@ -466,7 +481,6 @@ interface FileBackedStreamStoreOptions {
|
|
|
466
481
|
*/
|
|
467
482
|
declare class FileBackedStreamStore {
|
|
468
483
|
private db;
|
|
469
|
-
private fileManager;
|
|
470
484
|
private fileHandlePool;
|
|
471
485
|
private pendingLongPolls;
|
|
472
486
|
private dataDir;
|
|
@@ -695,6 +709,8 @@ declare class DurableStreamTestServer {
|
|
|
695
709
|
private isShuttingDown;
|
|
696
710
|
/** Injected faults for testing retry/resilience */
|
|
697
711
|
private injectedFaults;
|
|
712
|
+
private subscriptionManager;
|
|
713
|
+
private subscriptionRoutes;
|
|
698
714
|
constructor(options?: TestServerOptions);
|
|
699
715
|
/**
|
|
700
716
|
* Start the server.
|
|
@@ -764,6 +780,7 @@ declare class DurableStreamTestServer {
|
|
|
764
780
|
* Handle POST - append data
|
|
765
781
|
*/
|
|
766
782
|
private handleAppend;
|
|
783
|
+
private notifyStreamAppend;
|
|
767
784
|
/**
|
|
768
785
|
* Handle DELETE - delete stream
|
|
769
786
|
*/
|
|
@@ -886,4 +903,221 @@ declare function generateResponseCursor(clientCursor: string | undefined, option
|
|
|
886
903
|
declare function handleCursorCollision(currentCursor: string, previousCursor: string | undefined, options?: CursorOptions): string;
|
|
887
904
|
|
|
888
905
|
//#endregion
|
|
889
|
-
|
|
906
|
+
//#region src/crypto.d.ts
|
|
907
|
+
interface WebhookPublicJwk {
|
|
908
|
+
kty: `OKP`;
|
|
909
|
+
crv: `Ed25519`;
|
|
910
|
+
x: string;
|
|
911
|
+
kid: string;
|
|
912
|
+
use: `sig`;
|
|
913
|
+
alg: `EdDSA`;
|
|
914
|
+
}
|
|
915
|
+
interface WebhookJwks {
|
|
916
|
+
keys: Array<WebhookPublicJwk>;
|
|
917
|
+
}
|
|
918
|
+
/**
|
|
919
|
+
* Generate a unique wake ID.
|
|
920
|
+
*/
|
|
921
|
+
|
|
922
|
+
declare function getWebhookJwks(): WebhookJwks;
|
|
923
|
+
|
|
924
|
+
//#endregion
|
|
925
|
+
//#region src/subscription-types.d.ts
|
|
926
|
+
/**
|
|
927
|
+
* Sign a webhook payload for the Webhook-Signature header.
|
|
928
|
+
* Format: t=<timestamp>,kid=<key_id>,ed25519=<base64url_signature>
|
|
929
|
+
*/
|
|
930
|
+
type SubscriptionType = `webhook` | `pull-wake`;
|
|
931
|
+
type SubscriptionStatus = `active` | `failed`;
|
|
932
|
+
type SubscriptionLinkType = `glob` | `explicit`;
|
|
933
|
+
interface SubscriptionStreamLink {
|
|
934
|
+
path: string;
|
|
935
|
+
link_types: Set<SubscriptionLinkType>;
|
|
936
|
+
acked_offset: string;
|
|
937
|
+
}
|
|
938
|
+
interface SubscriptionWebhookConfig {
|
|
939
|
+
url: string;
|
|
940
|
+
}
|
|
941
|
+
interface SubscriptionRecord {
|
|
942
|
+
id: string;
|
|
943
|
+
type: SubscriptionType;
|
|
944
|
+
pattern?: string;
|
|
945
|
+
webhook?: SubscriptionWebhookConfig;
|
|
946
|
+
wake_stream?: string;
|
|
947
|
+
lease_ttl_ms: number;
|
|
948
|
+
description?: string;
|
|
949
|
+
created_at: string;
|
|
950
|
+
status: SubscriptionStatus;
|
|
951
|
+
config_hash: string;
|
|
952
|
+
streams: Map<string, SubscriptionStreamLink>;
|
|
953
|
+
generation: number;
|
|
954
|
+
wake_id: string | null;
|
|
955
|
+
wake_snapshot: Map<string, string>;
|
|
956
|
+
token: string | null;
|
|
957
|
+
holder: string | null;
|
|
958
|
+
lease_timer: ReturnType<typeof setTimeout> | null;
|
|
959
|
+
retry_count: number;
|
|
960
|
+
retry_timer: ReturnType<typeof setTimeout> | null;
|
|
961
|
+
next_attempt_at: number | null;
|
|
962
|
+
}
|
|
963
|
+
interface SubscriptionStreamInfo {
|
|
964
|
+
path: string;
|
|
965
|
+
link_type: SubscriptionLinkType;
|
|
966
|
+
acked_offset: string;
|
|
967
|
+
tail_offset: string;
|
|
968
|
+
has_pending: boolean;
|
|
969
|
+
}
|
|
970
|
+
interface SubscriptionCreateInput {
|
|
971
|
+
type: SubscriptionType;
|
|
972
|
+
pattern?: string;
|
|
973
|
+
streams: Array<string>;
|
|
974
|
+
webhook?: {
|
|
975
|
+
url: string;
|
|
976
|
+
};
|
|
977
|
+
wake_stream?: string;
|
|
978
|
+
lease_ttl_ms: number;
|
|
979
|
+
description?: string;
|
|
980
|
+
}
|
|
981
|
+
interface SubscriptionCallbackRequest {
|
|
982
|
+
wake_id?: string;
|
|
983
|
+
generation?: number;
|
|
984
|
+
acks?: Array<{
|
|
985
|
+
stream?: string;
|
|
986
|
+
path?: string;
|
|
987
|
+
offset: string;
|
|
988
|
+
}>;
|
|
989
|
+
done?: boolean;
|
|
990
|
+
}
|
|
991
|
+
type SubscriptionErrorCode = `INVALID_REQUEST` | `SUBSCRIPTION_NOT_FOUND` | `SUBSCRIPTION_ALREADY_EXISTS` | `WEBHOOK_URL_REJECTED` | `TOKEN_INVALID` | `TOKEN_EXPIRED` | `FENCED` | `ALREADY_CLAIMED` | `NO_PENDING_WORK` | `INVALID_OFFSET`;
|
|
992
|
+
interface SubscriptionError {
|
|
993
|
+
code: SubscriptionErrorCode;
|
|
994
|
+
message: string;
|
|
995
|
+
current_holder?: string;
|
|
996
|
+
generation?: number;
|
|
997
|
+
}
|
|
998
|
+
|
|
999
|
+
//#endregion
|
|
1000
|
+
//#region src/subscription-manager.d.ts
|
|
1001
|
+
interface StreamLike {
|
|
1002
|
+
currentOffset: string;
|
|
1003
|
+
softDeleted?: boolean;
|
|
1004
|
+
}
|
|
1005
|
+
interface SubscriptionStreamStore {
|
|
1006
|
+
has: (path: string) => boolean;
|
|
1007
|
+
get: (path: string) => StreamLike | undefined;
|
|
1008
|
+
list: () => Array<string>;
|
|
1009
|
+
append: (path: string, data: Uint8Array) => unknown;
|
|
1010
|
+
}
|
|
1011
|
+
declare function validateWebhookUrl(rawUrl: string): {
|
|
1012
|
+
ok: true;
|
|
1013
|
+
} | {
|
|
1014
|
+
ok: false;
|
|
1015
|
+
message: string;
|
|
1016
|
+
};
|
|
1017
|
+
declare class SubscriptionManager {
|
|
1018
|
+
private readonly subscriptions;
|
|
1019
|
+
private readonly streamStore;
|
|
1020
|
+
private readonly callbackBaseUrl;
|
|
1021
|
+
private readonly webhooksEnabled;
|
|
1022
|
+
private isShuttingDown;
|
|
1023
|
+
constructor(opts: {
|
|
1024
|
+
callbackBaseUrl: string;
|
|
1025
|
+
streamStore: SubscriptionStreamStore;
|
|
1026
|
+
webhooksEnabled?: boolean;
|
|
1027
|
+
});
|
|
1028
|
+
createOrConfirm(id: string, input: SubscriptionCreateInput): {
|
|
1029
|
+
subscription: SubscriptionRecord;
|
|
1030
|
+
created: boolean;
|
|
1031
|
+
} | {
|
|
1032
|
+
error: SubscriptionError;
|
|
1033
|
+
};
|
|
1034
|
+
get(id: string): SubscriptionRecord | undefined;
|
|
1035
|
+
delete(id: string): boolean;
|
|
1036
|
+
addExplicitStreams(id: string, streams: Array<string>): boolean;
|
|
1037
|
+
removeExplicitStream(id: string, streamPath: string): boolean;
|
|
1038
|
+
onStreamAppend(absolutePath: string): Promise<void>;
|
|
1039
|
+
onStreamDeleted(absolutePath: string): void;
|
|
1040
|
+
handleWebhookCallback(id: string, token: string, request: SubscriptionCallbackRequest): Promise<{
|
|
1041
|
+
status: number;
|
|
1042
|
+
body: Record<string, unknown>;
|
|
1043
|
+
}>;
|
|
1044
|
+
claim(id: string, worker: string): Promise<{
|
|
1045
|
+
status: number;
|
|
1046
|
+
body: Record<string, unknown>;
|
|
1047
|
+
}>;
|
|
1048
|
+
ack(id: string, token: string, request: SubscriptionCallbackRequest): Promise<{
|
|
1049
|
+
status: number;
|
|
1050
|
+
body: Record<string, unknown>;
|
|
1051
|
+
}>;
|
|
1052
|
+
release(id: string, token: string, request: SubscriptionCallbackRequest): Promise<{
|
|
1053
|
+
status: number;
|
|
1054
|
+
body?: Record<string, unknown>;
|
|
1055
|
+
}>;
|
|
1056
|
+
serialize(subscription: SubscriptionRecord): Record<string, unknown>;
|
|
1057
|
+
getWebhookJwks(): ReturnType<typeof getWebhookJwks>;
|
|
1058
|
+
shutdown(): void;
|
|
1059
|
+
private maybeWake;
|
|
1060
|
+
private createWake;
|
|
1061
|
+
private deliverWebhook;
|
|
1062
|
+
private scheduleWebhookRetry;
|
|
1063
|
+
private writePullWakeEvent;
|
|
1064
|
+
private autoAckWakeSnapshot;
|
|
1065
|
+
private applyAcks;
|
|
1066
|
+
private validateWakeToken;
|
|
1067
|
+
private triggerNextWakeIfPending;
|
|
1068
|
+
private hasPendingWork;
|
|
1069
|
+
private firstPendingStream;
|
|
1070
|
+
private streamInfos;
|
|
1071
|
+
private linkStream;
|
|
1072
|
+
private listStreams;
|
|
1073
|
+
private getTailOffset;
|
|
1074
|
+
private subscriptionActionUrl;
|
|
1075
|
+
private webhookJwksUrl;
|
|
1076
|
+
private webhookSigningMetadata;
|
|
1077
|
+
private extendLease;
|
|
1078
|
+
private clearLease;
|
|
1079
|
+
private tokenSubject;
|
|
1080
|
+
private errorResponse;
|
|
1081
|
+
}
|
|
1082
|
+
|
|
1083
|
+
//#endregion
|
|
1084
|
+
//#region src/subscription-routes.d.ts
|
|
1085
|
+
declare class SubscriptionRoutes {
|
|
1086
|
+
private readonly manager;
|
|
1087
|
+
constructor(manager: SubscriptionManager);
|
|
1088
|
+
handleRequest(method: string, path: string, req: IncomingMessage, res: ServerResponse): Promise<boolean>;
|
|
1089
|
+
private handleBase;
|
|
1090
|
+
private handleJwks;
|
|
1091
|
+
private handleStreams;
|
|
1092
|
+
private handleStream;
|
|
1093
|
+
private handleCallback;
|
|
1094
|
+
private handleClaim;
|
|
1095
|
+
private handleAck;
|
|
1096
|
+
private handleRelease;
|
|
1097
|
+
private parseCreateInput;
|
|
1098
|
+
private parseRoute;
|
|
1099
|
+
private readBearerToken;
|
|
1100
|
+
private readJson;
|
|
1101
|
+
private writeManagerResult;
|
|
1102
|
+
private writeJson;
|
|
1103
|
+
private writeError;
|
|
1104
|
+
private methodNotAllowed;
|
|
1105
|
+
}
|
|
1106
|
+
|
|
1107
|
+
//#endregion
|
|
1108
|
+
//#region src/glob.d.ts
|
|
1109
|
+
/**
|
|
1110
|
+
* Glob pattern matching for webhook subscription patterns.
|
|
1111
|
+
*
|
|
1112
|
+
* Supports:
|
|
1113
|
+
* - `*` matches exactly one path segment
|
|
1114
|
+
* - `**` matches zero or more path segments (recursive)
|
|
1115
|
+
* - Literal segments match exactly
|
|
1116
|
+
*/
|
|
1117
|
+
/**
|
|
1118
|
+
* Match a stream path against a glob pattern.
|
|
1119
|
+
*/
|
|
1120
|
+
declare function globMatch(pattern: string, path: string): boolean;
|
|
1121
|
+
|
|
1122
|
+
//#endregion
|
|
1123
|
+
export { CursorOptions, DEFAULT_CURSOR_EPOCH, DEFAULT_CURSOR_INTERVAL_SECONDS, DurableStreamTestServer, FileBackedStreamStore, PendingLongPoll, Stream, StreamLifecycleEvent, StreamLifecycleHook, StreamMessage, StreamStore, SubscriptionCallbackRequest, SubscriptionCreateInput, SubscriptionError, SubscriptionErrorCode, SubscriptionManager, SubscriptionRecord, SubscriptionRoutes, SubscriptionStatus, SubscriptionStreamInfo, SubscriptionStreamLink, SubscriptionType, TestServerOptions, calculateCursor, createRegistryHooks, decodeStreamPath, encodeStreamPath, generateResponseCursor, globMatch, handleCursorCollision, validateWebhookUrl };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { IncomingMessage, ServerResponse } from "node:http";
|
|
2
|
+
|
|
1
3
|
//#region src/types.d.ts
|
|
2
4
|
/**
|
|
3
5
|
* Types for the in-memory durable streams test server.
|
|
@@ -5,6 +7,12 @@
|
|
|
5
7
|
/**
|
|
6
8
|
* A single message in a stream.
|
|
7
9
|
*/
|
|
10
|
+
/**
|
|
11
|
+
* Types for the in-memory durable streams test server.
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* A single message in a stream.
|
|
15
|
+
*/
|
|
8
16
|
interface StreamMessage {
|
|
9
17
|
/**
|
|
10
18
|
* The raw bytes of the message.
|
|
@@ -172,6 +180,13 @@ interface TestServerOptions {
|
|
|
172
180
|
* Default: October 9, 2024 00:00:00 UTC.
|
|
173
181
|
*/
|
|
174
182
|
cursorEpoch?: Date;
|
|
183
|
+
/**
|
|
184
|
+
* Enable webhook subscriptions.
|
|
185
|
+
* Pull-wake subscription routes are always mounted, but type=webhook creates
|
|
186
|
+
* are rejected unless this is true.
|
|
187
|
+
* Default: false.
|
|
188
|
+
*/
|
|
189
|
+
webhooks?: boolean;
|
|
175
190
|
}
|
|
176
191
|
/**
|
|
177
192
|
* Producer state for idempotent writes.
|
|
@@ -466,7 +481,6 @@ interface FileBackedStreamStoreOptions {
|
|
|
466
481
|
*/
|
|
467
482
|
declare class FileBackedStreamStore {
|
|
468
483
|
private db;
|
|
469
|
-
private fileManager;
|
|
470
484
|
private fileHandlePool;
|
|
471
485
|
private pendingLongPolls;
|
|
472
486
|
private dataDir;
|
|
@@ -695,6 +709,8 @@ declare class DurableStreamTestServer {
|
|
|
695
709
|
private isShuttingDown;
|
|
696
710
|
/** Injected faults for testing retry/resilience */
|
|
697
711
|
private injectedFaults;
|
|
712
|
+
private subscriptionManager;
|
|
713
|
+
private subscriptionRoutes;
|
|
698
714
|
constructor(options?: TestServerOptions);
|
|
699
715
|
/**
|
|
700
716
|
* Start the server.
|
|
@@ -764,6 +780,7 @@ declare class DurableStreamTestServer {
|
|
|
764
780
|
* Handle POST - append data
|
|
765
781
|
*/
|
|
766
782
|
private handleAppend;
|
|
783
|
+
private notifyStreamAppend;
|
|
767
784
|
/**
|
|
768
785
|
* Handle DELETE - delete stream
|
|
769
786
|
*/
|
|
@@ -886,4 +903,221 @@ declare function generateResponseCursor(clientCursor: string | undefined, option
|
|
|
886
903
|
declare function handleCursorCollision(currentCursor: string, previousCursor: string | undefined, options?: CursorOptions): string;
|
|
887
904
|
|
|
888
905
|
//#endregion
|
|
889
|
-
|
|
906
|
+
//#region src/crypto.d.ts
|
|
907
|
+
interface WebhookPublicJwk {
|
|
908
|
+
kty: `OKP`;
|
|
909
|
+
crv: `Ed25519`;
|
|
910
|
+
x: string;
|
|
911
|
+
kid: string;
|
|
912
|
+
use: `sig`;
|
|
913
|
+
alg: `EdDSA`;
|
|
914
|
+
}
|
|
915
|
+
interface WebhookJwks {
|
|
916
|
+
keys: Array<WebhookPublicJwk>;
|
|
917
|
+
}
|
|
918
|
+
/**
|
|
919
|
+
* Generate a unique wake ID.
|
|
920
|
+
*/
|
|
921
|
+
|
|
922
|
+
declare function getWebhookJwks(): WebhookJwks;
|
|
923
|
+
|
|
924
|
+
//#endregion
|
|
925
|
+
//#region src/subscription-types.d.ts
|
|
926
|
+
/**
|
|
927
|
+
* Sign a webhook payload for the Webhook-Signature header.
|
|
928
|
+
* Format: t=<timestamp>,kid=<key_id>,ed25519=<base64url_signature>
|
|
929
|
+
*/
|
|
930
|
+
type SubscriptionType = `webhook` | `pull-wake`;
|
|
931
|
+
type SubscriptionStatus = `active` | `failed`;
|
|
932
|
+
type SubscriptionLinkType = `glob` | `explicit`;
|
|
933
|
+
interface SubscriptionStreamLink {
|
|
934
|
+
path: string;
|
|
935
|
+
link_types: Set<SubscriptionLinkType>;
|
|
936
|
+
acked_offset: string;
|
|
937
|
+
}
|
|
938
|
+
interface SubscriptionWebhookConfig {
|
|
939
|
+
url: string;
|
|
940
|
+
}
|
|
941
|
+
interface SubscriptionRecord {
|
|
942
|
+
id: string;
|
|
943
|
+
type: SubscriptionType;
|
|
944
|
+
pattern?: string;
|
|
945
|
+
webhook?: SubscriptionWebhookConfig;
|
|
946
|
+
wake_stream?: string;
|
|
947
|
+
lease_ttl_ms: number;
|
|
948
|
+
description?: string;
|
|
949
|
+
created_at: string;
|
|
950
|
+
status: SubscriptionStatus;
|
|
951
|
+
config_hash: string;
|
|
952
|
+
streams: Map<string, SubscriptionStreamLink>;
|
|
953
|
+
generation: number;
|
|
954
|
+
wake_id: string | null;
|
|
955
|
+
wake_snapshot: Map<string, string>;
|
|
956
|
+
token: string | null;
|
|
957
|
+
holder: string | null;
|
|
958
|
+
lease_timer: ReturnType<typeof setTimeout> | null;
|
|
959
|
+
retry_count: number;
|
|
960
|
+
retry_timer: ReturnType<typeof setTimeout> | null;
|
|
961
|
+
next_attempt_at: number | null;
|
|
962
|
+
}
|
|
963
|
+
interface SubscriptionStreamInfo {
|
|
964
|
+
path: string;
|
|
965
|
+
link_type: SubscriptionLinkType;
|
|
966
|
+
acked_offset: string;
|
|
967
|
+
tail_offset: string;
|
|
968
|
+
has_pending: boolean;
|
|
969
|
+
}
|
|
970
|
+
interface SubscriptionCreateInput {
|
|
971
|
+
type: SubscriptionType;
|
|
972
|
+
pattern?: string;
|
|
973
|
+
streams: Array<string>;
|
|
974
|
+
webhook?: {
|
|
975
|
+
url: string;
|
|
976
|
+
};
|
|
977
|
+
wake_stream?: string;
|
|
978
|
+
lease_ttl_ms: number;
|
|
979
|
+
description?: string;
|
|
980
|
+
}
|
|
981
|
+
interface SubscriptionCallbackRequest {
|
|
982
|
+
wake_id?: string;
|
|
983
|
+
generation?: number;
|
|
984
|
+
acks?: Array<{
|
|
985
|
+
stream?: string;
|
|
986
|
+
path?: string;
|
|
987
|
+
offset: string;
|
|
988
|
+
}>;
|
|
989
|
+
done?: boolean;
|
|
990
|
+
}
|
|
991
|
+
type SubscriptionErrorCode = `INVALID_REQUEST` | `SUBSCRIPTION_NOT_FOUND` | `SUBSCRIPTION_ALREADY_EXISTS` | `WEBHOOK_URL_REJECTED` | `TOKEN_INVALID` | `TOKEN_EXPIRED` | `FENCED` | `ALREADY_CLAIMED` | `NO_PENDING_WORK` | `INVALID_OFFSET`;
|
|
992
|
+
interface SubscriptionError {
|
|
993
|
+
code: SubscriptionErrorCode;
|
|
994
|
+
message: string;
|
|
995
|
+
current_holder?: string;
|
|
996
|
+
generation?: number;
|
|
997
|
+
}
|
|
998
|
+
|
|
999
|
+
//#endregion
|
|
1000
|
+
//#region src/subscription-manager.d.ts
|
|
1001
|
+
interface StreamLike {
|
|
1002
|
+
currentOffset: string;
|
|
1003
|
+
softDeleted?: boolean;
|
|
1004
|
+
}
|
|
1005
|
+
interface SubscriptionStreamStore {
|
|
1006
|
+
has: (path: string) => boolean;
|
|
1007
|
+
get: (path: string) => StreamLike | undefined;
|
|
1008
|
+
list: () => Array<string>;
|
|
1009
|
+
append: (path: string, data: Uint8Array) => unknown;
|
|
1010
|
+
}
|
|
1011
|
+
declare function validateWebhookUrl(rawUrl: string): {
|
|
1012
|
+
ok: true;
|
|
1013
|
+
} | {
|
|
1014
|
+
ok: false;
|
|
1015
|
+
message: string;
|
|
1016
|
+
};
|
|
1017
|
+
declare class SubscriptionManager {
|
|
1018
|
+
private readonly subscriptions;
|
|
1019
|
+
private readonly streamStore;
|
|
1020
|
+
private readonly callbackBaseUrl;
|
|
1021
|
+
private readonly webhooksEnabled;
|
|
1022
|
+
private isShuttingDown;
|
|
1023
|
+
constructor(opts: {
|
|
1024
|
+
callbackBaseUrl: string;
|
|
1025
|
+
streamStore: SubscriptionStreamStore;
|
|
1026
|
+
webhooksEnabled?: boolean;
|
|
1027
|
+
});
|
|
1028
|
+
createOrConfirm(id: string, input: SubscriptionCreateInput): {
|
|
1029
|
+
subscription: SubscriptionRecord;
|
|
1030
|
+
created: boolean;
|
|
1031
|
+
} | {
|
|
1032
|
+
error: SubscriptionError;
|
|
1033
|
+
};
|
|
1034
|
+
get(id: string): SubscriptionRecord | undefined;
|
|
1035
|
+
delete(id: string): boolean;
|
|
1036
|
+
addExplicitStreams(id: string, streams: Array<string>): boolean;
|
|
1037
|
+
removeExplicitStream(id: string, streamPath: string): boolean;
|
|
1038
|
+
onStreamAppend(absolutePath: string): Promise<void>;
|
|
1039
|
+
onStreamDeleted(absolutePath: string): void;
|
|
1040
|
+
handleWebhookCallback(id: string, token: string, request: SubscriptionCallbackRequest): Promise<{
|
|
1041
|
+
status: number;
|
|
1042
|
+
body: Record<string, unknown>;
|
|
1043
|
+
}>;
|
|
1044
|
+
claim(id: string, worker: string): Promise<{
|
|
1045
|
+
status: number;
|
|
1046
|
+
body: Record<string, unknown>;
|
|
1047
|
+
}>;
|
|
1048
|
+
ack(id: string, token: string, request: SubscriptionCallbackRequest): Promise<{
|
|
1049
|
+
status: number;
|
|
1050
|
+
body: Record<string, unknown>;
|
|
1051
|
+
}>;
|
|
1052
|
+
release(id: string, token: string, request: SubscriptionCallbackRequest): Promise<{
|
|
1053
|
+
status: number;
|
|
1054
|
+
body?: Record<string, unknown>;
|
|
1055
|
+
}>;
|
|
1056
|
+
serialize(subscription: SubscriptionRecord): Record<string, unknown>;
|
|
1057
|
+
getWebhookJwks(): ReturnType<typeof getWebhookJwks>;
|
|
1058
|
+
shutdown(): void;
|
|
1059
|
+
private maybeWake;
|
|
1060
|
+
private createWake;
|
|
1061
|
+
private deliverWebhook;
|
|
1062
|
+
private scheduleWebhookRetry;
|
|
1063
|
+
private writePullWakeEvent;
|
|
1064
|
+
private autoAckWakeSnapshot;
|
|
1065
|
+
private applyAcks;
|
|
1066
|
+
private validateWakeToken;
|
|
1067
|
+
private triggerNextWakeIfPending;
|
|
1068
|
+
private hasPendingWork;
|
|
1069
|
+
private firstPendingStream;
|
|
1070
|
+
private streamInfos;
|
|
1071
|
+
private linkStream;
|
|
1072
|
+
private listStreams;
|
|
1073
|
+
private getTailOffset;
|
|
1074
|
+
private subscriptionActionUrl;
|
|
1075
|
+
private webhookJwksUrl;
|
|
1076
|
+
private webhookSigningMetadata;
|
|
1077
|
+
private extendLease;
|
|
1078
|
+
private clearLease;
|
|
1079
|
+
private tokenSubject;
|
|
1080
|
+
private errorResponse;
|
|
1081
|
+
}
|
|
1082
|
+
|
|
1083
|
+
//#endregion
|
|
1084
|
+
//#region src/subscription-routes.d.ts
|
|
1085
|
+
declare class SubscriptionRoutes {
|
|
1086
|
+
private readonly manager;
|
|
1087
|
+
constructor(manager: SubscriptionManager);
|
|
1088
|
+
handleRequest(method: string, path: string, req: IncomingMessage, res: ServerResponse): Promise<boolean>;
|
|
1089
|
+
private handleBase;
|
|
1090
|
+
private handleJwks;
|
|
1091
|
+
private handleStreams;
|
|
1092
|
+
private handleStream;
|
|
1093
|
+
private handleCallback;
|
|
1094
|
+
private handleClaim;
|
|
1095
|
+
private handleAck;
|
|
1096
|
+
private handleRelease;
|
|
1097
|
+
private parseCreateInput;
|
|
1098
|
+
private parseRoute;
|
|
1099
|
+
private readBearerToken;
|
|
1100
|
+
private readJson;
|
|
1101
|
+
private writeManagerResult;
|
|
1102
|
+
private writeJson;
|
|
1103
|
+
private writeError;
|
|
1104
|
+
private methodNotAllowed;
|
|
1105
|
+
}
|
|
1106
|
+
|
|
1107
|
+
//#endregion
|
|
1108
|
+
//#region src/glob.d.ts
|
|
1109
|
+
/**
|
|
1110
|
+
* Glob pattern matching for webhook subscription patterns.
|
|
1111
|
+
*
|
|
1112
|
+
* Supports:
|
|
1113
|
+
* - `*` matches exactly one path segment
|
|
1114
|
+
* - `**` matches zero or more path segments (recursive)
|
|
1115
|
+
* - Literal segments match exactly
|
|
1116
|
+
*/
|
|
1117
|
+
/**
|
|
1118
|
+
* Match a stream path against a glob pattern.
|
|
1119
|
+
*/
|
|
1120
|
+
declare function globMatch(pattern: string, path: string): boolean;
|
|
1121
|
+
|
|
1122
|
+
//#endregion
|
|
1123
|
+
export { CursorOptions, DEFAULT_CURSOR_EPOCH, DEFAULT_CURSOR_INTERVAL_SECONDS, DurableStreamTestServer, FileBackedStreamStore, PendingLongPoll, Stream, StreamLifecycleEvent, StreamLifecycleHook, StreamMessage, StreamStore, SubscriptionCallbackRequest, SubscriptionCreateInput, SubscriptionError, SubscriptionErrorCode, SubscriptionManager, SubscriptionRecord, SubscriptionRoutes, SubscriptionStatus, SubscriptionStreamInfo, SubscriptionStreamLink, SubscriptionType, TestServerOptions, calculateCursor, createRegistryHooks, decodeStreamPath, encodeStreamPath, generateResponseCursor, globMatch, handleCursorCollision, validateWebhookUrl };
|