Skip to content

Commit

Permalink
changed: extend compose.up return value
Browse files Browse the repository at this point in the history
  • Loading branch information
Viktor Pasynok committed Nov 5, 2024
1 parent 02c08d4 commit db89ce3
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 26 deletions.
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": "@grlt-hub/app-compose",
"version": "1.0.0-next.0",
"version": "1.0.0-next.3",
"type": "module",
"private": false,
"main": "dist/index.js",
Expand Down
36 changes: 33 additions & 3 deletions src/compose/__tests__/up.spec-d.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,36 @@
import type { AnyContainer } from '../../createContainer';
import type { StoreValue } from 'effector';
import { createContainer, type AnyContainer } from '../../createContainer';
import { compose } from '../index';

test('compose.up parameters', () => {
expectTypeOf<Parameters<typeof compose.up>[0]>().toEqualTypeOf<AnyContainer[]>();
describe('compose.up', () => {
test('parameters', () => {
expectTypeOf<Parameters<typeof compose.up>[0]>().toEqualTypeOf<AnyContainer[]>();
});

test('return type', async () => {
const a = createContainer({
id: 'a',
start: () => ({ api: { t: () => true } }),
});
const b = createContainer({
id: 'b',
start: () => ({ api: { f: () => false } }),
});

const upResult = await compose.up([a, b]);

type UpResult = {
hasErrors: boolean;
statuses: {
[a.id]: StoreValue<typeof a.$status>;
[b.id]: StoreValue<typeof b.$status>;
};
apis: {
[a.id]?: { t: () => true };
[b.id]?: { f: () => false };
};
};

expectTypeOf<UpResult>().toEqualTypeOf<typeof upResult>();
});
});
47 changes: 32 additions & 15 deletions src/compose/__tests__/up.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,18 +22,18 @@ describe('compose.up', () => {
const a = createContainer({ id: genContainerId(), start: () => ({ api: null }) });

expect(compose.up([a])).resolves.toStrictEqual({
done: true,
hasErrors: false,
statuses: { [a.id]: CONTAINER_STATUS.done },
apis: { [a.id]: null },
});
});
test('enabled=true', () => {
const a = createContainer({ id: genContainerId(), start: () => ({ api: null }), enable: T });

expect(compose.up([a])).resolves.toStrictEqual({
done: true,
hasErrors: false,
statuses: { [a.id]: CONTAINER_STATUS.done },
apis: { [a.id]: null },
});
});
test('enabled=Promise<true>', () => {
Expand All @@ -44,18 +44,18 @@ describe('compose.up', () => {
});

expect(compose.up([a])).resolves.toStrictEqual({
done: true,
hasErrors: false,
statuses: { [a.id]: CONTAINER_STATUS.done },
apis: { [a.id]: null },
});
});
test('enabled=false', () => {
const a = createContainer({ id: genContainerId(), start: () => ({ api: null }), enable: F });

expect(compose.up([a])).resolves.toStrictEqual({
done: true,
hasErrors: false,
statuses: { [a.id]: CONTAINER_STATUS.off },
apis: {},
});
});
test('enabled=Promise<false>', () => {
Expand All @@ -66,9 +66,9 @@ describe('compose.up', () => {
});

expect(compose.up([a])).resolves.toStrictEqual({
done: true,
hasErrors: false,
statuses: { [a.id]: CONTAINER_STATUS.off },
apis: {},
});
});
});
Expand All @@ -80,9 +80,9 @@ describe('compose.up', () => {
const c = createContainer({ id: genContainerId(), start: () => ({ api: null }) });

expect(compose.up([a, b, c])).resolves.toStrictEqual({
done: true,
hasErrors: false,
statuses: { [a.id]: CONTAINER_STATUS.done, [b.id]: CONTAINER_STATUS.done, [c.id]: CONTAINER_STATUS.done },
apis: { [a.id]: null, [b.id]: null, [c.id]: null },
});
});
test('NOT all enabled', () => {
Expand All @@ -91,9 +91,9 @@ describe('compose.up', () => {
const c = createContainer({ id: genContainerId(), start: () => ({ api: null }) });

expect(compose.up([a, b, c])).resolves.toStrictEqual({
done: true,
hasErrors: false,
statuses: { [a.id]: CONTAINER_STATUS.done, [b.id]: CONTAINER_STATUS.off, [c.id]: CONTAINER_STATUS.done },
apis: { [a.id]: null, [c.id]: null },
});
});
});
Expand All @@ -114,9 +114,9 @@ describe('compose.up', () => {
});

expect(compose.up([a, b, c])).resolves.toStrictEqual({
done: true,
hasErrors: false,
statuses: { [a.id]: CONTAINER_STATUS.done, [b.id]: CONTAINER_STATUS.off, [c.id]: CONTAINER_STATUS.done },
apis: { [a.id]: null, [c.id]: null },
});
});
});
Expand Down Expand Up @@ -153,7 +153,7 @@ describe('compose.up', () => {
const accountsList = createContainer({
id: 'accounts-list',
dependsOn: [accountsEntity],
start: () => ({ api: { select: (x: string) => x } }),
start: () => ({ api: { select: null } }),
enable: (d) => d.accounts.list.length > 0,
});
const accountTransfers = createContainer({
Expand Down Expand Up @@ -210,7 +210,6 @@ describe('compose.up', () => {
]),
),
).rejects.toStrictEqual({
done: true,
hasErrors: true,
statuses: {
[userEntity.id]: CONTAINER_STATUS.done,
Expand All @@ -225,6 +224,17 @@ describe('compose.up', () => {
[hiddenEntity.id]: CONTAINER_STATUS.off,
[hiddenFeature.id]: CONTAINER_STATUS.off,
},
apis: {
[accountsEntity.id]: {
list: ['usd', 'eur'],
},
[accountsList.id]: {
select: null,
},
[userEntity.id]: {
id: '777',
},
},
});
});
});
Expand All @@ -245,12 +255,12 @@ describe('edge cases', () => {
});

expect(compose.up([a, b])).rejects.toStrictEqual({
done: true,
hasErrors: true,
statuses: {
[a.id]: 'fail',
[b.id]: 'fail',
},
apis: {},
});
});
test('optionalDependsOn failed', () => {
Expand All @@ -268,12 +278,14 @@ describe('edge cases', () => {
});

expect(compose.up([a, b])).rejects.toStrictEqual({
done: true,
hasErrors: true,
statuses: {
[a.id]: 'fail',
[b.id]: 'done',
},
apis: {
[b.id]: null,
},
});
});

Expand All @@ -297,13 +309,15 @@ describe('edge cases', () => {
});

expect(compose.up([a, b, c])).rejects.toStrictEqual({
done: true,
hasErrors: true,
statuses: {
[a.id]: 'fail',
[b.id]: 'done',
[c.id]: 'fail',
},
apis: {
[b.id]: null,
},
});
});

Expand All @@ -327,13 +341,16 @@ describe('edge cases', () => {
});

expect(compose.up([a, b, c])).rejects.toStrictEqual({
done: true,
hasErrors: true,
statuses: {
[a.id]: 'fail',
[b.id]: 'done',
[c.id]: 'done',
},
apis: {
[b.id]: null,
[c.id]: null,
},
});
});
test('dependsOn failed | optionalDependsOn failed', () => {
Expand All @@ -359,13 +376,13 @@ describe('edge cases', () => {
});

expect(compose.up([a, b, c])).rejects.toStrictEqual({
done: true,
hasErrors: true,
statuses: {
[a.id]: 'fail',
[b.id]: 'fail',
[c.id]: 'fail',
},
apis: {},
});
});
});
Expand Down
31 changes: 26 additions & 5 deletions src/compose/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { clearNode, combine, createEffect, launch, sample, type Store } from 'effector';
import { clearNode, combine, createEffect, launch, sample, type Store, type StoreValue } from 'effector';
import { type AnyContainer, CONTAINER_STATUS, type ContainerStatus } from '../createContainer';

const validateContainerId = (id: string, set: Set<string>) => {
Expand All @@ -16,7 +16,22 @@ const statusIs = {
idle: (s: ContainerStatus) => s === CONTAINER_STATUS.idle,
};

const upFn = async (containers: AnyContainer[], config?: { debug?: boolean }) => {
type Statuses<T extends AnyContainer[]> = {
[K in T[number]['id']]: ContainerStatus;
};
type APIs<T extends AnyContainer[]> = {
[K in T[number] as K['id']]?: K extends { start: (...args: any[]) => any }
? Awaited<ReturnType<K['start']>>['api']
: never;
};

type UpResult<T extends AnyContainer[]> = {
hasErrors: boolean;
statuses: Statuses<T>;
apis: APIs<T>;
};

const upFn = async <T extends AnyContainer[]>(containers: T, config?: { debug?: boolean }): Promise<UpResult<T>> => {
const CONTAINER_IDS = new Set<string>();

for (const container of containers) {
Expand Down Expand Up @@ -105,14 +120,20 @@ const upFn = async (containers: AnyContainer[], config?: { debug?: boolean }) =>
return new Promise((resolve, reject) => {
$result.watch((x) => {
if (x.done === true) {
apis = {};
nodesToClear.forEach((x) => clearNode(x, { deep: true }));
const res = {
hasErrors: x.hasErrors,
statuses: x.statuses,
apis,
};
apis = {};

if (x.hasErrors) {
reject(x);
reject(res);
}

resolve(x);
// @ts-expect-error
resolve(res);
}
});
});
Expand Down

0 comments on commit db89ce3

Please sign in to comment.