Skip to content

Commit 17e1623

Browse files
committed
Improve init lifecycle hook types and fix tabler icons on spans
1 parent 2c44e59 commit 17e1623

File tree

10 files changed

+131
-56
lines changed

10 files changed

+131
-56
lines changed

apps/webapp/app/components/runs/v3/RunIcon.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ type SpanNameIcons = {
2828
const spanNameIcons: SpanNameIcons[] = [{ matcher: /^prisma:/, iconName: "brand-prisma" }];
2929

3030
export function RunIcon({ name, className, spanName }: TaskIconProps) {
31+
console.log("spanName", spanName, name);
32+
3133
const spanNameIcon = spanNameIcons.find(({ matcher }) => matcher.test(spanName));
3234

3335
if (spanNameIcon) {
@@ -44,6 +46,9 @@ export function RunIcon({ name, className, spanName }: TaskIconProps) {
4446
}
4547

4648
if (!name) return <Squares2X2Icon className={cn(className, "text-text-dimmed")} />;
49+
if (tablerIcons.has(name)) {
50+
return <TablerIcon name={name} className={className} />;
51+
}
4752

4853
switch (name) {
4954
case "task":

packages/core/src/v3/lifecycle-hooks-api.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ export type {
88
OnInitHookFunction,
99
AnyOnInitHookFunction,
1010
RegisteredHookFunction,
11+
TaskInitHookParams,
1112
} from "./lifecycleHooks/types.js";
1213

1314
export * as lifecycleHooksAdapters from "./lifecycleHooks/adapters.js";

packages/core/src/v3/lifecycleHooks/manager.ts

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,20 @@ import {
66
} from "./types.js";
77

88
export class StandardLifecycleHooksManager implements LifecycleHooksManager {
9-
private initHooks: Map<string, RegisteredHookFunction<AnyOnInitHookFunction>> = new Map();
10-
private taskInitHooks: Map<string, string> = new Map();
9+
private globalInitHooks: Map<string, RegisteredHookFunction<AnyOnInitHookFunction>> = new Map();
10+
private taskInitHooks: Map<string, RegisteredHookFunction<AnyOnInitHookFunction>> = new Map();
1111

1212
registerGlobalInitHook(hook: RegisterHookFunctionParams<AnyOnInitHookFunction>): void {
1313
// if there is no id, lets generate one based on the contents of the function
1414
const id = generateHookId(hook);
1515

1616
const registeredHook = {
1717
id,
18-
name: hook.id ?? hook.fn.name,
18+
name: hook.id ?? hook.fn.name ? (hook.fn.name === "" ? undefined : hook.fn.name) : undefined,
1919
fn: hook.fn,
2020
};
2121

22-
this.initHooks.set(id, registeredHook);
22+
this.globalInitHooks.set(id, registeredHook);
2323
}
2424

2525
registerTaskInitHook(
@@ -32,18 +32,15 @@ export class StandardLifecycleHooksManager implements LifecycleHooksManager {
3232
fn: hook.fn,
3333
};
3434

35-
this.initHooks.set(registeredHook.id, registeredHook);
36-
this.taskInitHooks.set(taskId, registeredHook.id);
35+
this.taskInitHooks.set(taskId, registeredHook);
3736
}
3837

3938
getTaskInitHook(taskId: string): AnyOnInitHookFunction | undefined {
40-
const hookId = this.taskInitHooks.get(taskId);
41-
if (!hookId) return undefined;
42-
return this.initHooks.get(hookId)?.fn;
39+
return this.taskInitHooks.get(taskId)?.fn;
4340
}
4441

4542
getGlobalInitHooks(): RegisteredHookFunction<AnyOnInitHookFunction>[] {
46-
return Array.from(this.initHooks.values());
43+
return Array.from(this.globalInitHooks.values());
4744
}
4845
}
4946

@@ -69,5 +66,9 @@ export class NoopLifecycleHooksManager implements LifecycleHooksManager {
6966
}
7067

7168
function generateHookId(hook: RegisterHookFunctionParams<any>): string {
72-
return hook.id ?? hook.fn.name ?? hook.fn.toString();
69+
return hook.id ?? hook.fn.name
70+
? hook.fn.name === ""
71+
? hook.fn.toString()
72+
: hook.fn.name
73+
: hook.fn.toString();
7374
}

packages/core/src/v3/lifecycleHooks/types.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,17 @@
11
import { TaskRunContext } from "../schemas/index.js";
22

3-
export type OnInitHookFunction<TPayload, TInitOutput> = (params: {
3+
export type TaskInitHookParams<TPayload = unknown> = {
44
ctx: TaskRunContext;
55
payload: TPayload;
66
task: string;
77
signal?: AbortSignal;
8-
}) => TInitOutput | undefined | void | Promise<TInitOutput | undefined | void>;
8+
};
9+
10+
export type OnInitHookFunction<TPayload, TInitOutput extends Record<string, unknown>> = (
11+
params: TaskInitHookParams<TPayload>
12+
) => TInitOutput | undefined | void | Promise<TInitOutput | undefined | void>;
913

10-
export type AnyOnInitHookFunction = OnInitHookFunction<unknown, unknown>;
14+
export type AnyOnInitHookFunction = OnInitHookFunction<unknown, Record<string, unknown>>;
1115

1216
export type RegisterHookFunctionParams<THookFunction extends (params: any) => any> = {
1317
id?: string;

packages/core/src/v3/semanticInternalAttributes.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ export const SemanticInternalAttributes = {
3333
STYLE_ICON: "$style.icon",
3434
STYLE_VARIANT: "$style.variant",
3535
STYLE_ACCESSORY: "$style.accessory",
36+
COLLAPSED: "$collapsed",
3637
METADATA: "$metadata",
3738
TRIGGER: "$trigger",
3839
PAYLOAD: "$payload",

packages/core/src/v3/workers/taskExecutor.ts

Lines changed: 72 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,13 @@ import { VERSION } from "../../version.js";
33
import { ApiError, RateLimitError } from "../apiClient/errors.js";
44
import { ConsoleInterceptor } from "../consoleInterceptor.js";
55
import { isInternalError, parseError, sanitizeError, TaskPayloadParsedError } from "../errors.js";
6-
import { lifecycleHooks, runMetadata, TriggerConfig, waitUntil } from "../index.js";
6+
import {
7+
flattenAttributes,
8+
lifecycleHooks,
9+
runMetadata,
10+
TriggerConfig,
11+
waitUntil,
12+
} from "../index.js";
713
import { recordSpanException, TracingSDK } from "../otel/index.js";
814
import { runTimelineMetrics } from "../run-timeline-metrics-api.js";
915
import {
@@ -288,58 +294,87 @@ export class TaskExecutor {
288294
return this._tracer.startActiveSpan(
289295
"hooks.init",
290296
async (span) => {
291-
return await runTimelineMetrics.measureMetric("trigger.dev/execution", "init", async () => {
292-
// Store global hook results in an array
293-
const globalResults = [];
294-
for (const hook of globalInitHooks) {
295-
const result = await this._tracer.startActiveSpan(
296-
hook.name ?? "global",
297-
async (span) => {
298-
return await hook.fn({ payload, ctx, signal, task: this.task.id });
299-
},
300-
{
301-
attributes: {
302-
[SemanticInternalAttributes.STYLE_ICON]: "function",
297+
const result = await runTimelineMetrics.measureMetric(
298+
"trigger.dev/execution",
299+
"init",
300+
async () => {
301+
// Store global hook results in an array
302+
const globalResults = [];
303+
for (const hook of globalInitHooks) {
304+
const result = await this._tracer.startActiveSpan(
305+
hook.name ?? "global",
306+
async (span) => {
307+
const result = await hook.fn({ payload, ctx, signal, task: this.task.id });
308+
309+
if (result && typeof result === "object" && !Array.isArray(result)) {
310+
span.setAttributes(flattenAttributes(result));
311+
312+
return result;
313+
}
314+
315+
return {};
303316
},
317+
{
318+
attributes: {
319+
[SemanticInternalAttributes.STYLE_ICON]: "tabler-function",
320+
},
321+
}
322+
);
323+
// Only include object results
324+
if (result && typeof result === "object" && !Array.isArray(result)) {
325+
globalResults.push(result);
304326
}
305-
);
306-
// Only include object results
307-
if (result && typeof result === "object" && !Array.isArray(result)) {
308-
globalResults.push(result);
309327
}
310-
}
311328

312-
// Merge all global results into a single object
313-
const mergedGlobalResults = Object.assign({}, ...globalResults);
329+
// Merge all global results into a single object
330+
const mergedGlobalResults = Object.assign({}, ...globalResults);
314331

315-
if (taskInitHook) {
316-
const taskResult = await this._tracer.startActiveSpan(
317-
"task",
318-
async (span) => {
319-
return await taskInitHook({ payload, ctx, signal, task: this.task.id });
320-
},
321-
{
322-
attributes: {
323-
[SemanticInternalAttributes.STYLE_ICON]: "function",
332+
if (taskInitHook) {
333+
const taskResult = await this._tracer.startActiveSpan(
334+
"task",
335+
async (span) => {
336+
const result = await taskInitHook({ payload, ctx, signal, task: this.task.id });
337+
338+
if (result && typeof result === "object" && !Array.isArray(result)) {
339+
span.setAttributes(flattenAttributes(result));
340+
341+
return result;
342+
}
343+
344+
return {};
324345
},
346+
{
347+
attributes: {
348+
[SemanticInternalAttributes.STYLE_ICON]: "tabler-function",
349+
},
350+
}
351+
);
352+
353+
// Only merge if taskResult is an object
354+
if (taskResult && typeof taskResult === "object" && !Array.isArray(taskResult)) {
355+
return { ...mergedGlobalResults, ...taskResult };
325356
}
326-
);
327357

328-
// Only merge if taskResult is an object
329-
if (taskResult && typeof taskResult === "object" && !Array.isArray(taskResult)) {
330-
return { ...mergedGlobalResults, ...taskResult };
358+
// If taskResult isn't an object, return global results
359+
return mergedGlobalResults;
331360
}
332361

333-
// If taskResult isn't an object, return global results
334362
return mergedGlobalResults;
335363
}
364+
);
336365

337-
return mergedGlobalResults;
338-
});
366+
if (result && typeof result === "object" && !Array.isArray(result)) {
367+
span.setAttributes(flattenAttributes(result));
368+
369+
return result;
370+
}
371+
372+
return;
339373
},
340374
{
341375
attributes: {
342-
[SemanticInternalAttributes.STYLE_ICON]: "function",
376+
[SemanticInternalAttributes.STYLE_ICON]: "tabler-function",
377+
[SemanticInternalAttributes.COLLAPSED]: true,
343378
},
344379
}
345380
);

packages/trigger-sdk/src/v3/hooks.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,11 @@
1-
import { lifecycleHooks, type AnyOnInitHookFunction } from "@trigger.dev/core/v3";
1+
import {
2+
lifecycleHooks,
3+
type AnyOnInitHookFunction,
4+
type TaskInitHookParams,
5+
type OnInitHookFunction,
6+
} from "@trigger.dev/core/v3";
7+
8+
export type { AnyOnInitHookFunction, TaskInitHookParams, OnInitHookFunction };
29

310
export function onInit(name: string, fn: AnyOnInitHookFunction): void;
411
export function onInit(fn: AnyOnInitHookFunction): void;

packages/trigger-sdk/src/v3/tasks.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ export type {
4747
TaskFromIdentifier,
4848
};
4949

50+
export type * from "./hooks.js";
51+
5052
/** Creates a task that can be triggered
5153
* @param options - Task options
5254
* @example

references/hello-world/src/trigger/example.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,15 @@ import { setTimeout } from "timers/promises";
33

44
export const helloWorldTask = task({
55
id: "hello-world",
6-
run: async (payload: any, { ctx }) => {
7-
logger.debug("debug: Hello, world!", { payload });
6+
init: async (payload, { ctx }) => {
7+
logger.info("Hello, world from the init", { ctx, payload });
8+
9+
return {
10+
foobar: "baz",
11+
};
12+
},
13+
run: async (payload: any, { ctx, init }) => {
14+
logger.debug("debug: Hello, world!", { payload, init });
815
logger.info("info: Hello, world!", { payload });
916
logger.log("log: Hello, world!", { payload });
1017
logger.warn("warn: Hello, world!", { payload });

references/hello-world/src/trigger/init.ts

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { logger, tasks } from "@trigger.dev/sdk";
1+
import { logger, type TaskInitHookParams, tasks } from "@trigger.dev/sdk";
22

33
// tasks.onSuccess(({ ctx, payload, output }) => {
44
// logger.info("Hello, world from the success", { ctx, payload });
@@ -28,6 +28,18 @@ import { logger, tasks } from "@trigger.dev/sdk";
2828
// logger.info("Hello, world from the start", { ctx, payload });
2929
// });
3030

31-
tasks.onInit("logging", ({ ctx, payload, task }) => {
31+
tasks.onInit(({ ctx, payload, task }) => {
3232
logger.info("Hello, world from the init", { ctx, payload, task });
33+
34+
return {
35+
foo: "bar",
36+
};
37+
});
38+
39+
tasks.onInit(({ ctx, payload, task }) => {
40+
logger.info("Hello, world from the init 2", { ctx, payload, task });
41+
42+
return {
43+
bar: "baz",
44+
};
3345
});

0 commit comments

Comments
 (0)