-
Notifications
You must be signed in to change notification settings - Fork 20
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(plugins): draft implementation of golem plugins
- Loading branch information
1 parent
bf1fab1
commit 195b624
Showing
4 changed files
with
119 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
import { MarketApi } from "ya-ts-client"; | ||
import { GlobalPluginManager, GolemPlugin, registerGlobalPlugin } from "./globalPluginManager"; | ||
|
||
const linearPricingOnlyPlugin: GolemPlugin = { | ||
name: "linearPricingOnlyPlugin", | ||
version: "1.0.0", | ||
register(golem) { | ||
golem.market.registerHook("beforeDemandPublished", (demand) => { | ||
demand.properties["golem.com.pricing.model"] = "linear"; | ||
return demand; | ||
}); | ||
|
||
golem.market.registerHook("filterInitialProposal", (proposal) => { | ||
if (proposal.properties["golem.com.pricing.model"] !== "linear") { | ||
return { isAccepted: false, reason: "Invalid pricing model" }; | ||
} | ||
return { isAccepted: true }; | ||
}); | ||
|
||
golem.market.on("demandPublished", (demand) => { | ||
console.log("demand has been published", demand); | ||
}); | ||
}, | ||
}; | ||
|
||
registerGlobalPlugin(linearPricingOnlyPlugin); | ||
|
||
// inside demand publishing logic | ||
const createDemandDTO = () => ({}) as MarketApi.DemandDTO; | ||
let demand = createDemandDTO(); | ||
const hooks = GlobalPluginManager.getHooks("beforeDemandPublished"); | ||
for (const hook of hooks) { | ||
demand = await hook(demand); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
import EventEmitter from "eventemitter3"; | ||
import { MarketEvents, MarketHooks, MarketPluginContext } from "./marketPluginContext"; | ||
|
||
type GolemPluginContext = { | ||
market: MarketPluginContext; | ||
}; | ||
export type GolemPlugin = { | ||
name: string; | ||
version: string; | ||
register(context: GolemPluginContext): void; | ||
}; | ||
|
||
type AllHooks = MarketHooks; // | DeploymentHooks | PaymentHooks | ... | ||
type AllEvents = MarketEvents; // | DeploymentEvents | PaymentEvents | ... | ||
|
||
export class GlobalPluginManager { | ||
static eventEmitter = new EventEmitter<AllEvents>(); | ||
static hooks = new Map<keyof AllHooks, AllHooks[keyof AllHooks][]>(); | ||
|
||
static registerHook<T extends keyof AllHooks>(hookName: T, hook: AllHooks[T]) { | ||
if (!this.hooks.has(hookName)) { | ||
this.hooks.set(hookName, []); | ||
} | ||
this.hooks.get(hookName)!.push(hook as NonNullable<AllHooks[T]>); | ||
} | ||
|
||
static registerPlugin(plugin: GolemPlugin) { | ||
const ctx = { | ||
market: new MarketPluginContext( | ||
(eventName, callback) => GlobalPluginManager.eventEmitter.on(eventName, callback), | ||
(hookName, hook) => GlobalPluginManager.registerHook(hookName, hook), | ||
), | ||
// deployment: ... | ||
// payment: ... | ||
// ... | ||
}; | ||
plugin.register(ctx); | ||
} | ||
static getHooks<T extends keyof AllHooks>(hookName: T): AllHooks[T][] { | ||
return (this.hooks.get(hookName) || []) as AllHooks[T][]; | ||
} | ||
} | ||
|
||
export function registerGlobalPlugin(...plugins: GolemPlugin[]) { | ||
plugins.forEach((plugin) => GlobalPluginManager.registerPlugin(plugin)); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import { PluginContext } from "./pluginContext"; | ||
import { MarketApi } from "ya-ts-client"; | ||
type DemandDTO = MarketApi.DemandDTO; | ||
type ProposalDTO = MarketApi.ProposalDTO; | ||
|
||
type OkOrNot = { isAccepted: true } | { isAccepted: false; reason: string }; | ||
export type MarketHooks = { | ||
beforeDemandPublished: (demand: DemandDTO) => DemandDTO | Promise<DemandDTO>; | ||
filterInitialProposal: (proposal: ProposalDTO) => OkOrNot | Promise<OkOrNot>; | ||
}; | ||
|
||
export type MarketEvents = { | ||
demandPublished: (demand: DemandDTO) => void; | ||
initialProposalReceived: (proposal: ProposalDTO) => void; | ||
}; | ||
|
||
export class MarketPluginContext extends PluginContext<MarketHooks, MarketEvents> {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import EventEmitter from "eventemitter3"; | ||
|
||
export abstract class PluginContext< | ||
Hooks extends { [key: string]: (...args: never[]) => unknown }, | ||
Events extends { [key: string]: (...args: never[]) => unknown }, | ||
> { | ||
constructor( | ||
private registerEventFn: <T extends EventEmitter.EventNames<Events>>( | ||
eventName: T, | ||
callback: EventEmitter.EventListener<Events, T>, | ||
) => void, | ||
private registerHookFn: (hookName: keyof Hooks, hook: Hooks[keyof Hooks]) => void, | ||
) {} | ||
|
||
registerHook<T extends keyof Hooks>(hookName: T, hook: Hooks[T]) { | ||
this.registerHookFn(hookName, hook); | ||
} | ||
|
||
on<T extends EventEmitter.EventNames<Events>>(eventName: T, callback: EventEmitter.EventListener<Events, T>) { | ||
this.registerEventFn(eventName, callback); | ||
} | ||
} |