dynamodb-reactive 0.3.0 → 0.5.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 +121 -43
- package/dist/{client-Zb67giI5.d.ts → client-wZQ9XC9S.d.ts} +11 -0
- package/dist/client.cjs +53 -55
- package/dist/client.cjs.map +1 -1
- package/dist/client.d.cts +1 -1
- package/dist/client.d.ts +1 -1
- package/dist/client.js +53 -55
- package/dist/client.js.map +1 -1
- package/dist/cloudflare.cjs +461 -0
- package/dist/cloudflare.cjs.map +1 -0
- package/dist/cloudflare.d.cts +129 -0
- package/dist/cloudflare.d.ts +129 -0
- package/dist/cloudflare.js +456 -0
- package/dist/cloudflare.js.map +1 -0
- package/dist/cluster.cjs +66 -66
- package/dist/cluster.cjs.map +1 -1
- package/dist/cluster.d.cts +2 -78
- package/dist/cluster.d.ts +2 -78
- package/dist/cluster.js +66 -66
- package/dist/cluster.js.map +1 -1
- package/dist/core.cjs +1 -3
- package/dist/core.cjs.map +1 -1
- package/dist/core.js +1 -3
- package/dist/core.js.map +1 -1
- package/dist/hub.cjs +164 -0
- package/dist/hub.cjs.map +1 -0
- package/dist/hub.d.cts +91 -0
- package/dist/hub.d.ts +91 -0
- package/dist/hub.js +157 -0
- package/dist/hub.js.map +1 -0
- package/dist/index.cjs +1 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +1 -3
- package/dist/index.js.map +1 -1
- package/dist/infra.cjs +19 -33
- package/dist/infra.cjs.map +1 -1
- package/dist/infra.js +19 -33
- package/dist/infra.js.map +1 -1
- package/dist/protocol-C4Syt_Bl.d.ts +78 -0
- package/dist/react.cjs +56 -65
- package/dist/react.cjs.map +1 -1
- package/dist/react.js +56 -65
- package/dist/react.js.map +1 -1
- package/dist/server.cjs +46 -139
- package/dist/server.cjs.map +1 -1
- package/dist/server.js +46 -139
- package/dist/server.js.map +1 -1
- package/package.json +42 -24
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { SubscribeRequest, SnapshotResponse, UnsubscribeRequest, JsonPatch } from './cluster.cjs';
|
|
2
|
+
import { HubSocket, HubPaths } from './hub.cjs';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Cloudflare Durable Object shell for the reactive hub. It is structural: it
|
|
6
|
+
* takes the Durable Object's `ctx` instead of extending `DurableObject`, so this
|
|
7
|
+
* entry imports nothing from `cloudflare:workers` and builds like every other
|
|
8
|
+
* entry. Your Durable Object class owns its name and migrations and delegates
|
|
9
|
+
* `fetch`, `webSocketMessage`, `webSocketClose` and `webSocketError` to it, plus
|
|
10
|
+
* `alarm` when it tracks presence.
|
|
11
|
+
*/
|
|
12
|
+
/** Set by the route handler on requests it forwards to the hub; never trusted from clients. */
|
|
13
|
+
declare const HUB_PRINCIPAL_HEADER = "x-reactive-principal";
|
|
14
|
+
/** A hibernatable Workers WebSocket, as far as the hub needs it. */
|
|
15
|
+
interface DurableObjectWebSocket extends HubSocket {
|
|
16
|
+
close(code?: number, reason?: string): void;
|
|
17
|
+
}
|
|
18
|
+
/** The parts of `DurableObjectState` the hub uses. */
|
|
19
|
+
interface DurableObjectStateLike {
|
|
20
|
+
acceptWebSocket(socket: DurableObjectWebSocket, tags?: string[]): void;
|
|
21
|
+
getWebSockets(tag?: string): DurableObjectWebSocket[];
|
|
22
|
+
setWebSocketAutoResponse?(pair?: unknown): void;
|
|
23
|
+
/** When the runtime last answered this socket's `ping` itself; needed for presence. */
|
|
24
|
+
getWebSocketAutoResponseTimestamp?(socket: DurableObjectWebSocket): Date | null;
|
|
25
|
+
storage: {
|
|
26
|
+
get<T>(key: string): Promise<T | undefined>;
|
|
27
|
+
put<T>(key: string, value: T): Promise<void>;
|
|
28
|
+
/** Needed for presence. */
|
|
29
|
+
getAlarm?(): Promise<number | null>;
|
|
30
|
+
/** Needed for presence. */
|
|
31
|
+
setAlarm?(scheduledTime: number): Promise<void>;
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
/** Anything with a Durable Object stub's `fetch`. */
|
|
35
|
+
interface HubStub {
|
|
36
|
+
fetch(request: Request): Promise<Response>;
|
|
37
|
+
}
|
|
38
|
+
type WebSocketPairConstructor = new () => {
|
|
39
|
+
0: DurableObjectWebSocket;
|
|
40
|
+
1: DurableObjectWebSocket;
|
|
41
|
+
};
|
|
42
|
+
interface DurableObjectHubOptions {
|
|
43
|
+
paths: HubPaths;
|
|
44
|
+
/** Storage key for a path's version. Defaults to `version:<path>`. */
|
|
45
|
+
versionKey?: (path: string) => string;
|
|
46
|
+
maxAttachmentBytes?: number;
|
|
47
|
+
/**
|
|
48
|
+
* Answers the client's `ping` with `pong` without waking the Durable Object.
|
|
49
|
+
* Defaults to true.
|
|
50
|
+
*/
|
|
51
|
+
autoPong?: boolean;
|
|
52
|
+
/**
|
|
53
|
+
* Tracks whether these principals hold a live socket, so the hub can report a
|
|
54
|
+
* worker as online without the worker polling over HTTP. Requires `autoPong`.
|
|
55
|
+
*/
|
|
56
|
+
presence?: HubPresenceOptions;
|
|
57
|
+
/** Workers' `WebSocketPair`; injectable for tests. */
|
|
58
|
+
WebSocketPair?: WebSocketPairConstructor;
|
|
59
|
+
/** Creates a connection id; injectable for tests. */
|
|
60
|
+
randomId?: () => string;
|
|
61
|
+
}
|
|
62
|
+
interface HubPresenceOptions {
|
|
63
|
+
principals: readonly string[];
|
|
64
|
+
/**
|
|
65
|
+
* A socket whose last `ping` is older than this is closed as dead, which is how
|
|
66
|
+
* a peer that vanished without a close frame is noticed. Clients must ping more
|
|
67
|
+
* often than this. @default 90000
|
|
68
|
+
*/
|
|
69
|
+
timeoutMs?: number;
|
|
70
|
+
/**
|
|
71
|
+
* Called when a principal gains its first live socket or loses its last one,
|
|
72
|
+
* for example to `notify` a status path. The last reported state is kept in
|
|
73
|
+
* storage under `presence:<principal>`, so each change is reported once.
|
|
74
|
+
*/
|
|
75
|
+
onChange?: (principal: string, present: boolean) => void | Promise<void>;
|
|
76
|
+
}
|
|
77
|
+
/** Wires the hub core to a Durable Object's hibernatable WebSockets and storage. */
|
|
78
|
+
declare function createDurableObjectHub(ctx: DurableObjectStateLike, options: DurableObjectHubOptions): {
|
|
79
|
+
hub: {
|
|
80
|
+
message(socket: HubSocket, raw: string): void;
|
|
81
|
+
subscribe(request: SubscribeRequest, principal: string): Promise<SnapshotResponse>;
|
|
82
|
+
unsubscribe(request: UnsubscribeRequest, principal: string): void;
|
|
83
|
+
notify(path: string): Promise<void>;
|
|
84
|
+
publish(path: string, patches: JsonPatch[]): Promise<void>;
|
|
85
|
+
};
|
|
86
|
+
/** The Durable Object's `fetch`: WebSocket upgrades and actions from `hubClient`. */
|
|
87
|
+
fetch(request: Request): Promise<Response>;
|
|
88
|
+
webSocketMessage(socket: DurableObjectWebSocket, message: string | ArrayBuffer): void;
|
|
89
|
+
webSocketClose(socket: DurableObjectWebSocket, code: number): Promise<void>;
|
|
90
|
+
webSocketError(socket: DurableObjectWebSocket): Promise<void>;
|
|
91
|
+
/** Whether `principal` holds a socket that has pinged within the presence timeout. */
|
|
92
|
+
present(principal: string): boolean;
|
|
93
|
+
/**
|
|
94
|
+
* The Durable Object's `alarm` when presence is tracked: closes silent
|
|
95
|
+
* sockets, reports principals that lost their last one, and reschedules.
|
|
96
|
+
*/
|
|
97
|
+
alarm(): Promise<void>;
|
|
98
|
+
};
|
|
99
|
+
type DurableObjectHub = ReturnType<typeof createDurableObjectHub>;
|
|
100
|
+
/** Calls a hub Durable Object from the Worker. */
|
|
101
|
+
declare function hubClient(stub: HubStub): {
|
|
102
|
+
/** Forwards a reactive HTTP request and returns the hub's response unchanged. */
|
|
103
|
+
request: (body: SubscribeRequest | UnsubscribeRequest, principal: string) => Promise<Response>;
|
|
104
|
+
notify: (path: string) => Promise<void>;
|
|
105
|
+
publish: (path: string, patches: JsonPatch[]) => Promise<void>;
|
|
106
|
+
};
|
|
107
|
+
interface ReactiveRoutes {
|
|
108
|
+
/** `POST` exchanges a credential for a signed ticket. */
|
|
109
|
+
ticket: string;
|
|
110
|
+
/** WebSocket upgrade, authenticated by the ticket in the `token` query parameter. */
|
|
111
|
+
socket: string;
|
|
112
|
+
/** Reactive HTTP subscribe and unsubscribe, authenticated by the ticket as a bearer token. */
|
|
113
|
+
reactive: string;
|
|
114
|
+
}
|
|
115
|
+
interface ReactiveRoutesOptions {
|
|
116
|
+
routes: ReactiveRoutes;
|
|
117
|
+
/** Ticket signing secret. Requests get 503 when it is not configured. */
|
|
118
|
+
secret: string | undefined;
|
|
119
|
+
/** The hub Durable Object stub that serves these routes. */
|
|
120
|
+
hub: () => HubStub;
|
|
121
|
+
/** Returns the principal for a ticket request, or undefined to answer 401. */
|
|
122
|
+
authenticate(request: Request): string | undefined | Promise<string | undefined>;
|
|
123
|
+
ticketLifetimeSeconds?: number;
|
|
124
|
+
}
|
|
125
|
+
/** Serves the ticket, socket and reactive HTTP routes; `undefined` for any other path. */
|
|
126
|
+
declare function handleReactiveRoutes(request: Request, options: ReactiveRoutesOptions): Promise<Response | undefined>;
|
|
127
|
+
|
|
128
|
+
export { HUB_PRINCIPAL_HEADER, createDurableObjectHub, handleReactiveRoutes, hubClient };
|
|
129
|
+
export type { DurableObjectHub, DurableObjectHubOptions, DurableObjectStateLike, DurableObjectWebSocket, HubStub, ReactiveRoutes, ReactiveRoutesOptions };
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { SubscribeRequest, SnapshotResponse, UnsubscribeRequest, JsonPatch } from './cluster.js';
|
|
2
|
+
import { HubSocket, HubPaths } from './hub.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Cloudflare Durable Object shell for the reactive hub. It is structural: it
|
|
6
|
+
* takes the Durable Object's `ctx` instead of extending `DurableObject`, so this
|
|
7
|
+
* entry imports nothing from `cloudflare:workers` and builds like every other
|
|
8
|
+
* entry. Your Durable Object class owns its name and migrations and delegates
|
|
9
|
+
* `fetch`, `webSocketMessage`, `webSocketClose` and `webSocketError` to it, plus
|
|
10
|
+
* `alarm` when it tracks presence.
|
|
11
|
+
*/
|
|
12
|
+
/** Set by the route handler on requests it forwards to the hub; never trusted from clients. */
|
|
13
|
+
declare const HUB_PRINCIPAL_HEADER = "x-reactive-principal";
|
|
14
|
+
/** A hibernatable Workers WebSocket, as far as the hub needs it. */
|
|
15
|
+
interface DurableObjectWebSocket extends HubSocket {
|
|
16
|
+
close(code?: number, reason?: string): void;
|
|
17
|
+
}
|
|
18
|
+
/** The parts of `DurableObjectState` the hub uses. */
|
|
19
|
+
interface DurableObjectStateLike {
|
|
20
|
+
acceptWebSocket(socket: DurableObjectWebSocket, tags?: string[]): void;
|
|
21
|
+
getWebSockets(tag?: string): DurableObjectWebSocket[];
|
|
22
|
+
setWebSocketAutoResponse?(pair?: unknown): void;
|
|
23
|
+
/** When the runtime last answered this socket's `ping` itself; needed for presence. */
|
|
24
|
+
getWebSocketAutoResponseTimestamp?(socket: DurableObjectWebSocket): Date | null;
|
|
25
|
+
storage: {
|
|
26
|
+
get<T>(key: string): Promise<T | undefined>;
|
|
27
|
+
put<T>(key: string, value: T): Promise<void>;
|
|
28
|
+
/** Needed for presence. */
|
|
29
|
+
getAlarm?(): Promise<number | null>;
|
|
30
|
+
/** Needed for presence. */
|
|
31
|
+
setAlarm?(scheduledTime: number): Promise<void>;
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
/** Anything with a Durable Object stub's `fetch`. */
|
|
35
|
+
interface HubStub {
|
|
36
|
+
fetch(request: Request): Promise<Response>;
|
|
37
|
+
}
|
|
38
|
+
type WebSocketPairConstructor = new () => {
|
|
39
|
+
0: DurableObjectWebSocket;
|
|
40
|
+
1: DurableObjectWebSocket;
|
|
41
|
+
};
|
|
42
|
+
interface DurableObjectHubOptions {
|
|
43
|
+
paths: HubPaths;
|
|
44
|
+
/** Storage key for a path's version. Defaults to `version:<path>`. */
|
|
45
|
+
versionKey?: (path: string) => string;
|
|
46
|
+
maxAttachmentBytes?: number;
|
|
47
|
+
/**
|
|
48
|
+
* Answers the client's `ping` with `pong` without waking the Durable Object.
|
|
49
|
+
* Defaults to true.
|
|
50
|
+
*/
|
|
51
|
+
autoPong?: boolean;
|
|
52
|
+
/**
|
|
53
|
+
* Tracks whether these principals hold a live socket, so the hub can report a
|
|
54
|
+
* worker as online without the worker polling over HTTP. Requires `autoPong`.
|
|
55
|
+
*/
|
|
56
|
+
presence?: HubPresenceOptions;
|
|
57
|
+
/** Workers' `WebSocketPair`; injectable for tests. */
|
|
58
|
+
WebSocketPair?: WebSocketPairConstructor;
|
|
59
|
+
/** Creates a connection id; injectable for tests. */
|
|
60
|
+
randomId?: () => string;
|
|
61
|
+
}
|
|
62
|
+
interface HubPresenceOptions {
|
|
63
|
+
principals: readonly string[];
|
|
64
|
+
/**
|
|
65
|
+
* A socket whose last `ping` is older than this is closed as dead, which is how
|
|
66
|
+
* a peer that vanished without a close frame is noticed. Clients must ping more
|
|
67
|
+
* often than this. @default 90000
|
|
68
|
+
*/
|
|
69
|
+
timeoutMs?: number;
|
|
70
|
+
/**
|
|
71
|
+
* Called when a principal gains its first live socket or loses its last one,
|
|
72
|
+
* for example to `notify` a status path. The last reported state is kept in
|
|
73
|
+
* storage under `presence:<principal>`, so each change is reported once.
|
|
74
|
+
*/
|
|
75
|
+
onChange?: (principal: string, present: boolean) => void | Promise<void>;
|
|
76
|
+
}
|
|
77
|
+
/** Wires the hub core to a Durable Object's hibernatable WebSockets and storage. */
|
|
78
|
+
declare function createDurableObjectHub(ctx: DurableObjectStateLike, options: DurableObjectHubOptions): {
|
|
79
|
+
hub: {
|
|
80
|
+
message(socket: HubSocket, raw: string): void;
|
|
81
|
+
subscribe(request: SubscribeRequest, principal: string): Promise<SnapshotResponse>;
|
|
82
|
+
unsubscribe(request: UnsubscribeRequest, principal: string): void;
|
|
83
|
+
notify(path: string): Promise<void>;
|
|
84
|
+
publish(path: string, patches: JsonPatch[]): Promise<void>;
|
|
85
|
+
};
|
|
86
|
+
/** The Durable Object's `fetch`: WebSocket upgrades and actions from `hubClient`. */
|
|
87
|
+
fetch(request: Request): Promise<Response>;
|
|
88
|
+
webSocketMessage(socket: DurableObjectWebSocket, message: string | ArrayBuffer): void;
|
|
89
|
+
webSocketClose(socket: DurableObjectWebSocket, code: number): Promise<void>;
|
|
90
|
+
webSocketError(socket: DurableObjectWebSocket): Promise<void>;
|
|
91
|
+
/** Whether `principal` holds a socket that has pinged within the presence timeout. */
|
|
92
|
+
present(principal: string): boolean;
|
|
93
|
+
/**
|
|
94
|
+
* The Durable Object's `alarm` when presence is tracked: closes silent
|
|
95
|
+
* sockets, reports principals that lost their last one, and reschedules.
|
|
96
|
+
*/
|
|
97
|
+
alarm(): Promise<void>;
|
|
98
|
+
};
|
|
99
|
+
type DurableObjectHub = ReturnType<typeof createDurableObjectHub>;
|
|
100
|
+
/** Calls a hub Durable Object from the Worker. */
|
|
101
|
+
declare function hubClient(stub: HubStub): {
|
|
102
|
+
/** Forwards a reactive HTTP request and returns the hub's response unchanged. */
|
|
103
|
+
request: (body: SubscribeRequest | UnsubscribeRequest, principal: string) => Promise<Response>;
|
|
104
|
+
notify: (path: string) => Promise<void>;
|
|
105
|
+
publish: (path: string, patches: JsonPatch[]) => Promise<void>;
|
|
106
|
+
};
|
|
107
|
+
interface ReactiveRoutes {
|
|
108
|
+
/** `POST` exchanges a credential for a signed ticket. */
|
|
109
|
+
ticket: string;
|
|
110
|
+
/** WebSocket upgrade, authenticated by the ticket in the `token` query parameter. */
|
|
111
|
+
socket: string;
|
|
112
|
+
/** Reactive HTTP subscribe and unsubscribe, authenticated by the ticket as a bearer token. */
|
|
113
|
+
reactive: string;
|
|
114
|
+
}
|
|
115
|
+
interface ReactiveRoutesOptions {
|
|
116
|
+
routes: ReactiveRoutes;
|
|
117
|
+
/** Ticket signing secret. Requests get 503 when it is not configured. */
|
|
118
|
+
secret: string | undefined;
|
|
119
|
+
/** The hub Durable Object stub that serves these routes. */
|
|
120
|
+
hub: () => HubStub;
|
|
121
|
+
/** Returns the principal for a ticket request, or undefined to answer 401. */
|
|
122
|
+
authenticate(request: Request): string | undefined | Promise<string | undefined>;
|
|
123
|
+
ticketLifetimeSeconds?: number;
|
|
124
|
+
}
|
|
125
|
+
/** Serves the ticket, socket and reactive HTTP routes; `undefined` for any other path. */
|
|
126
|
+
declare function handleReactiveRoutes(request: Request, options: ReactiveRoutesOptions): Promise<Response | undefined>;
|
|
127
|
+
|
|
128
|
+
export { HUB_PRINCIPAL_HEADER, createDurableObjectHub, handleReactiveRoutes, hubClient };
|
|
129
|
+
export type { DurableObjectHub, DurableObjectHubOptions, DurableObjectStateLike, DurableObjectWebSocket, HubStub, ReactiveRoutes, ReactiveRoutesOptions };
|