@bunworks/inngest-realtime 0.1.0 → 0.1.5
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/CHANGELOG.md +6 -6
- package/README.md +1 -1
- package/_virtual/_rolldown/runtime.cjs +29 -0
- package/api.cjs +45 -0
- package/api.cjs.map +1 -0
- package/api.mjs +44 -0
- package/api.mjs.map +1 -0
- package/channel.cjs +67 -0
- package/channel.cjs.map +1 -0
- package/channel.d.cts +19 -0
- package/channel.d.cts.map +1 -0
- package/channel.d.mts +19 -0
- package/channel.d.mts.map +1 -0
- package/channel.mjs +66 -0
- package/channel.mjs.map +1 -0
- package/env.cjs +72 -0
- package/env.cjs.map +1 -0
- package/env.mjs +71 -0
- package/env.mjs.map +1 -0
- package/hooks.cjs +147 -0
- package/hooks.cjs.map +1 -0
- package/hooks.d.cts +70 -0
- package/hooks.d.cts.map +1 -0
- package/hooks.d.mts +70 -0
- package/hooks.d.mts.map +1 -0
- package/hooks.mjs +144 -0
- package/hooks.mjs.map +1 -0
- package/index.cjs +19 -0
- package/index.d.cts +5 -0
- package/index.d.mts +6 -0
- package/index.mjs +7 -0
- package/middleware.cjs +41 -0
- package/middleware.cjs.map +1 -0
- package/middleware.d.cts +29 -0
- package/middleware.d.cts.map +1 -0
- package/middleware.d.mts +29 -0
- package/middleware.d.mts.map +1 -0
- package/middleware.mjs +34 -0
- package/middleware.mjs.map +1 -0
- package/package.json +6 -5
- package/subscribe/StreamFanout.cjs +47 -0
- package/subscribe/StreamFanout.cjs.map +1 -0
- package/subscribe/StreamFanout.mjs +46 -0
- package/subscribe/StreamFanout.mjs.map +1 -0
- package/subscribe/TokenSubscription.cjs +438 -0
- package/subscribe/TokenSubscription.cjs.map +1 -0
- package/subscribe/TokenSubscription.mjs +436 -0
- package/subscribe/TokenSubscription.mjs.map +1 -0
- package/subscribe/helpers.cjs +41 -0
- package/subscribe/helpers.cjs.map +1 -0
- package/subscribe/helpers.d.cts +64 -0
- package/subscribe/helpers.d.cts.map +1 -0
- package/subscribe/helpers.d.mts +64 -0
- package/subscribe/helpers.d.mts.map +1 -0
- package/subscribe/helpers.mjs +40 -0
- package/subscribe/helpers.mjs.map +1 -0
- package/subscribe/index.cjs +1 -0
- package/subscribe/index.d.mts +1 -0
- package/subscribe/index.mjs +3 -0
- package/topic.cjs +30 -0
- package/topic.cjs.map +1 -0
- package/topic.d.cts +19 -0
- package/topic.d.cts.map +1 -0
- package/topic.d.mts +19 -0
- package/topic.d.mts.map +1 -0
- package/topic.mjs +28 -0
- package/topic.mjs.map +1 -0
- package/types.cjs +45 -0
- package/types.cjs.map +1 -0
- package/types.d.cts +241 -0
- package/types.d.cts.map +1 -0
- package/types.d.mts +241 -0
- package/types.d.mts.map +1 -0
- package/types.mjs +39 -0
- package/types.mjs.map +1 -0
- package/util.cjs +72 -0
- package/util.cjs.map +1 -0
- package/util.mjs +69 -0
- package/util.mjs.map +1 -0
- package/CLAUDE.md +0 -69
- package/bun.lock +0 -527
- package/eslint.config.mjs +0 -19
- package/src/api.ts +0 -83
- package/src/channel.ts +0 -122
- package/src/env.d.ts +0 -15
- package/src/env.ts +0 -152
- package/src/hooks.ts +0 -256
- package/src/index.test.ts +0 -840
- package/src/index.ts +0 -4
- package/src/middleware.ts +0 -68
- package/src/subscribe/StreamFanout.ts +0 -82
- package/src/subscribe/TokenSubscription.ts +0 -524
- package/src/subscribe/helpers.ts +0 -153
- package/src/subscribe/index.ts +0 -1
- package/src/topic.ts +0 -51
- package/src/types.ts +0 -499
- package/src/util.ts +0 -104
- package/tsconfig.build.json +0 -7
- package/tsconfig.json +0 -114
- package/tsdown.config.ts +0 -18
- package/vitest.config.ts +0 -22
package/src/subscribe/helpers.ts
DELETED
|
@@ -1,153 +0,0 @@
|
|
|
1
|
-
import { getEnvVar } from "../env";
|
|
2
|
-
import type { Realtime } from "../types";
|
|
3
|
-
import { TokenSubscription } from "./TokenSubscription";
|
|
4
|
-
|
|
5
|
-
export interface BunworksApp {
|
|
6
|
-
apiBaseUrl?: string;
|
|
7
|
-
api?: {
|
|
8
|
-
signingKey?: string;
|
|
9
|
-
signingKeyFallback?: string;
|
|
10
|
-
getSubscriptionToken?: (channelId: string, topics: string[]) => Promise<string>;
|
|
11
|
-
};
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* Подписка на realtime канал
|
|
16
|
-
*/
|
|
17
|
-
export const subscribe = async <
|
|
18
|
-
const InputChannel extends Realtime.Channel | string,
|
|
19
|
-
const InputTopics extends (keyof Realtime.Channel.InferTopics<
|
|
20
|
-
Realtime.Channel.AsChannel<InputChannel>
|
|
21
|
-
> &
|
|
22
|
-
string)[],
|
|
23
|
-
const TToken extends Realtime.Subscribe.Token<
|
|
24
|
-
Realtime.Channel.AsChannel<InputChannel>,
|
|
25
|
-
InputTopics
|
|
26
|
-
>,
|
|
27
|
-
const TOutput extends Realtime.Subscribe.StreamSubscription<TToken>,
|
|
28
|
-
>(
|
|
29
|
-
/**
|
|
30
|
-
* Токен подписки с настройками
|
|
31
|
-
*/
|
|
32
|
-
token: {
|
|
33
|
-
/**
|
|
34
|
-
* Экземпляр приложения Bunworks
|
|
35
|
-
*/
|
|
36
|
-
app?: BunworksApp;
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* ID канала или объект канала
|
|
40
|
-
*/
|
|
41
|
-
channel: Realtime.Subscribe.InferChannelInput<InputChannel>;
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* Список топиков для подписки
|
|
45
|
-
*/
|
|
46
|
-
topics: InputTopics;
|
|
47
|
-
},
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* Callback для обработки сообщений
|
|
51
|
-
*/
|
|
52
|
-
callback?: Realtime.Subscribe.Callback<TToken>,
|
|
53
|
-
): Promise<TOutput> => {
|
|
54
|
-
const app = token.app;
|
|
55
|
-
const api = app?.api;
|
|
56
|
-
|
|
57
|
-
// Allow users to specify public env vars for the target URLs, but do not
|
|
58
|
-
// allow this for signing keys, as they should never be on a client.
|
|
59
|
-
const maybeApiBaseUrl =
|
|
60
|
-
app?.apiBaseUrl ||
|
|
61
|
-
getEnvVar("BUNWORKS_BASE_URL") ||
|
|
62
|
-
getEnvVar("BUNWORKS_API_BASE_URL");
|
|
63
|
-
|
|
64
|
-
const maybeSigningKey =
|
|
65
|
-
api?.signingKey || getEnvVar("BUNWORKS_SIGNING_KEY");
|
|
66
|
-
|
|
67
|
-
const maybeSigningKeyFallback =
|
|
68
|
-
api?.signingKeyFallback || getEnvVar("BUNWORKS_SIGNING_KEY_FALLBACK");
|
|
69
|
-
|
|
70
|
-
const subscription = new TokenSubscription(
|
|
71
|
-
token as Realtime.Subscribe.Token,
|
|
72
|
-
maybeApiBaseUrl,
|
|
73
|
-
maybeSigningKey,
|
|
74
|
-
maybeSigningKeyFallback,
|
|
75
|
-
);
|
|
76
|
-
|
|
77
|
-
const retStream = subscription.getJsonStream();
|
|
78
|
-
const callbackStream = subscription.getJsonStream();
|
|
79
|
-
|
|
80
|
-
await subscription.connect();
|
|
81
|
-
|
|
82
|
-
const extras = {
|
|
83
|
-
getJsonStream: () => subscription.getJsonStream(),
|
|
84
|
-
getEncodedStream: () => subscription.getEncodedStream(),
|
|
85
|
-
};
|
|
86
|
-
|
|
87
|
-
if (callback) {
|
|
88
|
-
subscription.useCallback(callback, callbackStream);
|
|
89
|
-
} else {
|
|
90
|
-
callbackStream.cancel("Not needed");
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
return Object.assign(retStream, extras) as unknown as TOutput;
|
|
94
|
-
};
|
|
95
|
-
|
|
96
|
-
/**
|
|
97
|
-
* Получение токена подписки
|
|
98
|
-
*/
|
|
99
|
-
export const getSubscriptionToken = async <
|
|
100
|
-
const InputChannel extends Realtime.Channel | string,
|
|
101
|
-
const InputTopics extends (keyof Realtime.Channel.InferTopics<
|
|
102
|
-
Realtime.Channel.AsChannel<InputChannel>
|
|
103
|
-
> &
|
|
104
|
-
string)[],
|
|
105
|
-
const TToken extends Realtime.Subscribe.Token<
|
|
106
|
-
Realtime.Channel.AsChannel<InputChannel>,
|
|
107
|
-
InputTopics
|
|
108
|
-
>,
|
|
109
|
-
>(
|
|
110
|
-
/**
|
|
111
|
-
* Экземпляр приложения Bunworks
|
|
112
|
-
*/
|
|
113
|
-
app: BunworksApp,
|
|
114
|
-
|
|
115
|
-
/**
|
|
116
|
-
* Параметры подписки
|
|
117
|
-
*/
|
|
118
|
-
args: {
|
|
119
|
-
/**
|
|
120
|
-
* ID канала или объект канала
|
|
121
|
-
*/
|
|
122
|
-
channel: Realtime.Subscribe.InferChannelInput<InputChannel>;
|
|
123
|
-
|
|
124
|
-
/**
|
|
125
|
-
* Список топиков
|
|
126
|
-
*/
|
|
127
|
-
topics: InputTopics;
|
|
128
|
-
},
|
|
129
|
-
): Promise<TToken> => {
|
|
130
|
-
const channelId =
|
|
131
|
-
typeof args.channel === "string" ? args.channel : args.channel.name;
|
|
132
|
-
|
|
133
|
-
if (!channelId) {
|
|
134
|
-
throw new Error("Требуется ID канала для создания токена подписки");
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
const key = await app.api?.getSubscriptionToken?.(
|
|
138
|
-
channelId,
|
|
139
|
-
args.topics,
|
|
140
|
-
);
|
|
141
|
-
|
|
142
|
-
if (!key) {
|
|
143
|
-
throw new Error("Не удалось получить токен подписки");
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
const token = {
|
|
147
|
-
channel: channelId,
|
|
148
|
-
topics: args.topics,
|
|
149
|
-
key,
|
|
150
|
-
} as TToken;
|
|
151
|
-
|
|
152
|
-
return token;
|
|
153
|
-
};
|
package/src/subscribe/index.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from "./helpers";
|
package/src/topic.ts
DELETED
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
import { type StandardSchemaV1 } from "@standard-schema/spec";
|
|
2
|
-
import { type Realtime } from "./types.js";
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* TODO
|
|
6
|
-
*/
|
|
7
|
-
export const topic: Realtime.Topic.Builder = (
|
|
8
|
-
/**
|
|
9
|
-
* TODO
|
|
10
|
-
*/
|
|
11
|
-
id,
|
|
12
|
-
) => {
|
|
13
|
-
return new TopicDefinitionImpl(id);
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
export class TopicDefinitionImpl<
|
|
17
|
-
TTopicId extends string = string,
|
|
18
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
19
|
-
TPublish = any,
|
|
20
|
-
TSubscribe = TPublish,
|
|
21
|
-
> implements Realtime.Topic.Definition<TTopicId, TPublish, TSubscribe>
|
|
22
|
-
{
|
|
23
|
-
public name: TTopicId;
|
|
24
|
-
#schema?: StandardSchemaV1;
|
|
25
|
-
|
|
26
|
-
constructor(name: TTopicId, schema?: StandardSchemaV1) {
|
|
27
|
-
this.name = name;
|
|
28
|
-
this.#schema = schema;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
public type<
|
|
32
|
-
const UPublish,
|
|
33
|
-
const USubscribe = UPublish,
|
|
34
|
-
>(): Realtime.Topic.Definition<TTopicId, UPublish, USubscribe> {
|
|
35
|
-
return this as Realtime.Topic.Definition<TTopicId, UPublish, USubscribe>;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
public schema<const TSchema extends StandardSchemaV1>(
|
|
39
|
-
schema: TSchema,
|
|
40
|
-
): Realtime.Topic.Definition<
|
|
41
|
-
TTopicId,
|
|
42
|
-
StandardSchemaV1.InferInput<TSchema>,
|
|
43
|
-
StandardSchemaV1.InferOutput<TSchema>
|
|
44
|
-
> {
|
|
45
|
-
return new TopicDefinitionImpl(this.name, schema);
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
public getSchema(): StandardSchemaV1 | undefined {
|
|
49
|
-
return this.#schema;
|
|
50
|
-
}
|
|
51
|
-
}
|
package/src/types.ts
DELETED
|
@@ -1,499 +0,0 @@
|
|
|
1
|
-
import { type StandardSchemaV1 } from "@standard-schema/spec";
|
|
2
|
-
import { z } from "zod";
|
|
3
|
-
|
|
4
|
-
export namespace Realtime {
|
|
5
|
-
export type PublishFn = <
|
|
6
|
-
TMessage extends MaybePromise<Realtime.Message.Input>,
|
|
7
|
-
>(
|
|
8
|
-
message: TMessage,
|
|
9
|
-
) => Promise<Awaited<TMessage>["data"]>;
|
|
10
|
-
|
|
11
|
-
export type Token<
|
|
12
|
-
TChannel extends Channel | Channel.Definition,
|
|
13
|
-
TTopics extends (keyof Channel.InferTopics<
|
|
14
|
-
Channel.Definition.AsChannel<TChannel>
|
|
15
|
-
> &
|
|
16
|
-
string)[] = (keyof Channel.InferTopics<
|
|
17
|
-
Channel.Definition.AsChannel<TChannel>
|
|
18
|
-
> &
|
|
19
|
-
string)[],
|
|
20
|
-
> = TChannel extends Channel.Definition
|
|
21
|
-
? Subscribe.Token<Channel.Definition.AsChannel<TChannel>, TTopics>
|
|
22
|
-
: TChannel extends Channel
|
|
23
|
-
? Subscribe.Token<TChannel, TTopics>
|
|
24
|
-
: never;
|
|
25
|
-
|
|
26
|
-
export namespace Subscribe {
|
|
27
|
-
export type InferChannelInput<T> = T extends Realtime.Channel.Definition
|
|
28
|
-
? Realtime.Channel.Definition.InferId<T>
|
|
29
|
-
: T;
|
|
30
|
-
|
|
31
|
-
export type StreamSubscription<
|
|
32
|
-
TSubscribeToken extends Token = Token,
|
|
33
|
-
TData extends Simplify<Token.InferMessage<TSubscribeToken>> = Simplify<
|
|
34
|
-
Token.InferMessage<TSubscribeToken>
|
|
35
|
-
>,
|
|
36
|
-
> = ReadableStream<TData> & {
|
|
37
|
-
/**
|
|
38
|
-
* Get a new readable stream from the subscription that delivers JSON chunks.
|
|
39
|
-
*
|
|
40
|
-
* The stream starts when this function is called and will not contain any
|
|
41
|
-
* messages that were sent before this function was called.
|
|
42
|
-
*/
|
|
43
|
-
getJsonStream(): ReadableStream<TData>;
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* Get a new readable stream from the subscription that delivers
|
|
47
|
-
* SSE-compatible chunks, which are compatible with the `EventSource` API
|
|
48
|
-
* and generally used for streaming data from a server to the browser.
|
|
49
|
-
*
|
|
50
|
-
* The stream starts when this function is called and will not contain any
|
|
51
|
-
* messages that were sent before this function was called.
|
|
52
|
-
*/
|
|
53
|
-
getEncodedStream(): ReadableStream<Uint8Array>;
|
|
54
|
-
};
|
|
55
|
-
|
|
56
|
-
export type Callback<
|
|
57
|
-
TSubscribeToken extends Subscribe.Token = Subscribe.Token,
|
|
58
|
-
> = (message: Token.InferMessage<TSubscribeToken>) => void;
|
|
59
|
-
|
|
60
|
-
export interface Token<
|
|
61
|
-
TChannel extends Channel | Channel.Definition = Channel,
|
|
62
|
-
TTopics extends
|
|
63
|
-
(keyof Channel.InferTopics<TChannel>)[] = (keyof Channel.InferTopics<TChannel>)[],
|
|
64
|
-
> {
|
|
65
|
-
// key used to auth - could be undefined as then we can do a cold subscribe
|
|
66
|
-
key?: string | undefined;
|
|
67
|
-
channel: Realtime.Channel.Definition.AsChannel<TChannel>;
|
|
68
|
-
topics: TTopics;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
export namespace Token {
|
|
72
|
-
export type InferChannel<TToken extends Token> = TToken extends Token<
|
|
73
|
-
infer IChannel,
|
|
74
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
75
|
-
any
|
|
76
|
-
>
|
|
77
|
-
? IChannel
|
|
78
|
-
: Channel;
|
|
79
|
-
|
|
80
|
-
export type InferTopicData<
|
|
81
|
-
TToken extends Token,
|
|
82
|
-
TChannelTopics extends Record<
|
|
83
|
-
string,
|
|
84
|
-
Topic.Definition
|
|
85
|
-
> = Channel.InferTopics<Token.InferChannel<TToken>>,
|
|
86
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
87
|
-
> = TToken extends Token<any, infer ITopics>
|
|
88
|
-
? { [K in ITopics[number]]: TChannelTopics[K] }
|
|
89
|
-
: never;
|
|
90
|
-
|
|
91
|
-
export type InferMessage<TToken extends Token> = Simplify<
|
|
92
|
-
Realtime.Message<
|
|
93
|
-
Channel.InferId<Token.InferChannel<TToken>>,
|
|
94
|
-
Token.InferTopicData<TToken>
|
|
95
|
-
>
|
|
96
|
-
>;
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
// We need to use a `Message` type so that we can appropriately type incoming
|
|
101
|
-
// and outgoing messages with generics, but we also need to validate these at
|
|
102
|
-
// runtime.
|
|
103
|
-
//
|
|
104
|
-
// Ideally in the future we use protobuf for this, but for now we use Zod.
|
|
105
|
-
// This type is used to assert that the Zod schema matches the generic type.
|
|
106
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
107
|
-
type _AssertMessageSchemaMatchesGeneric = Expect<
|
|
108
|
-
IsEqual<z.output<typeof messageSchema>, Message.Raw>
|
|
109
|
-
>;
|
|
110
|
-
|
|
111
|
-
export const messageSchema = z
|
|
112
|
-
.object({
|
|
113
|
-
channel: z.string().optional(),
|
|
114
|
-
topic: z.string().optional(),
|
|
115
|
-
data: z.any(),
|
|
116
|
-
run_id: z.string().optional(),
|
|
117
|
-
fn_id: z.string().optional(),
|
|
118
|
-
created_at: z
|
|
119
|
-
.string()
|
|
120
|
-
.optional()
|
|
121
|
-
.transform((v) => (v ? new Date(v) : undefined)),
|
|
122
|
-
env_id: z.string().optional(),
|
|
123
|
-
stream_id: z.string().optional(),
|
|
124
|
-
kind: z.enum([
|
|
125
|
-
"step",
|
|
126
|
-
"run",
|
|
127
|
-
"data",
|
|
128
|
-
"ping",
|
|
129
|
-
"pong",
|
|
130
|
-
"closing",
|
|
131
|
-
"event",
|
|
132
|
-
"sub",
|
|
133
|
-
"unsub",
|
|
134
|
-
"datastream-start",
|
|
135
|
-
"datastream-end",
|
|
136
|
-
"chunk",
|
|
137
|
-
]),
|
|
138
|
-
})
|
|
139
|
-
.transform(({ data, ...rest }) => {
|
|
140
|
-
return {
|
|
141
|
-
...rest,
|
|
142
|
-
data: data ?? undefined,
|
|
143
|
-
};
|
|
144
|
-
});
|
|
145
|
-
|
|
146
|
-
// Subscribe (output) msg
|
|
147
|
-
export type Message<
|
|
148
|
-
TChannelId extends string = string,
|
|
149
|
-
TTopics extends Record<string, Realtime.Topic.Definition> = Record<
|
|
150
|
-
string,
|
|
151
|
-
Realtime.Topic.Definition
|
|
152
|
-
>,
|
|
153
|
-
> = {
|
|
154
|
-
[K in keyof TTopics]:
|
|
155
|
-
| {
|
|
156
|
-
topic: K;
|
|
157
|
-
channel: TChannelId;
|
|
158
|
-
data: Realtime.Topic.InferSubscribe<TTopics[K]>;
|
|
159
|
-
runId?: string;
|
|
160
|
-
fnId?: string;
|
|
161
|
-
createdAt: Date;
|
|
162
|
-
envId?: string;
|
|
163
|
-
kind: "data";
|
|
164
|
-
}
|
|
165
|
-
| {
|
|
166
|
-
topic: K;
|
|
167
|
-
channel: TChannelId;
|
|
168
|
-
data: Realtime.Topic.InferSubscribe<TTopics[K]>;
|
|
169
|
-
runId?: string;
|
|
170
|
-
fnId?: string;
|
|
171
|
-
kind: "datastream-start" | "datastream-end" | "chunk";
|
|
172
|
-
streamId: string;
|
|
173
|
-
stream: ReadableStream<Realtime.Topic.InferSubscribe<TTopics[K]>>;
|
|
174
|
-
};
|
|
175
|
-
}[keyof TTopics];
|
|
176
|
-
|
|
177
|
-
export namespace Message {
|
|
178
|
-
// Publish (input) msg
|
|
179
|
-
export type Input<
|
|
180
|
-
TChannelId extends string = string,
|
|
181
|
-
TTopicId extends string = string,
|
|
182
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
183
|
-
TData = any,
|
|
184
|
-
> = {
|
|
185
|
-
channel: TChannelId;
|
|
186
|
-
topic: TTopicId;
|
|
187
|
-
data: TData;
|
|
188
|
-
};
|
|
189
|
-
|
|
190
|
-
export type Raw<
|
|
191
|
-
TChannelId extends string = string,
|
|
192
|
-
TTopics extends Record<string, Realtime.Topic.Definition> = Record<
|
|
193
|
-
string,
|
|
194
|
-
Realtime.Topic.Definition
|
|
195
|
-
>,
|
|
196
|
-
> = {
|
|
197
|
-
[K in keyof TTopics]: {
|
|
198
|
-
topic?: K;
|
|
199
|
-
stream_id?: string;
|
|
200
|
-
data: Realtime.Topic.InferSubscribe<TTopics[K]>;
|
|
201
|
-
channel?: TChannelId;
|
|
202
|
-
run_id?: string;
|
|
203
|
-
fn_id?: string;
|
|
204
|
-
created_at?: Date;
|
|
205
|
-
env_id?: string;
|
|
206
|
-
kind:
|
|
207
|
-
| "step" // step data
|
|
208
|
-
| "run" // run results
|
|
209
|
-
| "data" // misc stream data from `ctx.publish()`
|
|
210
|
-
| "datastream-start"
|
|
211
|
-
| "datastream-end"
|
|
212
|
-
| "ping" // keepalive server -> client
|
|
213
|
-
| "pong" // keepalive client -> server
|
|
214
|
-
| "closing" // server is closing connection, client should reconnect
|
|
215
|
-
| "event" // event sent to inngest
|
|
216
|
-
| "sub"
|
|
217
|
-
| "unsub"
|
|
218
|
-
| "chunk";
|
|
219
|
-
};
|
|
220
|
-
}[keyof TTopics];
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
export type Channel<
|
|
224
|
-
TChannelId extends string = string,
|
|
225
|
-
TTopics extends Record<string, Realtime.Topic.Definition> = Record<
|
|
226
|
-
string,
|
|
227
|
-
Realtime.Topic.Definition
|
|
228
|
-
>,
|
|
229
|
-
> = {
|
|
230
|
-
[K in
|
|
231
|
-
| IsLiteral<keyof TTopics, keyof TTopics, never>
|
|
232
|
-
| "name"
|
|
233
|
-
| "topics"]: K extends "name"
|
|
234
|
-
? string
|
|
235
|
-
: K extends "topics"
|
|
236
|
-
? TTopics
|
|
237
|
-
: Realtime.Topic<TChannelId, TTopics[K]>;
|
|
238
|
-
};
|
|
239
|
-
|
|
240
|
-
export namespace Channel {
|
|
241
|
-
export type Like = {
|
|
242
|
-
channel: string;
|
|
243
|
-
topics: string[];
|
|
244
|
-
};
|
|
245
|
-
|
|
246
|
-
export type InferId<TChannel extends Channel> = TChannel extends Channel<
|
|
247
|
-
infer IId,
|
|
248
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
249
|
-
any
|
|
250
|
-
>
|
|
251
|
-
? IId
|
|
252
|
-
: string;
|
|
253
|
-
|
|
254
|
-
export type AsChannel<T extends Channel | string> = T extends Channel
|
|
255
|
-
? T
|
|
256
|
-
: T extends string
|
|
257
|
-
? Realtime.Channel<T>
|
|
258
|
-
: never;
|
|
259
|
-
|
|
260
|
-
export type InferTopics<
|
|
261
|
-
TChannel extends Channel | Channel.Definition,
|
|
262
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
263
|
-
> = TChannel extends Channel.Definition<any, infer ITopics>
|
|
264
|
-
? ITopics
|
|
265
|
-
: // eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
266
|
-
TChannel extends Channel<any, infer ITopics>
|
|
267
|
-
? ITopics
|
|
268
|
-
: Record<string, Realtime.Topic.Definition>;
|
|
269
|
-
|
|
270
|
-
export interface Definition<
|
|
271
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
272
|
-
TChannelBuilderFn extends BuilderFn = (...args: any[]) => string,
|
|
273
|
-
TTopics extends Record<string, Topic.Definition> = Record<
|
|
274
|
-
string,
|
|
275
|
-
Topic.Definition
|
|
276
|
-
>,
|
|
277
|
-
> {
|
|
278
|
-
(
|
|
279
|
-
...args: Parameters<TChannelBuilderFn>
|
|
280
|
-
): Channel<ReturnType<TChannelBuilderFn>, TTopics>;
|
|
281
|
-
|
|
282
|
-
addTopic<UTopic extends Topic.Definition>(
|
|
283
|
-
topic: UTopic,
|
|
284
|
-
): Definition<TChannelBuilderFn, AddTopic<TTopics, UTopic>>;
|
|
285
|
-
|
|
286
|
-
topics: TTopics;
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
export namespace Definition {
|
|
290
|
-
export type InferId<TChannel extends Definition> =
|
|
291
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
292
|
-
TChannel extends Definition<infer IBuilder, any>
|
|
293
|
-
? ReturnType<IBuilder>
|
|
294
|
-
: string;
|
|
295
|
-
|
|
296
|
-
export type InferTopics<TChannel extends Definition> =
|
|
297
|
-
TChannel extends Definition<
|
|
298
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
299
|
-
any,
|
|
300
|
-
infer ITopics
|
|
301
|
-
>
|
|
302
|
-
? ITopics
|
|
303
|
-
: Record<string, Topic.Definition>;
|
|
304
|
-
|
|
305
|
-
export type AsChannel<T extends Definition | Channel> =
|
|
306
|
-
T extends Definition
|
|
307
|
-
? Channel<InferId<T>, InferTopics<T>>
|
|
308
|
-
: T extends Channel
|
|
309
|
-
? T
|
|
310
|
-
: never;
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
export type AddTopic<
|
|
314
|
-
TCurr extends Record<string, Topic.Definition>,
|
|
315
|
-
TInc extends Topic.Definition,
|
|
316
|
-
TIncWrapped extends Record<TInc["name"], TInc> = Record<
|
|
317
|
-
TInc["name"],
|
|
318
|
-
TInc
|
|
319
|
-
>,
|
|
320
|
-
> = IsStringLiteral<keyof TCurr & string> extends true
|
|
321
|
-
? Simplify<Omit<TCurr, TInc["name"]> & TIncWrapped>
|
|
322
|
-
: TIncWrapped;
|
|
323
|
-
|
|
324
|
-
export type BuilderFn<TChannelId extends string = string> = (
|
|
325
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
326
|
-
...args: any[]
|
|
327
|
-
) => TChannelId;
|
|
328
|
-
|
|
329
|
-
export type Builder = <
|
|
330
|
-
const TChannelId extends string,
|
|
331
|
-
const TIdInput extends TChannelId | BuilderFn<TChannelId>,
|
|
332
|
-
>(
|
|
333
|
-
id: TIdInput,
|
|
334
|
-
) => TIdInput extends TChannelId
|
|
335
|
-
? Channel.Definition<() => TIdInput>
|
|
336
|
-
: TIdInput extends BuilderFn<TChannelId>
|
|
337
|
-
? Channel.Definition<TIdInput>
|
|
338
|
-
: never;
|
|
339
|
-
}
|
|
340
|
-
|
|
341
|
-
export type Topic<
|
|
342
|
-
TChannelId extends string = string,
|
|
343
|
-
TTopic extends Topic.Definition = Topic.Definition,
|
|
344
|
-
> = (
|
|
345
|
-
data: Topic.InferPublish<TTopic>,
|
|
346
|
-
) => Promise<
|
|
347
|
-
Realtime.Message.Input<
|
|
348
|
-
TChannelId,
|
|
349
|
-
Topic.InferId<TTopic>,
|
|
350
|
-
Topic.InferPublish<TTopic>
|
|
351
|
-
>
|
|
352
|
-
>;
|
|
353
|
-
|
|
354
|
-
export namespace Topic {
|
|
355
|
-
export type Like = {
|
|
356
|
-
name: string;
|
|
357
|
-
};
|
|
358
|
-
|
|
359
|
-
export interface Definition<
|
|
360
|
-
TTopicId extends string = string,
|
|
361
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
362
|
-
TPublish = any,
|
|
363
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
364
|
-
_TSubscribe = TPublish,
|
|
365
|
-
> {
|
|
366
|
-
name: TTopicId;
|
|
367
|
-
|
|
368
|
-
// Deliberately doesn't include `USubscribe` typing, as there's no schema
|
|
369
|
-
// to perform transformations.
|
|
370
|
-
type<const UPublish>(): Definition<TTopicId, UPublish>;
|
|
371
|
-
|
|
372
|
-
schema<const TSchema extends StandardSchemaV1>(
|
|
373
|
-
schema: TSchema,
|
|
374
|
-
): Definition<
|
|
375
|
-
TTopicId,
|
|
376
|
-
StandardSchemaV1.InferInput<TSchema>,
|
|
377
|
-
StandardSchemaV1.InferOutput<TSchema>
|
|
378
|
-
>;
|
|
379
|
-
|
|
380
|
-
getSchema(): StandardSchemaV1 | undefined;
|
|
381
|
-
}
|
|
382
|
-
|
|
383
|
-
export type InferId<TTopic extends Topic.Definition> =
|
|
384
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
385
|
-
TTopic extends Topic.Definition<infer IId, any, any> ? IId : string;
|
|
386
|
-
|
|
387
|
-
export type InferPublish<TTopic extends Topic.Definition> =
|
|
388
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
389
|
-
TTopic extends Topic.Definition<any, infer IPublish, any>
|
|
390
|
-
? IPublish
|
|
391
|
-
: // eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
392
|
-
any;
|
|
393
|
-
|
|
394
|
-
export type InferSubscribe<TTopic extends Topic.Definition> =
|
|
395
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
396
|
-
TTopic extends Topic.Definition<any, any, infer ISubscribe>
|
|
397
|
-
? ISubscribe
|
|
398
|
-
: // eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
399
|
-
any;
|
|
400
|
-
|
|
401
|
-
export type Builder = <const TTopicId extends string>(
|
|
402
|
-
id: TTopicId,
|
|
403
|
-
) => Topic.Definition<TTopicId>;
|
|
404
|
-
}
|
|
405
|
-
}
|
|
406
|
-
|
|
407
|
-
/**
|
|
408
|
-
* Expects that a value resolves to `true`, useful for asserting type checks.
|
|
409
|
-
*/
|
|
410
|
-
export type Expect<T extends true> = T;
|
|
411
|
-
|
|
412
|
-
/**
|
|
413
|
-
Returns a boolean for whether the two given types are equal.
|
|
414
|
-
|
|
415
|
-
{@link https://github.com/microsoft/TypeScript/issues/27024#issuecomment-421529650}
|
|
416
|
-
{@link https://stackoverflow.com/questions/68961864/how-does-the-equals-work-in-typescript/68963796#68963796}
|
|
417
|
-
|
|
418
|
-
Use-cases:
|
|
419
|
-
- If you want to make a conditional branch based on the result of a comparison of two types.
|
|
420
|
-
|
|
421
|
-
@example
|
|
422
|
-
```
|
|
423
|
-
import type {IsEqual} from 'type-fest';
|
|
424
|
-
|
|
425
|
-
// This type returns a boolean for whether the given array includes the given item.
|
|
426
|
-
// `IsEqual` is used to compare the given array at position 0 and the given item and then return true if they are equal.
|
|
427
|
-
type Includes<Value extends readonly any[], Item> =
|
|
428
|
-
Value extends readonly [Value[0], ...infer rest]
|
|
429
|
-
? IsEqual<Value[0], Item> extends true
|
|
430
|
-
? true
|
|
431
|
-
: Includes<rest, Item>
|
|
432
|
-
: false;
|
|
433
|
-
```
|
|
434
|
-
*/
|
|
435
|
-
export type IsEqual<A, B> = (<G>() => G extends A ? 1 : 2) extends <
|
|
436
|
-
G,
|
|
437
|
-
>() => G extends B ? 1 : 2
|
|
438
|
-
? true
|
|
439
|
-
: false;
|
|
440
|
-
|
|
441
|
-
/**
|
|
442
|
-
* Given a type `T`, return `Then` if `T` is a string, number, or symbol
|
|
443
|
-
* literal, else `Else`.
|
|
444
|
-
*
|
|
445
|
-
* `Then` defaults to `true` and `Else` defaults to `false`.
|
|
446
|
-
*
|
|
447
|
-
* Useful for determining if an object is a generic type or has known keys.
|
|
448
|
-
*
|
|
449
|
-
* @example
|
|
450
|
-
* ```ts
|
|
451
|
-
* type IsLiteralType = IsLiteral<"foo">; // true
|
|
452
|
-
* type IsLiteralType = IsLiteral<string>; // false
|
|
453
|
-
*
|
|
454
|
-
* type IsLiteralType = IsLiteral<1>; // true
|
|
455
|
-
* type IsLiteralType = IsLiteral<number>; // false
|
|
456
|
-
*
|
|
457
|
-
* type IsLiteralType = IsLiteral<symbol>; // true
|
|
458
|
-
* type IsLiteralType = IsLiteral<typeof Symbol.iterator>; // false
|
|
459
|
-
*
|
|
460
|
-
* type T0 = { foo: string };
|
|
461
|
-
* type HasAllKnownKeys = IsLiteral<keyof T0>; // true
|
|
462
|
-
*
|
|
463
|
-
* type T1 = { [x: string]: any; foo: boolean };
|
|
464
|
-
* type HasAllKnownKeys = IsLiteral<keyof T1>; // false
|
|
465
|
-
* ```
|
|
466
|
-
*/
|
|
467
|
-
export type IsLiteral<T, Then = true, Else = false> = string extends T
|
|
468
|
-
? Else
|
|
469
|
-
: number extends T
|
|
470
|
-
? Else
|
|
471
|
-
: symbol extends T
|
|
472
|
-
? Else
|
|
473
|
-
: Then;
|
|
474
|
-
|
|
475
|
-
/**
|
|
476
|
-
* Returns `true` if the given generic `T` is a string literal, e.g. `"foo"`, or
|
|
477
|
-
* `false` if it is a string type, e.g. `string`.
|
|
478
|
-
*
|
|
479
|
-
* Useful for checking whether the keys of an object are known or not.
|
|
480
|
-
*
|
|
481
|
-
* @example
|
|
482
|
-
* ```ts
|
|
483
|
-
* // false
|
|
484
|
-
* type ObjIsGeneric = IsStringLiteral<keyof Record<string, boolean>>;
|
|
485
|
-
*
|
|
486
|
-
* // true
|
|
487
|
-
* type ObjIsKnown = IsStringLiteral<keyof { foo: boolean; }>; // true
|
|
488
|
-
* ```
|
|
489
|
-
*
|
|
490
|
-
* @internal
|
|
491
|
-
*/
|
|
492
|
-
export type IsStringLiteral<T extends string> = string extends T ? false : true;
|
|
493
|
-
|
|
494
|
-
/**
|
|
495
|
-
* Returns the given generic as either itself or a promise of itself.
|
|
496
|
-
*/
|
|
497
|
-
export type MaybePromise<T> = T | Promise<T>;
|
|
498
|
-
|
|
499
|
-
export type Simplify<T> = { [KeyType in keyof T]: T[KeyType] } & {};
|