Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions .github/workflows/npm-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ jobs:
publish-npm:
needs: build
runs-on: ubuntu-latest
permissions:
# Required for publishing to npm using "Trusted Publisher" OIDC authentication
contents: read
id-token: write
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
Expand All @@ -42,6 +46,4 @@ jobs:
with:
path: ./lib
key: ${{ github.sha }}
- run: npm publish
env:
NODE_AUTH_TOKEN: ${{secrets.npm_token}}
- run: npm publish --provenance
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "swampyer",
"version": "1.5.2",
"version": "1.6.0",
"description": "A lightweight WAMP client implementing the WAMP v2 basic profile",
"main": "lib/index.js",
"module": "lib/index.js",
Expand Down
35 changes: 35 additions & 0 deletions src/swampyer.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -741,6 +741,41 @@ describe(`${Swampyer.prototype.call.name}()`, () => {
});
});

describe(`${Swampyer.prototype.callWithResult.name}()`, () => {
const args = ['my_args'];
const kwargs = { my: 'kwargs' };

const resultDetails = { someWampInfo: 'info' };

beforeEach(async () => {
await openWamp();
});

it('sends a call request and receives the result', async () => {
const promise = wamp.callWithResult('com.test.something', args, kwargs);
const request = await transportProvider.transport.read();
expect(request).toEqual([MessageTypes.Call, expect.any(Number), {}, 'com.test.something', args, kwargs]);
transportProvider.sendToLib(MessageTypes.Result, [request[1] as number, resultDetails, ['something'], { something: 'else' }]);
expect(await promise).toEqual([['something'], { something: 'else' }, resultDetails]);
});

it('throws an error if the call request fails', async () => {
const promise = wamp.callWithResult('com.test.something', args, kwargs);
const request = await transportProvider.transport.read();
expect(request).toEqual([MessageTypes.Call, expect.any(Number), {}, 'com.test.something', args, kwargs]);
transportProvider.sendToLib(MessageTypes.Error, [MessageTypes.Call, request[1] as number, {}, 'something bad', [], {}]);
await expect(promise).rejects.toBeInstanceOf(SwampyerOperationError);
});

it('throws an error if a GOODBYE message is received before the call can be finished', async () => {
const promise = wamp.callWithResult('com.test.something', args, kwargs);
const request = await transportProvider.transport.read();
expect(request).toEqual([MessageTypes.Call, expect.any(Number), {}, 'com.test.something', args, kwargs]);
transportProvider.sendToLib(MessageTypes.Goodbye, [{}, 'com.some.reason']);
await expect(promise).rejects.toBeInstanceOf(ConnectionClosedError);
});
});

describe(`${Swampyer.prototype.unregister.name}()`, () => {
const regId = 1234;

Expand Down
37 changes: 33 additions & 4 deletions src/swampyer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,7 @@ export class Swampyer {
}

/**
* Call a WAMP URI and get its result
* Call a WAMP URI and get the full result
*
* @param uri The WAMP URI to call
*
Expand All @@ -281,14 +281,43 @@ export class Swampyer {
* @param args Positional arguments
* @param kwargs Keyword arguments
* @param options Settings for how the registration should be done. This may vary between WAMP servers
* @returns Arbitrary data returned by the call operation
* @returns A tuple containing the raw `args`, `kwargs` and the WAMP call's result `details`
*/
async call(uri: string, args: unknown[] = [], kwargs: Object = {}, options: CallOptions = {}): Promise<unknown> {
async callWithResult(
uri: string,
args: unknown[] = [],
kwargs: Object = {},
options: CallOptions = {}
): Promise<[args: unknown[], kwargs: Object, wampCallResultDetails: Object]> {
this.throwIfNotOpen();
const fullUri = options.withoutUriBase ? uri : this.getFullUri(uri);
const requestId = this.callRequestId;
this.callRequestId += 1;
const [, , resultArray] = await this.sendRequest(MessageTypes.Call, [requestId, options, fullUri, args, kwargs], MessageTypes.Result);
const [, details, resultArgs, resultKwargs] = await this.sendRequest(
MessageTypes.Call,
[requestId, options, fullUri, args, kwargs],
MessageTypes.Result
);
return [resultArgs, resultKwargs, details];
}

/**
* Call a WAMP URI and get the `args[0]` value from the result directly. This is convenient
* if the WAMP URI only ever returns useful data via the first positional argument.
*
* If you need access to the full result then use {@link callWithResult callWithResult()} instead.
*
* @param uri The WAMP URI to call
*
* If the `uriBase` options was defined when opening the connection then `uriBase` will be
* prepended to the provided URI (unless the appropriate value is set in `options`)
* @param args Positional arguments
* @param kwargs Keyword arguments
* @param options Settings for how the registration should be done. This may vary between WAMP servers
* @returns Arbitrary data defined at the `args[0]` value in the call operation's result
*/
async call(uri: string, args: unknown[] = [], kwargs: Object = {}, options: CallOptions = {}): Promise<unknown> {
const [resultArray] = await this.callWithResult(uri, args, kwargs, options);
return resultArray[0];
}

Expand Down