Skip to content

Commit

Permalink
Merge pull request #1262 from moleculerjs/remove-legacy-event-handler
Browse files Browse the repository at this point in the history
[0.15] Remove legacy event handler
  • Loading branch information
icebob authored Nov 25, 2023
2 parents b95b2a8 + 2b5688a commit 9b9a5db
Show file tree
Hide file tree
Showing 11 changed files with 124 additions and 255 deletions.
35 changes: 35 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,41 @@ The reason is desribed in this issue: https://github.com/moleculerjs/moleculer/i

If you use one of those, you should change it to one of these schemaless serializers: MsgPack, Notepack.io, JSON, JSONExt, CBOR

## Legacy event handler is removed

The legacy event handler signature (`user.created(payload, sender, eventName)`) is removed. You should use the new `Context` based signature which was introduced in version 0.14.

**Legacy event handler**

```js
module.exports = {
name: "accounts",
events: {
"user.created"(payload, sender, eventName) {
// ...
}
}
};
```

**Supported event handler**

```js
module.exports = {
name: "accounts",
events: {
"user.created"(ctx) {
console.log("Payload:", ctx.params);
console.log("Sender:", ctx.nodeID);
console.log("We have also metadata:", ctx.meta);
console.log("The called event name:", ctx.eventName);

// ...
}
}
};
```

## Action streaming

The built-in `Stream` sending has been rewritten. Now it accepts `params` besides the `Stream` instance.
Expand Down
35 changes: 35 additions & 0 deletions docs/MIGRATION_GUIDE_0.15.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,41 @@ This documentation leads you how you can migrate your project to be compatible w
>}
>```
## Legacy event handler is removed
The legacy event handler signature (`user.created(payload, sender, eventName)`) is removed. You should use the new `Context` based signature which was introduced in version 0.14.
**Legacy event handler**
```js
module.exports = {
name: "accounts",
events: {
"user.created"(payload, sender, eventName) {
// ...
}
}
};
```
**Supported event handler**

```js
module.exports = {
name: "accounts",
events: {
"user.created"(ctx) {
console.log("Payload:", ctx.params);
console.log("Sender:", ctx.nodeID);
console.log("We have also metadata:", ctx.meta);
console.log("The called event name:", ctx.eventName);

// ...
}
}
};
```

## New action streaming

The built-in `Stream` sending has been rewritten. Now it accepts `params` besides the `Stream` instance.
Expand Down
25 changes: 3 additions & 22 deletions src/service.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

const _ = require("lodash");
const { ServiceSchemaError, MoleculerError } = require("./errors");
const { isObject, isFunction, flatten, functionArguments, uniq } = require("./utils");
const { isObject, isFunction, flatten, uniq } = require("./utils");

/**
* Import types
Expand Down Expand Up @@ -38,10 +38,6 @@ function wrapToArray(o) {
return Array.isArray(o) ? o : [o];
}

function isNewSignature(args) {
return args.length > 0 && ["ctx", "context"].indexOf(args[0].toLowerCase()) !== -1;
}

/**
* Service class
*
Expand Down Expand Up @@ -468,15 +464,10 @@ class Service {
// New: handler(ctx)
let handler;
if (isFunction(event.handler)) {
const args = functionArguments(event.handler);
handler = this.Promise.method(event.handler);
// @ts-ignore
handler.__newSignature = event.context === true || isNewSignature(args);
} else if (Array.isArray(event.handler)) {
handler = event.handler.map(h => {
const args = functionArguments(h);
h = this.Promise.method(h);
h.__newSignature = event.context === true || isNewSignature(args);
return h;
});
}
Expand All @@ -488,22 +479,12 @@ class Service {
if (isFunction(handler)) {
// Call single handler
event.handler = function (ctx) {
return handler.apply(
self,
handler.__newSignature ? [ctx] : [ctx.params, ctx.nodeID, ctx.eventName, ctx]
);
return handler.call(self, ctx);
};
} else if (Array.isArray(handler)) {
// Call multiple handler
event.handler = function (ctx) {
return self.Promise.all(
handler.map(fn =>
fn.apply(
self,
fn.__newSignature ? [ctx] : [ctx.params, ctx.nodeID, ctx.eventName, ctx]
)
)
);
return self.Promise.all(handler.map(fn => fn.call(self, ctx)));
};
}

Expand Down
4 changes: 0 additions & 4 deletions src/utils.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,3 @@ export declare function makeDirs(path: string): void;
export declare function parseByteString(value: string): number;

export declare function uniq(arr: Array<String|Number>): Array<String|Number>;

export declare function functionArguments(function_: Function): Array<String>;


118 changes: 0 additions & 118 deletions src/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -504,124 +504,6 @@ const utils = {
return false;
},

/**
* Detects the argument names of a function.
* Credits: https://github.com/sindresorhus/fn-args
*
* @param {Function} function_
* @returns {Array<String>}
*/
functionArguments(function_) {
if (typeof function_ !== "function") {
throw new TypeError("Expected a function");
}

const commentRegex = /(\/\*([\s\S]*?)\*\/|([^:]|^)\/\/(.*)$)/gm;
const quotes = ["`", '"', "'"];

const functionSource = function_.toString().replace(commentRegex, ""); // Function with no comments

let functionWithNoDefaults = "";
let depth = 0; // () [] {}
let index = 0;

// To remove default values we can not use regexp because finite automaton can not handle such
// things as (potential) infinity-nested blocks (), [], {}

// Remove default values
for (; index < functionSource.length && functionSource.charAt(index) !== ")"; index += 1) {
// Exiting if an arrow occurs. Needed when arrow function without '()'.
if (functionSource.startsWith("=>", index)) {
functionWithNoDefaults = functionSource;
index = functionSource.length;
break;
}

// If we found a default value - skip it
if (functionSource.charAt(index) === "=") {
for (
;
index < functionSource.length &&
((functionSource.charAt(index) !== "," &&
functionSource.charAt(index) !== ")") ||
depth !== 0);
index += 1
) {
// Skip all quotes
let wasQuote = false;

for (const quote of quotes) {
if (functionSource.charAt(index) === quote) {
index += 1;

for (
;
index < functionSource.length &&
functionSource.charAt(index) !== quote;

) {
index += 1;
}

wasQuote = true;
break;
}
}

// If any quote type was skipped, start the cycle again
if (wasQuote) {
continue;
}

switch (
functionSource.charAt(index) // Keeps correct depths of all types of parenthesises
) {
case "(":
case "[":
case "{":
depth += 1;
break;
case ")":
case "]":
case "}":
depth -= 1;
break;
default:
}
}

if (functionSource.charAt(index) === ",") {
functionWithNoDefaults += ",";
}

if (functionSource.charAt(index) === ")") {
// Quits from the cycle immediately
functionWithNoDefaults += ")";
break;
}
} else {
functionWithNoDefaults += functionSource.charAt(index);
}
}

if (index < functionSource.length && functionSource.charAt(index) === ")") {
functionWithNoDefaults += ")";
}

// The first part matches parens-less arrow functions
// The second part matches the rest
const regexFnArguments = /^(?:async)?([^=()]+)=|\(([^)]+)\)/;

const match = regexFnArguments.exec(functionWithNoDefaults);

return match
? (match[1] || match[2])
.split(",")
.map(x => x.trim())
.filter(Boolean)
: [];
},

/**
* Creates a duplicate-free version of an array
*
Expand Down
11 changes: 5 additions & 6 deletions test/integration/broker-transit.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,12 +72,11 @@ describe("Test RPC", () => {
it("should emit & receive an event via transporter", () => {
return b1.call("echo.emitter", { a: 5 }).then(() => {
expect(eventHandler).toHaveBeenCalledTimes(1);
expect(eventHandler).toHaveBeenCalledWith(
{ a: 5 },
"node-2",
"emitter.hello.event",
expect.any(b1.ContextFactory)
);
expect(eventHandler).toHaveBeenCalledWith(expect.any(b1.ContextFactory));
let ctx = eventHandler.mock.calls[0][0];
expect(ctx.params).toEqual({ a: 5 });
expect(ctx.eventName).toBe("emitter.hello.event");
expect(ctx.nodeID).toBe("node-2");
});
});

Expand Down
Loading

0 comments on commit 9b9a5db

Please sign in to comment.