Skip to content

Commit

Permalink
Add shorthands for common methods (#315)
Browse files Browse the repository at this point in the history
* Add `debounce(source, timeout)` shorthand

* Add `delay(source, timeout)`

* Add `throttle(source, timeout)` shorthand

* add `status(fx)` shorthand

* Add `pending(effects)` shorthand

* Add `inFlight(effects)` shorthand

* Add `combineEvents(events)` shorthand

* Add `spread(targets)` shorthand

* Add `time(clock)` shorthand

* Update sids in snapshots
  • Loading branch information
zerobias committed Dec 15, 2023
1 parent 4a0e139 commit 777a8e7
Show file tree
Hide file tree
Showing 39 changed files with 1,872 additions and 353 deletions.
2 changes: 1 addition & 1 deletion integration/cra/src/demo.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@ import { $pending } from './demo';
test('should have sid', () => {
expect($pending.sid).toBeDefined();
expect($pending.sid).not.toBeNull();
expect($pending.sid).toMatchInlineSnapshot(`"-y29r2v|a37bj0"`);
expect($pending.sid).toMatchInlineSnapshot(`"-y29r2v|a4upb3"`);
});
4 changes: 2 additions & 2 deletions integration/custom/test/integration.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ test('status has sid', () => {

expect($status.sid).toBeDefined();
expect($status.sid).not.toBeNull();
expect($status.sid).toMatchInlineSnapshot(`"-o5m1b3|abrgim"`);
expect($status.sid).toMatchInlineSnapshot(`"-o5m1b3|ph7d4u"`);
});

test('pending macro works as expected', () => {
Expand All @@ -38,7 +38,7 @@ test('pending macro works as expected', () => {

expect($pending.sid).toBeDefined();
expect($pending.sid).not.toBeNull();
expect($pending.sid).toMatchInlineSnapshot(`"-hszfx7|a37bj0"`);
expect($pending.sid).toMatchInlineSnapshot(`"-hszfx7|a4upb3"`);
});

function waitFor<T>(unit: Event<T>) {
Expand Down
219 changes: 219 additions & 0 deletions src/combine-events/combine-events.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,152 @@ test('source: shape', () => {
`);
});

test('source: shape (shorthand)', () => {
const fn = jest.fn();

const event1 = createEvent<string | void>();
const event2 = createEvent<string | void>();
const event3 = createEvent<string | void>();
const event4 = createEvent<string | void>();
const event5 = createEvent<string | void>();

type Target = Event<{
event1: string | void;
event2: string | void;
event3: string | void;
event4: string | void;
event5: string | void;
}>;

const event: Target = combineEvents({
event1,
event2,
event3,
event4,
event5,
});

event.watch(fn);

event1();
event1();
event2('-');
event3('c');
event2('b');
event2();
event4();
event4('d');
event5('e');

expect(argumentHistory(fn)).toMatchInlineSnapshot(`
[
{
"event1": undefined,
"event2": undefined,
"event3": "c",
"event4": "d",
"event5": "e",
},
]
`);

event1('a');
event2('-');
event3();
event2('b');
event3();

expect(argumentHistory(fn)).toMatchInlineSnapshot(`
[
{
"event1": undefined,
"event2": undefined,
"event3": "c",
"event4": "d",
"event5": "e",
},
]
`);
event4('-');
event4();
event5('e');

expect(argumentHistory(fn)).toMatchInlineSnapshot(`
[
{
"event1": undefined,
"event2": undefined,
"event3": "c",
"event4": "d",
"event5": "e",
},
{
"event1": "a",
"event2": "b",
"event3": undefined,
"event4": undefined,
"event5": "e",
},
]
`);

event1('1');
event2('-');
event3('-');
event2('2');
event3('3');
event4('-');
event4('4');

expect(argumentHistory(fn)).toMatchInlineSnapshot(`
[
{
"event1": undefined,
"event2": undefined,
"event3": "c",
"event4": "d",
"event5": "e",
},
{
"event1": "a",
"event2": "b",
"event3": undefined,
"event4": undefined,
"event5": "e",
},
]
`);

event5('5');
event5('-');

expect(argumentHistory(fn)).toMatchInlineSnapshot(`
[
{
"event1": undefined,
"event2": undefined,
"event3": "c",
"event4": "d",
"event5": "e",
},
{
"event1": "a",
"event2": "b",
"event3": undefined,
"event4": undefined,
"event5": "e",
},
{
"event1": "1",
"event2": "2",
"event3": "3",
"event4": "4",
"event5": "5",
},
]
`);
});

test('source: array', () => {
const fn = jest.fn();

Expand Down Expand Up @@ -225,6 +371,79 @@ test('source: array', () => {
`);
});

test('source: array (shorthand)', () => {
const fn = jest.fn();

const event1 = createEvent<string | void>();
const event2 = createEvent<string | void>();
const event3 = createEvent<string | void>();
const event4 = createEvent<string | void>();
const event5 = createEvent<string | void>();

type Target = Event<
[string | void, string | void, string | void, string | void, string | void]
>;

const event: Target = combineEvents([event1, event2, event3, event4, event5]);

event.watch(fn);

event1();
event1();
event2('-');
event3('c');
event2('b');
event2();
event4();
event4('d');
event5('e');

event1('a');
event2('-');
event3();
event2('b');
event3();
event4('-');
event4();
event5('e');

event1('1');
event2('-');
event3('-');
event2('2');
event3('3');
event4('-');
event4('4');
event5('5');
event5('-');

expect(argumentHistory(fn)).toMatchInlineSnapshot(`
[
[
undefined,
undefined,
"c",
"d",
"e",
],
[
"a",
"b",
undefined,
undefined,
"e",
],
[
"1",
"2",
"3",
"4",
"5",
],
]
`);
});

test('example from readme', () => {
const fn = jest.fn();

Expand Down
35 changes: 23 additions & 12 deletions src/combine-events/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import {
Event,
EventAsReturnType,
is,
merge,
sample,
Store,
Unit,
Expand Down Expand Up @@ -44,15 +43,21 @@ export function combineEvents<
T extends UnitTargetable<P extends Tuple ? P : Partial<P>>,
>(config: { events: Events<P>; target: T; reset?: Unit<any> }): ReturnTarget<P, T>;

export function combineEvents<P>({
events,
reset,
target = createEvent(),
}: {
events: Events<any>;
reset?: Unit<any>;
target?: UnitTargetable<any> | Unit<any>;
}) {
export function combineEvents<P extends Shape>(
events: Events<P>,
): EventAsReturnType<P>;

export function combineEvents<P>(
args:
| {
events: Events<any>;
reset?: Unit<any>;
target?: UnitTargetable<any> | Unit<any>;
}
| Events<any>,
) {
const argsShape = isEventsShape(args) ? { events: args } : args;
const { events, reset, target = createEvent() } = argsShape;
if (!(is.unit(target) && is.targetable(target)))
throwError('target should be a targetable unit');
if (reset && !is.unit(reset)) throwError('reset should be a unit');
Expand All @@ -64,11 +69,11 @@ export function combineEvents<P>({
const $counter = createStore(keys.length, { serialize: 'ignore' });
const $results = createStore(defaultShape, { serialize: 'ignore' });

$counter.reset(sample({ source: target }));
sample({ source: target, target: $counter.reinit });
$results.reset(target);

if (reset) {
$counter.reset(sample({ source: reset }));
sample({ source: reset, target: $counter.reinit });
$results.reset(reset);
}

Expand Down Expand Up @@ -104,6 +109,12 @@ export function combineEvents<P>({
return target;
}

function isEventsShape<P>(args: any): args is Events<any> {
return Object.keys(args).some(
(key) => !['events', 'reset', 'target'].includes(key) && is.unit(args[key]),
);
}

function throwError(message: string) {
throw new Error(message);
}
Loading

0 comments on commit 777a8e7

Please sign in to comment.