mokup 2.2.1 → 2.3.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.
package/dist/bundle.cjs CHANGED
@@ -1,8 +1,10 @@
1
1
  'use strict';
2
2
 
3
- const bundle = require('./shared/mokup.zkaN1ADs.cjs');
4
- require('./shared/mokup.C7-7PDF7.cjs');
3
+ const bundle = require('./shared/mokup.BXPIIxtS.cjs');
4
+ require('./shared/mokup.Dy9VDphS.cjs');
5
5
  require('@mokup/shared/pathe');
6
+ require('@mokup/shared/path-utils');
7
+ require('@mokup/shared/timing');
6
8
 
7
9
 
8
10
 
package/dist/bundle.d.cts CHANGED
@@ -1,5 +1,5 @@
1
- import { R as RouteTable } from './shared/mokup.DeotZ0g8.cjs';
2
- export { a as ResolvedRoute } from './shared/mokup.DeotZ0g8.cjs';
1
+ import { R as RouteTable } from './shared/mokup.Dkqu10Hk.cjs';
2
+ export { a as ResolvedRoute } from './shared/mokup.Dkqu10Hk.cjs';
3
3
  import '@mokup/runtime';
4
4
  import '@mokup/shared';
5
5
  import '@mokup/shared/hono';
@@ -8,6 +8,9 @@ import '@mokup/shared/hono';
8
8
  * Build the source for a virtual mokup bundle module.
9
9
  *
10
10
  * @param params - Bundle build parameters.
11
+ * @param params.routes - Resolved routes to serialize.
12
+ * @param params.root - Workspace root path.
13
+ * @param params.resolveModulePath - Optional module resolver.
11
14
  * @returns JavaScript source string.
12
15
  *
13
16
  * @example
package/dist/bundle.d.mts CHANGED
@@ -1,5 +1,5 @@
1
- import { R as RouteTable } from './shared/mokup.DeotZ0g8.mjs';
2
- export { a as ResolvedRoute } from './shared/mokup.DeotZ0g8.mjs';
1
+ import { R as RouteTable } from './shared/mokup.Dkqu10Hk.mjs';
2
+ export { a as ResolvedRoute } from './shared/mokup.Dkqu10Hk.mjs';
3
3
  import '@mokup/runtime';
4
4
  import '@mokup/shared';
5
5
  import '@mokup/shared/hono';
@@ -8,6 +8,9 @@ import '@mokup/shared/hono';
8
8
  * Build the source for a virtual mokup bundle module.
9
9
  *
10
10
  * @param params - Bundle build parameters.
11
+ * @param params.routes - Resolved routes to serialize.
12
+ * @param params.root - Workspace root path.
13
+ * @param params.resolveModulePath - Optional module resolver.
11
14
  * @returns JavaScript source string.
12
15
  *
13
16
  * @example
package/dist/bundle.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { R as RouteTable } from './shared/mokup.DeotZ0g8.js';
2
- export { a as ResolvedRoute } from './shared/mokup.DeotZ0g8.js';
1
+ import { R as RouteTable } from './shared/mokup.Dkqu10Hk.js';
2
+ export { a as ResolvedRoute } from './shared/mokup.Dkqu10Hk.js';
3
3
  import '@mokup/runtime';
4
4
  import '@mokup/shared';
5
5
  import '@mokup/shared/hono';
@@ -8,6 +8,9 @@ import '@mokup/shared/hono';
8
8
  * Build the source for a virtual mokup bundle module.
9
9
  *
10
10
  * @param params - Bundle build parameters.
11
+ * @param params.routes - Resolved routes to serialize.
12
+ * @param params.root - Workspace root path.
13
+ * @param params.resolveModulePath - Optional module resolver.
11
14
  * @returns JavaScript source string.
12
15
  *
13
16
  * @example
package/dist/bundle.mjs CHANGED
@@ -1,3 +1,5 @@
1
- export { b as buildBundleModule } from './shared/mokup.vAap-D_L.mjs';
2
- import './shared/mokup.JBCzv4xR.mjs';
1
+ export { b as buildBundleModule } from './shared/mokup.CsBTglhs.mjs';
2
+ import './shared/mokup.Iqw32OxC.mjs';
3
3
  import '@mokup/shared/pathe';
4
+ import '@mokup/shared/path-utils';
5
+ import '@mokup/shared/timing';
package/dist/index.cjs CHANGED
@@ -1,12 +1,90 @@
1
1
  'use strict';
2
2
 
3
3
  const middlewareSymbol = Symbol.for("mokup.config.middlewares");
4
- function createRegistry(list) {
5
- return {
6
- use: (...handlers) => {
7
- list.push(...handlers);
4
+ const contextStack = [];
5
+ function getActiveContext() {
6
+ const context = contextStack[contextStack.length - 1];
7
+ if (!context) {
8
+ throw new Error("onBeforeAll/onAfterAll must be called inside defineConfig()");
9
+ }
10
+ return context;
11
+ }
12
+ function runWithContext(context, fn) {
13
+ contextStack.push(context);
14
+ try {
15
+ const result = fn();
16
+ if (isPromise(result)) {
17
+ return result.finally(() => {
18
+ contextStack.pop();
19
+ });
20
+ }
21
+ contextStack.pop();
22
+ return result;
23
+ } catch (error) {
24
+ contextStack.pop();
25
+ throw error;
26
+ }
27
+ }
28
+ function isPromise(value) {
29
+ return !!value && typeof value.then === "function";
30
+ }
31
+ function normalizeHookError(policy) {
32
+ if (policy === "throw" || policy === "silent") {
33
+ return policy;
34
+ }
35
+ return "warn";
36
+ }
37
+ function reportHookError(error, policy) {
38
+ if (policy === "silent") {
39
+ return;
40
+ }
41
+ if (policy === "warn") {
42
+ console.warn("[mokup] defineConfig hook failed:", error);
43
+ }
44
+ }
45
+ function runHookSequence(stage, hooks, policy, setStage) {
46
+ if (hooks.length === 0) {
47
+ return;
48
+ }
49
+ setStage(stage);
50
+ let chain = null;
51
+ const runHook = (hook) => {
52
+ try {
53
+ const result = hook();
54
+ if (isPromise(result)) {
55
+ return result.catch((error) => {
56
+ if (policy === "throw") {
57
+ throw error;
58
+ }
59
+ reportHookError(error, policy);
60
+ });
61
+ }
62
+ return void 0;
63
+ } catch (error) {
64
+ if (policy === "throw") {
65
+ throw error;
66
+ }
67
+ reportHookError(error, policy);
68
+ return void 0;
8
69
  }
9
70
  };
71
+ for (const hook of hooks) {
72
+ if (chain) {
73
+ chain = chain.then(() => runHook(hook));
74
+ continue;
75
+ }
76
+ const result = runHook(hook);
77
+ if (isPromise(result)) {
78
+ chain = result;
79
+ }
80
+ }
81
+ if (!chain) {
82
+ setStage("normal");
83
+ return;
84
+ }
85
+ return chain.finally(() => {
86
+ setStage("normal");
87
+ });
10
88
  }
11
89
  function attachMetadata(config, meta) {
12
90
  Object.defineProperty(config, middlewareSymbol, {
@@ -15,21 +93,70 @@ function attachMetadata(config, meta) {
15
93
  });
16
94
  return config;
17
95
  }
96
+ function normalizeConfig(value) {
97
+ return value && typeof value === "object" ? value : {};
98
+ }
99
+ function onBeforeAll(handler) {
100
+ if (typeof handler !== "function") {
101
+ throw new TypeError("onBeforeAll expects a function");
102
+ }
103
+ const context = getActiveContext();
104
+ context.hooks.pre.push(handler);
105
+ }
106
+ function onAfterAll(handler) {
107
+ if (typeof handler !== "function") {
108
+ throw new TypeError("onAfterAll expects a function");
109
+ }
110
+ const context = getActiveContext();
111
+ context.hooks.post.push(handler);
112
+ }
18
113
  function defineConfig(input) {
19
114
  if (typeof input === "function") {
20
115
  const pre = [];
21
116
  const normal = [];
22
117
  const post = [];
118
+ let stage = "normal";
119
+ const app = {
120
+ use: (...handlers) => {
121
+ if (stage === "pre") {
122
+ pre.push(...handlers);
123
+ return;
124
+ }
125
+ if (stage === "post") {
126
+ post.push(...handlers);
127
+ return;
128
+ }
129
+ normal.push(...handlers);
130
+ }
131
+ };
23
132
  const context = {
24
- pre: createRegistry(pre),
25
- normal: createRegistry(normal),
26
- post: createRegistry(post)
133
+ app,
134
+ hooks: { pre: [], post: [] },
135
+ setStage: (next) => {
136
+ stage = next;
137
+ }
138
+ };
139
+ const result = runWithContext(context, () => input({ app }));
140
+ const finalize = (value) => {
141
+ const config2 = normalizeConfig(value);
142
+ const policy = normalizeHookError(config2.hookError);
143
+ const preResult = runHookSequence("pre", context.hooks.pre, policy, context.setStage);
144
+ const runPost = () => runHookSequence("post", context.hooks.post, policy, context.setStage);
145
+ if (isPromise(preResult)) {
146
+ return preResult.then(runPost).then(() => attachMetadata(config2, { pre, normal, post }));
147
+ }
148
+ const postResult = runPost();
149
+ if (isPromise(postResult)) {
150
+ return postResult.then(() => attachMetadata(config2, { pre, normal, post }));
151
+ }
152
+ return attachMetadata(config2, { pre, normal, post });
27
153
  };
28
- const result = input(context);
29
- const config2 = result && typeof result === "object" ? result : {};
30
- return attachMetadata(config2, { pre, normal, post });
154
+ if (isPromise(result)) {
155
+ return result.then(finalize);
156
+ }
157
+ return finalize(result);
31
158
  }
32
- const config = input && typeof input === "object" ? input : {};
159
+ const config = normalizeConfig(input);
33
160
  return attachMetadata(config, { pre: [], normal: [], post: [] });
34
161
  }
35
162
 
@@ -39,3 +166,5 @@ function defineHandler(input) {
39
166
 
40
167
  exports.defineConfig = defineConfig;
41
168
  exports.defineHandler = defineHandler;
169
+ exports.onAfterAll = onAfterAll;
170
+ exports.onBeforeAll = onBeforeAll;
package/dist/index.d.cts CHANGED
@@ -1,42 +1,51 @@
1
- import { e as RouteDirectoryConfig, c as MiddlewareRegistry, d as RequestHandler, g as RouteRule } from './shared/mokup.DeotZ0g8.cjs';
2
- export { H as HttpMethod, b as MiddlewarePosition, M as MokupPluginOptions, f as RouteResponse, h as RuntimeMode, S as ServiceWorkerOptions, V as VitePluginOptions, i as VitePluginOptionsInput } from './shared/mokup.DeotZ0g8.cjs';
1
+ import { e as RouteDirectoryConfig, d as RequestHandler, g as RouteRule } from './shared/mokup.Dkqu10Hk.cjs';
2
+ export { k as HookErrorPolicy, H as HttpMethod, b as MiddlewarePosition, c as MiddlewareRegistry, M as MokupPluginOptions, f as RouteResponse, h as RuntimeMode, S as ServiceWorkerOptions, V as VitePluginOptions, i as VitePluginOptionsInput } from './shared/mokup.Dkqu10Hk.cjs';
3
+ import { MiddlewareHandler } from '@mokup/shared/hono';
3
4
  export { Context, MiddlewareHandler } from '@mokup/shared/hono';
4
5
  export { PlaygroundOptionsInput } from '@mokup/shared';
5
6
  import '@mokup/runtime';
6
7
 
8
+ type HookHandler = () => void | Promise<void>;
9
+ interface ConfigApp {
10
+ use: (...handlers: MiddlewareHandler[]) => void;
11
+ }
7
12
  type DefineConfigFactory = (context: {
8
- pre: MiddlewareRegistry;
9
- normal: MiddlewareRegistry;
10
- post: MiddlewareRegistry;
11
- }) => RouteDirectoryConfig | void;
13
+ app: ConfigApp;
14
+ }) => RouteDirectoryConfig | void | Promise<RouteDirectoryConfig | void>;
15
+ declare function onBeforeAll(handler: HookHandler): void;
16
+ declare function onAfterAll(handler: HookHandler): void;
12
17
  /**
13
- * Define a directory config with Hono-style middleware registration.
18
+ * Define a directory config with hook-based middleware registration.
14
19
  *
15
20
  * @param input - Config object or factory callback.
16
21
  * @returns Route directory config with middleware metadata.
17
22
  *
18
23
  * @example
19
- * import { defineConfig } from 'mokup'
24
+ * import { defineConfig, onBeforeAll, onAfterAll } from 'mokup'
20
25
  *
21
- * export default defineConfig(({ pre, normal, post }) => {
22
- * pre.use(async (c, next) => {
23
- * c.header('x-before', '1')
24
- * await next()
26
+ * export default defineConfig(({ app }) => {
27
+ * onBeforeAll(() => {
28
+ * app.use(async (c, next) => {
29
+ * c.header('x-before', '1')
30
+ * await next()
31
+ * })
25
32
  * })
26
33
  *
27
- * normal.use(async (_c, next) => {
34
+ * app.use(async (_c, next) => {
28
35
  * await next()
29
36
  * })
30
37
  *
31
- * post.use(async (c, next) => {
32
- * await next()
33
- * c.header('x-after', '1')
38
+ * onAfterAll(() => {
39
+ * app.use(async (c, next) => {
40
+ * await next()
41
+ * c.header('x-after', '1')
42
+ * })
34
43
  * })
35
44
  *
36
45
  * return { delay: 120 }
37
46
  * })
38
47
  */
39
- declare function defineConfig(input: RouteDirectoryConfig | DefineConfigFactory): RouteDirectoryConfig;
48
+ declare function defineConfig(input: RouteDirectoryConfig | DefineConfigFactory): RouteDirectoryConfig | Promise<RouteDirectoryConfig>;
40
49
 
41
50
  /**
42
51
  * Define a mock route handler with type hints.
@@ -64,4 +73,4 @@ declare function defineConfig(input: RouteDirectoryConfig | DefineConfigFactory)
64
73
  declare function defineHandler(input: RequestHandler): RequestHandler;
65
74
  declare function defineHandler(input: RouteRule): RouteRule;
66
75
 
67
- export { MiddlewareRegistry, RequestHandler, RouteDirectoryConfig, RouteRule, defineConfig, defineHandler };
76
+ export { RequestHandler, RouteDirectoryConfig, RouteRule, defineConfig, defineHandler, onAfterAll, onBeforeAll };
package/dist/index.d.mts CHANGED
@@ -1,42 +1,51 @@
1
- import { e as RouteDirectoryConfig, c as MiddlewareRegistry, d as RequestHandler, g as RouteRule } from './shared/mokup.DeotZ0g8.mjs';
2
- export { H as HttpMethod, b as MiddlewarePosition, M as MokupPluginOptions, f as RouteResponse, h as RuntimeMode, S as ServiceWorkerOptions, V as VitePluginOptions, i as VitePluginOptionsInput } from './shared/mokup.DeotZ0g8.mjs';
1
+ import { e as RouteDirectoryConfig, d as RequestHandler, g as RouteRule } from './shared/mokup.Dkqu10Hk.mjs';
2
+ export { k as HookErrorPolicy, H as HttpMethod, b as MiddlewarePosition, c as MiddlewareRegistry, M as MokupPluginOptions, f as RouteResponse, h as RuntimeMode, S as ServiceWorkerOptions, V as VitePluginOptions, i as VitePluginOptionsInput } from './shared/mokup.Dkqu10Hk.mjs';
3
+ import { MiddlewareHandler } from '@mokup/shared/hono';
3
4
  export { Context, MiddlewareHandler } from '@mokup/shared/hono';
4
5
  export { PlaygroundOptionsInput } from '@mokup/shared';
5
6
  import '@mokup/runtime';
6
7
 
8
+ type HookHandler = () => void | Promise<void>;
9
+ interface ConfigApp {
10
+ use: (...handlers: MiddlewareHandler[]) => void;
11
+ }
7
12
  type DefineConfigFactory = (context: {
8
- pre: MiddlewareRegistry;
9
- normal: MiddlewareRegistry;
10
- post: MiddlewareRegistry;
11
- }) => RouteDirectoryConfig | void;
13
+ app: ConfigApp;
14
+ }) => RouteDirectoryConfig | void | Promise<RouteDirectoryConfig | void>;
15
+ declare function onBeforeAll(handler: HookHandler): void;
16
+ declare function onAfterAll(handler: HookHandler): void;
12
17
  /**
13
- * Define a directory config with Hono-style middleware registration.
18
+ * Define a directory config with hook-based middleware registration.
14
19
  *
15
20
  * @param input - Config object or factory callback.
16
21
  * @returns Route directory config with middleware metadata.
17
22
  *
18
23
  * @example
19
- * import { defineConfig } from 'mokup'
24
+ * import { defineConfig, onBeforeAll, onAfterAll } from 'mokup'
20
25
  *
21
- * export default defineConfig(({ pre, normal, post }) => {
22
- * pre.use(async (c, next) => {
23
- * c.header('x-before', '1')
24
- * await next()
26
+ * export default defineConfig(({ app }) => {
27
+ * onBeforeAll(() => {
28
+ * app.use(async (c, next) => {
29
+ * c.header('x-before', '1')
30
+ * await next()
31
+ * })
25
32
  * })
26
33
  *
27
- * normal.use(async (_c, next) => {
34
+ * app.use(async (_c, next) => {
28
35
  * await next()
29
36
  * })
30
37
  *
31
- * post.use(async (c, next) => {
32
- * await next()
33
- * c.header('x-after', '1')
38
+ * onAfterAll(() => {
39
+ * app.use(async (c, next) => {
40
+ * await next()
41
+ * c.header('x-after', '1')
42
+ * })
34
43
  * })
35
44
  *
36
45
  * return { delay: 120 }
37
46
  * })
38
47
  */
39
- declare function defineConfig(input: RouteDirectoryConfig | DefineConfigFactory): RouteDirectoryConfig;
48
+ declare function defineConfig(input: RouteDirectoryConfig | DefineConfigFactory): RouteDirectoryConfig | Promise<RouteDirectoryConfig>;
40
49
 
41
50
  /**
42
51
  * Define a mock route handler with type hints.
@@ -64,4 +73,4 @@ declare function defineConfig(input: RouteDirectoryConfig | DefineConfigFactory)
64
73
  declare function defineHandler(input: RequestHandler): RequestHandler;
65
74
  declare function defineHandler(input: RouteRule): RouteRule;
66
75
 
67
- export { MiddlewareRegistry, RequestHandler, RouteDirectoryConfig, RouteRule, defineConfig, defineHandler };
76
+ export { RequestHandler, RouteDirectoryConfig, RouteRule, defineConfig, defineHandler, onAfterAll, onBeforeAll };
package/dist/index.d.ts CHANGED
@@ -1,44 +1,53 @@
1
1
  /// <reference path="./types/virtual.d.ts" />
2
2
 
3
- import { e as RouteDirectoryConfig, c as MiddlewareRegistry, d as RequestHandler, g as RouteRule } from './shared/mokup.DeotZ0g8.js';
4
- export { H as HttpMethod, b as MiddlewarePosition, M as MokupPluginOptions, f as RouteResponse, h as RuntimeMode, S as ServiceWorkerOptions, V as VitePluginOptions, i as VitePluginOptionsInput } from './shared/mokup.DeotZ0g8.js';
3
+ import { e as RouteDirectoryConfig, d as RequestHandler, g as RouteRule } from './shared/mokup.Dkqu10Hk.js';
4
+ export { k as HookErrorPolicy, H as HttpMethod, b as MiddlewarePosition, c as MiddlewareRegistry, M as MokupPluginOptions, f as RouteResponse, h as RuntimeMode, S as ServiceWorkerOptions, V as VitePluginOptions, i as VitePluginOptionsInput } from './shared/mokup.Dkqu10Hk.js';
5
+ import { MiddlewareHandler } from '@mokup/shared/hono';
5
6
  export { Context, MiddlewareHandler } from '@mokup/shared/hono';
6
7
  export { PlaygroundOptionsInput } from '@mokup/shared';
7
8
  import '@mokup/runtime';
8
9
 
10
+ type HookHandler = () => void | Promise<void>;
11
+ interface ConfigApp {
12
+ use: (...handlers: MiddlewareHandler[]) => void;
13
+ }
9
14
  type DefineConfigFactory = (context: {
10
- pre: MiddlewareRegistry;
11
- normal: MiddlewareRegistry;
12
- post: MiddlewareRegistry;
13
- }) => RouteDirectoryConfig | void;
15
+ app: ConfigApp;
16
+ }) => RouteDirectoryConfig | void | Promise<RouteDirectoryConfig | void>;
17
+ declare function onBeforeAll(handler: HookHandler): void;
18
+ declare function onAfterAll(handler: HookHandler): void;
14
19
  /**
15
- * Define a directory config with Hono-style middleware registration.
20
+ * Define a directory config with hook-based middleware registration.
16
21
  *
17
22
  * @param input - Config object or factory callback.
18
23
  * @returns Route directory config with middleware metadata.
19
24
  *
20
25
  * @example
21
- * import { defineConfig } from 'mokup'
26
+ * import { defineConfig, onBeforeAll, onAfterAll } from 'mokup'
22
27
  *
23
- * export default defineConfig(({ pre, normal, post }) => {
24
- * pre.use(async (c, next) => {
25
- * c.header('x-before', '1')
26
- * await next()
28
+ * export default defineConfig(({ app }) => {
29
+ * onBeforeAll(() => {
30
+ * app.use(async (c, next) => {
31
+ * c.header('x-before', '1')
32
+ * await next()
33
+ * })
27
34
  * })
28
35
  *
29
- * normal.use(async (_c, next) => {
36
+ * app.use(async (_c, next) => {
30
37
  * await next()
31
38
  * })
32
39
  *
33
- * post.use(async (c, next) => {
34
- * await next()
35
- * c.header('x-after', '1')
40
+ * onAfterAll(() => {
41
+ * app.use(async (c, next) => {
42
+ * await next()
43
+ * c.header('x-after', '1')
44
+ * })
36
45
  * })
37
46
  *
38
47
  * return { delay: 120 }
39
48
  * })
40
49
  */
41
- declare function defineConfig(input: RouteDirectoryConfig | DefineConfigFactory): RouteDirectoryConfig;
50
+ declare function defineConfig(input: RouteDirectoryConfig | DefineConfigFactory): RouteDirectoryConfig | Promise<RouteDirectoryConfig>;
42
51
 
43
52
  /**
44
53
  * Define a mock route handler with type hints.
@@ -66,4 +75,4 @@ declare function defineConfig(input: RouteDirectoryConfig | DefineConfigFactory)
66
75
  declare function defineHandler(input: RequestHandler): RequestHandler;
67
76
  declare function defineHandler(input: RouteRule): RouteRule;
68
77
 
69
- export { MiddlewareRegistry, RequestHandler, RouteDirectoryConfig, RouteRule, defineConfig, defineHandler };
78
+ export { RequestHandler, RouteDirectoryConfig, RouteRule, defineConfig, defineHandler, onAfterAll, onBeforeAll };
package/dist/index.mjs CHANGED
@@ -1,10 +1,88 @@
1
1
  const middlewareSymbol = Symbol.for("mokup.config.middlewares");
2
- function createRegistry(list) {
3
- return {
4
- use: (...handlers) => {
5
- list.push(...handlers);
2
+ const contextStack = [];
3
+ function getActiveContext() {
4
+ const context = contextStack[contextStack.length - 1];
5
+ if (!context) {
6
+ throw new Error("onBeforeAll/onAfterAll must be called inside defineConfig()");
7
+ }
8
+ return context;
9
+ }
10
+ function runWithContext(context, fn) {
11
+ contextStack.push(context);
12
+ try {
13
+ const result = fn();
14
+ if (isPromise(result)) {
15
+ return result.finally(() => {
16
+ contextStack.pop();
17
+ });
18
+ }
19
+ contextStack.pop();
20
+ return result;
21
+ } catch (error) {
22
+ contextStack.pop();
23
+ throw error;
24
+ }
25
+ }
26
+ function isPromise(value) {
27
+ return !!value && typeof value.then === "function";
28
+ }
29
+ function normalizeHookError(policy) {
30
+ if (policy === "throw" || policy === "silent") {
31
+ return policy;
32
+ }
33
+ return "warn";
34
+ }
35
+ function reportHookError(error, policy) {
36
+ if (policy === "silent") {
37
+ return;
38
+ }
39
+ if (policy === "warn") {
40
+ console.warn("[mokup] defineConfig hook failed:", error);
41
+ }
42
+ }
43
+ function runHookSequence(stage, hooks, policy, setStage) {
44
+ if (hooks.length === 0) {
45
+ return;
46
+ }
47
+ setStage(stage);
48
+ let chain = null;
49
+ const runHook = (hook) => {
50
+ try {
51
+ const result = hook();
52
+ if (isPromise(result)) {
53
+ return result.catch((error) => {
54
+ if (policy === "throw") {
55
+ throw error;
56
+ }
57
+ reportHookError(error, policy);
58
+ });
59
+ }
60
+ return void 0;
61
+ } catch (error) {
62
+ if (policy === "throw") {
63
+ throw error;
64
+ }
65
+ reportHookError(error, policy);
66
+ return void 0;
6
67
  }
7
68
  };
69
+ for (const hook of hooks) {
70
+ if (chain) {
71
+ chain = chain.then(() => runHook(hook));
72
+ continue;
73
+ }
74
+ const result = runHook(hook);
75
+ if (isPromise(result)) {
76
+ chain = result;
77
+ }
78
+ }
79
+ if (!chain) {
80
+ setStage("normal");
81
+ return;
82
+ }
83
+ return chain.finally(() => {
84
+ setStage("normal");
85
+ });
8
86
  }
9
87
  function attachMetadata(config, meta) {
10
88
  Object.defineProperty(config, middlewareSymbol, {
@@ -13,21 +91,70 @@ function attachMetadata(config, meta) {
13
91
  });
14
92
  return config;
15
93
  }
94
+ function normalizeConfig(value) {
95
+ return value && typeof value === "object" ? value : {};
96
+ }
97
+ function onBeforeAll(handler) {
98
+ if (typeof handler !== "function") {
99
+ throw new TypeError("onBeforeAll expects a function");
100
+ }
101
+ const context = getActiveContext();
102
+ context.hooks.pre.push(handler);
103
+ }
104
+ function onAfterAll(handler) {
105
+ if (typeof handler !== "function") {
106
+ throw new TypeError("onAfterAll expects a function");
107
+ }
108
+ const context = getActiveContext();
109
+ context.hooks.post.push(handler);
110
+ }
16
111
  function defineConfig(input) {
17
112
  if (typeof input === "function") {
18
113
  const pre = [];
19
114
  const normal = [];
20
115
  const post = [];
116
+ let stage = "normal";
117
+ const app = {
118
+ use: (...handlers) => {
119
+ if (stage === "pre") {
120
+ pre.push(...handlers);
121
+ return;
122
+ }
123
+ if (stage === "post") {
124
+ post.push(...handlers);
125
+ return;
126
+ }
127
+ normal.push(...handlers);
128
+ }
129
+ };
21
130
  const context = {
22
- pre: createRegistry(pre),
23
- normal: createRegistry(normal),
24
- post: createRegistry(post)
131
+ app,
132
+ hooks: { pre: [], post: [] },
133
+ setStage: (next) => {
134
+ stage = next;
135
+ }
136
+ };
137
+ const result = runWithContext(context, () => input({ app }));
138
+ const finalize = (value) => {
139
+ const config2 = normalizeConfig(value);
140
+ const policy = normalizeHookError(config2.hookError);
141
+ const preResult = runHookSequence("pre", context.hooks.pre, policy, context.setStage);
142
+ const runPost = () => runHookSequence("post", context.hooks.post, policy, context.setStage);
143
+ if (isPromise(preResult)) {
144
+ return preResult.then(runPost).then(() => attachMetadata(config2, { pre, normal, post }));
145
+ }
146
+ const postResult = runPost();
147
+ if (isPromise(postResult)) {
148
+ return postResult.then(() => attachMetadata(config2, { pre, normal, post }));
149
+ }
150
+ return attachMetadata(config2, { pre, normal, post });
25
151
  };
26
- const result = input(context);
27
- const config2 = result && typeof result === "object" ? result : {};
28
- return attachMetadata(config2, { pre, normal, post });
152
+ if (isPromise(result)) {
153
+ return result.then(finalize);
154
+ }
155
+ return finalize(result);
29
156
  }
30
- const config = input && typeof input === "object" ? input : {};
157
+ const config = normalizeConfig(input);
31
158
  return attachMetadata(config, { pre: [], normal: [], post: [] });
32
159
  }
33
160
 
@@ -35,4 +162,4 @@ function defineHandler(input) {
35
162
  return input;
36
163
  }
37
164
 
38
- export { defineConfig, defineHandler };
165
+ export { defineConfig, defineHandler, onAfterAll, onBeforeAll };
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- const manifest = require('./mokup.C7-7PDF7.cjs');
3
+ const manifest = require('./mokup.Dy9VDphS.cjs');
4
4
 
5
5
  function buildBundleModule(params) {
6
6
  const { manifest: manifest$1, modules } = manifest.buildManifestData({