@izumisy-tailor/omakase-modules 0.2.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/README.md +0 -28
  2. package/docs/generated/README.md +35 -0
  3. package/docs/generated/_media/creating-modules.md +471 -0
  4. package/docs/{tutorials → generated/_media}/using-modules.md +69 -20
  5. package/docs/generated/builder/README.md +25 -0
  6. package/docs/generated/builder/functions/defineModule.md +60 -0
  7. package/docs/generated/builder/functions/withModuleConfiguration.md +68 -0
  8. package/docs/generated/builder/type-aliases/AnyDefinedModule.md +57 -0
  9. package/docs/generated/builder/type-aliases/ConfiguredDependencies.md +44 -0
  10. package/docs/generated/builder/type-aliases/ConfiguredModule.md +60 -0
  11. package/docs/generated/builder/type-aliases/DefinedModule.md +93 -0
  12. package/docs/generated/builder/type-aliases/DependencyModules.md +29 -0
  13. package/docs/generated/builder/type-aliases/EmptyDependencies.md +34 -0
  14. package/docs/generated/builder/type-aliases/ModuleBuilder.md +124 -0
  15. package/docs/generated/builder/type-aliases/ModuleBuilderProps.md +42 -0
  16. package/docs/generated/builder/type-aliases/ModuleFactoryContext.md +40 -0
  17. package/docs/generated/builder/type-aliases/TablesFromNames.md +28 -0
  18. package/docs/generated/config/README.md +19 -0
  19. package/docs/generated/config/classes/ModuleLoader.md +128 -0
  20. package/docs/generated/config/functions/loadModules.md +79 -0
  21. package/docs/generated/config/sdk/README.md +16 -0
  22. package/docs/generated/config/sdk/functions/getModulesReference.md +81 -0
  23. package/docs/generated/config/sdk/functions/loadModuleForDev.md +53 -0
  24. package/docs/generated/config/sdk/type-aliases/GetModulesReferenceOptions.md +60 -0
  25. package/docs/generated/config/type-aliases/LoadedModules.md +162 -0
  26. package/docs/generated/modules.md +11 -0
  27. package/package.json +17 -18
  28. package/src/builder/helpers.ts +388 -28
  29. package/src/builder/index.ts +8 -1
  30. package/src/builder/register.ts +38 -25
  31. package/src/config/module-loader.ts +251 -21
  32. package/src/config/sdk/dev-context.ts +82 -0
  33. package/src/config/sdk/index.ts +2 -1
  34. package/src/config/sdk/paths.ts +124 -13
  35. package/src/config/sdk/wrapper/base.ts +185 -0
  36. package/src/config/sdk/wrapper/generator.ts +89 -0
  37. package/src/config/sdk/wrapper/strategies.ts +121 -0
  38. package/docs/examples/data-models/core/inventory-module.md +0 -230
  39. package/docs/examples/data-models/core/order-module.md +0 -132
  40. package/docs/examples/data-models/scenarios/inventory-reservation-scenario.md +0 -73
  41. package/docs/examples/data-models/scenarios/multi-storefront-order-scenario.md +0 -99
  42. package/docs/examples/data-models/scenarios/order-payment-status-scenario.md +0 -92
  43. package/docs/examples/data-models/scenarios/procurement-order-scenario.md +0 -95
  44. package/docs/tutorials/creating-modules.md +0 -256
  45. package/src/config/module-registry.ts +0 -22
  46. package/src/stub-loader/index.ts +0 -3
  47. package/src/stub-loader/interface.ts +0 -40
package/package.json CHANGED
@@ -1,26 +1,17 @@
1
1
  {
2
2
  "name": "@izumisy-tailor/omakase-modules",
3
3
  "private": false,
4
- "version": "0.2.0",
4
+ "version": "0.4.0",
5
5
  "description": "Modularization mechanism for Tailor Platform application powered by Tailor SDK",
6
6
  "type": "module",
7
7
  "files": [
8
- "src",
9
- "docs"
8
+ "docs/generated",
9
+ "src"
10
10
  ],
11
11
  "exports": {
12
- ".": {
13
- "default": "./src/config/index.ts"
14
- },
15
- "./config/sdk": {
16
- "default": "./src/config/sdk/index.ts"
17
- },
18
- "./builder": {
19
- "default": "./src/builder/index.ts"
20
- },
21
- "./config/loader": {
22
- "default": "./src/stub-loader/index.ts"
23
- }
12
+ ".": "./src/config/index.ts",
13
+ "./config/sdk": "./src/config/sdk/index.ts",
14
+ "./builder": "./src/builder/index.ts"
24
15
  },
25
16
  "keywords": [
26
17
  "tailor-platform",
@@ -32,13 +23,21 @@
32
23
  "license": "MIT",
33
24
  "devDependencies": {
34
25
  "@types/node": "^25.0.3",
35
- "tsdown": "^0.18.0",
36
- "typescript": "^5"
26
+ "typedoc": "^0.28.15",
27
+ "typedoc-plugin-markdown": "^4.9.0",
28
+ "typescript": "^5",
29
+ "vite-tsconfig-paths": "^6.0.3",
30
+ "vitest": "^4.0.16"
37
31
  },
38
32
  "peerDependencies": {
39
33
  "@tailor-platform/sdk": "^0.20.0"
40
34
  },
35
+ "dependencies": {
36
+ "dedent": "^1.7.1"
37
+ },
41
38
  "scripts": {
42
- "type-check": "tsc"
39
+ "type-check": "tsc",
40
+ "test": "vitest run",
41
+ "docsgen": "typedoc"
43
42
  }
44
43
  }
@@ -1,51 +1,411 @@
1
- type ModuleBuilderProps<C extends Record<string, unknown>> = {
2
- config: C;
3
- };
1
+ import type { TailorDBType } from "@tailor-platform/sdk";
2
+
3
+ /**
4
+ * Represents a module with no dependencies.
5
+ *
6
+ * This is a branded type used internally to distinguish modules
7
+ * that have no dependencies from those that do. When defining a module
8
+ * without dependencies, you don't need to use this type directly.
9
+ *
10
+ * @example
11
+ * ```typescript
12
+ * // Modules without dependencies don't need to specify this type
13
+ * export default defineModule<MyConfig, MyTables>({
14
+ * packageName: "my-module",
15
+ * }).build();
16
+ * ```
17
+ */
18
+ export type EmptyDependencies = { readonly __empty?: never };
19
+
20
+ /**
21
+ * Properties required when configuring a module via `configure()`.
22
+ *
23
+ * The shape of this type varies based on whether the module has dependencies:
24
+ * - **Without dependencies**: `{ config: C }`
25
+ * - **With dependencies**: `{ config: C; dependencies: ConfiguredDependencies<Deps> }`
26
+ *
27
+ * @example
28
+ * ```typescript
29
+ * // Module without dependencies
30
+ * myModule.configure({
31
+ * config: { dbNamespace: "main-db" },
32
+ * });
33
+ *
34
+ * // Module with dependencies
35
+ * inventoryModule.configure({
36
+ * config: { dbNamespace: "main-db" },
37
+ * dependencies: {
38
+ * commerce: $commerceModule,
39
+ * order: $orderModule,
40
+ * },
41
+ * });
42
+ * ```
43
+ */
44
+ export type ModuleBuilderProps<
45
+ /**
46
+ * The configuration type for the module
47
+ */
48
+ C extends Record<string, unknown>,
49
+ /**
50
+ * The dependency modules record type
51
+ */
52
+ Deps extends DependencyModules
53
+ > = Deps extends EmptyDependencies
54
+ ? { config: C }
55
+ : { config: C; dependencies: ConfiguredDependencies<Deps> };
4
56
 
57
+ /**
58
+ * A module that has been configured with specific settings.
59
+ *
60
+ * This type represents the result of calling `configure()` on a {@link DefinedModule}.
61
+ * Configured modules can be passed as dependencies to other modules or used
62
+ * directly in your application's Tailor configuration.
63
+ *
64
+ * @example
65
+ * ```typescript
66
+ * // Create a configured module
67
+ * const $commerceModule = commerceModule.configure({
68
+ * config: { dbNamespace: "main-db" },
69
+ * });
70
+ *
71
+ * // Use as a dependency in another module
72
+ * const $inventoryModule = inventoryModule.configure({
73
+ * config: { dbNamespace: "main-db" },
74
+ * dependencies: {
75
+ * commerce: $commerceModule,
76
+ * },
77
+ * });
78
+ * ```
79
+ */
5
80
  export type ConfiguredModule<
81
+ /**
82
+ * The configuration type that was used to configure the module
83
+ */
6
84
  C extends Record<string, unknown> = Record<string, unknown>
7
85
  > = {
8
86
  packageName: string;
9
- moduleProps: ModuleBuilderProps<C>;
87
+ moduleProps: { config: C };
88
+ /**
89
+ * @internal Brand for config type identification in dependency checking.
90
+ */
91
+ readonly __configBrand?: C;
92
+ };
93
+
94
+ /**
95
+ * A record of module dependencies or an empty dependency set.
96
+ *
97
+ * This type represents the dependencies that a module can declare.
98
+ * It is either a record mapping dependency names to {@link AnyDefinedModule},
99
+ * or {@link EmptyDependencies} for modules without dependencies.
100
+ *
101
+ * @example
102
+ * ```typescript
103
+ * // Used internally when defining module dependencies
104
+ * defineModule<MyConfig, MyTables>({
105
+ * packageName: "my-module",
106
+ * }).withDependencies({
107
+ * commerce: commerceModule, // Record<string, AnyDefinedModule>
108
+ * order: orderModule,
109
+ * }).build();
110
+ * ```
111
+ */
112
+ export type DependencyModules =
113
+ | Record<string, AnyDefinedModule>
114
+ | EmptyDependencies;
115
+
116
+ /**
117
+ * A loosely-typed representation of any defined module.
118
+ *
119
+ * This type is used in dependency records where the exact type parameters
120
+ * of the module are not important. It provides the minimal interface needed
121
+ * to work with modules as dependencies.
122
+ *
123
+ * For strongly-typed module definitions, use {@link DefinedModule} instead.
124
+ *
125
+ * @see {@link DefinedModule} for the fully-typed module definition.
126
+ */
127
+ export type AnyDefinedModule = {
128
+ packageName: string;
129
+ dependencies: Record<string, any>;
130
+ configure: (props: any) => ConfiguredModule<any>;
131
+
132
+ /**
133
+ * @internal Brand for tables type identification in helper utilities.
134
+ */
135
+ readonly __tablesBrand?: any;
136
+
137
+ /**
138
+ * @internal Brand for config type identification in dependency checking.
139
+ */
140
+ readonly __configBrand?: any;
10
141
  };
11
142
 
143
+ /**
144
+ * Transforms a record of {@link DefinedModule}s into a record of {@link ConfiguredModule}s.
145
+ *
146
+ * This utility type is used to derive the expected shape of the `dependencies`
147
+ * property when configuring a module that has dependencies. It preserves
148
+ * the exact configuration type for each dependency module.
149
+ *
150
+ * @example
151
+ * ```typescript
152
+ * // When a module is defined with dependencies:
153
+ * defineModule<MyConfig, MyTables>({
154
+ * packageName: "my-module",
155
+ * }).withDependencies({
156
+ * commerce: commerceModule,
157
+ * order: orderModule,
158
+ * }).build();
159
+ *
160
+ * // The configure() method will expect:
161
+ * myModule.configure({
162
+ * config: { ... },
163
+ * dependencies: {
164
+ * commerce: ConfiguredModule<CommerceConfig>,
165
+ * order: ConfiguredModule<OrderConfig>,
166
+ * },
167
+ * });
168
+ * ```
169
+ */
170
+ export type ConfiguredDependencies<
171
+ /**
172
+ * The dependency modules record to transform
173
+ */
174
+ Deps extends DependencyModules
175
+ > = {
176
+ [K in keyof Deps as K extends "__empty" ? never : K]: Deps[K] extends {
177
+ readonly __configBrand?: infer C;
178
+ }
179
+ ? C extends Record<string, unknown>
180
+ ? ConfiguredModule<C>
181
+ : never
182
+ : never;
183
+ };
184
+
185
+ /**
186
+ * A fully defined, reusable module that can be configured and composed.
187
+ *
188
+ * This is the primary type for modules created with {@link defineModule}.
189
+ * A `DefinedModule` encapsulates:
190
+ * - The module's package name for identification
191
+ * - Its dependencies on other modules
192
+ * - A `configure()` method to create a {@link ConfiguredModule}
193
+ * - Optional development configuration for local testing
194
+ *
195
+ * @example
196
+ * ```typescript
197
+ * // Define a module
198
+ * const inventoryModule = defineModule<InventoryConfig, InventoryTables>({
199
+ * packageName: "inventory-module",
200
+ * })
201
+ * .withDependencies({ commerce: commerceModule })
202
+ * .withDevConfig({ dbNamespace: "dev" })
203
+ * .build();
204
+ *
205
+ * // Configure the module for use
206
+ * const $inventory = inventoryModule.configure({
207
+ * config: { dbNamespace: "production" },
208
+ * dependencies: {
209
+ * commerce: $commerceModule,
210
+ * },
211
+ * });
212
+ * ```
213
+ */
12
214
  export type DefinedModule<
215
+ /**
216
+ * The configuration schema for the module
217
+ */
13
218
  C extends Record<string, unknown>,
14
- Tables extends Record<string, unknown> = Record<string, unknown>
219
+ /**
220
+ * The TailorDB table definitions exported by the module
221
+ */
222
+ Tables extends Record<string, unknown> = Record<string, unknown>,
223
+ /**
224
+ * The dependency modules this module requires
225
+ */
226
+ Deps extends DependencyModules = EmptyDependencies
15
227
  > = {
16
228
  packageName: string;
17
- configure: (props: ModuleBuilderProps<C>) => ConfiguredModule<C>;
229
+ dependencies: Deps;
230
+ configure: (props: ModuleBuilderProps<C, Deps>) => ConfiguredModule<C>;
231
+ /**
232
+ * Default configuration for module development.
233
+ * Used by loadModuleForDev when no config is provided.
234
+ */
235
+ devConfig?: C;
18
236
  /**
19
237
  * @internal Type-only hook so that table shapes flow through helper utilities.
20
238
  */
21
239
  readonly __tablesBrand?: Tables;
240
+ /**
241
+ * @internal Brand for config type identification in dependency checking.
242
+ */
243
+ readonly __configBrand?: C;
22
244
  };
23
245
 
24
- export const defineModule = <
246
+ /**
247
+ * Intermediate builder type returned by defineModule.
248
+ * Use .withDependencies() to add dependencies, then call .build() to finalize.
249
+ * Modules without dependencies can call .build() directly.
250
+ */
251
+ export type ModuleBuilder<
25
252
  C extends Record<string, unknown>,
26
- Tables extends Record<string, unknown> = Record<string, unknown>
27
- >(baseProps: {
253
+ Tables extends Record<string, unknown>,
254
+ Deps extends DependencyModules = EmptyDependencies
255
+ > = {
256
+ /**
257
+ * Adds dependencies to the module definition.
258
+ * The Deps type is automatically inferred from the record.
259
+ *
260
+ * @example
261
+ * ```typescript
262
+ * export default defineModule<ModuleConfig, Tables>({
263
+ * packageName: "my-module",
264
+ * }).withDependencies({
265
+ * commerce: commerceModule,
266
+ * order: orderModule,
267
+ * }).build();
268
+ * ```
269
+ */
270
+ withDependencies: <const NewDeps extends DependencyModules>(
271
+ deps: NewDeps
272
+ ) => ModuleBuilder<C, Tables, NewDeps>;
28
273
  /**
29
- * The package name of the module.
274
+ * Sets the default configuration for module development.
275
+ * This config is used by loadModuleForDev when no config is provided.
276
+ *
277
+ * @example
278
+ * ```typescript
279
+ * export default defineModule<ModuleConfig, Tables>({
280
+ * packageName: "my-module",
281
+ * }).withDevConfig({
282
+ * dbNamespace: "main-db",
283
+ * }).build();
284
+ * ```
285
+ */
286
+ withDevConfig: (config: C) => ModuleBuilder<C, Tables, Deps>;
287
+ /**
288
+ * Finalizes the module definition and returns the DefinedModule.
289
+ * This must be called at the end of the builder chain to get the actual module.
290
+ *
291
+ * @example
292
+ * ```typescript
293
+ * // Without dependencies
294
+ * export default defineModule<ModuleConfig, Tables>({
295
+ * packageName: "my-module",
296
+ * }).build();
30
297
  *
31
- * This is required to be the same as the name field in package.json
298
+ * // With dependencies and dev config
299
+ * export default defineModule<ModuleConfig, Tables>({
300
+ * packageName: "my-module",
301
+ * })
302
+ * .withDependencies({ commerce: commerceModule })
303
+ * .withDevConfig({ dbNamespace: "dev" })
304
+ * .build();
305
+ * ```
32
306
  */
307
+ build: () => DefinedModule<C, Tables, Deps>;
308
+ };
309
+
310
+ /**
311
+ * Defines a reusable module with optional dependencies on other modules.
312
+ *
313
+ * @example
314
+ * ```typescript
315
+ * // Module without dependencies
316
+ * export default defineModule<ModuleConfig, Tables>({
317
+ * packageName: "my-module",
318
+ * }).build();
319
+ *
320
+ * // Module with dependencies - Deps type is automatically inferred
321
+ * import commerceModule from "omakase-module-commerce-core";
322
+ * import orderModule from "omakase-module-order";
323
+ *
324
+ * export default defineModule<ModuleConfig, Tables>({
325
+ * packageName: "my-module",
326
+ * }).withDependencies({
327
+ * commerce: commerceModule,
328
+ * order: orderModule,
329
+ * }).build();
330
+ *
331
+ * // When configuring a module with dependencies, pass them as a record:
332
+ * inventoryModule.configure({
333
+ * config: { dbNamespace: "main-db" },
334
+ * dependencies: {
335
+ * commerce: $commerceModule,
336
+ * order: $orderModule,
337
+ * },
338
+ * });
339
+ * ```
340
+ */
341
+ export const defineModule = <
342
+ C extends Record<string, unknown>,
343
+ Tables extends Record<string, unknown> = Record<string, unknown>
344
+ >(baseProps: {
33
345
  packageName: string;
34
- }): DefinedModule<C, Tables> => {
35
- return {
346
+ }): ModuleBuilder<C, Tables> => {
347
+ const createModule = <Deps extends DependencyModules>(
348
+ deps: Deps,
349
+ devConfig?: C
350
+ ): DefinedModule<C, Tables, Deps> => ({
36
351
  packageName: baseProps.packageName,
37
- configure: (props) => {
38
- return {
39
- packageName: baseProps.packageName,
40
- moduleProps: props,
41
- };
42
- },
43
- };
44
- };
45
-
46
- export type ModuleDependency<T extends DefinedModule<any, any>> =
47
- T extends DefinedModule<infer C, infer Tables>
48
- ? ConfiguredModule<C> & {
49
- readonly __tablesBrand?: Tables;
50
- }
51
- : never;
352
+ dependencies: deps,
353
+ devConfig,
354
+ configure: (props) => ({
355
+ packageName: baseProps.packageName,
356
+ moduleProps: { config: props.config },
357
+ }),
358
+ });
359
+
360
+ const createBuilder = <Deps extends DependencyModules>(
361
+ deps: Deps,
362
+ devConfig?: C
363
+ ): ModuleBuilder<C, Tables, Deps> => ({
364
+ withDependencies: <const NewDeps extends DependencyModules>(
365
+ newDeps: NewDeps
366
+ ): ModuleBuilder<C, Tables, NewDeps> => createBuilder(newDeps, devConfig),
367
+ withDevConfig: (config: C): ModuleBuilder<C, Tables, Deps> =>
368
+ createBuilder(deps, config),
369
+ build: (): DefinedModule<C, Tables, Deps> => createModule(deps, devConfig),
370
+ });
371
+
372
+ return createBuilder({} as EmptyDependencies);
373
+ };
374
+
375
+ // ============================================================================
376
+ // Utility Types for Module Development
377
+ // ============================================================================
378
+
379
+ /**
380
+ * Derives a tables type from a tableNames array.
381
+ * Use this to avoid manually defining a separate Tables type.
382
+ *
383
+ * @example
384
+ * ```typescript
385
+ * export const tableNames = ["product", "category"] as const;
386
+ * type MyTables = TablesFromNames<typeof tableNames>;
387
+ * // Result: { product: TailorDBType; category: TailorDBType }
388
+ * ```
389
+ */
390
+ export type TablesFromNames<T extends readonly string[]> = {
391
+ [K in T[number]]: TailorDBType;
392
+ };
393
+
394
+ /**
395
+ * Context passed to table builder functions.
396
+ * Provides access to the module's configuration.
397
+ *
398
+ * @example
399
+ * ```typescript
400
+ * export const buildProductTable = (
401
+ * { config }: ModuleFactoryContext<ModuleConfig>,
402
+ * deps: { category: TailorDBType }
403
+ * ) => {
404
+ * const prefix = config.dataModel?.product?.docNumberPrefix ?? "PROD";
405
+ * return db.type("Product", { ... });
406
+ * };
407
+ * ```
408
+ */
409
+ export type ModuleFactoryContext<C extends Record<string, unknown>> = {
410
+ config: C;
411
+ };
@@ -2,6 +2,13 @@ export {
2
2
  defineModule,
3
3
  type ConfiguredModule,
4
4
  type DefinedModule,
5
- type ModuleDependency,
5
+ type TablesFromNames,
6
+ type ModuleFactoryContext,
7
+ type DependencyModules,
8
+ type EmptyDependencies,
9
+ type ModuleBuilder,
10
+ type AnyDefinedModule,
11
+ type ModuleBuilderProps,
12
+ type ConfiguredDependencies,
6
13
  } from "./helpers";
7
14
  export { withModuleConfiguration } from "./register";
@@ -1,34 +1,47 @@
1
- import type { ModuleConfigLoaderReturn } from "../stub-loader/interface";
2
- import type { DefinedModule } from "./helpers";
3
-
4
- type ModuleFactoryContext<C extends Record<string, unknown>> = Awaited<
5
- ModuleConfigLoaderReturn<C>
6
- >;
1
+ import type { LoadedModules } from "../config/module-loader";
2
+ import type { DefinedModule, ModuleFactoryContext } from "./helpers";
7
3
 
8
4
  /**
9
- * Load a module's configuration, define something.
5
+ * Define module exports that depend on configuration from loadModules.
6
+ *
7
+ * This function returns a factory function that takes LoadedModules as input
8
+ * and produces the configured exports. The wrapper files generated by
9
+ * getModulesReference will call this factory with the app's loadModules result.
10
+ *
11
+ * @example
12
+ * ```typescript
13
+ * // In module's tailordb/index.ts
14
+ * export default withModuleConfiguration(moduleDef, (context) => {
15
+ * const inventory = buildInventoryTable(context);
16
+ * return { inventory };
17
+ * });
18
+ *
19
+ * // In module's executors that need dependency module tables:
20
+ * export default withModuleConfiguration(moduleDef, async (context, loadedModules) => {
21
+ * const { productVariant } = await loadedModules.getTables(commerceModuleTables);
22
+ * return createExecutor({ ... });
23
+ * });
10
24
  *
11
- * THis is a low-level utility composed by a specific builder function.
25
+ * // The wrapper file will call it like:
26
+ * // import factory from "module/backend/tailordb";
27
+ * // import modules from "../../modules";
28
+ * // export default await factory(modules);
29
+ * ```
12
30
  */
13
- export const withModuleConfiguration = async <
31
+ export const withModuleConfiguration = <
14
32
  C extends Record<string, unknown>,
15
33
  Tables extends Record<string, unknown>,
34
+ Deps extends Record<string, any>,
16
35
  Result
17
36
  >(
18
- module: DefinedModule<C, Tables>,
19
- factory: (context: ModuleFactoryContext<C>) => Result | Promise<Result>
20
- ) => {
21
- /**
22
- * This import intentionally uses a module path instead of a package path
23
- * to let the app override the implementation via tsconfig paths.
24
- *
25
- * For more details, see `moduleConfigLoader` in `./src/stub-loader/interface.ts`.
26
- *
27
- * Dynamic import is also important here to avoid "cannot acess before initialization" error.
28
- */
29
- const { default: configLoader } = await import(
30
- "@izumisy-tailor/omakase-modules/config/loader"
31
- );
32
- const moduleState = await configLoader.loadConfig(module);
33
- return await factory(moduleState);
37
+ module: DefinedModule<C, Tables, Deps>,
38
+ factory: (
39
+ context: ModuleFactoryContext<C>,
40
+ loadedModules: LoadedModules
41
+ ) => Result | Promise<Result>
42
+ ): ((loadedModules: LoadedModules) => Promise<Result>) => {
43
+ return async (loadedModules: LoadedModules) => {
44
+ const moduleState = loadedModules.loadConfig<C>(module);
45
+ return await factory(moduleState, loadedModules);
46
+ };
34
47
  };