Skip to content

Commit

Permalink
Merge pull request #3 from hyperse-io/feat/track
Browse files Browse the repository at this point in the history
Feat/track
  • Loading branch information
hyperse-net authored Aug 6, 2024
2 parents 816e5a9 + ea8deac commit 09dc3e9
Show file tree
Hide file tree
Showing 30 changed files with 613 additions and 439 deletions.
5 changes: 5 additions & 0 deletions .changeset/stupid-days-decide.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@hyperse/track": patch
---

perfect track pipeline
3 changes: 1 addition & 2 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,5 @@
},
"[jsonc]": {
"editor.formatOnSave": false
},
"commentTranslate.multiLineMerge": true
}
}
45 changes: 24 additions & 21 deletions src/adapter/adapter-base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,11 @@ export abstract class BaseAdapter<
{
private setupHook?: AdapterOptions['setup'];
private beforeHook?: AdapterBeforeFunction<Context, EventData>;
private transformHook?: AdapterTransformFunction<Context, EventData, any>;
private afterHook?: AdapterAfterFunction<
Context,
EventData,
Awaited<ReturnType<AdapterTransformFunction<Context, EventData, any>>>
>;
transformHookMap: {
[K in keyof EventData]?: AdapterTransformFunction<Context, K, EventData>;
} = {};

private afterHook?: AdapterAfterFunction<Context, EventData>;

abstract isTrackable(): boolean | Promise<boolean>;

Expand All @@ -45,29 +44,33 @@ export abstract class BaseAdapter<
this.beforeHook = fun;
}

public _mountAfterHook<ReportData>(
fun: AdapterAfterFunction<Context, EventData, ReportData>
): void {
public _mountAfterHook(fun: AdapterAfterFunction<Context, EventData>): void {
this.afterHook = fun;
}

public _mountTransformHook<ReportData>(
fun: AdapterTransformFunction<Context, EventData, ReportData>
public _mountTransformHook<EventType extends keyof EventData>(
eventType: EventType,
fun: AdapterTransformFunction<Context, EventType, EventData>
) {
this.transformHook = fun;
this.transformHookMap[eventType] = fun;
}

private executeTransform = async (
private executeTransform = async <EventType extends keyof EventData>(
ctx: Context,
eventType: keyof EventData,
eventData: EventData
eventType: EventType,
eventData: EventData[EventType]
) => {
if (!this.transformHook) {
if (Object.keys(this.transformHookMap).length < 1) {
ctx.logger?.warn('Adapter transform hook is not defined');
return eventData;
}
const transformHook = this.transformHookMap[eventType];

if (!transformHook) {
return eventData;
}
const result = await executeFunction(
this.transformHook,
transformHook as AdapterTransformFunction<Context, EventType, EventData>,
ctx,
eventType,
eventData
Expand All @@ -77,7 +80,7 @@ export abstract class BaseAdapter<

private executeReport = async <ReportData>(
ctx: Context,
eventData: EventData,
eventData: EventData[keyof EventData],
reportData: ReportData
): Promise<ReportData> => {
let setupResult;
Expand All @@ -96,10 +99,10 @@ export abstract class BaseAdapter<
* @param eventData - The data associated with the event.
* @returns A promise that resolves when the tracking is complete.
*/
public async track(
public async track<EventType extends keyof EventData>(
ctx: Context,
eventType: keyof EventData,
eventData: EventData
eventType: EventType,
eventData: EventData[EventType]
): Promise<void> {
await pipe(
async () =>
Expand Down
72 changes: 55 additions & 17 deletions src/adapter/adapter-builder.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import { UnionToTuple } from '../types/type-union-tuple.js';
import {
AdapterAfterFunction,
AdapterBeforeFunction,
AdapterTransformFunction,
AdapterReportData,
TrackAdapter,
} from '../types/types-adapter.js';
import { TrackAdapterOptions, TrackContext } from '../types/types-create.js';
import { TrackEventDataBase } from '../types/types-track.js';

/**
* Represents a builder for creating a track adapter.
* A builder for creating a track adapter.
*
* @template Context - The type of the track context.
* @template EventData - The type of the track event data.
Expand Down Expand Up @@ -53,13 +54,6 @@ export class AdapterBuilder<
};
}

private buildTransformChainer<ReportData>() {
return {
after: this.mountAfterHook<ReportData>,
build: this.executeBuild,
};
}

private buildAfterChainer() {
return {
build: this.executeBuild,
Expand All @@ -82,17 +76,61 @@ export class AdapterBuilder<
return this.buildBeforeChainer();
};

private mountTransformHook = <ReportData>(
fun: AdapterTransformFunction<Context, EventData, ReportData>
private buildTransformChainer() {
return {
after: this.mountAfterHook,
build: this.executeBuild,
};
}

private mountTransformHook = <
Key extends keyof LeftEventData,
LeftEventData = EventData,
>(
eventType: Key,
fun: (
ctx: Context,
eventType: Key,
eventData: LeftEventData[Key]
) => AdapterReportData | Promise<AdapterReportData>
) => {
this.adapter._mountTransformHook<ReportData>(fun);
return this.buildTransformChainer<ReportData>();
this.adapter._mountTransformHook(
eventType as keyof EventData,
fun as (...args: any[]) => AdapterReportData | Promise<AdapterReportData>
);
const transform = <
RightKey extends keyof RightEventData,
RightEventData = Omit<LeftEventData, Key>,
>(
eventType: RightKey,
fun: (
ctx: Context,
eventType: RightKey,
eventData: RightEventData[RightKey]
) => AdapterReportData | Promise<AdapterReportData>
) => {
this.adapter._mountTransformHook(
eventType as keyof EventData,
fun as (
...args: any[]
) => AdapterReportData | Promise<AdapterReportData>
);
return this.mountTransformHook<RightKey, RightEventData>(eventType, fun);
};
const result = {
transform: transform,
...this.buildTransformChainer(),
};

return result as UnionToTuple<
Exclude<keyof LeftEventData, Key>
>['length'] extends 0
? ReturnType<typeof this.buildTransformChainer>
: typeof result;
};

private mountAfterHook = <ReportData>(
fun: AdapterAfterFunction<Context, EventData, ReportData>
) => {
this.adapter._mountAfterHook<ReportData>(fun);
private mountAfterHook = (fun: AdapterAfterFunction<Context, EventData>) => {
this.adapter._mountAfterHook(fun);
return this.buildAfterChainer();
};

Expand Down
6 changes: 3 additions & 3 deletions src/adapter/create-adapter-builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ import { AdapterBuilder } from './adapter-builder.js';
* Creates an adapter builder for a given track adapter.
*
* @param adapter - The track adapter to build.
* @returns A promise that resolves to the initialized adapter builder.
* @throws {Error} If the adapter is not provided.
* @returns The initialized adapter builder.
* @throws Error if the adapter is not provided.
*/
export async function createAdapterBuilder<
export function createAdapterBuilder<
Context extends TrackContext<any>,
EventData extends TrackEventDataBase,
AdapterOptions extends TrackAdapterOptions<Context, EventData>,
Expand Down
1 change: 0 additions & 1 deletion src/constant/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
export * from './default-constant.js';
export * from './track-func.js';
13 changes: 0 additions & 13 deletions src/constant/track-func.ts

This file was deleted.

25 changes: 6 additions & 19 deletions src/core/create-track-builder.ts
Original file line number Diff line number Diff line change
@@ -1,33 +1,20 @@
import { executeFunction } from '../helpers/helper-execute.js';
import { TrackContext, TrackCreateOptions } from '../types/types-create.js';
import { TrackEventDataBase } from '../types/types-track.js';
import { TrackBuilder } from './track-builder.js';

/**
* Creates a track builder function.
* Creates a track builder instance.
*
* @param options - The track global options.
* @returns A promise that resolves to the initialized track builder.
* @template Context - The type of the track context.
* @template EventData - The type of the track event value.
* @template EventData - The type of the track event data.
* @param options - The options for creating the track builder.
* @returns A new instance of the TrackBuilder class.
*/
export const createTrackBuilder = async <
export const createTrackBuilder = <
Context extends TrackContext<any>,
EventData extends TrackEventDataBase,
>(
options: TrackCreateOptions<Context, EventData> = {}
) => {
const { eventData, logger, createData } = options;

const ctx = {
data: {},
logger: logger,
};

if (createData) {
const data = await executeFunction(createData, eventData);
ctx.data = data || {};
}

return new TrackBuilder<Context, EventData>(ctx as Context, eventData);
return new TrackBuilder<Context, EventData>(options);
};
Loading

0 comments on commit 09dc3e9

Please sign in to comment.