Skip to content

Commit

Permalink
support TTypes['events']
Browse files Browse the repository at this point in the history
  • Loading branch information
Andarist committed Sep 12, 2024
1 parent a0c962b commit 3ffa8dc
Show file tree
Hide file tree
Showing 3 changed files with 200 additions and 35 deletions.
10 changes: 7 additions & 3 deletions packages/xstate-store/src/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -258,15 +258,19 @@ export function createStore<
}: {
context: TContext;
on: {
[K in keyof TEventPayloadMap & string]:
[K in
| (keyof TEventPayloadMap & string)
| Cast<TTypes['events'], EventObject>['type']]:
| StoreAssigner<
NoInfer<TContext>,
{ type: K } & TEventPayloadMap[K],
{ type: K } & TEventPayloadMap[K] &
Cast<TTypes['events'], EventObject>,
Cast<TTypes['emitted'], EventObject>
>
| StorePropertyAssigner<
NoInfer<TContext>,
{ type: K } & TEventPayloadMap[K],
{ type: K } & TEventPayloadMap[K] &
Cast<TTypes['events'], EventObject>,
Cast<TTypes['emitted'], EventObject>
>;
};
Expand Down
32 changes: 0 additions & 32 deletions packages/xstate-store/test/store.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -204,38 +204,6 @@ it('can be inspected', () => {
]);
});

it('emits (types)', () =>
new Promise<void>((res) => {
const store = createStore({
types: {
emitted: {} as
| { type: 'increased'; upBy: number }
| { type: 'decreased'; downBy: number }
},
context: {
count: 0
},
on: {
inc: {
count: (ctx, _: {}, enq) => {
enq.emit({ type: 'increased', upBy: 1 });

// @ts-expect-error
enq.emit({ type: 'unknown' });
return ctx.count + 1;
}
}
}
});

store.on('increased', (ev) => {
expect(ev).toEqual({ type: 'increased', upBy: 1 });
res();
});

store.send({ type: 'inc' });
}));

it('emitted events can be subscribed to', () => {
const store = createStore({

Check failure on line 208 in packages/xstate-store/test/store.test.ts

View workflow job for this annotation

GitHub Actions / build

No overload matches this call.
types: {
Expand Down
193 changes: 193 additions & 0 deletions packages/xstate-store/test/types.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
import { createStore } from '../src';

describe('events', () => {
it('can infer supported events', () => {
const store = createStore({
types: {},
context: {},
on: {
INC: (ctx, payload: { upBy: number }) => {},
DEC: (ctx, payload: { downBy: number }) => {}
}
});

store.send({ type: 'INC', upBy: 1 });
store.send({ type: 'DEC', downBy: 1 });
store.send({
// @ts-expect-error
type: 'UNKNOWN'
});
store.send({
type: 'INC',
// @ts-expect-error
upBy: 'bazinga'
});
store.send({
type: 'DEC',
// @ts-expect-error
downBy: 'bazinga'
});
});

it('can provide event types', () => {
createStore({
types: {} as {
events:
| {
type: 'INC';
upBy: number;
}
| {
type: 'DEC';
downBy: number;
};
},
context: {},
on: {
INC: (ctx, payload) => {
payload satisfies { upBy: number };
},
DEC: (ctx, payload) => {
payload satisfies { downBy: number };
}
}
});
});

it('requires implementing transitions for all provided event types', () => {
// @ts-expect-error
createStore({
types: {} as {
events:
| {
type: 'INC';
upBy: number;
}
| {
type: 'DEC';
downBy: number;
};
},
context: {},
on: {
INC: () => {}
}
});
});
});

describe('emitted', () => {
it('can emit a known event', () => {
createStore({
types: {
emitted: {} as
| { type: 'increased'; upBy: number }
| { type: 'decreased'; downBy: number }
},
context: {},
on: {
inc: {
count: (ctx, _: {}, enq) => {
enq.emit({ type: 'increased', upBy: 1 });
return ctx;
}
}
}
});
});

it("can't emit an unknown event", () => {
createStore({
types: {
emitted: {} as
| { type: 'increased'; upBy: number }
| { type: 'decreased'; downBy: number }
},
context: {},
on: {
inc: {
count: (ctx, _: {}, enq) => {
enq.emit({
// @ts-expect-error
type: 'unknown'
});
return ctx;
}
}
}
});
});

it("can't emit a known event with wrong payload", () => {
createStore({
types: {
emitted: {} as
| { type: 'increased'; upBy: number }
| { type: 'decreased'; downBy: number }
},
context: {},
on: {
inc: {
count: (ctx, _: {}, enq) => {
enq.emit({
type: 'increased',
// @ts-expect-error
upBy: 'bazinga'
});
return ctx;
}
}
}
});
});

it('can emit an event when emitted events are unknown', () => {
createStore({
context: {},
on: {
inc: {
count: (ctx, _: {}, enq) => {
enq.emit({
type: 'unknown'
});
return ctx;
}
}
}
});
});

it('can subscribe to a known event', () => {
const store = createStore({
types: {
emitted: {} as
| { type: 'increased'; upBy: number }
| { type: 'decreased'; downBy: number }
},
context: {},
on: {}
});

store.on('increased', (ev) => {
ev satisfies { type: 'increased'; upBy: number };
});
});

it("can can't subscribe to a unknown event", () => {
const store = createStore({
types: {
emitted: {} as
| { type: 'increased'; upBy: number }
| { type: 'decreased'; downBy: number }
},
context: {},
on: {}
});

store.on(
// @ts-expect-error
'unknown',
(ev) => {}
);
});
});

0 comments on commit 3ffa8dc

Please sign in to comment.