Skip to content

Commit

Permalink
Fixed tests; split options type module
Browse files Browse the repository at this point in the history
  • Loading branch information
forman committed Dec 11, 2024
1 parent 3ba54dc commit d597c8e
Show file tree
Hide file tree
Showing 10 changed files with 110 additions and 104 deletions.
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import type { ComponentType, FC } from "react";
import { describe, it, expect, beforeEach, afterEach } from "vitest";
import { configureFramework, resolvePlugin } from "./configureFramework";
import { store } from "@/store";
import { registry } from "@/components/registry";
import { ComponentProps } from "@/components/Component";
import { FC } from "react";
import type { HostStore } from "@/types/state/host";
import type { Plugin } from "@/types/state/plugin";
import type { ComponentProps } from "@/components/Component";

function getComponents() {
function getComponents(): [string, ComponentType<ComponentProps>][] {
interface DivProps extends ComponentProps {
text: string;
}
Expand Down Expand Up @@ -40,7 +42,7 @@ describe("configureFramework", () => {

it("should subscribe to host store", () => {
const listeners = [];
const hostStore = {
const hostStore: HostStore = {
get: (_key: string) => null,
subscribe: (l: () => void) => {
listeners.push(l);
Expand Down Expand Up @@ -71,7 +73,7 @@ describe("resolvePlugin", () => {
});

it("should resolve a object", async () => {
const pluginObj = { components: getComponents() };
const pluginObj: Plugin = { components: getComponents() };
expect(registry.types.length).toBe(0);
const result = await resolvePlugin(pluginObj);
expect(result).toBe(pluginObj);
Expand All @@ -98,7 +100,7 @@ describe("resolvePlugin", () => {

it("should resolve undefined", async () => {
expect(registry.types.length).toBe(0);
const result = await resolvePlugin(undefined);
const result = await resolvePlugin(undefined as unknown as Plugin);
expect(result).toBe(undefined);
expect(registry.types.length).toBe(0);
});
Expand Down
7 changes: 4 additions & 3 deletions chartlets.js/packages/lib/src/actions/configureFramework.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { store } from "@/store";
import type { FrameworkOptions } from "@/types/state/options";
import type {
ComponentRegistration,
FrameworkOptions,
Plugin,
PluginLike,
} from "@/types/state/options";
} from "@/types/state/plugin";
import { registry } from "@/components/registry";
import { isPromise } from "@/utils/isPromise";
import { isFunction } from "@/utils/isFunction";
Expand Down Expand Up @@ -38,7 +39,7 @@ export function resolvePlugin(plugin: PluginLike): Promise<Plugin | undefined> {
registry.register(name, component);
},
);
return Promise.resolve(plugin);
return Promise.resolve(plugin as Plugin);
}
return Promise.resolve(undefined);
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { store } from "@/store";
import type {
CallbackRef,
CallbackRequest,
Expand All @@ -10,8 +9,8 @@ import { getInputValues } from "@/actions/helpers/getInputValues";
import { formatObjPath } from "@/utils/objPath";
import { invokeCallbacks } from "@/actions/helpers/invokeCallbacks";
import type { ContributionState } from "@/types/state/contribution";
import type { HostStore } from "@/types/state/options";
import type { store } from "@/store";
import type { HostStore } from "@/types/state/host";
import { store } from "@/store";

/**
* A reference to a property of an input of a callback of a contribution.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,7 @@ import {
normalizeObjPath,
setValue,
} from "@/utils/objPath";
import {
isMutableHostStore,
type MutableHostStore,
} from "@/types/state/options";
import { isMutableHostStore, type MutableHostStore } from "@/types/state/host";
import {
isHostChannel,
isComponentChannel,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {
} from "@/types/state/component";
import { formatObjPath, getValue, type ObjPathLike } from "@/utils/objPath";
import { isObject } from "@/utils/isObject";
import type { HostStore } from "@/types/state/options";
import type { HostStore } from "@/types/state/host";

export function getInputValues(
inputs: Input[],
Expand Down
10 changes: 3 additions & 7 deletions chartlets.js/packages/lib/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,6 @@ export {
} from "@/hooks";

// Application interface
export type {
FrameworkOptions,
HostStore,
MutableHostStore,
Plugin,
PluginLike,
} from "@/types/state/options";
export type { HostStore, MutableHostStore } from "@/types/state/host";
export type { Plugin, PluginLike } from "@/types/state/plugin";
export type { FrameworkOptions } from "@/types/state/options";
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import {
type MutableHostStore,
isHostStore,
isMutableHostStore,
} from "./options";
} from "./host";

const hostStore: HostStore = {
get: (name: string) => name,
Expand Down
60 changes: 60 additions & 0 deletions chartlets.js/packages/lib/src/types/state/host.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { isObject } from "@/utils/isObject";
import { isFunction } from "@/utils/isFunction";

/**
* The host store represents an interface to the state of
* the application that is using Chartlets.
*/
export interface HostStore {
/**
* Let Chartlets listen to changes in the host store that may
* cause different values to be returned from the `get()` method.
*
* @param listener A listener that is called when the
* host store changes
*/
subscribe: (listener: () => void) => void;

/**
* Get a property value from the host state.
*
* @param property The property name.
* @returns The property value.
*/
get: (property: string) => unknown;

/**
* **UNSTABLE API**
*
* Set a property value in the host state.
*
* @param property The property name.
* @param value The new property value.
*/
set?: (property: string, value: unknown) => void;
}

/**
* A mutable host store implements the `set()` method.
*/
export interface MutableHostStore extends HostStore {
/**
* **UNSTABLE API**
*
* Set a property value in the host state.
*
* @param property The property name.
* @param value The new property value.
*/
set: (property: string, value: unknown) => void;
}

export function isHostStore(value: unknown): value is HostStore {
return (
isObject(value) && isFunction(value.get) && isFunction(value.subscribe)
);
}

export function isMutableHostStore(value: unknown): value is MutableHostStore {
return isHostStore(value) && isFunction(value.set);
}
81 changes: 2 additions & 79 deletions chartlets.js/packages/lib/src/types/state/options.ts
Original file line number Diff line number Diff line change
@@ -1,84 +1,7 @@
import type { ComponentType } from "react";

import type { ApiOptions } from "@/types/api";
import type { PluginLike } from "@/types/state/plugin";
import type { HostStore } from "@/types/state/host";
import type { LoggingOptions } from "@/actions/helpers/configureLogging";
import type { ComponentProps } from "@/components/Component";
import { isObject } from "@/utils/isObject";
import { isFunction } from "@/utils/isFunction";

/**
* The host store represents an interface to the state of
* the application that is using Chartlets.
*/
export interface HostStore {
/**
* Let Chartlets listen to changes in the host store that may
* cause different values to be returned from the `get()` method.
*
* @param listener A listener that is called when the
* host store changes
*/
subscribe: (listener: () => void) => void;

/**
* Get a property value from the host state.
*
* @param property The property name.
* @returns The property value.
*/
get: (property: string) => unknown;

/**
* **UNSTABLE API**
*
* Set a property value in the host state.
*
* @param property The property name.
* @param value The new property value.
*/
set?: (property: string, value: unknown) => void;
}

/**
* A mutable host store implements the `set()` method.
*/
export interface MutableHostStore extends HostStore {
/**
* **UNSTABLE API**
*
* Set a property value in the host state.
*
* @param property The property name.
* @param value The new property value.
*/
set: (property: string, value: unknown) => void;
}

export function isHostStore(value: unknown): value is HostStore {
return (
isObject(value) && isFunction(value.get) && isFunction(value.subscribe)
);
}

export function isMutableHostStore(value: unknown): value is MutableHostStore {
return isHostStore(value) && isFunction(value.set);
}

/**
* A framework plugin.
* Plugins are no-arg functions that are called
* after the framework's initialisation.
* Most typically, a plugin wants to return new components
* in the `components` array:
* `{ components: [["MyComponent", MyComponent]] }`.
*/
export interface Plugin {
components?: ComponentRegistration[];
}

export type ComponentRegistration = [string, ComponentType<ComponentProps>];

export type PluginLike = Plugin | (() => Plugin) | Promise<PluginLike>;

/**
* Chartlets options to be provided
Expand Down
28 changes: 28 additions & 0 deletions chartlets.js/packages/lib/src/types/state/plugin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import type { ComponentType } from "react";
import type { ComponentProps } from "@/components/Component";

/**
* A component registration - a pair comprising the component type name
* and the React component.
*/
export type ComponentRegistration = [string, ComponentType<ComponentProps>];

/**
* A framework plugin.
* Plugins are no-arg functions that are called
* after the framework's initialisation.
* Most typically, a plugin wants to return new components
* in the `components` array:
* `{ components: [["MyComponent", MyComponent]] }`.
*/
export interface Plugin {
components?: ComponentRegistration[];
}

/**
* An object of type `Plugin`, or a function that returns a
* value that can be resolved to a `Plugin`,
* or a promise that resolves to a value that can be
* resolved to a `Plugin`.
*/
export type PluginLike = Plugin | (() => PluginLike) | Promise<PluginLike>;

0 comments on commit d597c8e

Please sign in to comment.