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

WIP global hooks exploration #1007

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions packages/config/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,12 @@
"esbuild": "^0.17.15",
"ethers": "^5.7.2",
"find-up": "^6.3.0",
"tapable": "^2.2.1",
"zod": "^3.21.4",
"zod-validation-error": "^1.3.0"
},
"devDependencies": {
"@types/tapable": "^2.2.3",
"tsup": "^6.7.0"
},
"gitHead": "914a1e0ae4a573d685841ca2ea921435057deb8f"
Expand Down
5 changes: 4 additions & 1 deletion packages/config/src/library/context.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { MUDConfigExtender } from "./core";
import { MUDConfigExtender, MUDHooks } from "./types";
import { MUDContextAlreadyCreatedError, MUDContextNotCreatedError } from "./errors";
import { defaultHooks } from "./defaultHooks";

export type GlobalWithMUDCoreContext = typeof global & {
__mudCoreContext: MUDCoreContext;
Expand Down Expand Up @@ -33,4 +34,6 @@ export class MUDCoreContext {
}

public readonly configExtenders: MUDConfigExtender[] = [];
// the typecast helps prevent typechecks after type extensions from erroring on defaultHooks not having a key
public readonly hooks: MUDHooks = defaultHooks as MUDHooks;
}
31 changes: 23 additions & 8 deletions packages/config/src/library/core.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,20 @@
import { MUDError } from "@latticexyz/common/errors";
import { MUDCoreContext } from "./context";

// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface MUDCoreUserConfig {}

// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface MUDCoreConfig {}

export type MUDConfigExtender = (config: MUDCoreConfig) => Record<string, unknown>;
import { MUDConfigExtender, MUDCoreConfig, MUDCoreUserConfig, MUDHooks } from "./types";

/** Resolver that sequentially passes the config through all the plugins */
export function mudCoreConfig(config: MUDCoreUserConfig): MUDCoreConfig {
// config types can change with plugins, `any` helps avoid errors when typechecking dependencies
// eslint-disable-next-line @typescript-eslint/no-explicit-any
let configAsAny = config as any;
const context = MUDCoreContext.getContext();

context.hooks.beforeAll.call(configAsAny);
for (const extender of context.configExtenders) {
configAsAny = extender(configAsAny);
}
context.hooks.afterAll.call(configAsAny);

return configAsAny;
}

Expand All @@ -25,3 +23,20 @@ export function extendMUDCoreConfig(extender: MUDConfigExtender) {
const context = MUDCoreContext.getContext();
context.configExtenders.push(extender);
}

export function initializeMUDHook<T extends keyof MUDHooks>(name: T, hook: MUDHooks[T]) {
const context = MUDCoreContext.getContext();
if (context.hooks[name]) {
throw new MUDError(`Hook "${name}" has already been initialized`);
}
context.hooks[name] = hook;
}

export function getMudHook(name: keyof MUDHooks) {
const context = MUDCoreContext.getContext();
const hook = context.hooks[name];
if (!hook) {
throw new MUDError(`Hook "${name}" has not been initialized`);
}
return hook;
}
7 changes: 7 additions & 0 deletions packages/config/src/library/defaultHooks.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { SyncHook } from "tapable";
import { MUDDefaultHooks } from "./types";

export const defaultHooks: MUDDefaultHooks = {
beforeAll: new SyncHook(["mudUserConfig"]),
afterAll: new SyncHook(["mudConfig"]),
};
1 change: 1 addition & 0 deletions packages/config/src/library/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ export * from "./context";
export * from "./core";
export * from "./dynamicResolution";
export * from "./errors";
export * from "./types";
export * from "./validation";
17 changes: 17 additions & 0 deletions packages/config/src/library/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { SyncHook } from "tapable";

// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface MUDCoreUserConfig {}

// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface MUDCoreConfig {}

export type MUDConfigExtender = (config: MUDCoreConfig) => Record<string, unknown>;

export interface MUDDefaultHooks {
beforeAll: SyncHook<MUDCoreUserConfig>;
afterAll: SyncHook<MUDCoreConfig>;
}

// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface MUDHooks extends MUDDefaultHooks {}
2 changes: 2 additions & 0 deletions packages/store/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,13 +53,15 @@
"@latticexyz/config": "workspace:*",
"@latticexyz/schema-type": "workspace:*",
"ethers": "^5.7.2",
"tapable": "^2.2.1",
"zod": "^3.21.4"
},
"devDependencies": {
"@typechain/ethers-v5": "^10.2.0",
"@types/ejs": "^3.1.1",
"@types/mocha": "^9.1.1",
"@types/node": "^18.15.11",
"@types/tapable": "^2.2.3",
"ds-test": "https://github.com/dapphub/ds-test.git#c9ce3f25bde29fc5eb9901842bf02850dfd2d084",
"ejs": "^3.1.8",
"forge-std": "https://github.com/foundry-rs/forge-std.git#b4f121555729b3afb3c5ffccb62ff4b6e2818fd3",
Expand Down
6 changes: 6 additions & 0 deletions packages/store/ts/library/hooks.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { MUDCoreConfig } from "@latticexyz/config";
import { SyncHook } from "tapable";

export type StoreHooks = {
preTablegen: SyncHook<MUDCoreConfig>;
};
1 change: 1 addition & 0 deletions packages/store/ts/library/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@
// (library neither creates nor extends MUDCoreContext when imported)
export * from "./config";
export * from "./render-solidity";
export * from "./hooks";
3 changes: 3 additions & 0 deletions packages/store/ts/library/render-solidity/tablegen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,13 @@ import { renderTypesFromConfig } from "./renderTypesFromConfig";
import { renderTableIndex } from "./renderTableIndex";
import { rmSync } from "fs";
import { StoreConfig } from "../config";
import { getMudHook } from "@latticexyz/config";

export async function tablegen(config: StoreConfig, outputBaseDirectory: string) {
const allTableOptions = getTableOptions(config);

//getMudHook("")

const uniqueTableDirectories = new Set(allTableOptions.map(({ outputPath }) => path.dirname(outputPath)));
for (const tableDir of uniqueTableDirectories) {
rmSync(path.join(outputBaseDirectory, tableDir), { recursive: true, force: true });
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { extendMUDCoreConfig, fromZodErrorCustom } from "@latticexyz/config";
import { extendMUDCoreConfig, fromZodErrorCustom, initializeMUDHook } from "@latticexyz/config";
import { SyncHook } from "tapable";
import { ZodError } from "zod";
import { zPluginStoreConfig } from "../library/config";

Expand All @@ -16,3 +17,5 @@ extendMUDCoreConfig((config) => {
}
}
});

initializeMUDHook("preTablegen", new SyncHook(["mudConfig"]));
4 changes: 3 additions & 1 deletion packages/store/ts/register/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@
import "@latticexyz/config/register";
export { mudCoreConfig, resolveTableId } from "@latticexyz/config/register";
// Extend core config and types
import "./configExtensions";
import "./contextExtensions";
import "./typeExtensions";
// Tap hooks
import "./tapHooks";

export { mudConfig } from "./mudConfig";
export type { ExpandMUDUserConfig } from "./typeExtensions";
9 changes: 9 additions & 0 deletions packages/store/ts/register/tapHooks.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { getMudHook } from "@latticexyz/config";

getMudHook("beforeAll").tap("store", () => {
console.log("called store's beforeAll hook");
});

getMudHook("afterAll").tap("store", () => {
console.log("called store's afterAll hook");
});
4 changes: 4 additions & 0 deletions packages/store/ts/register/typeExtensions.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { OrDefaults } from "@latticexyz/common/type-utils";
import { MUDCoreUserConfig } from "@latticexyz/config";
import { StoreHooks } from "../library";
import { ExpandTablesConfig, StoreConfig, StoreUserConfig } from "../library/config";
import { DEFAULTS, PATH_DEFAULTS } from "../library/config/defaults";

Expand All @@ -17,6 +18,9 @@ declare module "@latticexyz/config" {
// Other plugins receive this resolved config as their input.
// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface MUDCoreConfig extends StoreConfig {}

// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface MUDHooks extends StoreHooks {}
}

// store-specific helper to preserve strong types, depends on store's type extensions to the core config
Expand Down
22 changes: 22 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.