alemonjs 2.1.81 → 2.1.83-alpha.1

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 (42) hide show
  1. package/lib/app/event-error.d.ts +2 -0
  2. package/lib/app/event-error.js +20 -0
  3. package/lib/app/event-processor-callHandler.d.ts +5 -1
  4. package/lib/app/event-processor-callHandler.js +18 -2
  5. package/lib/app/event-processor-cycleFiles.d.ts +4 -1
  6. package/lib/app/event-processor-cycleFiles.js +21 -6
  7. package/lib/app/event-processor-cycleRoute.d.ts +4 -1
  8. package/lib/app/event-processor-cycleRoute.js +16 -2
  9. package/lib/app/event-processor-event.js +2 -2
  10. package/lib/app/event-processor-middleware.js +2 -2
  11. package/lib/app/event-processor-subscribe.js +31 -3
  12. package/lib/app/event-processor.js +6 -1
  13. package/lib/app/hook-event-context.d.ts +7 -3
  14. package/lib/app/hook-event-context.js +24 -5
  15. package/lib/app/hook-use/subscribe.js +3 -1
  16. package/lib/app/index.js +2 -2
  17. package/lib/app/lifecycle-callbacks.d.ts +14 -0
  18. package/lib/app/lifecycle-callbacks.js +99 -0
  19. package/lib/app/load_modules/loadChild.js +13 -10
  20. package/lib/app/router/dsl.js +2 -2
  21. package/lib/app/store.d.ts +2 -0
  22. package/lib/app/store.js +35 -12
  23. package/lib/cbp/connects/client.js +34 -32
  24. package/lib/cbp/connects/platform.js +45 -68
  25. package/lib/cbp/normalize.d.ts +16 -0
  26. package/lib/cbp/normalize.js +328 -0
  27. package/lib/cbp/processor/actions.js +15 -13
  28. package/lib/cbp/processor/api.js +15 -13
  29. package/lib/cbp/processor/config.d.ts +8 -4
  30. package/lib/cbp/processor/config.js +9 -5
  31. package/lib/cbp/server/main.js +28 -30
  32. package/lib/cbp/typings.d.ts +139 -0
  33. package/lib/client.js +11 -7
  34. package/lib/core/config.d.ts +3 -3
  35. package/lib/index.js +2 -2
  36. package/lib/server/routers/router.js +111 -17
  37. package/lib/types/actions.d.ts +20 -1
  38. package/lib/types/apis.d.ts +2 -1
  39. package/lib/types/cycle/index.d.ts +50 -0
  40. package/lib/types/event/index.d.ts +1 -0
  41. package/lib/types/subscribe/index.d.ts +1 -0
  42. package/package.json +1 -1
@@ -0,0 +1,2 @@
1
+ import type { EventErrorContext } from '../types';
2
+ export declare const dispatchEventError: (context: EventErrorContext) => Promise<boolean>;
@@ -0,0 +1,20 @@
1
+ import { getChildrenApp } from './store.js';
2
+ import { showErrorModule } from '../core/utils.js';
3
+
4
+ const dispatchEventError = async (context) => {
5
+ const app = getChildrenApp(context.appName);
6
+ const onEventError = app?.cycle?.onEventError;
7
+ if (!onEventError) {
8
+ return false;
9
+ }
10
+ try {
11
+ const result = await onEventError(context);
12
+ return result === 'continue';
13
+ }
14
+ catch (error) {
15
+ showErrorModule(error instanceof Error ? error : new Error(typeof error === 'string' ? error : 'onEventError failed'));
16
+ return false;
17
+ }
18
+ };
19
+
20
+ export { dispatchEventError };
@@ -1 +1,5 @@
1
- export declare const createCallHandler: (valueEvent: any) => (currents: any, nextEvent: any) => void;
1
+ import type { EventErrorPhase } from '../types';
2
+ export declare const createCallHandler: (valueEvent: any) => (currents: any, nextEvent: any, meta?: {
3
+ appName?: string;
4
+ phase?: EventErrorPhase;
5
+ }) => void;
@@ -3,9 +3,10 @@ import 'path';
3
3
  import 'yaml';
4
4
  import { showErrorModule } from '../core/utils.js';
5
5
  import { withEventContext, finishCurrentTrace } from './hook-event-context.js';
6
+ import { dispatchEventError } from './event-error.js';
6
7
 
7
8
  const createCallHandler = valueEvent => {
8
- const callHandler = (currents, nextEvent) => {
9
+ const callHandler = (currents, nextEvent, meta) => {
9
10
  let index = 0;
10
11
  let isClose = false;
11
12
  let isNext = false;
@@ -24,7 +25,10 @@ const createCallHandler = valueEvent => {
24
25
  isNext = true;
25
26
  nextEvent(...cns);
26
27
  };
27
- const res = await withEventContext(valueEvent, nextFn, () => currents[index](valueEvent, nextFn));
28
+ const res = await withEventContext(valueEvent, nextFn, () => currents[index](valueEvent, nextFn), {
29
+ appName: meta?.appName,
30
+ phase: meta?.phase
31
+ });
28
32
  if (res !== true) {
29
33
  if (!isNext) {
30
34
  finishCurrentTrace('consumed');
@@ -35,7 +39,19 @@ const createCallHandler = valueEvent => {
35
39
  }
36
40
  catch (err) {
37
41
  finishCurrentTrace('error');
42
+ const shouldContinue = meta?.appName && meta?.phase
43
+ ? await dispatchEventError({
44
+ event: valueEvent,
45
+ error: err,
46
+ appName: meta.appName,
47
+ phase: meta.phase
48
+ })
49
+ : false;
38
50
  showErrorModule(err);
51
+ if (shouldContinue) {
52
+ nextEvent();
53
+ return;
54
+ }
39
55
  return;
40
56
  }
41
57
  ++index;
@@ -1,4 +1,7 @@
1
1
  import { Next, Events, EventKeys, FileTreeNode, StoreResponseItem } from '../types';
2
2
  export declare const clearModuleCache: (path?: string) => void;
3
3
  export declare const createNextStep: <T extends EventKeys>(valueEvent: Events[T], select: T, next: Next, files: StoreResponseItem[], callHandler: (currents: any, nextEvent: any) => void) => Next;
4
- export declare const createFileTreeStep: <T extends EventKeys>(valueEvent: Events[T], select: T, next: Next, root: FileTreeNode, callHandler: (currents: any, nextEvent: any) => void) => Next;
4
+ export declare const createFileTreeStep: <T extends EventKeys>(valueEvent: Events[T], select: T, next: Next, root: FileTreeNode, callHandler: (currents: any, nextEvent: any, meta?: {
5
+ appName?: string;
6
+ phase?: "middleware" | "response";
7
+ }) => void, phase: "middleware" | "response") => Next;
@@ -1,5 +1,6 @@
1
1
  import { getCachedRegExp, showErrorModule } from '../core/utils.js';
2
2
  import { EventMessageText } from '../core/variable.js';
3
+ import { dispatchEventError } from './event-error.js';
3
4
 
4
5
  const moduleCache = new Map();
5
6
  const shouldSkipFile = (file, select, valueEvent) => {
@@ -37,7 +38,7 @@ const loadModule = async (filePath) => {
37
38
  moduleCache.set(filePath, mod);
38
39
  return mod;
39
40
  };
40
- const callHandlerFile = async (valueEvent, select, file, nextStep, callback) => {
41
+ const callHandlerFile = async (valueEvent, select, file, nextStep, callback, phase) => {
41
42
  try {
42
43
  const app = await loadModule(file.path);
43
44
  if (!app?.default?.current || !app?.default?.select) {
@@ -60,8 +61,16 @@ const callHandlerFile = async (valueEvent, select, file, nextStep, callback) =>
60
61
  callback(app);
61
62
  }
62
63
  catch (err) {
64
+ const shouldContinue = await dispatchEventError({
65
+ event: valueEvent,
66
+ error: err,
67
+ appName: file.appName,
68
+ phase
69
+ });
63
70
  showErrorModule(err);
64
- nextStep();
71
+ if (shouldContinue) {
72
+ nextStep();
73
+ }
65
74
  }
66
75
  };
67
76
  const createNextStep = (valueEvent, select, next, files, callHandler) => {
@@ -94,14 +103,14 @@ const createNextStep = (valueEvent, select, next, files, callHandler) => {
94
103
  }, app => {
95
104
  const currentsItem = Array.isArray(app.default.current) ? app.default.current : [app.default.current];
96
105
  currents.push(...currentsItem);
97
- });
106
+ }, 'response');
98
107
  if (currents.length > 0) {
99
108
  callHandler(currents, nextStep);
100
109
  }
101
110
  };
102
111
  return nextStep;
103
112
  };
104
- const createFileTreeStep = (valueEvent, select, next, root, callHandler) => {
113
+ const createFileTreeStep = (valueEvent, select, next, root, callHandler, phase) => {
105
114
  const processNode = (node, done) => {
106
115
  if (node.middleware?.path) {
107
116
  void checkMiddleware(node, done);
@@ -123,7 +132,7 @@ const createFileTreeStep = (valueEvent, select, next, root, callHandler) => {
123
132
  matched = true;
124
133
  const items = Array.isArray(app.default.current) ? app.default.current : [app.default.current];
125
134
  mwCurrents.push(...items);
126
- });
135
+ }, 'middleware');
127
136
  if (matched) {
128
137
  if (mwCurrents.length === 0) {
129
138
  void processContent(node, done);
@@ -141,6 +150,9 @@ const createFileTreeStep = (valueEvent, select, next, root, callHandler) => {
141
150
  return;
142
151
  }
143
152
  void processContent(node, done);
153
+ }, {
154
+ appName: node.middleware?.appName,
155
+ phase
144
156
  });
145
157
  }
146
158
  };
@@ -174,8 +186,11 @@ const createFileTreeStep = (valueEvent, select, next, root, callHandler) => {
174
186
  else {
175
187
  processFiles(node, idx + 1, filesDone, treeDone);
176
188
  }
189
+ }, {
190
+ appName: file.appName,
191
+ phase
177
192
  });
178
- });
193
+ }, phase);
179
194
  };
180
195
  const processChildNodes = (node, done) => {
181
196
  const childKeys = Array.from(node.children.keys());
@@ -1,2 +1,5 @@
1
1
  import { Next, Events, EventKeys, ResponseRoute } from '../types';
2
- export declare const createRouteProcessChildren: <T extends EventKeys>(valueEvent: Events[T], select: T, nextCycle: Next, callHandler: (currents: any, nextEvent: any) => void) => (nodes: ResponseRoute[], _pending: any[], next: () => Promise<void> | void) => void;
2
+ export declare const createRouteProcessChildren: <T extends EventKeys>(valueEvent: Events[T], select: T, nextCycle: Next, callHandler: (currents: any, nextEvent: any, meta?: {
3
+ appName?: string;
4
+ phase?: "route";
5
+ }) => void, phase: "route") => (nodes: ResponseRoute[], _pending: any[], next: () => Promise<void> | void) => void;
@@ -3,6 +3,7 @@ import 'fs';
3
3
  import 'path';
4
4
  import 'yaml';
5
5
  import { getCachedRegExp, showErrorModule } from '../core/utils.js';
6
+ import { dispatchEventError } from './event-error.js';
6
7
 
7
8
  const AsyncFunction = (async () => { }).constructor;
8
9
  function isAsyncFunction(fn) {
@@ -11,7 +12,7 @@ function isAsyncFunction(fn) {
11
12
  function isFunction(value) {
12
13
  return isAsyncFunction(value) || typeof value === 'function' || value instanceof Function;
13
14
  }
14
- const createRouteProcessChildren = (valueEvent, select, nextCycle, callHandler) => {
15
+ const createRouteProcessChildren = (valueEvent, select, nextCycle, callHandler, phase) => {
15
16
  const handlerResultCache = new Map();
16
17
  const collectHandlers = (tail) => {
17
18
  const result = [];
@@ -126,11 +127,24 @@ const createRouteProcessChildren = (valueEvent, select, nextCycle, callHandler)
126
127
  return;
127
128
  }
128
129
  void nextNode();
130
+ }, {
131
+ appName: node.appName,
132
+ phase
129
133
  });
130
134
  }
131
135
  catch (err) {
136
+ const shouldContinue = typeof node.appName === 'string'
137
+ ? await dispatchEventError({
138
+ event: valueEvent,
139
+ error: err,
140
+ appName: node.appName,
141
+ phase
142
+ })
143
+ : false;
132
144
  showErrorModule(err);
133
- void nextNode();
145
+ if (shouldContinue) {
146
+ void nextNode();
147
+ }
134
148
  }
135
149
  };
136
150
  void nextNode();
@@ -8,10 +8,10 @@ const responseRouterSingleton = new ResponseRouter();
8
8
  const expendEvent = (valueEvent, select, next) => {
9
9
  const root = responseTreeSingleton.value;
10
10
  const callHandler = createCallHandler(valueEvent);
11
- const nextEvent = createFileTreeStep(valueEvent, select, next, root, callHandler);
11
+ const nextEvent = createFileTreeStep(valueEvent, select, next, root, callHandler, 'response');
12
12
  const routes = responseRouterSingleton.value;
13
13
  const callRouteHandler = createCallHandler(valueEvent);
14
- const processChildren = createRouteProcessChildren(valueEvent, select, nextEvent, callRouteHandler);
14
+ const processChildren = createRouteProcessChildren(valueEvent, select, nextEvent, callRouteHandler, 'route');
15
15
  void processChildren(routes, [], nextEvent);
16
16
  };
17
17
 
@@ -8,10 +8,10 @@ const middlewareRouterSingleton = new MiddlewareRouter();
8
8
  const expendMiddleware = (valueEvent, select, next) => {
9
9
  const root = middlewareTreeSingleton.value;
10
10
  const callHandler = createCallHandler(valueEvent);
11
- const nextMiddleware = createFileTreeStep(valueEvent, select, next, root, callHandler);
11
+ const nextMiddleware = createFileTreeStep(valueEvent, select, next, root, callHandler, 'middleware');
12
12
  const routes = middlewareRouterSingleton.value;
13
13
  const callRouteHandler = createCallHandler(valueEvent);
14
- const processChildren = createRouteProcessChildren(valueEvent, select, nextMiddleware, callRouteHandler);
14
+ const processChildren = createRouteProcessChildren(valueEvent, select, nextMiddleware, callRouteHandler, 'route');
15
15
  void processChildren(routes, [], nextMiddleware);
16
16
  };
17
17
 
@@ -5,6 +5,7 @@ import { showErrorModule } from '../core/utils.js';
5
5
  import { getSubscribeList } from './store.js';
6
6
  import { SubscribeStatus } from './config.js';
7
7
  import { withEventContext, finishCurrentTrace } from './hook-event-context.js';
8
+ import { dispatchEventError } from './event-error.js';
8
9
 
9
10
  const expendSubscribe = (valueEvent, select, next, choose) => {
10
11
  const subListValue = getSubscribeList(choose, select);
@@ -64,15 +65,29 @@ const expendSubscribe = (valueEvent, select, next, choose) => {
64
65
  }
65
66
  };
66
67
  try {
67
- const result = withEventContext(valueEvent, Continue, () => item.data.current(valueEvent, Continue));
68
+ const result = withEventContext(valueEvent, Continue, () => item.data.current(valueEvent, Continue), {
69
+ appName: item.data.appName,
70
+ phase: 'subscribe'
71
+ });
68
72
  if (result && typeof result.then === 'function') {
69
73
  void result.then(() => {
70
74
  if (!isContinue) {
71
75
  finishCurrentTrace('consumed');
72
76
  }
73
- }, error => {
77
+ }, async (error) => {
74
78
  finishCurrentTrace('error');
79
+ const shouldContinue = typeof item.data.appName === 'string'
80
+ ? await dispatchEventError({
81
+ event: valueEvent,
82
+ error,
83
+ appName: item.data.appName,
84
+ phase: 'subscribe'
85
+ })
86
+ : false;
75
87
  showErrorModule(error);
88
+ if (shouldContinue) {
89
+ nextObserver(true);
90
+ }
76
91
  });
77
92
  return;
78
93
  }
@@ -82,7 +97,20 @@ const expendSubscribe = (valueEvent, select, next, choose) => {
82
97
  }
83
98
  catch (error) {
84
99
  finishCurrentTrace('error');
85
- showErrorModule(error);
100
+ void (async () => {
101
+ const shouldContinue = typeof item.data.appName === 'string'
102
+ ? await dispatchEventError({
103
+ event: valueEvent,
104
+ error,
105
+ appName: item.data.appName,
106
+ phase: 'subscribe'
107
+ })
108
+ : false;
109
+ showErrorModule(error);
110
+ if (shouldContinue) {
111
+ nextObserver(true);
112
+ }
113
+ })();
86
114
  }
87
115
  };
88
116
  nextObserver();
@@ -4,6 +4,7 @@ import { expendCycle } from './event-processor-cycle.js';
4
4
  import { withProcessorTrace, finishCurrentTrace } from './hook-event-context.js';
5
5
  import { ProcessorEventAutoClearMap, ProcessorEventUserAutoClearMap } from './store.js';
6
6
  import { getCachedRegExp, matchIn, fastHash } from '../core/utils.js';
7
+ import { dispatchEventStart } from './lifecycle-callbacks.js';
7
8
 
8
9
  const filter = ({ Now, store, INTERVAL }, MessageId) => {
9
10
  if (store.has(MessageId)) {
@@ -59,8 +60,12 @@ const callback = () => {
59
60
  };
60
61
  setTimeout(callback, processorRepeatedClearTimeMin);
61
62
  const onProcessor = (name, event, data) => {
62
- withProcessorTrace(name, event, () => {
63
+ void withProcessorTrace(name, event, async () => {
63
64
  try {
65
+ await dispatchEventStart({
66
+ event,
67
+ name
68
+ });
64
69
  const value = getConfigValue();
65
70
  const disabledTextRegular = value?.disabled_text_regular;
66
71
  if (disabledTextRegular && event['MessageText']) {
@@ -1,10 +1,14 @@
1
1
  import { Result } from '../core';
2
- import { EventKeys, Events } from '../types';
3
- export type EventTraceReason = 'filtered' | 'completed' | 'consumed' | 'error';
4
- export declare const withEventContext: <T extends EventKeys, R>(event: Events[T], next: (...args: boolean[]) => void, runner: () => R) => R;
2
+ import { EventErrorPhase, EventKeys, Events, EventTraceReason } from '../types';
3
+ export declare const withEventContext: <T extends EventKeys, R>(event: Events[T], next: (...args: boolean[]) => void, runner: () => R, options?: {
4
+ appName?: string;
5
+ phase?: EventErrorPhase;
6
+ }) => R;
5
7
  export declare const withProcessorTrace: <T extends EventKeys, R>(select: T, event: Events[T], runner: () => R) => R;
6
8
  export declare const getCurrentEvent: <T extends EventKeys>() => Events[T] | undefined;
7
9
  export declare const getCurrentNext: () => ((...args: boolean[]) => void) | undefined;
10
+ export declare const getCurrentAppName: () => string | undefined;
11
+ export declare const getCurrentPhase: () => EventErrorPhase | undefined;
8
12
  export declare const finishCurrentTrace: (reason: EventTraceReason) => void;
9
13
  export declare const markEventSendAttempt: <T extends EventKeys>(event?: Events[T]) => void;
10
14
  export declare const markEventSendSuccess: <T extends EventKeys>(event?: Events[T]) => void;
@@ -2,6 +2,7 @@ import { AsyncLocalStorage } from 'node:async_hooks';
2
2
  import { performance } from 'node:perf_hooks';
3
3
  import { getConfigValue } from '../core/config.js';
4
4
  import { ResultCode } from '../core/variable.js';
5
+ import { dispatchEventFinished } from './lifecycle-callbacks.js';
5
6
 
6
7
  const eventStore = new AsyncLocalStorage();
7
8
  const shouldShowLog = (event) => {
@@ -61,19 +62,31 @@ const createEventTrace = (select) => {
61
62
  message: 'event processor finished',
62
63
  data: createLogData(event, trace.select, reason, duration)
63
64
  });
64
- return;
65
65
  }
66
- logger.info(createLogText(event, trace.select, reason, duration));
66
+ else {
67
+ logger.info(createLogText(event, trace.select, reason, duration));
68
+ }
69
+ void dispatchEventFinished({
70
+ event,
71
+ name: trace.select,
72
+ reason,
73
+ duration,
74
+ hasSendAttempted: event._sendAttempted === true || event._has_send_attempt === true,
75
+ hasSendSucceeded: event._sendSucceeded === true || event._has_send_success === true,
76
+ lastSendError: event._lastSendError ?? event._last_send_error ?? null
77
+ });
67
78
  }
68
79
  };
69
80
  return trace;
70
81
  };
71
- const withEventContext = (event, next, runner) => {
82
+ const withEventContext = (event, next, runner, options) => {
72
83
  const current = eventStore.getStore();
73
84
  return eventStore.run({
74
85
  event,
75
86
  next,
76
- trace: current?.trace
87
+ trace: current?.trace,
88
+ appName: options?.appName ?? current?.appName,
89
+ phase: options?.phase ?? current?.phase
77
90
  }, runner);
78
91
  };
79
92
  const withProcessorTrace = (select, event, runner) => {
@@ -90,6 +103,12 @@ const getCurrentEvent = () => {
90
103
  const getCurrentNext = () => {
91
104
  return eventStore.getStore()?.next;
92
105
  };
106
+ const getCurrentAppName = () => {
107
+ return eventStore.getStore()?.appName;
108
+ };
109
+ const getCurrentPhase = () => {
110
+ return eventStore.getStore()?.phase;
111
+ };
93
112
  const finishCurrentTrace = (reason) => {
94
113
  eventStore.getStore()?.trace?.finish(reason);
95
114
  };
@@ -144,4 +163,4 @@ const recordEventSendResults = (results, event) => {
144
163
  }
145
164
  };
146
165
 
147
- export { finishCurrentTrace, getCurrentEvent, getCurrentNext, markEventSendAttempt, markEventSendFailure, markEventSendSuccess, recordEventSendResults, withEventContext, withProcessorTrace };
166
+ export { finishCurrentTrace, getCurrentAppName, getCurrentEvent, getCurrentNext, getCurrentPhase, markEventSendAttempt, markEventSendFailure, markEventSendSuccess, recordEventSendResults, withEventContext, withProcessorTrace };
@@ -1,12 +1,13 @@
1
1
  import { ResultCode } from '../../core/variable.js';
2
2
  import { SubscribeList } from '../store.js';
3
3
  import { SubscribeStatus } from '../config.js';
4
- import { getCurrentEvent } from '../hook-event-context.js';
4
+ import { getCurrentEvent, getCurrentAppName } from '../hook-event-context.js';
5
5
 
6
6
  function useSubscribe(eventOrSelects, maybeSelects) {
7
7
  const selects = (maybeSelects === undefined ? eventOrSelects : maybeSelects);
8
8
  const event = (maybeSelects === undefined ? undefined : eventOrSelects);
9
9
  const valueEvent = event ?? getCurrentEvent();
10
+ const appName = getCurrentAppName();
10
11
  if (typeof valueEvent !== 'object' || valueEvent === null) {
11
12
  logger.error({
12
13
  code: ResultCode.FailParams,
@@ -50,6 +51,7 @@ function useSubscribe(eventOrSelects, maybeSelects) {
50
51
  }
51
52
  }
52
53
  subList.value.append({
54
+ appName,
53
55
  choose,
54
56
  selects: curSelects,
55
57
  keys: values,
package/lib/app/index.js CHANGED
@@ -1,4 +1,4 @@
1
- export { ChildrenApp, Core, Logger, Middleware, MiddlewareRouter, MiddlewareTree, ProcessorEventAutoClearMap, ProcessorEventUserAutoClearMap, Response, ResponseMiddleware, ResponseRouter, ResponseTree, State, StateSubscribe, SubscribeList, bumpStoreVersion, clearRuntimeAppKoaRouters, core, disposeAllRuntimeApps, disposeRuntimeApp, getRuntimeApp, getRuntimeAppKoaRouters, getSubscribeList, hasRuntimeAppCapability, listRuntimeAppKoaRouters, listRuntimeApps, logger, registerRuntimeApp, setRuntimeAppKoaRouters, toRuntimeAppSnapshot, updateRuntimeAppCapabilities, updateRuntimeAppStatus } from './store.js';
1
+ export { ChildrenApp, Core, Logger, Middleware, MiddlewareRouter, MiddlewareTree, ProcessorEventAutoClearMap, ProcessorEventUserAutoClearMap, Response, ResponseMiddleware, ResponseRouter, ResponseTree, State, StateSubscribe, SubscribeList, bumpStoreVersion, clearRuntimeAppKoaRouters, core, disposeAllRuntimeApps, disposeRuntimeApp, getChildrenApp, getRuntimeApp, getRuntimeAppKoaRouters, getSubscribeList, hasRuntimeAppCapability, listChildrenApps, listRuntimeAppKoaRouters, listRuntimeApps, logger, registerRuntimeApp, setRuntimeAppKoaRouters, toRuntimeAppSnapshot, updateRuntimeAppCapabilities, updateRuntimeAppStatus } from './store.js';
2
2
  export { Expose, clearAllExpose, disposeExpose, registerExpose } from './expose.js';
3
3
  export { loadModels, run } from './load_modules/load.js';
4
4
  export { loadChildren, loadChildrenFile } from './load_modules/loadChild.js';
@@ -35,7 +35,7 @@ export { useUser } from './hook-use/user.js';
35
35
  export { useObserver, useSubscribe } from './hook-use/subscribe.js';
36
36
  export { createEvent, useEvent } from './hook-use/event.js';
37
37
  export { clearInterval, clearTimeout, listSchedule, pauseSchedule, resumeSchedule, setCron, setInterval, setTimeout } from './api/schedule.js';
38
- export { finishCurrentTrace, getCurrentEvent, getCurrentNext, markEventSendAttempt, markEventSendFailure, markEventSendSuccess, recordEventSendResults, withEventContext, withProcessorTrace } from './hook-event-context.js';
38
+ export { finishCurrentTrace, getCurrentAppName, getCurrentEvent, getCurrentNext, getCurrentPhase, markEventSendAttempt, markEventSendFailure, markEventSendSuccess, recordEventSendResults, withEventContext, withProcessorTrace } from './hook-event-context.js';
39
39
  export { registerAppDir, scheduleCancel, scheduleCancelAll, scheduleCancelByApp, scheduleCron, scheduleInterval, scheduleList, schedulePause, scheduleResume, scheduleTimeout, unregisterAppDir } from './schedule-store.js';
40
40
  export { createEventValue, createSelects, onSelects, onState, unChildren, unState, useState } from './event-utils.js';
41
41
  export { MessageDirect, createDataFormat, format, getMessageIntent, sendToChannel, sendToUser } from './message-api.js';
@@ -0,0 +1,14 @@
1
+ import type { EventFinishedContext, EventStartContext, HttpErrorContext, RuntimeStatusChangeContext } from '../types';
2
+ export declare const dispatchEventStart: (context: EventStartContext) => Promise<void>;
3
+ export declare const dispatchEventFinished: (context: EventFinishedContext) => Promise<void>;
4
+ export declare const dispatchHttpError: (context: HttpErrorContext) => Promise<boolean>;
5
+ export declare const dispatchRuntimeStatusChange: (context: RuntimeStatusChangeContext) => Promise<void>;
6
+ export declare const dispatchAppReady: (appName: string, store: {
7
+ response: any[];
8
+ responseMiddleware: {
9
+ [key: string]: any;
10
+ };
11
+ middleware: any[];
12
+ }) => Promise<void>;
13
+ export declare const dispatchAppDispose: (appName: string, error?: unknown) => Promise<void>;
14
+ export declare const dispatchDisposeAllApps: (error?: unknown) => Promise<void>;
@@ -0,0 +1,99 @@
1
+ import { showErrorModule } from '../core/utils.js';
2
+
3
+ const swallowLifecycleError = (error) => {
4
+ showErrorModule(error instanceof Error ? error : new Error(typeof error === 'string' ? error : 'Unknown lifecycle error'));
5
+ };
6
+ const getChildrenApps = () => {
7
+ return Object.values(global.alemonjsCore?.storeChildrenApp ?? {});
8
+ };
9
+ const getChildrenApp = (name) => {
10
+ return global.alemonjsCore?.storeChildrenApp?.[name] ?? null;
11
+ };
12
+ const dispatchEventStart = async (context) => {
13
+ const apps = getChildrenApps();
14
+ for (const app of apps) {
15
+ try {
16
+ await app.cycle?.onEventStart?.(context);
17
+ }
18
+ catch (error) {
19
+ swallowLifecycleError(error);
20
+ }
21
+ }
22
+ };
23
+ const dispatchEventFinished = async (context) => {
24
+ const apps = getChildrenApps();
25
+ for (const app of apps) {
26
+ try {
27
+ await app.cycle?.onEventFinished?.(context);
28
+ }
29
+ catch (error) {
30
+ swallowLifecycleError(error);
31
+ }
32
+ }
33
+ };
34
+ const dispatchHttpError = async (context) => {
35
+ const app = getChildrenApp(context.appName);
36
+ const handler = app?.cycle?.onHttpError;
37
+ if (!handler) {
38
+ return false;
39
+ }
40
+ try {
41
+ const result = await handler(context);
42
+ return result === 'handled';
43
+ }
44
+ catch (error) {
45
+ swallowLifecycleError(error);
46
+ return false;
47
+ }
48
+ };
49
+ const dispatchRuntimeStatusChange = async (context) => {
50
+ const app = getChildrenApp(context.appName);
51
+ const handler = app?.cycle?.onRuntimeStatusChange;
52
+ if (!handler) {
53
+ return;
54
+ }
55
+ try {
56
+ await handler(context);
57
+ }
58
+ catch (error) {
59
+ swallowLifecycleError(error);
60
+ }
61
+ };
62
+ const dispatchAppReady = async (appName, store) => {
63
+ const app = getChildrenApp(appName);
64
+ const handler = app?.cycle?.onReady;
65
+ if (!handler) {
66
+ return;
67
+ }
68
+ try {
69
+ await handler(store);
70
+ }
71
+ catch (error) {
72
+ throw error;
73
+ }
74
+ };
75
+ const dispatchAppDispose = async (appName, error) => {
76
+ const app = getChildrenApp(appName);
77
+ if (!app?.cycle) {
78
+ return;
79
+ }
80
+ try {
81
+ if (app.cycle.onDispose) {
82
+ await app.cycle.onDispose(error);
83
+ }
84
+ if (app.cycle.unMounted) {
85
+ await app.cycle.unMounted(error);
86
+ }
87
+ }
88
+ catch (disposeError) {
89
+ swallowLifecycleError(disposeError);
90
+ }
91
+ };
92
+ const dispatchDisposeAllApps = async (error) => {
93
+ const apps = getChildrenApps();
94
+ for (const app of apps) {
95
+ await dispatchAppDispose(app.name, error);
96
+ }
97
+ };
98
+
99
+ export { dispatchAppDispose, dispatchAppReady, dispatchDisposeAllApps, dispatchEventFinished, dispatchEventStart, dispatchHttpError, dispatchRuntimeStatusChange };
@@ -6,6 +6,7 @@ import { registerExpose } from '../expose.js';
6
6
  import { ResultCode, fileSuffixMiddleware } from '../../core/variable.js';
7
7
  import { registerAppDir, scheduleCancelByApp, unregisterAppDir } from '../schedule-store.js';
8
8
  import module$1 from 'module';
9
+ import { dispatchRuntimeStatusChange, dispatchAppDispose, dispatchAppReady } from '../lifecycle-callbacks.js';
9
10
 
10
11
  const initRequire = () => { };
11
12
  initRequire.resolve = () => '';
@@ -89,21 +90,19 @@ const loadChildren = async (mainPath, appName) => {
89
90
  app = await moduleApp.default.callback();
90
91
  }
91
92
  App.pushCycle(app);
93
+ await dispatchRuntimeStatusChange({
94
+ appName,
95
+ previousStatus: 'discovered',
96
+ status: 'loading'
97
+ });
92
98
  const unMounted = async (e) => {
93
99
  showErrorModule(e);
94
100
  clearRuntimeAppKoaRouters(appName);
95
101
  updateRuntimeAppStatus(appName, 'failed', e);
96
102
  scheduleCancelByApp(appName);
97
103
  unregisterAppDir(appName);
104
+ await dispatchAppDispose(appName, e);
98
105
  App.un();
99
- try {
100
- if (app?.unMounted) {
101
- await app.unMounted(e);
102
- }
103
- }
104
- catch (e) {
105
- showErrorModule(e);
106
- }
107
106
  };
108
107
  try {
109
108
  if (app?.onCreated) {
@@ -133,10 +132,12 @@ const loadChildren = async (mainPath, appName) => {
133
132
  expose: hasExposeCapability
134
133
  });
135
134
  App.on();
135
+ const emptyStore = { response: [], responseMiddleware: {}, middleware: [] };
136
136
  try {
137
137
  if (app?.onMounted) {
138
- await app.onMounted({ response: [], responseMiddleware: {}, middleware: [] });
138
+ await app.onMounted(emptyStore);
139
139
  }
140
+ await dispatchAppReady(appName, emptyStore);
140
141
  updateRuntimeAppStatus(appName, 'ready');
141
142
  }
142
143
  catch (e) {
@@ -202,10 +203,12 @@ const loadChildren = async (mainPath, appName) => {
202
203
  event: resData.length > 0 || Object.keys(resAndMwData).length > 0 || mwData.length > 0
203
204
  });
204
205
  App.on();
206
+ const mountedStore = { response: resData, responseMiddleware: resAndMwData, middleware: mwData };
205
207
  try {
206
208
  if (app?.onMounted) {
207
- await app.onMounted({ response: resData, responseMiddleware: resAndMwData, middleware: mwData });
209
+ await app.onMounted(mountedStore);
208
210
  }
211
+ await dispatchAppReady(appName, mountedStore);
209
212
  updateRuntimeAppStatus(appName, 'ready');
210
213
  }
211
214
  catch (e) {
@@ -690,10 +690,10 @@ class Router {
690
690
  const description = formatRouteDescription(routeEntry?.config.description);
691
691
  const schemaHints = buildSchemaHints(routeEntry?.config.schema);
692
692
  const replyLines = buildValidationReply({
693
- error: validation && !validation.valid ? validation.error : '参数校验失败',
693
+ error: validation?.valid === false ? validation.error : '参数校验失败',
694
694
  commandKey: result.commandKey,
695
695
  description,
696
- usage: validation && !validation.valid ? validation.usage : undefined,
696
+ usage: validation?.valid === false ? validation.usage : undefined,
697
697
  schemaHints
698
698
  });
699
699
  replyLines.forEach((line, index) => {
@@ -187,6 +187,8 @@ export declare class ChildrenApp {
187
187
  un(): void;
188
188
  get value(): import("../types").StoreChildrenApp;
189
189
  }
190
+ export declare const getChildrenApp: (name: string) => import("../types").StoreChildrenApp;
191
+ export declare const listChildrenApps: () => import("../types").StoreChildrenApp[];
190
192
  export declare const ProcessorEventAutoClearMap: Map<any, any>;
191
193
  export declare const ProcessorEventUserAutoClearMap: Map<any, any>;
192
194
  export declare const logger: any;