@quarry-systems/drift-event-listener 0.1.0 → 0.1.1-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.
- package/package.json +2 -2
- package/src/index.d.ts +140 -0
- package/src/index.js +350 -0
- package/src/index.js.map +1 -0
- package/src/plugin.manifest.d.ts +9 -0
- package/src/plugin.manifest.js +48 -0
- package/src/plugin.manifest.js.map +1 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@quarry-systems/drift-event-listener",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1-alpha.1",
|
|
4
4
|
"description": "Event listener and webhook plugin for Drift",
|
|
5
5
|
"main": "./src/index.js",
|
|
6
6
|
"types": "./src/index.d.ts",
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"vitest": "^2.1.0"
|
|
32
32
|
},
|
|
33
33
|
"files": [
|
|
34
|
-
"
|
|
34
|
+
"src",
|
|
35
35
|
"README.md",
|
|
36
36
|
"LICENSE.md",
|
|
37
37
|
"CHANGELOG.md"
|
package/src/index.d.ts
ADDED
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCG Event Listener Plugin
|
|
3
|
+
*
|
|
4
|
+
* Provides event listening capabilities for Managed Cyclic Graph nodes.
|
|
5
|
+
* Supports webhooks, pub/sub, polling, and custom event sources.
|
|
6
|
+
*/
|
|
7
|
+
import { Plugin } from '@quarry-systems/drift-core';
|
|
8
|
+
type AnyCtx = any;
|
|
9
|
+
export type EventSourceType = 'webhook' | 'poll' | 'pubsub' | 'custom';
|
|
10
|
+
export interface EventListenerConfig {
|
|
11
|
+
/** Type of event source */
|
|
12
|
+
source: EventSourceType;
|
|
13
|
+
/** Configuration specific to the event source type */
|
|
14
|
+
sourceConfig: WebhookConfig | PollConfig | PubSubConfig | CustomConfig;
|
|
15
|
+
/** Timeout in milliseconds (0 = no timeout) */
|
|
16
|
+
timeoutMs?: number;
|
|
17
|
+
/** Filter function to validate events */
|
|
18
|
+
filter?: (event: any) => boolean;
|
|
19
|
+
/** Transform function to process event payload */
|
|
20
|
+
transform?: (event: any, ctx: AnyCtx) => any;
|
|
21
|
+
/** Custom path to store event data (default: data.events.{nodeId}) */
|
|
22
|
+
storePath?: string;
|
|
23
|
+
/** Callback when event is received */
|
|
24
|
+
onEvent?: (event: any, ctx: AnyCtx) => void | Promise<void>;
|
|
25
|
+
/** Callback on timeout */
|
|
26
|
+
onTimeout?: (ctx: AnyCtx) => void | Promise<void>;
|
|
27
|
+
}
|
|
28
|
+
export interface WebhookConfig {
|
|
29
|
+
/** Webhook endpoint path */
|
|
30
|
+
path: string;
|
|
31
|
+
/** HTTP method to listen for */
|
|
32
|
+
method?: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';
|
|
33
|
+
/** Port to listen on (optional, uses existing server if available) */
|
|
34
|
+
port?: number;
|
|
35
|
+
/** Secret for webhook validation */
|
|
36
|
+
secret?: string;
|
|
37
|
+
/** Header name for secret validation */
|
|
38
|
+
secretHeader?: string;
|
|
39
|
+
}
|
|
40
|
+
export interface PollConfig {
|
|
41
|
+
/** URL to poll */
|
|
42
|
+
url: string;
|
|
43
|
+
/** Polling interval in milliseconds */
|
|
44
|
+
intervalMs: number;
|
|
45
|
+
/** Maximum number of poll attempts (0 = infinite) */
|
|
46
|
+
maxAttempts?: number;
|
|
47
|
+
/** HTTP method */
|
|
48
|
+
method?: 'GET' | 'POST';
|
|
49
|
+
/** Request headers */
|
|
50
|
+
headers?: Record<string, string>;
|
|
51
|
+
/** Condition to check if event is ready */
|
|
52
|
+
condition: (response: any) => boolean;
|
|
53
|
+
}
|
|
54
|
+
export interface PubSubConfig {
|
|
55
|
+
/** Topic/channel to subscribe to */
|
|
56
|
+
topic: string;
|
|
57
|
+
/** Pub/Sub provider ('memory' | 'redis' | 'custom') */
|
|
58
|
+
provider?: 'memory' | 'redis' | 'custom';
|
|
59
|
+
/** Custom subscriber function */
|
|
60
|
+
subscribe?: (topic: string, callback: (event: any) => void) => () => void;
|
|
61
|
+
}
|
|
62
|
+
export interface CustomConfig {
|
|
63
|
+
/** Custom event listener function */
|
|
64
|
+
listen: (ctx: AnyCtx) => Promise<any>;
|
|
65
|
+
}
|
|
66
|
+
export interface EventNode {
|
|
67
|
+
id: string;
|
|
68
|
+
meta: {
|
|
69
|
+
event: EventListenerConfig;
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
export interface EventMetadata {
|
|
73
|
+
source: EventSourceType;
|
|
74
|
+
receivedAt: number;
|
|
75
|
+
event: any;
|
|
76
|
+
timedOut: boolean;
|
|
77
|
+
attempts?: number;
|
|
78
|
+
}
|
|
79
|
+
declare class SimpleEventBus {
|
|
80
|
+
private subscribers;
|
|
81
|
+
subscribe(topic: string, callback: (event: any) => void): () => void;
|
|
82
|
+
publish(topic: string, event: any): void;
|
|
83
|
+
}
|
|
84
|
+
declare const globalEventBus: SimpleEventBus;
|
|
85
|
+
/**
|
|
86
|
+
* Create webhook listener configuration
|
|
87
|
+
*/
|
|
88
|
+
export declare function webhook(path: string, options?: Partial<WebhookConfig>): EventListenerConfig;
|
|
89
|
+
/**
|
|
90
|
+
* Create polling listener configuration
|
|
91
|
+
*/
|
|
92
|
+
export declare function poll(url: string, condition: (response: any) => boolean, intervalMs?: number): EventListenerConfig;
|
|
93
|
+
/**
|
|
94
|
+
* Create pub/sub listener configuration
|
|
95
|
+
*/
|
|
96
|
+
export declare function pubsub(topic: string, provider?: 'memory' | 'redis' | 'custom'): EventListenerConfig;
|
|
97
|
+
/**
|
|
98
|
+
* Create custom listener configuration
|
|
99
|
+
*/
|
|
100
|
+
export declare function custom(listen: (ctx: AnyCtx) => Promise<any>): EventListenerConfig;
|
|
101
|
+
/**
|
|
102
|
+
* Create an execute action that listens for an event
|
|
103
|
+
*
|
|
104
|
+
* @param nodeId - The node ID (used for storing event data in context)
|
|
105
|
+
* @param config - Event listener configuration
|
|
106
|
+
*
|
|
107
|
+
* @example
|
|
108
|
+
* ```typescript
|
|
109
|
+
* .node('waitForWebhook', {
|
|
110
|
+
* execute: [
|
|
111
|
+
* createEventAction('waitForWebhook', webhook('/payment-complete'))
|
|
112
|
+
* ]
|
|
113
|
+
* })
|
|
114
|
+
* ```
|
|
115
|
+
*/
|
|
116
|
+
export declare function createEventAction(nodeId: string, config: EventListenerConfig): {
|
|
117
|
+
id: string;
|
|
118
|
+
description: string;
|
|
119
|
+
run: (ctx: AnyCtx) => Promise<AnyCtx>;
|
|
120
|
+
};
|
|
121
|
+
/**
|
|
122
|
+
* MCG Event Listener Plugin
|
|
123
|
+
*
|
|
124
|
+
* Register this plugin to enable event listener nodes.
|
|
125
|
+
*
|
|
126
|
+
* @example
|
|
127
|
+
* ```typescript
|
|
128
|
+
* const graph = new ManagedCyclicGraph()
|
|
129
|
+
* .use(mcgEventListenerPlugin)
|
|
130
|
+
* .node('waitForEvent', {
|
|
131
|
+
* type: 'eventnode',
|
|
132
|
+
* meta: {
|
|
133
|
+
* event: pubsub('order-completed')
|
|
134
|
+
* }
|
|
135
|
+
* })
|
|
136
|
+
* ```
|
|
137
|
+
*/
|
|
138
|
+
export declare const mcgEventListenerPlugin: Plugin<AnyCtx, EventNode>;
|
|
139
|
+
export default mcgEventListenerPlugin;
|
|
140
|
+
export { globalEventBus };
|
package/src/index.js
ADDED
|
@@ -0,0 +1,350 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* MCG Event Listener Plugin
|
|
4
|
+
*
|
|
5
|
+
* Provides event listening capabilities for Managed Cyclic Graph nodes.
|
|
6
|
+
* Supports webhooks, pub/sub, polling, and custom event sources.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.globalEventBus = exports.mcgEventListenerPlugin = void 0;
|
|
10
|
+
exports.webhook = webhook;
|
|
11
|
+
exports.poll = poll;
|
|
12
|
+
exports.pubsub = pubsub;
|
|
13
|
+
exports.custom = custom;
|
|
14
|
+
exports.createEventAction = createEventAction;
|
|
15
|
+
// ============================================================================
|
|
16
|
+
// In-Memory Event Bus (Simple Implementation)
|
|
17
|
+
// ============================================================================
|
|
18
|
+
class SimpleEventBus {
|
|
19
|
+
constructor() {
|
|
20
|
+
this.subscribers = new Map();
|
|
21
|
+
}
|
|
22
|
+
subscribe(topic, callback) {
|
|
23
|
+
if (!this.subscribers.has(topic)) {
|
|
24
|
+
this.subscribers.set(topic, new Set());
|
|
25
|
+
}
|
|
26
|
+
this.subscribers.get(topic).add(callback);
|
|
27
|
+
// Return unsubscribe function
|
|
28
|
+
return () => {
|
|
29
|
+
this.subscribers.get(topic)?.delete(callback);
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
publish(topic, event) {
|
|
33
|
+
const callbacks = this.subscribers.get(topic);
|
|
34
|
+
if (callbacks) {
|
|
35
|
+
callbacks.forEach(cb => cb(event));
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
const globalEventBus = new SimpleEventBus();
|
|
40
|
+
exports.globalEventBus = globalEventBus;
|
|
41
|
+
// ============================================================================
|
|
42
|
+
// Event Source Implementations
|
|
43
|
+
// ============================================================================
|
|
44
|
+
/**
|
|
45
|
+
* Listen for webhook events
|
|
46
|
+
*/
|
|
47
|
+
async function listenWebhook(config, timeoutMs) {
|
|
48
|
+
return new Promise((resolve, reject) => {
|
|
49
|
+
const topic = `webhook:${config.path}`;
|
|
50
|
+
let timeoutId = null;
|
|
51
|
+
const unsubscribe = globalEventBus.subscribe(topic, (event) => {
|
|
52
|
+
// Validate secret if provided
|
|
53
|
+
if (config.secret && config.secretHeader) {
|
|
54
|
+
const providedSecret = event.headers?.[config.secretHeader];
|
|
55
|
+
if (providedSecret !== config.secret) {
|
|
56
|
+
return; // Invalid secret, ignore event
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
// Validate method if specified
|
|
60
|
+
if (config.method && event.method !== config.method) {
|
|
61
|
+
return; // Wrong method, ignore event
|
|
62
|
+
}
|
|
63
|
+
if (timeoutId)
|
|
64
|
+
clearTimeout(timeoutId);
|
|
65
|
+
unsubscribe();
|
|
66
|
+
resolve(event.body || event);
|
|
67
|
+
});
|
|
68
|
+
if (timeoutMs > 0) {
|
|
69
|
+
timeoutId = setTimeout(() => {
|
|
70
|
+
unsubscribe();
|
|
71
|
+
reject(new Error(`Webhook timeout after ${timeoutMs}ms`));
|
|
72
|
+
}, timeoutMs);
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Poll an endpoint until condition is met
|
|
78
|
+
*/
|
|
79
|
+
async function listenPoll(config, timeoutMs) {
|
|
80
|
+
const startTime = Date.now();
|
|
81
|
+
const maxAttempts = config.maxAttempts || 0;
|
|
82
|
+
let attempts = 0;
|
|
83
|
+
while (true) {
|
|
84
|
+
attempts++;
|
|
85
|
+
try {
|
|
86
|
+
// Make HTTP request
|
|
87
|
+
const response = await fetch(config.url, {
|
|
88
|
+
method: config.method || 'GET',
|
|
89
|
+
headers: config.headers
|
|
90
|
+
});
|
|
91
|
+
const data = await response.json();
|
|
92
|
+
// Check condition
|
|
93
|
+
if (config.condition(data)) {
|
|
94
|
+
return data;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
catch (error) {
|
|
98
|
+
// Continue polling on error
|
|
99
|
+
}
|
|
100
|
+
// Check timeout
|
|
101
|
+
if (timeoutMs > 0 && Date.now() - startTime >= timeoutMs) {
|
|
102
|
+
throw new Error(`Poll timeout after ${timeoutMs}ms`);
|
|
103
|
+
}
|
|
104
|
+
// Check max attempts
|
|
105
|
+
if (maxAttempts > 0 && attempts >= maxAttempts) {
|
|
106
|
+
throw new Error(`Max poll attempts (${maxAttempts}) reached`);
|
|
107
|
+
}
|
|
108
|
+
// Wait before next poll
|
|
109
|
+
await new Promise(resolve => setTimeout(resolve, config.intervalMs));
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Listen to pub/sub topic
|
|
114
|
+
*/
|
|
115
|
+
async function listenPubSub(config, timeoutMs) {
|
|
116
|
+
return new Promise((resolve, reject) => {
|
|
117
|
+
let timeoutId = null;
|
|
118
|
+
let unsubscribe = null;
|
|
119
|
+
const handleEvent = (event) => {
|
|
120
|
+
if (timeoutId)
|
|
121
|
+
clearTimeout(timeoutId);
|
|
122
|
+
if (unsubscribe)
|
|
123
|
+
unsubscribe();
|
|
124
|
+
resolve(event);
|
|
125
|
+
};
|
|
126
|
+
// Use custom subscriber or default to memory bus
|
|
127
|
+
if (config.subscribe) {
|
|
128
|
+
unsubscribe = config.subscribe(config.topic, handleEvent);
|
|
129
|
+
}
|
|
130
|
+
else {
|
|
131
|
+
unsubscribe = globalEventBus.subscribe(config.topic, handleEvent);
|
|
132
|
+
}
|
|
133
|
+
if (timeoutMs > 0) {
|
|
134
|
+
timeoutId = setTimeout(() => {
|
|
135
|
+
if (unsubscribe)
|
|
136
|
+
unsubscribe();
|
|
137
|
+
reject(new Error(`PubSub timeout after ${timeoutMs}ms`));
|
|
138
|
+
}, timeoutMs);
|
|
139
|
+
}
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Execute custom event listener
|
|
144
|
+
*/
|
|
145
|
+
async function listenCustom(config, ctx, timeoutMs) {
|
|
146
|
+
if (timeoutMs > 0) {
|
|
147
|
+
return Promise.race([
|
|
148
|
+
config.listen(ctx),
|
|
149
|
+
new Promise((_, reject) => setTimeout(() => reject(new Error(`Custom listener timeout after ${timeoutMs}ms`)), timeoutMs))
|
|
150
|
+
]);
|
|
151
|
+
}
|
|
152
|
+
return config.listen(ctx);
|
|
153
|
+
}
|
|
154
|
+
// ============================================================================
|
|
155
|
+
// Plugin Handler
|
|
156
|
+
// ============================================================================
|
|
157
|
+
const eventnode = async ({ ctx, node }) => {
|
|
158
|
+
const config = node.meta?.event;
|
|
159
|
+
if (!config) {
|
|
160
|
+
throw new Error(`Event listener node "${node.id}" missing event configuration in meta.event`);
|
|
161
|
+
}
|
|
162
|
+
const timeoutMs = config.timeoutMs ?? 0;
|
|
163
|
+
const receivedAt = Date.now();
|
|
164
|
+
let event;
|
|
165
|
+
let timedOut = false;
|
|
166
|
+
let attempts;
|
|
167
|
+
try {
|
|
168
|
+
// Listen based on source type
|
|
169
|
+
switch (config.source) {
|
|
170
|
+
case 'webhook':
|
|
171
|
+
event = await listenWebhook(config.sourceConfig, timeoutMs);
|
|
172
|
+
break;
|
|
173
|
+
case 'poll':
|
|
174
|
+
const pollConfig = config.sourceConfig;
|
|
175
|
+
event = await listenPoll(pollConfig, timeoutMs);
|
|
176
|
+
attempts = pollConfig.maxAttempts;
|
|
177
|
+
break;
|
|
178
|
+
case 'pubsub':
|
|
179
|
+
event = await listenPubSub(config.sourceConfig, timeoutMs);
|
|
180
|
+
break;
|
|
181
|
+
case 'custom':
|
|
182
|
+
event = await listenCustom(config.sourceConfig, ctx, timeoutMs);
|
|
183
|
+
break;
|
|
184
|
+
default:
|
|
185
|
+
throw new Error(`Unknown event source type: ${config.source}`);
|
|
186
|
+
}
|
|
187
|
+
// Apply filter if provided
|
|
188
|
+
if (config.filter && !config.filter(event)) {
|
|
189
|
+
throw new Error('Event filtered out');
|
|
190
|
+
}
|
|
191
|
+
// Apply transformation if provided
|
|
192
|
+
if (config.transform) {
|
|
193
|
+
event = config.transform(event, ctx);
|
|
194
|
+
}
|
|
195
|
+
// Call onEvent callback
|
|
196
|
+
if (config.onEvent) {
|
|
197
|
+
await config.onEvent(event, ctx);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
catch (error) {
|
|
201
|
+
if (error.message?.includes('timeout')) {
|
|
202
|
+
timedOut = true;
|
|
203
|
+
event = null;
|
|
204
|
+
// Call onTimeout callback
|
|
205
|
+
if (config.onTimeout) {
|
|
206
|
+
await config.onTimeout(ctx);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
else {
|
|
210
|
+
throw error;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
// Store metadata in context
|
|
214
|
+
const metadata = {
|
|
215
|
+
source: config.source,
|
|
216
|
+
receivedAt,
|
|
217
|
+
event,
|
|
218
|
+
timedOut,
|
|
219
|
+
attempts
|
|
220
|
+
};
|
|
221
|
+
const storePath = config.storePath || `data.events.${node.id}`;
|
|
222
|
+
const pathParts = storePath.split('.');
|
|
223
|
+
let target = ctx;
|
|
224
|
+
for (let i = 0; i < pathParts.length - 1; i++) {
|
|
225
|
+
const part = pathParts[i];
|
|
226
|
+
if (!target[part]) {
|
|
227
|
+
target[part] = {};
|
|
228
|
+
}
|
|
229
|
+
target = target[part];
|
|
230
|
+
}
|
|
231
|
+
const finalKey = pathParts[pathParts.length - 1];
|
|
232
|
+
target[finalKey] = metadata;
|
|
233
|
+
return ctx;
|
|
234
|
+
};
|
|
235
|
+
// ============================================================================
|
|
236
|
+
// Helper Functions
|
|
237
|
+
// ============================================================================
|
|
238
|
+
/**
|
|
239
|
+
* Create webhook listener configuration
|
|
240
|
+
*/
|
|
241
|
+
function webhook(path, options) {
|
|
242
|
+
return {
|
|
243
|
+
source: 'webhook',
|
|
244
|
+
sourceConfig: {
|
|
245
|
+
path,
|
|
246
|
+
method: options?.method || 'POST',
|
|
247
|
+
...options
|
|
248
|
+
}
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* Create polling listener configuration
|
|
253
|
+
*/
|
|
254
|
+
function poll(url, condition, intervalMs = 1000) {
|
|
255
|
+
return {
|
|
256
|
+
source: 'poll',
|
|
257
|
+
sourceConfig: {
|
|
258
|
+
url,
|
|
259
|
+
condition,
|
|
260
|
+
intervalMs,
|
|
261
|
+
method: 'GET'
|
|
262
|
+
}
|
|
263
|
+
};
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* Create pub/sub listener configuration
|
|
267
|
+
*/
|
|
268
|
+
function pubsub(topic, provider = 'memory') {
|
|
269
|
+
return {
|
|
270
|
+
source: 'pubsub',
|
|
271
|
+
sourceConfig: {
|
|
272
|
+
topic,
|
|
273
|
+
provider
|
|
274
|
+
}
|
|
275
|
+
};
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
278
|
+
* Create custom listener configuration
|
|
279
|
+
*/
|
|
280
|
+
function custom(listen) {
|
|
281
|
+
return {
|
|
282
|
+
source: 'custom',
|
|
283
|
+
sourceConfig: {
|
|
284
|
+
listen
|
|
285
|
+
}
|
|
286
|
+
};
|
|
287
|
+
}
|
|
288
|
+
// ============================================================================
|
|
289
|
+
// Action Creator (Convenience Wrapper)
|
|
290
|
+
// ============================================================================
|
|
291
|
+
/**
|
|
292
|
+
* Create an execute action that listens for an event
|
|
293
|
+
*
|
|
294
|
+
* @param nodeId - The node ID (used for storing event data in context)
|
|
295
|
+
* @param config - Event listener configuration
|
|
296
|
+
*
|
|
297
|
+
* @example
|
|
298
|
+
* ```typescript
|
|
299
|
+
* .node('waitForWebhook', {
|
|
300
|
+
* execute: [
|
|
301
|
+
* createEventAction('waitForWebhook', webhook('/payment-complete'))
|
|
302
|
+
* ]
|
|
303
|
+
* })
|
|
304
|
+
* ```
|
|
305
|
+
*/
|
|
306
|
+
function createEventAction(nodeId, config) {
|
|
307
|
+
return {
|
|
308
|
+
id: `event-${nodeId}`,
|
|
309
|
+
description: `Event Listener: ${config.source}`,
|
|
310
|
+
run: async (ctx) => {
|
|
311
|
+
const tempNode = {
|
|
312
|
+
id: nodeId,
|
|
313
|
+
meta: { event: config }
|
|
314
|
+
};
|
|
315
|
+
return await eventnode({
|
|
316
|
+
ctx,
|
|
317
|
+
node: tempNode,
|
|
318
|
+
runId: 'inline-action',
|
|
319
|
+
step: 0
|
|
320
|
+
});
|
|
321
|
+
}
|
|
322
|
+
};
|
|
323
|
+
}
|
|
324
|
+
// ============================================================================
|
|
325
|
+
// Plugin Export
|
|
326
|
+
// ============================================================================
|
|
327
|
+
/**
|
|
328
|
+
* MCG Event Listener Plugin
|
|
329
|
+
*
|
|
330
|
+
* Register this plugin to enable event listener nodes.
|
|
331
|
+
*
|
|
332
|
+
* @example
|
|
333
|
+
* ```typescript
|
|
334
|
+
* const graph = new ManagedCyclicGraph()
|
|
335
|
+
* .use(mcgEventListenerPlugin)
|
|
336
|
+
* .node('waitForEvent', {
|
|
337
|
+
* type: 'eventnode',
|
|
338
|
+
* meta: {
|
|
339
|
+
* event: pubsub('order-completed')
|
|
340
|
+
* }
|
|
341
|
+
* })
|
|
342
|
+
* ```
|
|
343
|
+
*/
|
|
344
|
+
exports.mcgEventListenerPlugin = {
|
|
345
|
+
nodes: {
|
|
346
|
+
eventnode,
|
|
347
|
+
},
|
|
348
|
+
};
|
|
349
|
+
exports.default = exports.mcgEventListenerPlugin;
|
|
350
|
+
//# sourceMappingURL=index.js.map
|
package/src/index.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../libs/drift/drift-plugins/mcg-event-listener/src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Plugin Manifest for @quarry-systems/mcg-event-listener
|
|
3
|
+
*
|
|
4
|
+
* This manifest declares the plugin's metadata, capabilities, and requirements.
|
|
5
|
+
* It enables future security policies, sandboxing, and hosted execution.
|
|
6
|
+
*/
|
|
7
|
+
import type { PluginManifest } from '@quarry-systems/drift-contracts';
|
|
8
|
+
export declare const manifest: PluginManifest;
|
|
9
|
+
export default manifest;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Plugin Manifest for @quarry-systems/mcg-event-listener
|
|
4
|
+
*
|
|
5
|
+
* This manifest declares the plugin's metadata, capabilities, and requirements.
|
|
6
|
+
* It enables future security policies, sandboxing, and hosted execution.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.manifest = void 0;
|
|
10
|
+
exports.manifest = {
|
|
11
|
+
name: '@quarry-systems/mcg-event-listener',
|
|
12
|
+
version: '0.6.0',
|
|
13
|
+
apiVersion: '1.0',
|
|
14
|
+
description: 'Event listener plugin for Managed Cyclic Graph (MCG)',
|
|
15
|
+
author: {
|
|
16
|
+
name: 'Quarry Systems',
|
|
17
|
+
email: 'support@quarrysystems.com',
|
|
18
|
+
},
|
|
19
|
+
license: 'ISC',
|
|
20
|
+
type: ['node'],
|
|
21
|
+
capabilities: {
|
|
22
|
+
network: false,
|
|
23
|
+
filesystem: false,
|
|
24
|
+
secrets: false,
|
|
25
|
+
subprocess: false,
|
|
26
|
+
},
|
|
27
|
+
nodes: [
|
|
28
|
+
{
|
|
29
|
+
id: 'eventListener',
|
|
30
|
+
name: 'Event Listener',
|
|
31
|
+
description: 'Listen for and handle events in the graph',
|
|
32
|
+
category: 'event',
|
|
33
|
+
},
|
|
34
|
+
],
|
|
35
|
+
services: [],
|
|
36
|
+
peerDependencies: {
|
|
37
|
+
'@quarry-systems/drift-core': '^0.6.0',
|
|
38
|
+
'@quarry-systems/drift-contracts': '^0.6.0',
|
|
39
|
+
},
|
|
40
|
+
keywords: ['drift', 'mcg', 'managed-cyclic-graph', 'plugin', 'event', 'listener', 'observer'],
|
|
41
|
+
repository: {
|
|
42
|
+
type: 'git',
|
|
43
|
+
url: 'https://github.com/quarry-systems/quarry-systems',
|
|
44
|
+
directory: 'libs/drift/drift-plugins/mcg-event-listener',
|
|
45
|
+
},
|
|
46
|
+
};
|
|
47
|
+
exports.default = exports.manifest;
|
|
48
|
+
//# sourceMappingURL=plugin.manifest.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin.manifest.js","sourceRoot":"","sources":["../../../../../../libs/drift/drift-plugins/mcg-event-listener/src/plugin.manifest.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AAIU,QAAA,QAAQ,GAAmB;IACtC,IAAI,EAAE,oCAAoC;IAC1C,OAAO,EAAE,OAAO;IAChB,UAAU,EAAE,KAAK;IAEjB,WAAW,EAAE,sDAAsD;IAEnE,MAAM,EAAE;QACN,IAAI,EAAE,gBAAgB;QACtB,KAAK,EAAE,2BAA2B;KACnC;IAED,OAAO,EAAE,KAAK;IAEd,IAAI,EAAE,CAAC,MAAM,CAAC;IAEd,YAAY,EAAE;QACZ,OAAO,EAAE,KAAK;QACd,UAAU,EAAE,KAAK;QACjB,OAAO,EAAE,KAAK;QACd,UAAU,EAAE,KAAK;KAClB;IAED,KAAK,EAAE;QACL;YACE,EAAE,EAAE,eAAe;YACnB,IAAI,EAAE,gBAAgB;YACtB,WAAW,EAAE,2CAA2C;YACxD,QAAQ,EAAE,OAAO;SAClB;KACF;IAED,QAAQ,EAAE,EAAE;IAEZ,gBAAgB,EAAE;QAChB,4BAA4B,EAAE,QAAQ;QACtC,iCAAiC,EAAE,QAAQ;KAC5C;IAED,QAAQ,EAAE,CAAC,OAAO,EAAE,KAAK,EAAE,sBAAsB,EAAE,QAAQ,EAAE,OAAO,EAAE,UAAU,EAAE,UAAU,CAAC;IAE7F,UAAU,EAAE;QACV,IAAI,EAAE,KAAK;QACX,GAAG,EAAE,kDAAkD;QACvD,SAAS,EAAE,6CAA6C;KACzD;CACF,CAAC;AAEF,kBAAe,gBAAQ,CAAC"}
|