From 9f6fabd8513b4d76efa842ffb6e6a832b9aa645f Mon Sep 17 00:00:00 2001 From: Owen Pearson Date: Mon, 16 May 2022 18:17:07 +0100 Subject: [PATCH 1/9] Add type definitions for lifecycle status results --- ably.d.ts | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/ably.d.ts b/ably.d.ts index 67709c0a55..5077b08b98 100644 --- a/ably.d.ts +++ b/ably.d.ts @@ -118,6 +118,30 @@ declare namespace Types { type Transport = 'web_socket' | 'xhr_streaming' | 'xhr_polling' | 'jsonp' | 'comet'; + interface ChannelDetails { + channelId: string; + name: string; + status: ChannelStatus; + } + + interface ChannelStatus { + isActive: boolean; + occupancy: ChannelOccupancy; + } + + interface ChannelOccupancy { + metrics: ChannelMetrics; + } + + interface ChannelMetrics { + connections: number; + presenceConnections: number; + presenceMembers: number; + presenceSubscribers: number; + publishers: number; + subscribers: number; + } + // Interfaces interface ClientOptions extends AuthOptions { /** From eb2d2311dc13d4f5f450a386a54d63311cd6239d Mon Sep 17 00:00:00 2001 From: Owen Pearson Date: Mon, 16 May 2022 21:43:32 +0100 Subject: [PATCH 2/9] Make Resource.get generic --- common/lib/client/resource.ts | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/common/lib/client/resource.ts b/common/lib/client/resource.ts index 15a06f0ce7..6f8b71eab8 100644 --- a/common/lib/client/resource.ts +++ b/common/lib/client/resource.ts @@ -30,7 +30,7 @@ function withAuthDetails( } } -function unenvelope(callback: ResourceCallback, format: Utils.Format | null): ResourceCallback { +function unenvelope(callback: ResourceCallback, format: Utils.Format | null): ResourceCallback { return (err, body, outerHeaders, unpacked, outerStatusCode) => { if (err && !body) { callback(err); @@ -88,8 +88,8 @@ function urlFromPathAndParams(path: string, params: Record) { return path + (params ? '?' : '') + paramString(params); } -function logResponseHandler( - callback: ResourceCallback, +function logResponseHandler( + callback: ResourceCallback, method: HttpMethods, path: string, params: Record @@ -116,27 +116,27 @@ function logResponseHandler( ); } if (callback) { - callback(err, body, headers, unpacked, statusCode); + callback(err, body as T, headers, unpacked, statusCode); } }; } -export type ResourceCallback = ( +export type ResourceCallback = ( err: ErrorInfo | null, - body?: unknown, + body?: T, headers?: Record, unpacked?: boolean, statusCode?: number ) => void; class Resource { - static get( + static get( rest: Rest, path: string, headers: Record, params: Record, envelope: Utils.Format | null, - callback: ResourceCallback + callback: ResourceCallback ): void { Resource.do(HttpMethods.Get, rest, path, null, headers, params, envelope, callback); } @@ -188,7 +188,7 @@ class Resource { Resource.do(HttpMethods.Put, rest, path, body, headers, params, envelope, callback); } - static do( + static do( method: HttpMethods, rest: Rest, path: string, @@ -196,7 +196,7 @@ class Resource { headers: Record, params: Record, envelope: Utils.Format | null, - callback: ResourceCallback + callback: ResourceCallback ): void { if (Logger.shouldLog(Logger.LOG_MICRO)) { callback = logResponseHandler(callback, method, path, params); From f7710418c11b489d577a0b20492b1eb389f029e9 Mon Sep 17 00:00:00 2001 From: Owen Pearson Date: Mon, 16 May 2022 21:43:56 +0100 Subject: [PATCH 3/9] Add implementation for channel status API --- common/lib/client/channel.ts | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/common/lib/client/channel.ts b/common/lib/client/channel.ts index 2be4280475..415c0bda7b 100644 --- a/common/lib/client/channel.ts +++ b/common/lib/client/channel.ts @@ -8,9 +8,10 @@ import ErrorInfo from '../types/errorinfo'; import PaginatedResource, { PaginatedResult } from './paginatedresource'; import Resource, { ResourceCallback } from './resource'; import { ChannelOptions } from '../../types/channel'; -import { PaginatedResultCallback } from '../../types/utils'; +import { PaginatedResultCallback, StandardCallback } from '../../types/utils'; import Rest from './rest'; import Realtime from './realtime'; +import * as API from '../../../ably'; interface RestHistoryParams { start?: number; @@ -189,6 +190,17 @@ class Channel extends EventEmitter { _publish(requestBody: unknown, headers: Record, params: any, callback: ResourceCallback): void { Resource.post(this.rest, this.basePath + '/messages', requestBody, headers, params, null, callback); } + + status(callback?: StandardCallback): void | Promise { + if (typeof callback !== 'function' && this.rest.options.promises) { + return Utils.promisify(this, 'status', []); + } + + const format = this.rest.options.useBinaryProtocol ? Utils.Format.msgpack : Utils.Format.json; + const headers = Utils.defaultPostHeaders(format); + + Resource.get(this.rest, this.basePath, headers, {}, format, callback || noop); + } } export default Channel; From 8e0f0a8d3f69c8def605a31dcdc9ac7260f4ddc2 Mon Sep 17 00:00:00 2001 From: Owen Pearson Date: Mon, 16 May 2022 21:47:06 +0100 Subject: [PATCH 4/9] Add callback and promise tests for RestChannel.status --- test/rest/status.test.js | 71 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 test/rest/status.test.js diff --git a/test/rest/status.test.js b/test/rest/status.test.js new file mode 100644 index 0000000000..3a0a2bbd8a --- /dev/null +++ b/test/rest/status.test.js @@ -0,0 +1,71 @@ +'use strict'; + +define(['shared_helper', 'chai'], function (helper, chai) { + var rest; + var utils = helper.Utils; + var expect = chai.expect; + + // RSL8 + describe('rest/status', function () { + this.timeout(30 * 1000); + + before(function (done) { + helper.setupApp(function (err) { + if (err) { + done(err); + return; + } + rest = helper.AblyRest(); + done(); + }); + }); + + it('status0', function (done) { + var channel = rest.channels.get('status0'); + channel.status(function (err, channelDetails) { + try { + expect(channelDetails.channelId).to.equal('status0'); + expect(channelDetails.status.isActive).to.be.a('boolean'); + var metrics = channelDetails.status.occupancy.metrics; + expect(metrics.connections).to.be.a('number'); + expect(metrics.presenceConnections).to.be.a('number'); + expect(metrics.presenceMembers).to.be.a('number'); + expect(metrics.presenceSubscribers).to.be.a('number'); + expect(metrics.publishers).to.be.a('number'); + expect(metrics.subscribers).to.be.a('number'); + done(); + } catch (err) { + done(err); + } + }); + }); + + if (typeof Promise !== 'undefined') { + it('statusPromise', function (done) { + var rest = helper.AblyRest({ promises: true }); + var channel = rest.channels.get('statusPromise'); + channel + .status() + .then(function (channelDetails) { + try { + expect(channelDetails.channelId).to.equal('statusPromise'); + expect(channelDetails.status.isActive).to.be.a('boolean'); + var metrics = channelDetails.status.occupancy.metrics; + expect(metrics.connections).to.be.a('number'); + expect(metrics.presenceConnections).to.be.a('number'); + expect(metrics.presenceMembers).to.be.a('number'); + expect(metrics.presenceSubscribers).to.be.a('number'); + expect(metrics.publishers).to.be.a('number'); + expect(metrics.subscribers).to.be.a('number'); + done(); + } catch (err) { + done(err); + } + }) + ['catch'](function (err) { + done(err); + }); + }); + } + }); +}); From 1924346974bb3f9a11187ed9003ef1c8ce92a51c Mon Sep 17 00:00:00 2001 From: Owen Pearson Date: Mon, 16 May 2022 21:54:55 +0100 Subject: [PATCH 5/9] Add README documentation for Channel.status --- README.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/README.md b/README.md index b31dca6e58..c0ce0bf215 100644 --- a/README.md +++ b/README.md @@ -459,6 +459,16 @@ client.stats(function(err, statsPage) { // statsPage as PaginatedResult client.time(function(err, time) { ... }); // time is in ms since epoch ``` +### Getting the status of a channel + +```javascript +channel.status(function(err, channelDetails) { + channelDetails.channelId // The name of the channel + channelDetails.status.isActive // A boolean indicating whether the channel is active + channelDetails.status.occupancy // Contains metadata relating to the occupants of the channel +}); +``` + ## Using the async API style ### Realtime Example @@ -530,6 +540,10 @@ const ablyRestPromiseExample = async () => { // Fetching the Ably service time const time = await client.time(); console.log(`Ably service time: ${time}`); + + // Getting the status of a channel + const channelDetails = await channel.status(); + console.log(channelDetails); client.close(); }; From 08ba046484c93e6b80ea5523599fba71fb106b69 Mon Sep 17 00:00:00 2001 From: Owen Pearson Date: Mon, 16 May 2022 21:55:10 +0100 Subject: [PATCH 6/9] Add Channel.status to public type API --- ably.d.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ably.d.ts b/ably.d.ts index 5077b08b98..71363d0934 100644 --- a/ably.d.ts +++ b/ably.d.ts @@ -674,6 +674,7 @@ declare namespace Types { publish(messages: any, callback?: errorCallback): void; publish(name: string, messages: any, callback?: errorCallback): void; publish(name: string, messages: any, options?: PublishOptions, callback?: errorCallback): void; + status(callback: StandardCallback): void; } class ChannelPromise extends ChannelBase { @@ -681,6 +682,7 @@ declare namespace Types { history: (params?: RestHistoryParams) => Promise>; publish(messages: any, options?: PublishOptions): Promise; publish(name: string, messages: any, options?: PublishOptions): Promise; + status(): Promise; } class RealtimeChannelBase extends EventEmitter { From a85cf714ce01850672991011591db71a746cb410 Mon Sep 17 00:00:00 2001 From: Owen Pearson Date: Tue, 17 May 2022 12:22:27 +0100 Subject: [PATCH 7/9] Remove ChannelDetails.name (deprecated in favour of channelId) --- ably.d.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/ably.d.ts b/ably.d.ts index 71363d0934..4bb6a8f451 100644 --- a/ably.d.ts +++ b/ably.d.ts @@ -120,7 +120,6 @@ declare namespace Types { interface ChannelDetails { channelId: string; - name: string; status: ChannelStatus; } From 435e339d704b5345953d3a389e0ce259359cc629 Mon Sep 17 00:00:00 2001 From: Owen Pearson Date: Fri, 27 May 2022 00:35:19 +0100 Subject: [PATCH 8/9] Remove browser/static from gitignore --- .gitignore | 1 - 1 file changed, 1 deletion(-) diff --git a/.gitignore b/.gitignore index 0bcff136f8..15e4cb7eff 100644 --- a/.gitignore +++ b/.gitignore @@ -4,5 +4,4 @@ ably-js.iml node_modules npm-debug.log .tool-versions -/browser/static build/ From 654699b7abf98fef65896920eb928199924471af Mon Sep 17 00:00:00 2001 From: Owen Pearson Date: Fri, 27 May 2022 00:37:08 +0100 Subject: [PATCH 9/9] Move channel status examples to be with other channel examples --- README.md | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 050aaea3f5..eccba53fc0 100644 --- a/README.md +++ b/README.md @@ -404,6 +404,16 @@ channel.presence.history(function(err, messagesPage) { // PaginatedResult channel.history({start: ..., end: ..., limit: ..., direction: ...}, function(err, messagesPage) { ...}); ``` +### Getting the status of a channel + +```javascript +channel.status(function(err, channelDetails) { + channelDetails.channelId // The name of the channel + channelDetails.status.isActive // A boolean indicating whether the channel is active + channelDetails.status.occupancy // Contains metadata relating to the occupants of the channel +}); +``` + ### Generate Token and Token Request See https://www.ably.com/docs/general/authentication for an @@ -460,16 +470,6 @@ client.stats(function(err, statsPage) { // statsPage as PaginatedResult client.time(function(err, time) { ... }); // time is in ms since epoch ``` -### Getting the status of a channel - -```javascript -channel.status(function(err, channelDetails) { - channelDetails.channelId // The name of the channel - channelDetails.status.isActive // A boolean indicating whether the channel is active - channelDetails.status.occupancy // Contains metadata relating to the occupants of the channel -}); -``` - ## Using the async API style ### Realtime Example @@ -528,6 +528,10 @@ const ablyRestPromiseExample = async () => { const history = await channel.history({ limit: 25 }); console.log(await history.current()); + // Getting the status of a channel + const channelDetails = await channel.status(); + console.log(channelDetails); + // Requesting a token const token = await client.auth.requestToken(tokenParams); @@ -542,10 +546,6 @@ const ablyRestPromiseExample = async () => { const time = await client.time(); console.log(`Ably service time: ${time}`); - // Getting the status of a channel - const channelDetails = await channel.status(); - console.log(channelDetails); - client.close(); };