@cjhd/cj-event-emitter 1.0.0 → 1.1.2

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.
@@ -0,0 +1,13 @@
1
+ {
2
+ "schema": "cj-package-v1",
3
+ "name": "@cjhd/cj-event-emitter",
4
+ "version": "1.1.2",
5
+ "payloadManifest": "encrypted-payload/manifest.json",
6
+ "entry": "index.js",
7
+ "assetsDir": "assets",
8
+ "generatedFiles": [
9
+ "assets/EventEmitter.js",
10
+ "index.js"
11
+ ],
12
+ "dependencies": []
13
+ }
@@ -0,0 +1,34 @@
1
+ /***********************************************************************
2
+ * EventEmitter.ts —— 轻量级全局事件管理器(支持 ctx 精确解绑 & targetOff)
3
+ *
4
+ * 修复点:
5
+ * - on / once 阶段拦截非函数 listener,避免 emit 阶段出现 fn.apply undefined。
6
+ * - emit 阶段二次防御并清理脏监听,不改变合法监听的执行语义。
7
+ * - off(type) 支持清空该事件全部监听,兼容常见 EventEmitter 用法。
8
+ ***********************************************************************/
9
+ type EventType = string | number | symbol;
10
+ export type AnyListener = (...args: any[]) => unknown;
11
+ export declare class EventEmitter {
12
+ /** Map<事件类型, Set<ListenerItem>> */
13
+ private readonly _map;
14
+ on(type: EventType, fn: AnyListener, ctx?: any): void;
15
+ once(type: EventType, fn: AnyListener, ctx?: any): void;
16
+ /**
17
+ * 取消指定回调
18
+ * - off(type):取消该事件全部监听
19
+ * - off(type, fn):取消所有同名函数
20
+ * - off(type, fn, ctx):仅取消 (fn, ctx) 组合
21
+ */
22
+ off(type: EventType, fn?: AnyListener, ctx?: any): void;
23
+ /**
24
+ * 根据 ctx 移除当前 EventEmitter 上的所有监听
25
+ * 等同于 Cocos EventTarget.targetOff
26
+ */
27
+ targetOff(ctx: any): void;
28
+ /**
29
+ * 取消某事件全部监听;不传 type ⇒ 清空所有事件
30
+ */
31
+ offAll(type?: EventType): void;
32
+ emit(type: EventType, ...args: any[]): void;
33
+ }
34
+ export {};
@@ -0,0 +1,6 @@
1
+ function __cjLicenseError() {
2
+ throw new Error("[CJHD License] Runtime package is not unlocked. Expected license file: extensions/pkg/node_modules/@cjhd/cj-cocos-license/bin/cj-runtime-license.json. Then run: node extensions/pkg/node_modules/@cjhd/cj-cocos-license/bin/cj-license.js --mode install --force");
3
+ }
4
+
5
+ export class EventEmitter { constructor() { __cjLicenseError(); } }
6
+ export function __cj_package_not_unlocked__() { __cjLicenseError(); }
@@ -0,0 +1,32 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import childProcess from 'node:child_process';
4
+ import { fileURLToPath } from 'node:url';
5
+
6
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
7
+ const packageRoot = path.resolve(__dirname, '..');
8
+ const cjhdRoot = path.dirname(packageRoot);
9
+ const pkgRoot = path.resolve(cjhdRoot, '../..');
10
+ const cli = path.join(cjhdRoot, 'cj-cocos-license', 'bin', 'cj-license.js');
11
+
12
+ if (!fs.existsSync(cli)) {
13
+ console.warn('[CJHD License] @cjhd/cj-cocos-license is not installed; keeping unauthorized stubs.');
14
+ process.exit(0);
15
+ }
16
+
17
+ const result = childProcess.spawnSync(process.execPath, [
18
+ cli,
19
+ '--mode',
20
+ 'install',
21
+ '--soft',
22
+ '--pkg-root',
23
+ pkgRoot
24
+ ], {
25
+ cwd: pkgRoot,
26
+ stdio: 'inherit',
27
+ shell: false
28
+ });
29
+
30
+ if (result.status !== 0) {
31
+ console.warn('[CJHD License] install unlock check did not complete; keeping unauthorized stubs.');
32
+ }
@@ -0,0 +1,29 @@
1
+ {
2
+ "schema": "cj-encrypted-payload-v1",
3
+ "packageName": "@cjhd/cj-event-emitter",
4
+ "packageVersion": "1.1.2",
5
+ "algorithm": "AES-256-GCM",
6
+ "kdf": "HKDF-SHA256",
7
+ "sourceHash": "129d209fe3d626f9a33f9216f6b24379cbbabdb908e47ee39e52b83229db23f9",
8
+ "payloadHash": "ecd16fc90841f80044abe4015b6747ca885630de24ebd5f31fb3dd9949195b2f",
9
+ "files": [
10
+ {
11
+ "out": "assets/EventEmitter.js",
12
+ "bin": "files/assets__EventEmitter.js.bin",
13
+ "iv": "P5DYctQ0GGurRdvi",
14
+ "authTag": "VfHs22dc8x1hfIYmhyUPBA==",
15
+ "sha256": "9158b2e2f5ed0e5a7cec070510d483cbf0d7e9ec1e0c88ea216662f0710d5186"
16
+ },
17
+ {
18
+ "out": "index.js",
19
+ "bin": "files/index.js.bin",
20
+ "iv": "AebTV57yPFrNgIyJ",
21
+ "authTag": "NMZYANeFvh6MRuqScDm8hw==",
22
+ "sha256": "4742c8af69dcde9e83eeedd2dbcbe2fe5d51881cc201eeb3bc6b5c59750df402"
23
+ }
24
+ ],
25
+ "publicExports": [
26
+ "EventEmitter"
27
+ ],
28
+ "createdAt": "2026-05-20T02:39:03.265Z"
29
+ }
package/index.d.ts ADDED
@@ -0,0 +1 @@
1
+ export { EventEmitter } from './assets/EventEmitter';
package/index.js ADDED
@@ -0,0 +1,6 @@
1
+ function __cjLicenseError() {
2
+ throw new Error("[CJHD License] Runtime package is not unlocked. Expected license file: extensions/pkg/node_modules/@cjhd/cj-cocos-license/bin/cj-runtime-license.json. Then run: node extensions/pkg/node_modules/@cjhd/cj-cocos-license/bin/cj-license.js --mode install --force");
3
+ }
4
+
5
+ export { EventEmitter } from './assets/EventEmitter.js';
6
+ export function __cj_package_not_unlocked__() { __cjLicenseError(); }
package/package.json CHANGED
@@ -1,11 +1,10 @@
1
1
  {
2
2
  "name": "@cjhd/cj-event-emitter",
3
- "version": "1.0.0",
4
- "engine": ">=3.8.0",
3
+ "version": "1.1.2",
5
4
  "description": "全局事件触发器:零依赖、轻量级",
6
- "main": "index.ts",
5
+ "main": "./index.js",
7
6
  "scripts": {
8
- "test": "echo \"Error: no test specified\" && exit 1"
7
+ "postinstall": "node ./bin/package-postinstall.js"
9
8
  },
10
9
  "repository": {
11
10
  "type": "git",
@@ -16,5 +15,43 @@
16
15
  "registry": "https://registry.npmjs.org"
17
16
  },
18
17
  "author": "超M <402879660@qq.com>",
19
- "license": "MIT"
18
+ "license": "SEE LICENSE IN README.md",
19
+ "type": "module",
20
+ "browser": "./index.js",
21
+ "types": "./index.d.ts",
22
+ "exports": {
23
+ ".": {
24
+ "types": "./index.d.ts",
25
+ "browser": "./index.js",
26
+ "import": "./index.js",
27
+ "default": "./index.js"
28
+ },
29
+ "./assets/*": {
30
+ "types": "./assets/*.d.ts",
31
+ "browser": "./assets/*.js",
32
+ "import": "./assets/*.js",
33
+ "default": "./assets/*.js"
34
+ },
35
+ "./package.json": "./package.json"
36
+ },
37
+ "files": [
38
+ "package.json",
39
+ "README.md",
40
+ "index.d.ts",
41
+ "index.js",
42
+ "assets/**/*.d.ts",
43
+ "assets/**/*.js",
44
+ "encrypted-payload/**",
45
+ "bin/**",
46
+ ".cj-package.json"
47
+ ],
48
+ "dependencies": {},
49
+ "peerDependencies": {
50
+ "@cjhd/cj-cocos-license": "^1.0.0"
51
+ },
52
+ "peerDependenciesMeta": {
53
+ "@cjhd/cj-cocos-license": {
54
+ "optional": true
55
+ }
56
+ }
20
57
  }
@@ -1,129 +0,0 @@
1
- /***********************************************************************
2
- * EventEmitter.ts —— 轻量级全局事件管理器(支持 ctx 精确解绑 & targetOff)
3
- *
4
- * 修复点:
5
- * - on / once 阶段拦截非函数 listener,避免 emit 阶段出现 fn.apply undefined。
6
- * - emit 阶段二次防御并清理脏监听,不改变合法监听的执行语义。
7
- * - off(type) 支持清空该事件全部监听,兼容常见 EventEmitter 用法。
8
- ***********************************************************************/
9
-
10
- type EventType = string | number | symbol;
11
- export type AnyListener = (...args: any[]) => unknown;
12
-
13
- /** 内部包装:记录回调与上下文 */
14
- interface ListenerItem {
15
- fn: AnyListener;
16
- ctx?: any;
17
- once?: boolean;
18
- }
19
-
20
- function isValidListener(fn: unknown): fn is AnyListener {
21
- return typeof fn === "function";
22
- }
23
-
24
- export class EventEmitter {
25
- /** Map<事件类型, Set<ListenerItem>> */
26
- private readonly _map = new Map<EventType, Set<ListenerItem>>();
27
-
28
- /* ───────────── 监听 ───────────── */
29
-
30
- on(type: EventType, fn: AnyListener, ctx?: any): void {
31
- if (!isValidListener(fn)) {
32
- console.warn("[EventEmitter] ignore invalid on listener:", type, fn);
33
- return;
34
- }
35
-
36
- let set = this._map.get(type);
37
- if (!set) {
38
- set = new Set<ListenerItem>();
39
- this._map.set(type, set);
40
- }
41
- set.add({ fn, ctx });
42
- }
43
-
44
- once(type: EventType, fn: AnyListener, ctx?: any): void {
45
- if (!isValidListener(fn)) {
46
- console.warn("[EventEmitter] ignore invalid once listener:", type, fn);
47
- return;
48
- }
49
-
50
- let set = this._map.get(type);
51
- if (!set) {
52
- set = new Set<ListenerItem>();
53
- this._map.set(type, set);
54
- }
55
- set.add({ fn, ctx, once: true });
56
- }
57
-
58
- /* ───────────── 取消监听 ───────────── */
59
-
60
- /**
61
- * 取消指定回调
62
- * - off(type):取消该事件全部监听
63
- * - off(type, fn):取消所有同名函数
64
- * - off(type, fn, ctx):仅取消 (fn, ctx) 组合
65
- */
66
- off(type: EventType, fn?: AnyListener, ctx?: any): void {
67
- const set = this._map.get(type);
68
- if (!set) return;
69
-
70
- if (fn === undefined || fn === null) {
71
- this._map.delete(type);
72
- return;
73
- }
74
-
75
- for (const item of Array.from(set)) {
76
- if (!item || item.fn !== fn) continue;
77
- if (ctx !== undefined && ctx !== item.ctx) continue;
78
- set.delete(item);
79
- }
80
- if (set.size === 0) this._map.delete(type);
81
- }
82
-
83
- /**
84
- * 根据 ctx 移除当前 EventEmitter 上的所有监听
85
- * 等同于 Cocos EventTarget.targetOff
86
- */
87
- targetOff(ctx: any): void {
88
- if (ctx === undefined || ctx === null) return;
89
-
90
- for (const [type, set] of Array.from(this._map.entries())) {
91
- for (const item of Array.from(set)) {
92
- if (item && item.ctx === ctx) set.delete(item);
93
- }
94
- if (set.size === 0) this._map.delete(type);
95
- }
96
- }
97
-
98
- /**
99
- * 取消某事件全部监听;不传 type ⇒ 清空所有事件
100
- */
101
- offAll(type?: EventType): void {
102
- if (type === undefined) this._map.clear();
103
- else this._map.delete(type);
104
- }
105
-
106
- /* ───────────── 触发事件 ───────────── */
107
-
108
- emit(type: EventType, ...args: any[]): void {
109
- const set = this._map.get(type);
110
- if (!set) return;
111
-
112
- // 拷贝一份,防止回调里修改集合导致遍历异常
113
- const listeners = Array.from(set);
114
- for (const item of listeners) {
115
- if (!item || !isValidListener(item.fn)) {
116
- set.delete(item as any);
117
- console.warn("[EventEmitter] remove invalid listener while emitting:", type, item);
118
- continue;
119
- }
120
-
121
- try {
122
- item.fn.apply(item.ctx, args);
123
- } finally {
124
- if (item.once) set.delete(item);
125
- }
126
- }
127
- if (set.size === 0) this._map.delete(type);
128
- }
129
- }
@@ -1,9 +0,0 @@
1
- {
2
- "ver": "4.0.24",
3
- "importer": "typescript",
4
- "imported": true,
5
- "uuid": "de97f5f0-a281-4cfb-9138-c4266b84f188",
6
- "files": [],
7
- "subMetas": {},
8
- "userData": {}
9
- }
package/assets.meta DELETED
@@ -1,9 +0,0 @@
1
- {
2
- "ver": "1.2.0",
3
- "importer": "directory",
4
- "imported": true,
5
- "uuid": "7927f3d6-977d-4388-afc3-e365069e9754",
6
- "files": [],
7
- "subMetas": {},
8
- "userData": {}
9
- }
package/index.ts DELETED
@@ -1,2 +0,0 @@
1
- // 负责导出assets下的模块,如: export { default } from './assets/xxx.ts'
2
- export { EventEmitter } from './assets/EventEmitter';
package/index.ts.meta DELETED
@@ -1,9 +0,0 @@
1
- {
2
- "ver": "4.0.24",
3
- "importer": "typescript",
4
- "imported": true,
5
- "uuid": "875ad7b0-b2f1-4157-bb41-d6465bfa1a07",
6
- "files": [],
7
- "subMetas": {},
8
- "userData": {}
9
- }
package/package.json.meta DELETED
@@ -1,11 +0,0 @@
1
- {
2
- "ver": "2.0.1",
3
- "importer": "json",
4
- "imported": true,
5
- "uuid": "ab519119-3f49-4697-b90d-28f076d502b5",
6
- "files": [
7
- ".json"
8
- ],
9
- "subMetas": {},
10
- "userData": {}
11
- }
File without changes