Skip to content

Commit

Permalink
add config init (#480)
Browse files Browse the repository at this point in the history
Co-authored-by: Anmol <[email protected]>
  • Loading branch information
Zetazzz and Anmol1696 authored Jun 13, 2024
1 parent 6a82750 commit a8cf01b
Show file tree
Hide file tree
Showing 6 changed files with 191 additions and 21 deletions.
35 changes: 30 additions & 5 deletions clients/js/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ yarn starship start
# test
yarn starship:test

# watch
# watch
yarn starship:watch
```

Expand Down Expand Up @@ -205,7 +205,7 @@ client.undeploy();
client.teardown();
```

## StarshipJS Usage
## StarshipJS Usage

[`StarshipJS`](https://github.com/cosmology-tech/starship/tree/main/clients/js/packages/starshipjs) is a utility library that provides helpers to leverage [Starship](https://github.com/cosmology-tech/starship)'s internal chain registry, emulating the style of code used in projects like [cosmos-kit](https://github.com/cosmology-tech/cosmos-kit).

Expand All @@ -220,16 +220,41 @@ import { join } from 'path';
// Path to your YAML configuration file
const configFile = join(__dirname, 'your-config.yaml');

// Set the configuration file in StarshipJS
ConfigContext.setConfigFile(configFile);
// using init for init the config and a default connected registry fetcher.
await ConfigContext.init(configFile);

```

### Registry

Using init for init the config and pass an optional customized registry fetcher.

```js
import { useRegistry, ConfigContext } from 'starshipjs';
import { join } from 'path';

// Path to your YAML configuration file
const configFile = join(__dirname, 'your-config.yaml');

const fetcher = new ChainRegistryFetcher({
// your own options
});

await ConfigContext.init(configFile, fetcher);
```

Or use `useRegistry` to get a registry fetcher.

```js
import { useRegistry, ConfigContext } from 'starshipjs';
import { join } from 'path';

// Path to your YAML configuration file
const configFile = join(__dirname, 'your-config.yaml');

const fetcher = await useRegistry(configFile);

ConfigContext.setRegistry(await useRegistry(Config.configFile));
await ConfigContext.init(configFile, fetcher);
```

## Chain Info
Expand Down
33 changes: 29 additions & 4 deletions clients/js/packages/starshipjs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ yarn starship start-ports
yarn starship stop
```

## Using the Client
## Using the Client

StarshipJS is a utility library that provides helpers to leverage [Starship](https://github.com/cosmology-tech/starship)'s internal chain registry, emulating the style of code used in projects like [cosmos-kit](https://github.com/cosmology-tech/cosmos-kit).

Expand All @@ -107,16 +107,41 @@ import { join } from 'path';
// Path to your YAML configuration file
const configFile = join(__dirname, 'your-config.yaml');

// Set the configuration file in StarshipJS
ConfigContext.setConfigFile(configFile);
// using init for init the config and a default connected registry fetcher.
await ConfigContext.init(configFile);

```

### Registry

Using init for init the config and pass an optional customized registry fetcher.

```js
import { useRegistry, ConfigContext } from 'starshipjs';
import { join } from 'path';

// Path to your YAML configuration file
const configFile = join(__dirname, 'your-config.yaml');

const fetcher = new ChainRegistryFetcher({
// your own options
});

await ConfigContext.init(configFile, fetcher);
```

Or use `useRegistry` to get a registry fetcher.

```js
import { useRegistry, ConfigContext } from 'starshipjs';
import { join } from 'path';

// Path to your YAML configuration file
const configFile = join(__dirname, 'your-config.yaml');

const fetcher = await useRegistry(configFile);

ConfigContext.setRegistry(await useRegistry(Config.configFile));
await ConfigContext.init(configFile, fetcher);
```

## Chain Info
Expand Down
25 changes: 25 additions & 0 deletions clients/js/packages/starshipjs/__tests__/config.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import path from "path";

import { Config, ConfigContext } from "../src/config";
import { ChainRegistryFetcher } from "@chain-registry/client";

// it's more recommended to use ConfigContext.init to set the config file and registry.
it("1. throws without init;\n 2. init the setup and gets config;\n 3. throws when double init;\n", async () => {
expect(() => ConfigContext.registry).toThrow();
expect(() => ConfigContext.configFile).toThrow();

const file = path.join(__dirname, "../../../__fixtures__", "config.yaml");

// for unit test, only setup a chain registry fetcher without fetching.
await Config.init(file, new ChainRegistryFetcher());

const registry = ConfigContext.registry;
const configFile = ConfigContext.configFile;

expect(registry).toBeInstanceOf(ChainRegistryFetcher);
expect(configFile).toBe(file);

expect(
async () => await ConfigContext.init(file, new ChainRegistryFetcher())
).rejects.toThrow();
});
29 changes: 29 additions & 0 deletions clients/js/packages/starshipjs/__tests__/legacy.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import path from "path";

import { Config, ConfigContext } from "../src/config";
import { ChainRegistryFetcher } from "@chain-registry/client";

// people can still use legacy ConfigContext to set the config file and registry.
it("1. throws without init;\n 2. throws only init partially;\n 3. init the setup and gets config;\n 4. throws when double init;\n", async () => {
expect(() => ConfigContext.registry).toThrow();
expect(() => ConfigContext.configFile).toThrow();

const file = path.join(__dirname, "../../../__fixtures__", "config.yaml");

ConfigContext.setConfigFile(file);

expect(() => ConfigContext.registry).toThrow();
expect(() => ConfigContext.configFile).toThrow();

ConfigContext.setRegistry(new ChainRegistryFetcher());

const registry = ConfigContext.registry;
const configFile = ConfigContext.configFile;

expect(registry).toBeInstanceOf(ChainRegistryFetcher);
expect(configFile).toBe(file);

expect(
async () => await ConfigContext.init(file, new ChainRegistryFetcher())
).rejects.toThrow();
});
88 changes: 77 additions & 11 deletions clients/js/packages/starshipjs/src/config.ts
Original file line number Diff line number Diff line change
@@ -1,33 +1,99 @@
import { ChainRegistryFetcher } from '@chain-registry/client';
import { ChainRegistryFetcher } from "@chain-registry/client";

import { useRegistry } from "./hooks";

export class Config {
private static instance: Config;
// keep instantiation private to enforce singletone
private constructor() {}
public registry?: ChainRegistryFetcher;
public configFile?: string;
private isConfigInitialized = false;
private isRegistryInitialized = false;

// keep instantiation private to enforce singletone
private constructor() {}
private static instance: Config;

setConfigFile(configFile: string) {
this.configFile = configFile;
this.isConfigInitialized = true;
}

setRegistry(registry: ChainRegistryFetcher) {
this.registry = registry;
this.isRegistryInitialized = true;
}

private get isInitialized() {
return this.isConfigInitialized && this.isRegistryInitialized;
}

// init config with a config file and an optional registry fetcher
// if no registry fetcher is provided, it will use the default registry fetcher
// by enforcing the use of the init method, we can ensure that the config is initialized
public static async init(
configFile: string,
registryFetcher?: ChainRegistryFetcher
) {
if (Config.instance && Config.instance.isInitialized) {
throw new Error("Config is already initialized.");
}

const fetcher = registryFetcher ?? (await useRegistry(configFile));

Config.instance = new Config();
Config.instance.setConfigFile(configFile);
Config.instance.setRegistry(fetcher);
}

public static getInstance(): Config {
if (!Config.instance || !Config.instance.isInitialized) {
throw new Error("Config's not initialized.");
}

return Config.instance;
}

/**
* set the config file path
* @param configFile
* @depracated it's not recommended to set the configFile directly. Use init instead.
*/
public static setConfigFile(configFile: string) {
if (!Config.instance) {
Config.instance = new Config();
}
return Config.instance;

Config.instance.setConfigFile(configFile);
}

setConfigFile(configFile: string) {
this.configFile = configFile;
/**
* set the chain registry fetcher
* @param registry
* @depracated it's not recommended to set the registry directly. Use init instead.
*/
public static setRegistry(registry: ChainRegistryFetcher) {
if (!Config.instance) {
Config.instance = new Config();
}

Config.instance.setRegistry(registry);
}

setRegistry(registry: ChainRegistryFetcher) {
this.registry = registry;
public static get configFile() {
// use getInstance to ensure that the config is initialized.
return Config.getInstance().configFile;
}

public static get registry() {
// use getInstance to ensure that the config is initialized.
return Config.getInstance().registry;
}
}

export interface ChainConfig {
registry: {
ports: {
rest: number;
}
};
};
chains: Array<{
id: string;
Expand All @@ -43,4 +109,4 @@ export interface ChainConfig {
}>;
}

export const ConfigContext = Config.getInstance();
export const ConfigContext = Config;
2 changes: 1 addition & 1 deletion clients/js/packages/starshipjs/src/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import fs from 'fs';
import yaml from 'js-yaml';
import fetch from 'node-fetch';

import { ChainConfig, ConfigContext } from './config';
import { type ChainConfig, ConfigContext } from './config';

export const useRegistry = async (configFile: string): Promise<ChainRegistryFetcher> => {
const config = yaml.load(fs.readFileSync(configFile, 'utf8')) as ChainConfig;
Expand Down

0 comments on commit a8cf01b

Please sign in to comment.