Skip to content

Commit

Permalink
Standardized callback for watchSnapshot and scheduleSnapshotAutoUpdate (
Browse files Browse the repository at this point in the history
  • Loading branch information
petruki authored May 15, 2024
1 parent f671d0b commit a47caa0
Show file tree
Hide file tree
Showing 7 changed files with 65 additions and 38 deletions.
14 changes: 9 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ The context properties stores all information regarding connectivity.

> Initialization
```ts
import { Switcher } from "https://deno.land/x/switcher4deno@v[VERSION]/mod.ts";
import { Client } from "https://deno.land/x/switcher4deno@v[VERSION]/mod.ts";

const url = 'https://api.switcherapi.com';
const apiKey = '[API_KEY]';
Expand Down Expand Up @@ -207,9 +207,10 @@ const version = await Client.loadSnapshot();
Activate and monitor snapshot changes using this feature. Optionally, you can implement any action based on the callback response.

```ts
Client.watchSnapshot(
() => console.log('In-memory snapshot updated'),
(err: any) => console.log(err));
Client.watchSnapshot({
success: () => console.log('In-memory snapshot updated'),
reject: (err: Error) => console.log(err)
});
```

## Snapshot version check
Expand All @@ -224,5 +225,8 @@ You can also schedule a snapshot update using the method below.<br>
It allows you to run the Client SDK in local mode (zero latency) and still have the snapshot updated automatically.

```ts
Client.scheduleSnapshotAutoUpdate(1 * 60 * 60 * 24); // 24 hours
Client.scheduleSnapshotAutoUpdate(3000, {
success: (updated) => console.log('Snapshot updated', updated),
reject: (err: Error) => console.log(err)
});
```
33 changes: 22 additions & 11 deletions src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import { Auth } from './lib/remote-auth.ts';
*
* 1. Use Client.buildContext() to define the arguments to connect to the API.
* 2. Use Client.getSwitcher() to create a new instance of Switcher.
* 3. Use the instance created to call isItOn to query the API.
* 3. Use the instance created to call isItOn to execute criteria evaluation.
*/
export class Client {
private static _testEnabled = DEFAULT_TEST_MODE;
Expand Down Expand Up @@ -178,14 +178,16 @@ export class Client {
* Start watching snapshot files for modifications
*
* @param success when snapshot has successfully updated
* @param error when any error has thrown when attempting to load snapshot
* @param reject when any error has thrown when attempting to load snapshot
*/
static async watchSnapshot(
success: () => void | Promise<void> = () => {},
error: (err: Error) => void = () => {},
): Promise<void> {
static async watchSnapshot(callback: {
success?: () => void | Promise<void>;
reject?: (err: Error) => void;
} = {}): Promise<void> {
const { success = () => {}, reject = () => {} } = callback;

if (Client._testEnabled || !Client._options.snapshotLocation?.length) {
return error(new Error('Watch Snapshot cannot be used in test mode or without a snapshot location'));
return reject(new Error('Watch Snapshot cannot be used in test mode or without a snapshot location'));
}

const snapshotFile = `${Client._options.snapshotLocation}/${Client._context.environment}.json`;
Expand All @@ -200,7 +202,7 @@ export class Client {

Client._watchDebounce.set(
dataString,
setTimeout(() => Client._onModifySnapshot(dataString, event, success, error), 20),
setTimeout(() => Client._onModifySnapshot(dataString, event, success, reject), 20),
);
}
}
Expand Down Expand Up @@ -251,15 +253,24 @@ export class Client {
*/
static scheduleSnapshotAutoUpdate(
interval?: number,
success?: (updated: boolean) => void,
reject?: (err: Error) => void,
callback: {
success?: (updated: boolean) => void;
reject?: (err: Error) => void;
} = {},
) {
const { success = () => {}, reject = () => {} } = callback;

if (interval) {
Client._options.snapshotAutoUpdateInterval = interval;
}

if (Client._options.snapshotAutoUpdateInterval && Client._options.snapshotAutoUpdateInterval > 0) {
SnapshotAutoUpdater.schedule(Client._options.snapshotAutoUpdateInterval, this.checkSnapshot, success, reject);
SnapshotAutoUpdater.schedule(
Client._options.snapshotAutoUpdateInterval,
this.checkSnapshot,
success,
reject,
);
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/lib/bypasser/key.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Type definition for Switcher Keys which are used to mock results
* Key record used to store key response when bypassing criteria execution
*/
export default class Key {
key: string;
Expand Down
4 changes: 2 additions & 2 deletions src/lib/utils/snapshotAutoUpdater.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ export default class SnapshotAutoUpdater {
static schedule(
interval: number,
checkSnapshot: () => Promise<boolean>,
success: (updated: boolean) => void = () => {},
reject: (err: Error) => void = () => {},
success: (updated: boolean) => void,
reject: (err: Error) => void,
) {
if (this._intervalId) {
this.terminate();
Expand Down
16 changes: 9 additions & 7 deletions test/playground/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -141,10 +141,11 @@ const _testWatchSnapshot = async () => {
.catch(() => console.log('Failed to load Snapshot'));

const switcher = Client.getSwitcher();

Client.watchSnapshot(
async () => console.log('In-memory snapshot updated', await switcher.isItOn(SWITCHER_KEY)),
(err: Error) => console.log(err));

Client.watchSnapshot({
success: async () => console.log('In-memory snapshot updated', await switcher.isItOn(SWITCHER_KEY)),
reject: (err: Error) => console.log(err)
});
};

// Requires remote API
Expand All @@ -155,9 +156,10 @@ const _testSnapshotAutoUpdate = async () => {
await Client.loadSnapshot(false, true);
const switcher = Client.getSwitcher();

Client.scheduleSnapshotAutoUpdate(3,
(updated) => console.log('In-memory snapshot updated', updated),
(err: Error) => console.log(err));
Client.scheduleSnapshotAutoUpdate(3, {
success: (updated) => console.log('In-memory snapshot updated', updated),
reject: (err: Error) => console.log(err)
});

setInterval(async () => {
const time = Date.now();
Expand Down
10 changes: 7 additions & 3 deletions test/switcher-snapshot.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -153,8 +153,10 @@ describe('E2E test - Client local - Snapshot:', function () {
});

let snapshotUpdated = false;
Client.scheduleSnapshotAutoUpdate(1, (updated) => snapshotUpdated = updated);

Client.scheduleSnapshotAutoUpdate(1, {
success: (updated) => snapshotUpdated = updated
});

await Client.loadSnapshot(false, true);

const switcher = Client.getSwitcher();
Expand Down Expand Up @@ -188,7 +190,9 @@ describe('E2E test - Client local - Snapshot:', function () {
});

let error: Error | undefined;
Client.scheduleSnapshotAutoUpdate(1, undefined, (err: Error) => error = err);
Client.scheduleSnapshotAutoUpdate(1, {
reject: (err: Error) => error = err
});

await Client.loadSnapshot(false, true);

Expand Down
24 changes: 15 additions & 9 deletions test/switcher-watch-snapshot.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,11 @@ describe('E2E test - Client local - Watch Snapshot:', function () {

it('should read from updated snapshot', async function () {
const switcher = Client.getSwitcher();
Client.watchSnapshot(async () => {
assertFalse(await switcher.isItOn('FF2FOR2030'));
WaitSafe.finish();
Client.watchSnapshot({
success: async () => {
assertFalse(await switcher.isItOn('FF2FOR2030'));
WaitSafe.finish();
}
});

switcher.isItOn('FF2FOR2030').then((val) => {
Expand All @@ -71,9 +73,11 @@ describe('E2E test - Client local - Watch Snapshot:', function () {

it('should NOT read from updated snapshot - invalid JSON', async function () {
const switcher = Client.getSwitcher();
Client.watchSnapshot(undefined, (err: any) => {
assertEquals(err.message, 'Something went wrong: It was not possible to load the file at generated-snapshots/');
WaitSafe.finish();
Client.watchSnapshot({
reject: (err: any) => {
assertEquals(err.message, 'Something went wrong: It was not possible to load the file at generated-snapshots/');
WaitSafe.finish();
}
});

switcher.isItOn('FF2FOR2030').then((val) => {
Expand All @@ -87,9 +91,11 @@ describe('E2E test - Client local - Watch Snapshot:', function () {

it('should NOT allow to watch snapshot - Client test is enabled', async function () {
Client.testMode();
Client.watchSnapshot(undefined, (err: any) => {
assertEquals(err.message, 'Watch Snapshot cannot be used in test mode or without a snapshot location');
WaitSafe.finish();
Client.watchSnapshot({
reject: (err: any) => {
assertEquals(err.message, 'Watch Snapshot cannot be used in test mode or without a snapshot location');
WaitSafe.finish();
}
});

await WaitSafe.wait();
Expand Down

0 comments on commit a47caa0

Please sign in to comment.