alemonjs 2.1.53 → 2.1.54

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.
@@ -2,4 +2,5 @@ import { DefineRouterFunc } from '../types';
2
2
  export declare const lazy: <T extends {
3
3
  default: any;
4
4
  }>(fnc: () => Promise<T>) => (() => Promise<T["default"]>);
5
+ export declare function runHandler(loader: () => Promise<any>, args: any[]): Promise<any>;
5
6
  export declare const defineRouter: DefineRouterFunc;
@@ -11,10 +11,15 @@ const lazy = (fnc) => {
11
11
  };
12
12
  return back;
13
13
  };
14
+ async function runHandler(loader, args) {
15
+ const mod = await loader();
16
+ const handler = mod.default ?? mod;
17
+ return handler(...args);
18
+ }
14
19
  const defineRouter = routes => {
15
20
  return {
16
21
  current: routes
17
22
  };
18
23
  };
19
24
 
20
- export { defineRouter, lazy };
25
+ export { defineRouter, lazy, runHandler };
@@ -121,9 +121,7 @@ const createFileTreeStep = (valueEvent, select, next, root, callHandler) => {
121
121
  void processContent(node, done);
122
122
  }, app => {
123
123
  matched = true;
124
- const items = Array.isArray(app.default.current)
125
- ? app.default.current
126
- : [app.default.current];
124
+ const items = Array.isArray(app.default.current) ? app.default.current : [app.default.current];
127
125
  mwCurrents.push(...items);
128
126
  });
129
127
  if (matched) {
@@ -168,9 +166,7 @@ const createFileTreeStep = (valueEvent, select, next, root, callHandler) => {
168
166
  void callHandlerFile(valueEvent, select, file, () => {
169
167
  processFiles(node, idx + 1, filesDone, treeDone);
170
168
  }, app => {
171
- const fileCurrents = Array.isArray(app.default.current)
172
- ? app.default.current
173
- : [app.default.current];
169
+ const fileCurrents = Array.isArray(app.default.current) ? app.default.current : [app.default.current];
174
170
  callHandler(fileCurrents, (cn, ...cns) => {
175
171
  if (cn) {
176
172
  treeDone(true, ...cns);
@@ -0,0 +1,16 @@
1
+ import { ExposeProvideConfig, ExposeListItem, ExposeWatchEvent, ExposeSchemaItem } from '../types';
2
+ type WatchCallback = (event: ExposeWatchEvent) => void;
3
+ export declare function registerExpose(appName: string, configs: ExposeProvideConfig[]): void;
4
+ export declare class Expose {
5
+ #private;
6
+ static create(): Expose;
7
+ provide(config: ExposeProvideConfig): this;
8
+ getConfigs(): ExposeProvideConfig[];
9
+ list(protocol?: string): ExposeListItem[];
10
+ invoke(protocol: string, appName: string, action: string, value?: any): any;
11
+ schema(): ExposeSchemaItem[];
12
+ watch(protocolOrCallback: string | WatchCallback, callback?: WatchCallback): () => void;
13
+ }
14
+ export declare function disposeExpose(appName: string): void;
15
+ export declare function clearAllExpose(): void;
16
+ export {};
@@ -0,0 +1,190 @@
1
+ const storeExpose = new Map();
2
+ const protocolWatchers = new Map();
3
+ const globalWatchers = new Set();
4
+ function emitWatch(event) {
5
+ const watchers = protocolWatchers.get(event.protocol);
6
+ if (watchers) {
7
+ for (const cb of watchers) {
8
+ try {
9
+ cb(event);
10
+ }
11
+ catch {
12
+ }
13
+ }
14
+ }
15
+ for (const cb of globalWatchers) {
16
+ try {
17
+ cb(event);
18
+ }
19
+ catch {
20
+ }
21
+ }
22
+ }
23
+ function registerExpose(appName, configs) {
24
+ for (const config of configs) {
25
+ const protocol = config.name;
26
+ if (!storeExpose.has(protocol)) {
27
+ storeExpose.set(protocol, new Map());
28
+ }
29
+ const providers = storeExpose.get(protocol);
30
+ if (providers.has(appName)) {
31
+ console.warn(`[expose] ${appName} already provided "${protocol}", overwriting.`);
32
+ }
33
+ providers.set(appName, { appName, config });
34
+ }
35
+ }
36
+ class Expose {
37
+ #configs = [];
38
+ static create() {
39
+ return new Expose();
40
+ }
41
+ provide(config) {
42
+ this.#configs.push(config);
43
+ return this;
44
+ }
45
+ getConfigs() {
46
+ return this.#configs;
47
+ }
48
+ list(protocol) {
49
+ const result = [];
50
+ if (protocol) {
51
+ const providers = storeExpose.get(protocol);
52
+ if (!providers) {
53
+ return result;
54
+ }
55
+ for (const [, entry] of providers) {
56
+ result.push(createListItem(entry, protocol));
57
+ }
58
+ }
59
+ else {
60
+ for (const [proto, providers] of storeExpose) {
61
+ for (const [, entry] of providers) {
62
+ result.push(createListItem(entry, proto));
63
+ }
64
+ }
65
+ }
66
+ return result;
67
+ }
68
+ invoke(protocol, appName, action, value) {
69
+ const providers = storeExpose.get(protocol);
70
+ if (!providers) {
71
+ throw new Error(`[expose] protocol "${protocol}" not found`);
72
+ }
73
+ const entry = providers.get(appName);
74
+ if (!entry) {
75
+ throw new Error(`[expose] provider "${appName}" not found in protocol "${protocol}"`);
76
+ }
77
+ const actionMeta = entry.config.actions[action];
78
+ if (!actionMeta) {
79
+ throw new Error(`[expose] action "${action}" not found in "${protocol}" of "${appName}"`);
80
+ }
81
+ const result = actionMeta.handler(value);
82
+ if (action !== 'read') {
83
+ emitWatch({
84
+ name: appName,
85
+ protocol,
86
+ action,
87
+ value
88
+ });
89
+ }
90
+ return result;
91
+ }
92
+ schema() {
93
+ const result = [];
94
+ for (const [protocol, providers] of storeExpose) {
95
+ const firstEntry = providers.values().next().value;
96
+ if (!firstEntry) {
97
+ continue;
98
+ }
99
+ const actions = {};
100
+ for (const [actionName, meta] of Object.entries(firstEntry.config.actions)) {
101
+ actions[actionName] = {
102
+ description: meta.description,
103
+ ...(meta.params ? { params: meta.params } : {}),
104
+ ...(meta.returns ? { returns: meta.returns } : {})
105
+ };
106
+ }
107
+ result.push({
108
+ protocol,
109
+ description: firstEntry.config.description,
110
+ providers: Array.from(providers.keys()).map(name => ({ name })),
111
+ actions,
112
+ invoke: 'Expose.invoke(protocol, appName, action, value?)'
113
+ });
114
+ }
115
+ return result;
116
+ }
117
+ watch(protocolOrCallback, callback) {
118
+ if (typeof protocolOrCallback === 'function') {
119
+ const cb = protocolOrCallback;
120
+ globalWatchers.add(cb);
121
+ return () => {
122
+ globalWatchers.delete(cb);
123
+ };
124
+ }
125
+ const protocol = protocolOrCallback;
126
+ if (!callback) {
127
+ throw new Error('[expose] watch(protocol, callback) requires a callback');
128
+ }
129
+ if (!protocolWatchers.has(protocol)) {
130
+ protocolWatchers.set(protocol, new Set());
131
+ }
132
+ protocolWatchers.get(protocol).add(callback);
133
+ return () => {
134
+ const set = protocolWatchers.get(protocol);
135
+ if (set) {
136
+ set.delete(callback);
137
+ if (set.size === 0) {
138
+ protocolWatchers.delete(protocol);
139
+ }
140
+ }
141
+ };
142
+ }
143
+ }
144
+ function createListItem(entry, protocol) {
145
+ const actions = {};
146
+ for (const [actionName, meta] of Object.entries(entry.config.actions)) {
147
+ actions[actionName] = {
148
+ description: meta.description,
149
+ ...(meta.params ? { params: meta.params } : {}),
150
+ ...(meta.returns ? { returns: meta.returns } : {})
151
+ };
152
+ }
153
+ return {
154
+ name: entry.appName,
155
+ protocol,
156
+ description: entry.config.description,
157
+ actions,
158
+ invoke(action, value) {
159
+ const actionMeta = entry.config.actions[action];
160
+ if (!actionMeta) {
161
+ throw new Error(`[expose] action "${action}" not found in "${protocol}" of "${entry.appName}"`);
162
+ }
163
+ const result = actionMeta.handler(value);
164
+ if (action !== 'read') {
165
+ emitWatch({
166
+ name: entry.appName,
167
+ protocol,
168
+ action,
169
+ value
170
+ });
171
+ }
172
+ return result;
173
+ }
174
+ };
175
+ }
176
+ function disposeExpose(appName) {
177
+ for (const [protocol, providers] of storeExpose) {
178
+ providers.delete(appName);
179
+ if (providers.size === 0) {
180
+ storeExpose.delete(protocol);
181
+ }
182
+ }
183
+ }
184
+ function clearAllExpose() {
185
+ storeExpose.clear();
186
+ protocolWatchers.clear();
187
+ globalWatchers.clear();
188
+ }
189
+
190
+ export { Expose, clearAllExpose, disposeExpose, registerExpose };
@@ -1,4 +1,5 @@
1
1
  export * from './store.js';
2
+ export * from './expose.js';
2
3
  export * from './load_modules/index.js';
3
4
  export * from './define-children.js';
4
5
  export * from './define-platform.js';
package/lib/app/index.js CHANGED
@@ -1,11 +1,12 @@
1
1
  export { ChildrenApp, Core, Logger, Middleware, MiddlewareRouter, MiddlewareTree, ProcessorEventAutoClearMap, ProcessorEventUserAutoClearMap, Response, ResponseMiddleware, ResponseRouter, ResponseTree, State, StateSubscribe, SubscribeList, bumpStoreVersion, core, getSubscribeList, logger } from './store.js';
2
+ export { Expose, clearAllExpose, disposeExpose, registerExpose } from './expose.js';
2
3
  export { loadModels, run } from './load_modules/load.js';
3
4
  export { loadChildren, loadChildrenFile } from './load_modules/loadChild.js';
4
5
  export { defineChildren } from './define-children.js';
5
6
  export { definePlatform } from './define-platform.js';
6
7
  export { defineResponse } from './define-response.js';
7
8
  export { defineMiddleware } from './define-middleware.js';
8
- export { defineRouter, lazy } from './define-router.js';
9
+ export { defineRouter, lazy, runHandler } from './define-router.js';
9
10
  export { FormatEvent, wrapEvent } from './event-format.js';
10
11
  export { onGroup } from './event-group.js';
11
12
  export { OnMiddleware, onMiddleware } from './event-middleware.js';
@@ -2,6 +2,7 @@ import { dirname, join } from 'path';
2
2
  import { existsSync } from 'fs';
3
3
  import { showErrorModule, getRecursiveDirFiles, createEventName } from '../../core/utils.js';
4
4
  import { ChildrenApp } from '../store.js';
5
+ import { registerExpose } from '../expose.js';
5
6
  import { ResultCode, fileSuffixMiddleware } from '../../core/variable.js';
6
7
  import module$1 from 'module';
7
8
 
@@ -67,6 +68,9 @@ const loadChildren = async (mainPath, appName) => {
67
68
  if (res && (res?.response || res?.middleware || res?.responseRouter || res?.middlewareRouter)) {
68
69
  App.register(res);
69
70
  }
71
+ if (res?.expose) {
72
+ registerExpose(appName, res.expose.getConfigs());
73
+ }
70
74
  App.on();
71
75
  try {
72
76
  if (app?.onMounted) {
@@ -8,11 +8,11 @@ export declare class Logger {
8
8
  export declare class Core {
9
9
  constructor();
10
10
  get value(): {
11
- storeState: import("..").ResponseState;
12
- storeStateSubscribe: import("..").StateSubscribeMap;
13
- storeSubscribeList: import("..").SubscribeKeysMap;
11
+ storeState: import("../types").ResponseState;
12
+ storeStateSubscribe: import("../types").StateSubscribeMap;
13
+ storeSubscribeList: import("../types").SubscribeKeysMap;
14
14
  storeChildrenApp: {
15
- [key: string]: import("..").StoreChildrenApp;
15
+ [key: string]: import("../types").StoreChildrenApp;
16
16
  };
17
17
  };
18
18
  }
@@ -75,16 +75,16 @@ export declare class ChildrenApp {
75
75
  pushCycle(data: ChildrenCycle): void;
76
76
  on(): void;
77
77
  un(): void;
78
- get value(): import("..").StoreChildrenApp;
78
+ get value(): import("../types").StoreChildrenApp;
79
79
  }
80
80
  export declare const ProcessorEventAutoClearMap: Map<any, any>;
81
81
  export declare const ProcessorEventUserAutoClearMap: Map<any, any>;
82
82
  export declare const logger: any;
83
83
  export declare const core: {
84
- storeState: import("..").ResponseState;
85
- storeStateSubscribe: import("..").StateSubscribeMap;
86
- storeSubscribeList: import("..").SubscribeKeysMap;
84
+ storeState: import("../types").ResponseState;
85
+ storeStateSubscribe: import("../types").StateSubscribeMap;
86
+ storeSubscribeList: import("../types").SubscribeKeysMap;
87
87
  storeChildrenApp: {
88
- [key: string]: import("..").StoreChildrenApp;
88
+ [key: string]: import("../types").StoreChildrenApp;
89
89
  };
90
90
  };
package/lib/app/store.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import { SinglyLinkedList } from './SinglyLinkedList.js';
2
2
  import { mkdirSync } from 'node:fs';
3
3
  import log4js from 'log4js';
4
+ import { disposeExpose } from './expose.js';
4
5
 
5
6
  const createLogger = () => {
6
7
  if (process.env.BROWSER_ENV === 'browser') {
@@ -424,6 +425,7 @@ class ChildrenApp {
424
425
  bumpStoreVersion();
425
426
  }
426
427
  un() {
428
+ disposeExpose(this.#name);
427
429
  delete alemonjsCore.storeChildrenApp[this.#name];
428
430
  bumpStoreVersion();
429
431
  }
package/lib/index.js CHANGED
@@ -6,13 +6,14 @@ export { cbpClient } from './cbp/connects/client.js';
6
6
  export { cbpPlatform } from './cbp/connects/platform.js';
7
7
  export { cbpServer } from './cbp/server/main.js';
8
8
  export { ChildrenApp, Core, Logger, Middleware, MiddlewareRouter, MiddlewareTree, ProcessorEventAutoClearMap, ProcessorEventUserAutoClearMap, Response, ResponseMiddleware, ResponseRouter, ResponseTree, State, StateSubscribe, SubscribeList, bumpStoreVersion, core, getSubscribeList, logger } from './app/store.js';
9
+ export { Expose, clearAllExpose, disposeExpose, registerExpose } from './app/expose.js';
9
10
  export { loadModels, run } from './app/load_modules/load.js';
10
11
  export { loadChildren, loadChildrenFile } from './app/load_modules/loadChild.js';
11
12
  export { defineChildren } from './app/define-children.js';
12
13
  export { definePlatform } from './app/define-platform.js';
13
14
  export { defineResponse } from './app/define-response.js';
14
15
  export { defineMiddleware } from './app/define-middleware.js';
15
- export { defineRouter, lazy } from './app/define-router.js';
16
+ export { defineRouter, lazy, runHandler } from './app/define-router.js';
16
17
  export { FormatEvent, wrapEvent } from './app/event-format.js';
17
18
  export { onGroup } from './app/event-group.js';
18
19
  export { OnMiddleware, onMiddleware } from './app/event-middleware.js';
@@ -2,6 +2,7 @@ import { ChildrenCycle, Next } from '../cycle';
2
2
  import { ClientAPI } from '../client';
3
3
  import { EventKeys, Events } from './map';
4
4
  import { DataEnums } from '../message';
5
+ import { Expose } from '../../app/expose';
5
6
  export type Current<T extends EventKeys> = (event: Events[T], next: Next) => Promise<boolean | void | undefined> | boolean | void | undefined;
6
7
  export type OnResponseValue<C, T extends EventKeys> = {
7
8
  current: C;
@@ -54,6 +55,7 @@ export type childrenCallbackRes = {
54
55
  middleware?: ReturnType<defineMiddlewareFunc>;
55
56
  responseRouter?: ReturnType<DefineRouterFunc>;
56
57
  middlewareRouter?: ReturnType<DefineRouterFunc>;
58
+ expose?: Expose;
57
59
  } | undefined;
58
60
  export type childrenCallback = ChildrenCycle & {
59
61
  register?: () => (childrenCallbackRes | undefined) | Promise<childrenCallbackRes | undefined>;
@@ -0,0 +1,41 @@
1
+ export interface ExposeActionMeta {
2
+ description: string;
3
+ params?: Record<string, string>;
4
+ returns?: Record<string, string>;
5
+ handler: (...args: any[]) => any;
6
+ }
7
+ export interface ExposeProvideConfig {
8
+ name: string;
9
+ description: string;
10
+ actions: Record<string, ExposeActionMeta>;
11
+ }
12
+ export interface ExposeListItem {
13
+ name: string;
14
+ protocol: string;
15
+ description: string;
16
+ actions: Record<string, {
17
+ description: string;
18
+ params?: Record<string, string>;
19
+ returns?: Record<string, string>;
20
+ }>;
21
+ invoke: (action: string, value?: any) => any;
22
+ }
23
+ export interface ExposeWatchEvent {
24
+ name: string;
25
+ protocol: string;
26
+ action: string;
27
+ value?: any;
28
+ }
29
+ export interface ExposeSchemaItem {
30
+ protocol: string;
31
+ description: string;
32
+ providers: {
33
+ name: string;
34
+ }[];
35
+ actions: Record<string, {
36
+ description: string;
37
+ params?: Record<string, string>;
38
+ returns?: Record<string, string>;
39
+ }>;
40
+ invoke: string;
41
+ }
@@ -0,0 +1 @@
1
+
@@ -23,6 +23,7 @@ export * from './message/index';
23
23
  export * from './package/index';
24
24
  export * from './state/index';
25
25
  export * from './store/res';
26
+ export * from './expose/index';
26
27
  export * from './subscribe';
27
28
  export * from './standard';
28
29
  export * from './actions';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "alemonjs",
3
- "version": "2.1.53",
3
+ "version": "2.1.54",
4
4
  "description": "bot script",
5
5
  "author": "lemonade",
6
6
  "license": "MIT",