@talex-touch/utils 1.0.18 → 1.0.20
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/channel/index.ts +49 -1
- package/common/index.ts +2 -0
- package/common/search/gather.ts +45 -0
- package/common/search/index.ts +67 -0
- package/common/storage/constants.ts +16 -2
- package/common/storage/entity/index.ts +2 -1
- package/common/storage/entity/openers.ts +32 -0
- package/common/storage/entity/shortcut-settings.ts +22 -0
- package/common/storage/shortcut-storage.ts +58 -0
- package/common/utils/file.ts +62 -0
- package/common/{utils.ts → utils/index.ts} +14 -2
- package/common/utils/polling.ts +184 -0
- package/common/utils/task-queue.ts +108 -0
- package/common/utils/time.ts +374 -0
- package/core-box/README.md +8 -8
- package/core-box/builder/index.ts +6 -0
- package/core-box/builder/tuff-builder.example.ts.bak +258 -0
- package/core-box/builder/tuff-builder.ts +1162 -0
- package/core-box/index.ts +5 -2
- package/core-box/run-tests.sh +7 -0
- package/core-box/search.ts +1 -536
- package/core-box/tuff/index.ts +6 -0
- package/core-box/tuff/tuff-dsl.ts +1412 -0
- package/electron/clipboard-helper.ts +199 -0
- package/electron/env-tool.ts +36 -2
- package/electron/file-parsers/index.ts +8 -0
- package/electron/file-parsers/parsers/text-parser.ts +109 -0
- package/electron/file-parsers/registry.ts +92 -0
- package/electron/file-parsers/types.ts +58 -0
- package/electron/index.ts +3 -0
- package/eventbus/index.ts +0 -7
- package/index.ts +3 -1
- package/package.json +4 -29
- package/plugin/channel.ts +48 -16
- package/plugin/index.ts +194 -30
- package/plugin/log/types.ts +11 -0
- package/plugin/node/index.ts +4 -0
- package/plugin/node/logger-manager.ts +113 -0
- package/plugin/{log → node}/logger.ts +41 -7
- package/plugin/plugin-source.ts +74 -0
- package/plugin/preload.ts +5 -15
- package/plugin/providers/index.ts +2 -0
- package/plugin/providers/registry.ts +47 -0
- package/plugin/providers/types.ts +54 -0
- package/plugin/risk/index.ts +1 -0
- package/plugin/risk/types.ts +20 -0
- package/plugin/sdk/enum/bridge-event.ts +4 -0
- package/plugin/sdk/enum/index.ts +1 -0
- package/plugin/sdk/hooks/bridge.ts +68 -0
- package/plugin/sdk/hooks/index.ts +2 -1
- package/plugin/sdk/hooks/life-cycle.ts +2 -4
- package/plugin/sdk/index.ts +2 -0
- package/plugin/sdk/storage.ts +84 -0
- package/plugin/sdk/types.ts +2 -2
- package/plugin/sdk/window/index.ts +5 -3
- package/preload/index.ts +2 -0
- package/preload/loading.ts +15 -0
- package/preload/renderer.ts +41 -0
- package/renderer/hooks/arg-mapper.ts +79 -0
- package/renderer/hooks/index.ts +2 -0
- package/renderer/hooks/initialize.ts +198 -0
- package/renderer/index.ts +3 -0
- package/renderer/storage/app-settings.ts +2 -0
- package/renderer/storage/base-storage.ts +1 -0
- package/renderer/storage/openers.ts +11 -0
- package/renderer/touch-sdk/env.ts +106 -0
- package/renderer/touch-sdk/index.ts +108 -0
- package/renderer/touch-sdk/terminal.ts +85 -0
- package/renderer/touch-sdk/utils.ts +61 -0
- package/search/levenshtein-utils.ts +39 -0
- package/search/types.ts +16 -16
- package/types/index.ts +2 -1
- package/types/modules/base.ts +146 -0
- package/types/modules/index.ts +4 -0
- package/types/modules/module-lifecycle.ts +148 -0
- package/types/modules/module-manager.ts +99 -0
- package/types/modules/module.ts +112 -0
- package/types/touch-app-core.ts +16 -93
- package/core-box/types.ts +0 -384
- package/plugin/log/logger-manager.ts +0 -60
package/search/types.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* @fileoverview Search Types and Utilities
|
|
3
3
|
*
|
|
4
4
|
* This module provides comprehensive type definitions and utility functions
|
|
5
|
-
* for search result items across the
|
|
5
|
+
* for search result items across the Tuff application. It defines
|
|
6
6
|
* the core interfaces and factory functions used by the search system,
|
|
7
7
|
* plugins, and UI components.
|
|
8
8
|
*
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
* - {@link IDataItem} - Extended interface for data processing results
|
|
12
12
|
* - {@link createDataItem} - Factory function for creating data items
|
|
13
13
|
*
|
|
14
|
-
* @author
|
|
14
|
+
* @author Tuff Team
|
|
15
15
|
* @since 1.0.0
|
|
16
16
|
* @version 1.0.0
|
|
17
17
|
*/
|
|
@@ -399,7 +399,7 @@ export interface IDataItem extends ISearchItem {
|
|
|
399
399
|
*/
|
|
400
400
|
export enum SearchMode {
|
|
401
401
|
INPUT = 'INPUT',
|
|
402
|
-
COMMAND = 'COMMAND',
|
|
402
|
+
COMMAND = 'COMMAND',
|
|
403
403
|
IMAGE = 'IMAGE',
|
|
404
404
|
FILE = 'FILE',
|
|
405
405
|
FEATURE = 'FEATURE'
|
|
@@ -411,13 +411,13 @@ export enum SearchMode {
|
|
|
411
411
|
export interface ISearchOptions {
|
|
412
412
|
/** 搜索模式 */
|
|
413
413
|
mode: SearchMode;
|
|
414
|
-
|
|
414
|
+
|
|
415
415
|
/** 最大结果数量 */
|
|
416
416
|
maxResults?: number;
|
|
417
|
-
|
|
417
|
+
|
|
418
418
|
/** 是否启用模糊匹配 */
|
|
419
419
|
fuzzyMatch?: boolean;
|
|
420
|
-
|
|
420
|
+
|
|
421
421
|
/** 搜索超时时间(毫秒) */
|
|
422
422
|
timeout?: number;
|
|
423
423
|
}
|
|
@@ -428,19 +428,19 @@ export interface ISearchOptions {
|
|
|
428
428
|
export interface IPluginSearchResult {
|
|
429
429
|
/** 插件名称 */
|
|
430
430
|
pluginName: string;
|
|
431
|
-
|
|
431
|
+
|
|
432
432
|
/** 搜索结果列表 */
|
|
433
433
|
items: ISearchItem[];
|
|
434
|
-
|
|
434
|
+
|
|
435
435
|
/** 推送时间戳 */
|
|
436
436
|
timestamp: number;
|
|
437
|
-
|
|
437
|
+
|
|
438
438
|
/** 查询关键词 */
|
|
439
439
|
query: string;
|
|
440
|
-
|
|
440
|
+
|
|
441
441
|
/** 结果总数 */
|
|
442
442
|
total: number;
|
|
443
|
-
|
|
443
|
+
|
|
444
444
|
/** 是否有更多结果 */
|
|
445
445
|
hasMore?: boolean;
|
|
446
446
|
}
|
|
@@ -451,19 +451,19 @@ export interface IPluginSearchResult {
|
|
|
451
451
|
export interface ISearchResultManager {
|
|
452
452
|
/** 推送搜索结果 */
|
|
453
453
|
pushItems(items: ISearchItem[]): void;
|
|
454
|
-
|
|
454
|
+
|
|
455
455
|
/** 清空搜索结果 */
|
|
456
456
|
clearItems(): void;
|
|
457
|
-
|
|
457
|
+
|
|
458
458
|
/** 获取当前搜索结果 */
|
|
459
459
|
getItems(): ISearchItem[];
|
|
460
|
-
|
|
460
|
+
|
|
461
461
|
/** 更新单个搜索结果 */
|
|
462
462
|
updateItem(id: string, item: Partial<ISearchItem>): boolean;
|
|
463
|
-
|
|
463
|
+
|
|
464
464
|
/** 删除单个搜索结果 */
|
|
465
465
|
removeItem(id: string): boolean;
|
|
466
|
-
|
|
466
|
+
|
|
467
467
|
/** 获取结果数量 */
|
|
468
468
|
getCount(): number;
|
|
469
469
|
}
|
package/types/index.ts
CHANGED
|
@@ -1 +1,2 @@
|
|
|
1
|
-
export * from './touch-app-core'
|
|
1
|
+
export * from './touch-app-core'
|
|
2
|
+
export * from './modules'
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unique key for a module.
|
|
3
|
+
* @public
|
|
4
|
+
*/
|
|
5
|
+
export type ModuleKey = symbol;
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Utility type representing a synchronous or asynchronous value.
|
|
9
|
+
* @public
|
|
10
|
+
*/
|
|
11
|
+
export type MaybePromise<T> = T | Promise<T>;
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Declarative file/directory configuration for a module (input).
|
|
15
|
+
*
|
|
16
|
+
* @remarks
|
|
17
|
+
* - **Single-directory rule**: Each module can own at most **one** directory.
|
|
18
|
+
* - If `create` is `false` (or omitted), the manager will not create a directory for the module.
|
|
19
|
+
* - If `create` is `true`, the directory name will default to a name derived from the module key/name,
|
|
20
|
+
* but can be overridden with `dirName` (e.g., use `"clipboard"` instead of `"ClipBoardModule"`).
|
|
21
|
+
* - `root` specifies the absolute root path under which the module directory will be created.
|
|
22
|
+
* If omitted, the manager can fall back to an application default (e.g., `app.modulesRoot`).
|
|
23
|
+
*
|
|
24
|
+
* This configuration is typically provided by the module author or the application at registration time.
|
|
25
|
+
*
|
|
26
|
+
* @public
|
|
27
|
+
*/
|
|
28
|
+
export interface ModuleFileConfig {
|
|
29
|
+
/**
|
|
30
|
+
* Whether to create a dedicated directory for this module.
|
|
31
|
+
*
|
|
32
|
+
* @defaultValue false
|
|
33
|
+
*/
|
|
34
|
+
create?: boolean;
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Optional custom directory name (basename only, no slashes).
|
|
38
|
+
*
|
|
39
|
+
* @example "clipboard"
|
|
40
|
+
*/
|
|
41
|
+
dirName?: string;
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Optional absolute root path under which the module directory will be created.
|
|
45
|
+
*
|
|
46
|
+
* @example "/var/app/modules"
|
|
47
|
+
*/
|
|
48
|
+
root?: string;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Resolved and normalized file/directory configuration for a module (output).
|
|
53
|
+
*
|
|
54
|
+
* @remarks
|
|
55
|
+
* Produced by the manager during module loading. It captures the final decision:
|
|
56
|
+
* - whether a directory will exist for the module (`create`)
|
|
57
|
+
* - the final directory name (`dirName`) if created
|
|
58
|
+
* - the final absolute directory path (`dirPath`) if created
|
|
59
|
+
*
|
|
60
|
+
* If the module does not own a directory (i.e., `create === false`), both `dirName` and `dirPath`
|
|
61
|
+
* will be `undefined`.
|
|
62
|
+
*
|
|
63
|
+
* @public
|
|
64
|
+
*/
|
|
65
|
+
export interface ResolvedModuleFileConfig {
|
|
66
|
+
/**
|
|
67
|
+
* Final boolean indicating if the module has a dedicated directory.
|
|
68
|
+
*/
|
|
69
|
+
create: boolean;
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Final directory name (basename), if a directory is created.
|
|
73
|
+
*/
|
|
74
|
+
dirName?: string;
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Final absolute path to the module directory, if a directory is created.
|
|
78
|
+
*/
|
|
79
|
+
dirPath?: string;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Lightweight abstraction over a module-owned directory.
|
|
84
|
+
*
|
|
85
|
+
* @remarks
|
|
86
|
+
* - **Single-directory rule**: A module can have **at most one** directory. If the module isn't configured
|
|
87
|
+
* to create/own a directory, the `directory` field in lifecycle contexts will be `undefined`.
|
|
88
|
+
* - Implementations can be backed by Node.js `fs`, a virtual filesystem, or any storage adapter.
|
|
89
|
+
*
|
|
90
|
+
* @public
|
|
91
|
+
*/
|
|
92
|
+
export interface ModuleDirectory {
|
|
93
|
+
/**
|
|
94
|
+
* Absolute path to the module directory.
|
|
95
|
+
*/
|
|
96
|
+
readonly path: string;
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Joins one or more path segments to the module directory path. Does not touch the filesystem.
|
|
100
|
+
*
|
|
101
|
+
* @param segments - One or more relative path segments.
|
|
102
|
+
* @returns The combined absolute path string.
|
|
103
|
+
*/
|
|
104
|
+
join(...segments: string[]): string;
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Ensures the directory exists, creating it if necessary.
|
|
108
|
+
*/
|
|
109
|
+
ensure(): MaybePromise<void>;
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Checks whether the directory exists.
|
|
113
|
+
*/
|
|
114
|
+
exists(): MaybePromise<boolean>;
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Lists entries in the directory (filenames/subdirectory names).
|
|
118
|
+
*
|
|
119
|
+
* @returns An array of entry names (not absolute paths).
|
|
120
|
+
*/
|
|
121
|
+
list(): MaybePromise<string[]>;
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Reads a file within the module directory.
|
|
125
|
+
*
|
|
126
|
+
* @param relativePath - Path relative to the module directory.
|
|
127
|
+
* @returns File contents as a Buffer or string (implementation-dependent).
|
|
128
|
+
*/
|
|
129
|
+
readFile(relativePath: string): MaybePromise<Buffer | string>;
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Writes a file within the module directory, creating parent folders if needed.
|
|
133
|
+
*
|
|
134
|
+
* @param relativePath - Path relative to the module directory.
|
|
135
|
+
* @param data - File content.
|
|
136
|
+
*/
|
|
137
|
+
writeFile(relativePath: string, data: string | Uint8Array): MaybePromise<void>;
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Removes a file or subdirectory within the module directory.
|
|
141
|
+
*
|
|
142
|
+
* @param relativePath - Path relative to the module directory. If omitted, implementations
|
|
143
|
+
* may remove the entire directory (use with caution).
|
|
144
|
+
*/
|
|
145
|
+
remove(relativePath?: string): MaybePromise<void>;
|
|
146
|
+
}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import { ITouchEventBus } from "packages/utils/eventbus";
|
|
2
|
+
import { ModuleKey } from ".";
|
|
3
|
+
import { TalexTouch } from "../touch-app-core";
|
|
4
|
+
import { ModuleDirectory, ResolvedModuleFileConfig } from "./base";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Base context available to all lifecycle phases.
|
|
8
|
+
*
|
|
9
|
+
* @typeParam E - Event map type for the touch event bus.
|
|
10
|
+
* @public
|
|
11
|
+
*/
|
|
12
|
+
export interface ModuleBaseContext<E> {
|
|
13
|
+
/**
|
|
14
|
+
* The application root object (TalexTouch).
|
|
15
|
+
*/
|
|
16
|
+
app: TalexTouch.TouchApp;
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* The module manager controlling creation, lifecycle, and lookup.
|
|
20
|
+
*/
|
|
21
|
+
manager: TalexTouch.IModuleManager<E>;
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* The unique key for the current module (same as the module's `name`).
|
|
25
|
+
*/
|
|
26
|
+
moduleKey: ModuleKey;
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Optional configuration accessor bound to the application or module.
|
|
30
|
+
*
|
|
31
|
+
* @param key - Configuration key.
|
|
32
|
+
* @returns The typed configuration value.
|
|
33
|
+
*/
|
|
34
|
+
config?<T = unknown>(key: string): T;
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Optional event bus bound to the application or module layer.
|
|
38
|
+
*/
|
|
39
|
+
events?: ITouchEventBus<E>;
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* The module's directory instance if a directory was created; otherwise `undefined`.
|
|
43
|
+
*
|
|
44
|
+
* @remarks
|
|
45
|
+
* **Single-directory rule**: Each module can expose at most one `ModuleDirectory` instance here.
|
|
46
|
+
*/
|
|
47
|
+
directory?: ModuleDirectory;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Context for the "create" phase (around instantiation and initial wiring).
|
|
52
|
+
*
|
|
53
|
+
* @typeParam E - Event map type for the touch event bus.
|
|
54
|
+
* @public
|
|
55
|
+
*/
|
|
56
|
+
export interface ModuleCreateContext<E> extends ModuleBaseContext<E> {
|
|
57
|
+
/**
|
|
58
|
+
* Resolved file/directory configuration for the module.
|
|
59
|
+
*/
|
|
60
|
+
file: ResolvedModuleFileConfig;
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Fully resolved module entry file path if a custom path was provided,
|
|
64
|
+
* or a default path computed by the manager; otherwise `undefined`.
|
|
65
|
+
*/
|
|
66
|
+
resolvedPath?: string;
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Indicates whether this load is part of a hot-reload/replace cycle.
|
|
70
|
+
*/
|
|
71
|
+
hot?: boolean;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Context for the "init" phase (resource preparation, subscriptions, scaffolding).
|
|
76
|
+
*
|
|
77
|
+
* @typeParam E - Event map type for the touch event bus.
|
|
78
|
+
* @public
|
|
79
|
+
*/
|
|
80
|
+
export interface ModuleInitContext<E> extends ModuleBaseContext<E> {
|
|
81
|
+
/**
|
|
82
|
+
* Optional hint that dependencies have been verified and are ready.
|
|
83
|
+
*/
|
|
84
|
+
depsReady?: boolean;
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Resolved file/directory configuration for the module.
|
|
88
|
+
*/
|
|
89
|
+
file: ResolvedModuleFileConfig;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Context for the "start" phase (module enters active/working state).
|
|
94
|
+
*
|
|
95
|
+
* @typeParam E - Event map type for the touch event bus.
|
|
96
|
+
* @public
|
|
97
|
+
*/
|
|
98
|
+
export interface ModuleStartContext<E> extends ModuleBaseContext<E> {
|
|
99
|
+
/**
|
|
100
|
+
* Optional startup arguments or mode flags.
|
|
101
|
+
*/
|
|
102
|
+
startArgs?: Record<string, unknown>;
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Resolved file/directory configuration for the module.
|
|
106
|
+
*/
|
|
107
|
+
file: ResolvedModuleFileConfig;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Context for the "stop" phase (module leaves the active/working state).
|
|
112
|
+
*
|
|
113
|
+
* @typeParam E - Event map type for the touch event bus.
|
|
114
|
+
* @public
|
|
115
|
+
*/
|
|
116
|
+
export interface ModuleStopContext<E> extends ModuleBaseContext<E> {
|
|
117
|
+
/**
|
|
118
|
+
* Reason for stopping. Useful for telemetry and cleanup branching.
|
|
119
|
+
* - `"normal"`: Voluntary shutdown or planned stop.
|
|
120
|
+
* - `"error"`: Unhandled error or fault.
|
|
121
|
+
* - `"hot-reload"`: Stop as part of a hot reload / replacement cycle.
|
|
122
|
+
* - `string`: Custom reason.
|
|
123
|
+
*/
|
|
124
|
+
reason?: "normal" | "error" | "hot-reload" | string;
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Resolved file/directory configuration for the module.
|
|
128
|
+
*/
|
|
129
|
+
file: ResolvedModuleFileConfig;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Context for the "destroy" phase (final teardown and resource release).
|
|
134
|
+
*
|
|
135
|
+
* @typeParam E - Event map type for the touch event bus.
|
|
136
|
+
* @public
|
|
137
|
+
*/
|
|
138
|
+
export interface ModuleDestroyContext<E> extends ModuleBaseContext<E> {
|
|
139
|
+
/**
|
|
140
|
+
* Indicates the module is being destroyed as part of application shutdown.
|
|
141
|
+
*/
|
|
142
|
+
appClosing?: boolean;
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Resolved file/directory configuration for the module.
|
|
146
|
+
*/
|
|
147
|
+
file: ResolvedModuleFileConfig;
|
|
148
|
+
}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { MaybePromise, ModuleDirectory, ModuleFileConfig, ModuleKey, ResolvedModuleFileConfig } from "./base";
|
|
2
|
+
import { IBaseModule, ModuleCtor, ModuleRegistrant } from "./module";
|
|
3
|
+
import { ModuleStopContext } from "./module-lifecycle";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Interface of the Module Manager.
|
|
7
|
+
*
|
|
8
|
+
* @typeParam E - Event map type used by the application's touch event bus.
|
|
9
|
+
* @remarks
|
|
10
|
+
* The manager is responsible for:
|
|
11
|
+
* - Registering modules (singletons), constructing instances when given a class.
|
|
12
|
+
* - Resolving {@link ModuleFileConfig} into a concrete {@link ResolvedModuleFileConfig} and, if requested,
|
|
13
|
+
* provisioning a single {@link ModuleDirectory} per module.
|
|
14
|
+
* - Driving lifecycle: `created?` → `init` → `start?` → `stop?` → `destroy`.
|
|
15
|
+
* - Providing lookup utilities (by key or, optionally, by constructor).
|
|
16
|
+
*
|
|
17
|
+
* @public
|
|
18
|
+
*/
|
|
19
|
+
export interface IBaseModuleManager<E = any> {
|
|
20
|
+
/**
|
|
21
|
+
* Registers and loads a module (instance or class).
|
|
22
|
+
*
|
|
23
|
+
* @typeParam T - Concrete module type.
|
|
24
|
+
* @param module - Either a prebuilt module instance or a class constructor.
|
|
25
|
+
* @returns `true` on success, `false` on no-op/failure (sync or async).
|
|
26
|
+
*
|
|
27
|
+
* @remarks
|
|
28
|
+
* - If a constructor is provided, the manager:
|
|
29
|
+
* 1) Builds a `ModuleCreateContext` (including resolved file config and optionally a directory).
|
|
30
|
+
* 2) Calls `new (createCtx)` to construct the module.
|
|
31
|
+
* 3) Invokes `created?()` (if present), then `init()`, then `start?()`.
|
|
32
|
+
* - If an instance is provided, step (2) is skipped; the same lifecycle calls apply.
|
|
33
|
+
* - The manager must preserve **singleton semantics** per {@link ModuleKey}.
|
|
34
|
+
*/
|
|
35
|
+
loadModule<T extends IBaseModule<E>>(module: ModuleRegistrant<T, E>): boolean | Promise<boolean>;
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Unloads a module by key.
|
|
39
|
+
*
|
|
40
|
+
* @param moduleKey - The unique key of the module to unload.
|
|
41
|
+
* @param reason - Optional stop reason, forwarded to the stop context.
|
|
42
|
+
* @returns `true` on success, `false` if not found or failed (sync or async).
|
|
43
|
+
*
|
|
44
|
+
* @remarks
|
|
45
|
+
* The manager should invoke `stop?()` (with a `ModuleStopContext`) followed by `destroy()`
|
|
46
|
+
* (with a `ModuleDestroyContext`), then remove the singleton instance.
|
|
47
|
+
*/
|
|
48
|
+
unloadModule(moduleKey: ModuleKey, reason?: ModuleStopContext<E>["reason"]): boolean | Promise<boolean>;
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Retrieves a module instance by key.
|
|
52
|
+
*
|
|
53
|
+
* @typeParam T - Expected module type.
|
|
54
|
+
* @param moduleKey - The unique key of the module.
|
|
55
|
+
* @returns The module instance if loaded; otherwise `undefined`.
|
|
56
|
+
*/
|
|
57
|
+
getModule<T extends IBaseModule<E> = IBaseModule<E>>(moduleKey: ModuleKey): T | undefined;
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Optional class-based getter for stronger typing.
|
|
61
|
+
*
|
|
62
|
+
* @typeParam T - Concrete module type.
|
|
63
|
+
* @param ctor - The module class used at registration time (or a class with the same static `key`).
|
|
64
|
+
* @returns The module instance if loaded; otherwise `undefined`.
|
|
65
|
+
*/
|
|
66
|
+
get<T extends IBaseModule<E>>(ctor: ModuleCtor<T, E>): T | undefined;
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Returns whether a module is currently loaded.
|
|
70
|
+
*/
|
|
71
|
+
hasModule(moduleKey: ModuleKey): boolean;
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Lists keys of all currently loaded modules.
|
|
75
|
+
*/
|
|
76
|
+
listModules(): readonly ModuleKey[];
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Optional helper interface some managers expose to centralize directory creation.
|
|
81
|
+
*
|
|
82
|
+
* @remarks
|
|
83
|
+
* This can be useful if module authors want to compute file paths before the module
|
|
84
|
+
* is actually loaded, or for tooling and diagnostics. Implementation is up to you.
|
|
85
|
+
*
|
|
86
|
+
* @public
|
|
87
|
+
*/
|
|
88
|
+
export interface IModuleDirectoryService {
|
|
89
|
+
/**
|
|
90
|
+
* Resolves a {@link ModuleFileConfig} to {@link ResolvedModuleFileConfig} without creating anything.
|
|
91
|
+
*/
|
|
92
|
+
resolve(moduleKey: ModuleKey, input?: ModuleFileConfig): ResolvedModuleFileConfig;
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Creates (or returns) the single {@link ModuleDirectory} for a module if configured to `create: true`.
|
|
96
|
+
* If `create !== true`, implementations should return `undefined`.
|
|
97
|
+
*/
|
|
98
|
+
ensure(moduleKey: ModuleKey, input?: ModuleFileConfig): MaybePromise<ModuleDirectory | undefined>;
|
|
99
|
+
}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { MaybePromise, ModuleFileConfig, ModuleKey } from "./base";
|
|
2
|
+
import { ModuleCreateContext, ModuleDestroyContext, ModuleInitContext, ModuleStartContext, ModuleStopContext } from "./module-lifecycle";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Contract that every module must implement.
|
|
6
|
+
*
|
|
7
|
+
* @typeParam E - Event map type used by the application's touch event bus.
|
|
8
|
+
* @remarks
|
|
9
|
+
* - A module is identified by a unique {@link ModuleKey} stored in {@link IModule.name}.
|
|
10
|
+
* - Each module may own **at most one** directory. Use {@link IModule.file} to declare
|
|
11
|
+
* if/where a directory should be created. If no directory is created, contexts will expose
|
|
12
|
+
* `directory: undefined`.
|
|
13
|
+
* - Lifecycle methods receive **phase-specific contexts** so that modules can access
|
|
14
|
+
* the manager, app, configuration, event bus, and (if any) the directory instance.
|
|
15
|
+
*
|
|
16
|
+
* @public
|
|
17
|
+
*/
|
|
18
|
+
export interface IBaseModule<E = any> {
|
|
19
|
+
/**
|
|
20
|
+
* Unique module key. Prefer `Symbol.for("your-module")` for global uniqueness.
|
|
21
|
+
*/
|
|
22
|
+
name: ModuleKey;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Optional custom module entry file path.
|
|
26
|
+
*
|
|
27
|
+
* @remarks
|
|
28
|
+
* If omitted, the manager can resolve a default location (e.g., inside the module's directory
|
|
29
|
+
* when one exists, or from an app-level modules root).
|
|
30
|
+
*/
|
|
31
|
+
filePath?: string;
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Declarative directory configuration for this module.
|
|
35
|
+
*
|
|
36
|
+
* @remarks
|
|
37
|
+
* - If `file.create === true`, the manager will compute a final directory name/path and
|
|
38
|
+
* expose a `ModuleDirectory` on all lifecycle contexts.
|
|
39
|
+
* - If `file.create !== true`, no directory will be created and `context.directory` will be `undefined`.
|
|
40
|
+
*/
|
|
41
|
+
file?: ModuleFileConfig;
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Optional hook invoked after construction/registration and before `init`.
|
|
45
|
+
* Use this for last-moment wiring that depends on resolved paths or file config.
|
|
46
|
+
*/
|
|
47
|
+
created?(ctx: ModuleCreateContext<E>): MaybePromise<void>;
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Called to perform resource preparation and subscription wiring.
|
|
51
|
+
*/
|
|
52
|
+
init(ctx: ModuleInitContext<E>): MaybePromise<void>;
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Called when the module should start its active work.
|
|
56
|
+
*/
|
|
57
|
+
start?(ctx: ModuleStartContext<E>): MaybePromise<void>;
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Called when the module should leave the active state but may still keep allocated resources.
|
|
61
|
+
*/
|
|
62
|
+
stop?(ctx: ModuleStopContext<E>): MaybePromise<void>;
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Called to perform final teardown and resource release.
|
|
66
|
+
*/
|
|
67
|
+
destroy(ctx: ModuleDestroyContext<E>): MaybePromise<void>;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Class-based module constructor signature (for OOP-style modules).
|
|
72
|
+
*
|
|
73
|
+
* @typeParam T - Concrete module type produced by this constructor.
|
|
74
|
+
* @typeParam E - Event map type used by the application's touch event bus.
|
|
75
|
+
* @remarks
|
|
76
|
+
* - The constructor receives a **create-phase** context so a class can read resolved paths
|
|
77
|
+
* or the computed directory before `created()` and `init()` run.
|
|
78
|
+
* - You may optionally expose `key` and `requires` as static metadata if you plan to add
|
|
79
|
+
* declarative dependency ordering later.
|
|
80
|
+
*
|
|
81
|
+
* @public
|
|
82
|
+
*/
|
|
83
|
+
export interface ModuleCtor<T extends IBaseModule<E>, E = any> {
|
|
84
|
+
new (ctx: ModuleCreateContext<E>): T;
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Optional class-level unique key.
|
|
88
|
+
* If omitted, the instance {@link IModule.name | name} must be used as the key.
|
|
89
|
+
*/
|
|
90
|
+
readonly key?: ModuleKey;
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Optional declarative dependencies expressed as other module keys.
|
|
94
|
+
* Useful if the manager performs topological ordering.
|
|
95
|
+
*/
|
|
96
|
+
readonly requires?: readonly ModuleKey[];
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Registration input accepted by the manager.
|
|
101
|
+
*
|
|
102
|
+
* @typeParam T - Concrete module type.
|
|
103
|
+
* @typeParam E - Event map type used by the application's touch event bus.
|
|
104
|
+
* @remarks
|
|
105
|
+
* - You can register either an already-built instance or a class constructor.
|
|
106
|
+
* - When a constructor is provided, the manager will call `new (createCtx)` to construct the instance.
|
|
107
|
+
*
|
|
108
|
+
* @public
|
|
109
|
+
*/
|
|
110
|
+
export type ModuleRegistrant<T extends IBaseModule<E>, E = any> =
|
|
111
|
+
| T
|
|
112
|
+
| ModuleCtor<T, E>;
|