Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Loosen component typing for multi-package usage #817

Merged
merged 9 commits into from
Jan 30, 2025
5 changes: 5 additions & 0 deletions .changeset/late-cups-smell.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"inngest": patch
---

`serve()` and `connect()` now have looser typing for `client` and `functions`, resulting in easier use of multiple `inngest` packages in a single process
28 changes: 23 additions & 5 deletions packages/inngest/src/components/Inngest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,9 @@ export type EventsFromOpts<TOpts extends ClientOptions> =
*
* @public
*/
export class Inngest<TClientOpts extends ClientOptions = ClientOptions> {
export class Inngest<TClientOpts extends ClientOptions = ClientOptions>
implements Inngest.Like
{
/**
* The ID of this instance, most commonly a reference to the application it
* resides in.
Expand Down Expand Up @@ -757,11 +759,27 @@ export const builtInMiddleware = (<T extends InngestMiddleware.Stack>(
*/
export namespace Inngest {
/**
* Represents any `Inngest` instance, regardless of generics and
* inference.
* Represents any `Inngest` instance, regardless of generics and inference.
*
* Prefer use of `Inngest.Like` where possible to ensure compatibility with
* multiple versions.
*/
export type Any = Inngest;

/**
* References any `Inngest` instance across library versions, useful for use
* in public APIs to ensure compatibility with multiple versions.
*
* Prefer use of `Inngest.Any` internally and `Inngest.Like` for public APIs.
*/
export interface Like {
readonly id: string;
apiBaseUrl: string | undefined;
eventBaseUrl: string | undefined;
env: string | null;
buildId?: string | undefined;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought we changed this to version id?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Coming in a later PR!

}

export type CreateFunction<TClient extends Inngest.Any> = <
TMiddleware extends InngestMiddleware.Stack,
TTrigger extends SingleOrArray<
Expand Down Expand Up @@ -843,7 +861,7 @@ export namespace Inngest {
*/
export type GetStepTools<
// eslint-disable-next-line @typescript-eslint/no-explicit-any
TInngest extends Inngest<any>,
TInngest extends Inngest.Any,
TTrigger extends keyof GetEvents<TInngest> &
string = keyof GetEvents<TInngest> & string,
> = GetFunctionInput<TInngest, TTrigger> extends { step: infer TStep }
Expand Down Expand Up @@ -989,5 +1007,5 @@ export type GetEvents<
* @public
*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export type ClientOptionsFromInngest<TInngest extends Inngest<any>> =
export type ClientOptionsFromInngest<TInngest extends Inngest.Any> =
TInngest extends Inngest<infer U> ? U : ClientOptions;
12 changes: 6 additions & 6 deletions packages/inngest/src/components/InngestCommHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,12 +79,12 @@ export interface ServeHandlerOptions extends RegisterOptions {
/**
* The `Inngest` instance used to declare all functions.
*/
client: Inngest.Any;
client: Inngest.Like;

/**
* An array of the functions to serve and register with Inngest.
*/
functions: readonly InngestFunction.Any[];
functions: readonly InngestFunction.Like[];
}

export interface InternalServeHandlerOptions extends ServeHandlerOptions {
Expand Down Expand Up @@ -122,12 +122,12 @@ interface InngestCommHandlerOptions<
* receiving events from the same service, as you can reuse a single
* definition of Inngest.
*/
client: Inngest.Any;
client: Inngest.Like;

/**
* An array of the functions to serve and register with Inngest.
*/
functions: readonly InngestFunction.Any[];
functions: readonly InngestFunction.Like[];

/**
* The `handler` is the function that will be called with your framework's
Expand Down Expand Up @@ -365,7 +365,7 @@ export class InngestCommHandler<
}

this.frameworkName = options.frameworkName;
this.client = options.client;
this.client = options.client as Inngest.Any;
this.id = options.id || this.client.id;

this.handler = options.handler as Handler;
Expand All @@ -380,7 +380,7 @@ export class InngestCommHandler<
);

// Ensure we filter any undefined functions in case of missing imports.
this.rawFns = options.functions.filter(Boolean);
this.rawFns = options.functions.filter(Boolean) as InngestFunction.Any[];

if (this.rawFns.length !== options.functions.length) {
// TODO PrettyError
Expand Down
8 changes: 7 additions & 1 deletion packages/inngest/src/components/InngestFunction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ export class InngestFunction<
TTriggers extends InngestFunction.Trigger<
TriggersFromClient<TClient>
>[] = InngestFunction.Trigger<TriggersFromClient<TClient>>[],
> {
> implements InngestFunction.Like
{
static stepId = "step";
static failureSuffix = "-failure";

Expand Down Expand Up @@ -282,6 +283,11 @@ export namespace InngestFunction {
any
>;

export interface Like {
name: string;
description?: string;
}

/**
* A user-friendly method of specifying a trigger for an Inngest function.
*
Expand Down
22 changes: 12 additions & 10 deletions packages/inngest/src/components/connect/index.ts
Original file line number Diff line number Diff line change
@@ -1,41 +1,42 @@
import { InngestCommHandler } from "../InngestCommHandler.js";
import { WaitGroup } from "@jpwilliams/waitgroup";
import debug, { type Debugger } from "debug";
import { ulid } from "ulid";
import { headerKeys, queryKeys } from "../../helpers/consts.js";
import { allProcessEnv, getPlatformName } from "../../helpers/env.js";
import { parseFnData } from "../../helpers/functions.js";
import { hashSigningKey } from "../../helpers/strings.js";
import {
ConnectMessage,
type GatewayExecutorRequestData,
GatewayMessageType,
gatewayMessageTypeToJSON,
SDKResponse,
SDKResponseStatus,
WorkerConnectRequestData,
WorkerRequestAckData,
type GatewayExecutorRequestData,
} from "../../proto/src/components/connect/protobuf/connect.js";
import { type Capabilities, type FunctionConfig } from "../../types.js";
import { version } from "../../version.js";
import { PREFERRED_EXECUTION_VERSION } from "../execution/InngestExecution.js";
import { type Inngest } from "../Inngest.js";
import { InngestCommHandler } from "../InngestCommHandler.js";
import { type InngestFunction } from "../InngestFunction.js";
import { MessageBuffer } from "./buffer.js";
import {
createStartRequest,
parseConnectMessage,
parseGatewayExecutorRequest,
parseStartResponse,
parseWorkerReplyAck,
} from "./messages.js";
import { onShutdown, retrieveSystemAttributes } from "./os.js";
import {
ConnectionState,
DEFAULT_SHUTDOWN_SIGNALS,
type ConnectHandlerOptions,
type WorkerConnection,
} from "./types.js";
import { WaitGroup } from "@jpwilliams/waitgroup";
import debug, { type Debugger } from "debug";
import { onShutdown, retrieveSystemAttributes } from "./os.js";
import { MessageBuffer } from "./buffer.js";
import { expBackoff, AuthError, ReconnectError } from "./util.js";
import { AuthError, expBackoff, ReconnectError } from "./util.js";

const ResponseAcknowlegeDeadline = 5_000;
const WorkerHeartbeatInterval = 10_000;
Expand Down Expand Up @@ -261,7 +262,8 @@ class WebSocketWorkerConnection implements WorkerConnection {
};

const functions: Array<FunctionConfig> = this.options.functions.flatMap(
(f) => f["getConfig"](new URL("http://example.com")) // refactor; base URL shouldn't be optional here; we likely need to fetch a different kind of config
(f) =>
(f as InngestFunction.Any)["getConfig"](new URL("http://example.com")) // refactor; base URL shouldn't be optional here; we likely need to fetch a different kind of config
);

const data: connectionEstablishData = {
Expand Down Expand Up @@ -866,11 +868,11 @@ class WebSocketWorkerConnection implements WorkerConnection {
}

export const connect = async (
inngest: Inngest.Any,
inngest: Inngest.Like,
options: ConnectHandlerOptions
// eslint-disable-next-line @typescript-eslint/require-await
): Promise<WorkerConnection> => {
const conn = new WebSocketWorkerConnection(inngest, options);
const conn = new WebSocketWorkerConnection(inngest as Inngest.Any, options);

await conn.connect();

Expand Down
2 changes: 1 addition & 1 deletion packages/inngest/src/components/connect/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export interface ConnectHandlerOptions extends RegisterOptions {
/**
* An array of the functions to serve and register with Inngest.
*/
functions: readonly InngestFunction.Any[];
functions: readonly InngestFunction.Like[];

instanceId: string;
maxConcurrency?: number;
Expand Down
2 changes: 1 addition & 1 deletion packages/inngest/src/fastify.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ import { type RegisterOptions, type SupportedFrameworkName } from "./types.js";
export const frameworkName: SupportedFrameworkName = "fastify";

type InngestPluginOptions = {
client: Inngest.Any;
client: Inngest.Like;
functions: InngestFunction.Any[];
options?: RegisterOptions;
};
Expand Down
2 changes: 1 addition & 1 deletion packages/inngest/src/helpers/errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -463,7 +463,7 @@ export const fixEventKeyMissingSteps = [
`Pass a key to the \`new Inngest()\` constructor using the \`${
"eventKey" satisfies keyof ClientOptions
}\` option`,
`Use \`inngest.${"setEventKey" satisfies keyof Inngest}()\` at runtime`,
`Use \`inngest.${"setEventKey" satisfies keyof Inngest.Any}()\` at runtime`,
];

/**
Expand Down
8 changes: 0 additions & 8 deletions packages/inngest/src/helpers/functions.test.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import { InngestFunction } from "@local/components/InngestFunction";
import { ExecutionVersion } from "@local/components/execution/InngestExecution";
import { parseFnData, type FnData } from "@local/helpers/functions";
import { type EventPayload } from "@local/types";
import { createClient } from "../test/helpers";

const randomstr = (): string => {
return (Math.random() + 1).toString(36).substring(2);
Expand Down Expand Up @@ -71,12 +69,6 @@ describe("#parseFnData", () => {
},
];

const fn = new InngestFunction(
createClient({ id: "test-client" }),
{ id: "test-fn", triggers: [{ event: "test-event" }] },
() => "test-return"
);

specs.forEach((test) => {
it(test.name, () => {
if (test.isOk) {
Expand Down
1 change: 0 additions & 1 deletion packages/inngest/src/helpers/functions.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { ZodError, z } from "zod";
import { type InngestApi } from "../api/api.js";
import { stepsSchemas } from "../api/schema.js";
import { type InngestFunction } from "../components/InngestFunction.js";
import {
ExecutionVersion,
PREFERRED_EXECUTION_VERSION,
Expand Down