@unchainedshop/events 1.1.3
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/README.md +3 -0
- package/babel.config.js +3 -0
- package/lib/EventDirector.d.ts +3 -0
- package/lib/EventDirector.js +66 -0
- package/lib/EventDirector.js.map +1 -0
- package/lib/events-index.d.ts +2 -0
- package/lib/events-index.js +6 -0
- package/lib/events-index.js.map +1 -0
- package/package.js +20 -0
- package/package.json +49 -0
- package/plugins/node-event-emitter.ts +20 -0
- package/plugins/redis.ts +30 -0
- package/tsconfig.build.json +26 -0
package/README.md
ADDED
package/babel.config.js
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { createLogger } from '@unchainedshop/logger';
|
|
2
|
+
const logger = createLogger('unchained:events');
|
|
3
|
+
export const defaultNormalizer = (context) => {
|
|
4
|
+
return {
|
|
5
|
+
userAgent: context?.userAgent,
|
|
6
|
+
language: context?.localeContext?.code,
|
|
7
|
+
country: context?.localeContext?.country,
|
|
8
|
+
remoteAddress: context?.remoteAddress,
|
|
9
|
+
referer: context?.req?.headers?.referer,
|
|
10
|
+
origin: context?.req?.headers?.origin,
|
|
11
|
+
userId: context?.userId,
|
|
12
|
+
};
|
|
13
|
+
};
|
|
14
|
+
const RegisteredEventsSet = new Set();
|
|
15
|
+
const RegisteredCallbacksSet = new Set();
|
|
16
|
+
let Adapter; // Public (customizable)
|
|
17
|
+
let HistoryAdapter; // (Per default: Core-events adapter to write into DB)
|
|
18
|
+
let ContextNormalizer = defaultNormalizer;
|
|
19
|
+
export const EventDirector = {
|
|
20
|
+
registerEvents: (events) => {
|
|
21
|
+
if (events.length) {
|
|
22
|
+
events.forEach((e) => RegisteredEventsSet.add(e));
|
|
23
|
+
logger.verbose(`EventDirector -> Registered ${JSON.stringify(events)}`);
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
getRegisteredEvents: () => {
|
|
27
|
+
return Array.from(RegisteredEventsSet);
|
|
28
|
+
},
|
|
29
|
+
setContextNormalizer: (fn) => {
|
|
30
|
+
ContextNormalizer = fn;
|
|
31
|
+
},
|
|
32
|
+
setEmitAdapter: (adapter) => {
|
|
33
|
+
Adapter = adapter;
|
|
34
|
+
},
|
|
35
|
+
getEmitAdapter: () => Adapter,
|
|
36
|
+
setEmitHistoryAdapter: (adapter) => {
|
|
37
|
+
HistoryAdapter = adapter;
|
|
38
|
+
},
|
|
39
|
+
getEmitHistoryAdapter: () => HistoryAdapter,
|
|
40
|
+
emit: async (eventName, data) => {
|
|
41
|
+
const extractedContext = ContextNormalizer(null);
|
|
42
|
+
if (!RegisteredEventsSet.has(eventName))
|
|
43
|
+
throw new Error(`Event with ${eventName} is not registered`);
|
|
44
|
+
Adapter?.publish(eventName, {
|
|
45
|
+
payload: { ...data },
|
|
46
|
+
context: extractedContext,
|
|
47
|
+
});
|
|
48
|
+
HistoryAdapter?.publish(eventName, {
|
|
49
|
+
payload: { ...data },
|
|
50
|
+
context: extractedContext,
|
|
51
|
+
});
|
|
52
|
+
logger.verbose(`EventDirector -> Emitted ${eventName} with ${JSON.stringify(data)}`);
|
|
53
|
+
},
|
|
54
|
+
subscribe: (eventName, callback) => {
|
|
55
|
+
const currentSubscription = `${eventName}${callback?.toString()}`; // used to avaoid registering the same event handler callback
|
|
56
|
+
if (!RegisteredEventsSet.has(eventName))
|
|
57
|
+
throw new Error(`Event with ${eventName} is not registered`);
|
|
58
|
+
if (!RegisteredCallbacksSet.has(currentSubscription)) {
|
|
59
|
+
Adapter?.subscribe(eventName, callback);
|
|
60
|
+
HistoryAdapter?.subscribe(eventName, callback);
|
|
61
|
+
RegisteredCallbacksSet.add(currentSubscription);
|
|
62
|
+
logger.verbose(`EventDirector -> Subscribed to ${eventName}`);
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
};
|
|
66
|
+
//# sourceMappingURL=EventDirector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EventDirector.js","sourceRoot":"","sources":["../src/EventDirector.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
declare const emit: (eventName: string, data?: string | Record<string, unknown>) => Promise<void>, getEmitAdapter: () => import("@unchainedshop/types/events").EmitAdapter, getEmitHistoryAdapter: () => import("@unchainedshop/types/events").EmitAdapter, getRegisteredEvents: () => string[], registerEvents: (events: string[]) => void, setEmitAdapter: (adapter: import("@unchainedshop/types/events").EmitAdapter) => void, setEmitHistoryAdapter: (adapter: import("@unchainedshop/types/events").EmitAdapter) => void, subscribe: (eventName: string, callback: (payload?: Record<string, unknown>) => void) => void;
|
|
2
|
+
export { emit, getEmitAdapter, getEmitHistoryAdapter, getRegisteredEvents, registerEvents, setEmitAdapter, setEmitHistoryAdapter, subscribe, };
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { EventDirector } from './EventDirector';
|
|
2
|
+
const { emit, getEmitAdapter, getEmitHistoryAdapter, getRegisteredEvents, registerEvents, setEmitAdapter, setEmitHistoryAdapter, subscribe, } = EventDirector;
|
|
3
|
+
const GLOBAL_EVENTS = ['PAGE_VIEW'];
|
|
4
|
+
registerEvents(GLOBAL_EVENTS);
|
|
5
|
+
export { emit, getEmitAdapter, getEmitHistoryAdapter, getRegisteredEvents, registerEvents, setEmitAdapter, setEmitHistoryAdapter, subscribe, };
|
|
6
|
+
//# sourceMappingURL=events-index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"events-index.js","sourceRoot":"","sources":["../src/events-index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAEhD,MAAM,EACJ,IAAI,EACJ,cAAc,EACd,qBAAqB,EACrB,mBAAmB,EACnB,cAAc,EACd,cAAc,EACd,qBAAqB,EACrB,SAAS,GACV,GAAG,aAAa,CAAC;AAElB,MAAM,aAAa,GAAG,CAAC,WAAW,CAAC,CAAC;AACpC,cAAc,CAAC,aAAa,CAAC,CAAC;AAE9B,OAAO,EACL,IAAI,EACJ,cAAc,EACd,qBAAqB,EACrB,mBAAmB,EACnB,cAAc,EACd,cAAc,EACd,qBAAqB,EACrB,SAAS,GACV,CAAC"}
|
package/package.js
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
Package.describe({
|
|
2
|
+
name: 'unchained:events',
|
|
3
|
+
version: '1.1.3',
|
|
4
|
+
summary: 'Unchained Engine: Event Director',
|
|
5
|
+
git: 'https://github.com/unchainedshop/unchained',
|
|
6
|
+
documentation: 'README.md',
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
Npm.depends({
|
|
10
|
+
redis: '4.1.0',
|
|
11
|
+
'@unchainedshop/logger': '1.1.3',
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
Package.onUse((api) => {
|
|
15
|
+
api.versionsFrom('2.7.3');
|
|
16
|
+
api.use('ecmascript');
|
|
17
|
+
api.use('typescript');
|
|
18
|
+
|
|
19
|
+
api.mainModule('src/events-index.ts', 'server');
|
|
20
|
+
});
|
package/package.json
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@unchainedshop/events",
|
|
3
|
+
"version": "1.1.3",
|
|
4
|
+
"main": "lib/events-index.js",
|
|
5
|
+
"types": "lib/events-index.d.ts",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"clean": "rm -rf lib",
|
|
9
|
+
"build": "npm run clean && tsc -p tsconfig.build.json",
|
|
10
|
+
"watch": "tsc --watch",
|
|
11
|
+
"link:core": "npm link @unchainedshop/types",
|
|
12
|
+
"test": "jest --watch"
|
|
13
|
+
},
|
|
14
|
+
"repository": {
|
|
15
|
+
"type": "git",
|
|
16
|
+
"url": "git+https://github.com/unchainedshop/unchained.git"
|
|
17
|
+
},
|
|
18
|
+
"keywords": [
|
|
19
|
+
"unchained",
|
|
20
|
+
"ecommerce",
|
|
21
|
+
"core"
|
|
22
|
+
],
|
|
23
|
+
"author": "Joël Meiller",
|
|
24
|
+
"license": "EUPL-1.2",
|
|
25
|
+
"bugs": {
|
|
26
|
+
"url": "https://github.com/unchainedshop/unchained/issues"
|
|
27
|
+
},
|
|
28
|
+
"homepage": "https://github.com/unchainedshop/unchained#readme",
|
|
29
|
+
"dependencies": {
|
|
30
|
+
"redis": "^4.1.0",
|
|
31
|
+
"@unchainedshop/logger": "latest"
|
|
32
|
+
},
|
|
33
|
+
"devDependencies": {
|
|
34
|
+
"@babel/core": "^7.18.6",
|
|
35
|
+
"@babel/preset-env": "^7.18.6",
|
|
36
|
+
"@babel/preset-typescript": "^7.18.6",
|
|
37
|
+
"@types/chai": "^4.3.1",
|
|
38
|
+
"@types/jest": "^28.1.3",
|
|
39
|
+
"@types/mocha": "^9.1.1",
|
|
40
|
+
"@unchainedshop/types": "latest",
|
|
41
|
+
"babel-jest": "^28.1.1",
|
|
42
|
+
"chai": "^4.3.6",
|
|
43
|
+
"cross-env": "^7.0.3",
|
|
44
|
+
"jest": "^28.1.1",
|
|
45
|
+
"ts-jest": "^28.0.5",
|
|
46
|
+
"ts-node": "^10.8.1",
|
|
47
|
+
"typescript": "^4.7.4"
|
|
48
|
+
}
|
|
49
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { EventEmitter } from 'events';
|
|
2
|
+
import { EmitAdapter } from '@unchainedshop/types/events';
|
|
3
|
+
import { setEmitAdapter } from 'meteor/unchained:events';
|
|
4
|
+
|
|
5
|
+
const NodeEventEmitter = (): EmitAdapter => {
|
|
6
|
+
const eventEmitter = new EventEmitter();
|
|
7
|
+
|
|
8
|
+
return {
|
|
9
|
+
publish: (eventName, payload) => {
|
|
10
|
+
eventEmitter.emit(eventName, payload);
|
|
11
|
+
},
|
|
12
|
+
|
|
13
|
+
subscribe: (eventName, callback) => {
|
|
14
|
+
return eventEmitter.on(eventName, callback);
|
|
15
|
+
},
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
const adapter = NodeEventEmitter();
|
|
20
|
+
setEmitAdapter(adapter);
|
package/plugins/redis.ts
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import redis from 'redis';
|
|
2
|
+
import { EmitAdapter } from '@unchainedshop/types/events';
|
|
3
|
+
import { setEmitAdapter } from 'meteor/unchained:events';
|
|
4
|
+
|
|
5
|
+
const { REDIS_PORT = 6379, REDIS_HOST = '127.0.0.1' } = process.env;
|
|
6
|
+
|
|
7
|
+
const subscribedEvents = new Set();
|
|
8
|
+
|
|
9
|
+
const RedisEventEmitter = (): EmitAdapter => {
|
|
10
|
+
const redisPublisher = redis.createClient({
|
|
11
|
+
url: `redis://${REDIS_HOST}:${REDIS_PORT}`,
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
const redisSubscriber = redis.createClient({
|
|
15
|
+
url: `redis://${REDIS_HOST}:${REDIS_PORT}`,
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
return {
|
|
19
|
+
publish: (eventName, payload) => redisPublisher.publish(eventName, JSON.stringify(payload)),
|
|
20
|
+
subscribe: (eventName, callback) => {
|
|
21
|
+
redisSubscriber.on('message', (_channelName, payload) => callback(payload));
|
|
22
|
+
if (!subscribedEvents.has(eventName)) {
|
|
23
|
+
redisSubscriber.subscribe(eventName);
|
|
24
|
+
subscribedEvents.add(eventName);
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
};
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
setEmitAdapter(RedisEventEmitter());
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"allowJs": true,
|
|
4
|
+
"allowSyntheticDefaultImports": true,
|
|
5
|
+
"declaration": true,
|
|
6
|
+
"esModuleInterop": true,
|
|
7
|
+
"experimentalDecorators": true,
|
|
8
|
+
"forceConsistentCasingInFileNames": true,
|
|
9
|
+
"lib": ["esnext"],
|
|
10
|
+
"module": "esnext",
|
|
11
|
+
"moduleResolution": "node",
|
|
12
|
+
"noImplicitReturns": true,
|
|
13
|
+
"noUnusedLocals": false,
|
|
14
|
+
"outDir": "lib",
|
|
15
|
+
"preserveWatchOutput": true,
|
|
16
|
+
"skipLibCheck": true,
|
|
17
|
+
"sourceMap": true,
|
|
18
|
+
"target": "esnext",
|
|
19
|
+
"types": ["node"],
|
|
20
|
+
"baseUrl": ".", // This must be specified if "paths" is.
|
|
21
|
+
"paths": {
|
|
22
|
+
"meteor/unchained:*": ["node_modules/@unchainedshop/types/index.d.ts"]
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
"include": ["src"]
|
|
26
|
+
}
|