feat: Add Session

This commit is contained in:
Wanjohi
2025-10-27 11:38:05 +03:00
parent 13cb3f15a7
commit 3a08e27614
6 changed files with 274 additions and 1554 deletions

View File

@@ -1,217 +1,45 @@
import {
type Session,
type RunTypes,
type InitOutput,
type StartOptions,
type inferSchemaIn,
type SchemaParseFn,
type SessionSchema,
type SessionOptions,
type SessionWithSchema,
type SessionWithSchemaOptions,
type RunHandleFromTypes,
type AnyRunTypes,
type SessionOptionsWithSchema,
getSchemaParseFn,
SessionRunPromise,
} from "@nestri/core/session/index";
import { Identifier } from "@nestri/core/id";
import { Session } from "@nestri/core/session/index";
// Overload: when payloadSchema is provided, payload type should be any
export function createRun<
TIdentifier extends string,
TOutput = unknown,
TInitOutput extends InitOutput = any,
>(
params: SessionOptionsWithSchema<TIdentifier, TOutput, TInitOutput>,
): Session<TIdentifier, any, TOutput>;
// Overload: normal case without payloadSchema
export function createRun<
TIdentifier extends string,
TInput = void,
TOutput = unknown,
TInitOutput extends InitOutput = any,
>(
params: SessionOptions<TIdentifier, TInput, TOutput, TInitOutput>,
): Session<TIdentifier, TInput, TOutput>;
export function createRun<
TIdentifier extends string,
TInput = void,
TOutput = unknown,
TInitOutput extends InitOutput = any,
>(
params:
| SessionOptions<TIdentifier, TInput, TOutput, TInitOutput>
| SessionOptionsWithSchema<TIdentifier, TOutput, TInitOutput>,
): Session<TIdentifier, TInput, TOutput> | Session<TIdentifier, any, TOutput> {
const session: Session<TIdentifier, TInput, TOutput> = {
id: params.id,
description: params.description,
jsonSchema: params.jsonSchema,
start: async (payload, options) => {
return await run_internal<RunTypes<TIdentifier, TInput, TOutput>>(
"run()",
params.id,
// Simple session creation function using our clean Session types
export function createSession(config: Session.Config): Session.Session {
const session: Session.Session = {
description: config.description,
start: async (payload: any) => {
console.log(
`Starting session ${config.description} with payload:`,
payload,
undefined,
{
queue: params.queue?.name,
...options,
},
);
// TODO: Implement actual session start logic
return {
id: `run_${Date.now()}` as `run_${string}`,
sessionIdentifier: config.description,
publicAccessToken: "mock_token",
};
},
startAndWait: (payload, options) => {
return new SessionRunPromise<TIdentifier, TOutput>((resolve, reject) => {
triggerAndWait_internal<TIdentifier, TInput, TOutput>(
"triggerAndWait()",
params.id,
payload,
undefined,
{
queue: params.queue?.name,
...options,
},
)
.then((result) => {
resolve(result);
})
.catch((error) => {
reject(error);
startAndWait: (payload: any) => {
console.log(
`Starting session ${config.description} and waiting with payload:`,
payload,
);
// TODO: Implement actual session start and wait logic
return new Promise((resolve) => {
setTimeout(() => {
resolve({
ok: true,
id: `run_${Date.now()}` as any,
sessionIdentifier: config.description,
});
}, params.id);
}, 1000);
});
},
};
registerTaskLifecycleHooks(params.id, params);
resourceCatalog.registerTaskMetadata({
id: params.id,
description: params.description,
queue: params.queue,
retry: params.retry
? { ...defaultRetryOptions, ...params.retry }
: undefined,
machine:
typeof params.machine === "string"
? { preset: params.machine }
: params.machine,
maxDuration: params.maxDuration,
payloadSchema: params.jsonSchema,
fns: {
run: params.run,
},
});
const queue = params.queue;
if (queue && typeof queue.name === "string") {
resourceCatalog.registerQueueMetadata({
name: queue.name,
concurrencyLimit: queue.concurrencyLimit,
});
}
// @ts-expect-error
session[Symbol.for("nestri/session")] = true;
// Store the run function for later execution
(session as any)._runFunction = config.run;
return session;
}
export function createSchemaTask<
TIdentifier extends string,
TSchema extends SessionSchema | undefined = undefined,
TOutput = unknown,
TInitOutput extends InitOutput = any,
>(
params: SessionWithSchemaOptions<TIdentifier, TSchema, TOutput, TInitOutput>,
): SessionWithSchema<TIdentifier, TSchema, TOutput> {
const parsePayload = params.schema
? getSchemaParseFn<inferSchemaIn<TSchema>>(params.schema)
: undefined;
const session: SessionWithSchema<TIdentifier, TSchema, TOutput> = {
id: params.id,
description: params.description,
schema: params.schema,
start: async (payload, options, requestOptions) => {
return await run_internal<
RunTypes<TIdentifier, inferSchemaIn<TSchema>, TOutput>
>(
"run()",
params.id,
payload,
parsePayload,
{
queue: params.queue?.name,
...options,
},
requestOptions,
);
},
startAndWait: (payload, options) => {
return new SessionRunPromise<TIdentifier, TOutput>((resolve, reject) => {
triggerAndWait_internal<TIdentifier, inferSchemaIn<TSchema>, TOutput>(
"triggerAndWait()",
params.id,
payload,
parsePayload,
{
queue: params.queue?.name,
...options,
},
)
.then((result) => {
resolve(result);
})
.catch((error) => {
reject(error);
});
}, params.id);
},
};
registerTaskLifecycleHooks(params.id, params);
resourceCatalog.registerTaskMetadata({
id: params.id,
description: params.description,
queue: params.queue,
retry: params.retry
? { ...defaultRetryOptions, ...params.retry }
: undefined,
machine: { preset: params.machine },
maxDuration: params.maxDuration,
fns: {
run: params.run,
parsePayload,
},
schema: params.schema,
});
const queue = params.queue;
if (queue && typeof queue.name === "string") {
resourceCatalog.registerQueueMetadata({
name: queue.name,
concurrencyLimit: queue.concurrencyLimit,
});
}
// @ts-expect-error
session[Symbol.for("nestri/session")] = true;
return session;
}
export const session = createRun;
export const schemaSession = createSchemaTask;
async function run_internal<TRunTypes extends AnyRunTypes>(
name: string,
id: TRunTypes["sessionIdentifier"],
payload: TRunTypes["payload"],
parsePayload?: SchemaParseFn<TRunTypes["payload"]>,
options?: StartOptions,
requestOptions?: any, //TriggerApiRequestOptions,
): Promise<RunHandleFromTypes<TRunTypes>> {}
export const session = createSession;