Skip to content

Commit

Permalink
Release 0.9.0
Browse files Browse the repository at this point in the history
- Moved `CalendarEvent.move` to `Schedule`
- Added `Functions.isValue`
- Added `take`, `skip`, `append`, `prepend`, `join`, `empty`, and
`reverse` to `Iterator` (resolves #7)
- Added `setExcluded`, `setCancelled`, `move`, `forecast` (resolves
#8), and `getSingleEventSpan` to `Schedule`
  • Loading branch information
ClickerMonkey committed Jun 19, 2018
1 parent 020f657 commit 941b2e1
Show file tree
Hide file tree
Showing 12 changed files with 949 additions and 88 deletions.
2 changes: 1 addition & 1 deletion package.json
@@ -1,6 +1,6 @@
{
"name": "dayspan",
"version": "0.8.1",
"version": "0.9.0",
"description": "A date & schedule library to use for advanced calendars in TypeScript and JS",
"main": "umd/dayspan.js",
"mainName": "ds",
Expand Down
53 changes: 7 additions & 46 deletions src/CalendarEvent.ts
@@ -1,12 +1,10 @@

import { Constants } from './Constants';
import { Day, DayProperty } from './Day';
import { Day } from './Day';
import { DaySpan, DaySpanBounds } from './DaySpan';
import { Event } from './Event';
import { Identifier, IdentifierInput } from './Identifier';
import { Schedule } from './Schedule';
import { Parse } from './Parse';
import { FrequencyCheck } from './Frequency';


/**
Expand Down Expand Up @@ -176,7 +174,7 @@ export class CalendarEvent<T, M>
*/
public get identifierType(): Identifier
{
return this.fullDay ? Identifier.Day : Identifier.Time;
return this.schedule.identifierType;
}

/**
Expand Down Expand Up @@ -233,7 +231,7 @@ export class CalendarEvent<T, M>
*/
public cancel(cancelled: boolean = true): this
{
this.schedule.cancel.set( this.start, cancelled, this.identifierType );
this.schedule.setCancelled( this.start, cancelled );
this.cancelled = cancelled;

return this;
Expand All @@ -247,12 +245,7 @@ export class CalendarEvent<T, M>
*/
public exclude(excluded: boolean = true): this
{
let schedule: Schedule<M> = this.schedule;
let type: Identifier = this.identifierType;
let time: Day = this.start;

schedule.exclude.set( time, excluded, type );
schedule.include.set( time, !excluded, type );
this.schedule.setExcluded( this.start, excluded );

return this;
}
Expand All @@ -266,43 +259,11 @@ export class CalendarEvent<T, M>
* to match the timestamp provided.
*
* @param toTime The timestamp to move this event to.
* @returns Whether the event was moved to the given time.
*/
public move(toTime: Day): this
public move(toTime: Day): boolean
{
let schedule: Schedule<M> = this.schedule;

if (schedule.isSingleEvent())
{
for (let check of schedule.checks)
{
let prop: DayProperty = check.property;
let value = toTime[ prop ];
let frequency: FrequencyCheck = Parse.frequency( [value], prop );

schedule[ prop ] = frequency;
}

schedule.updateChecks();
}
else
{
let type: Identifier = this.identifierType;
let fromTime: Day = this.start;

schedule.exclude.set( fromTime, true, type );
schedule.exclude.set( toTime, false, type );

schedule.include.set( toTime, true, type );
schedule.include.set( fromTime, false, type );

if (this.meta !== null)
{
schedule.meta.unset( fromTime, type );
schedule.meta.set( toTime, this.meta, type );
}
}

return this;
return this.schedule.move( toTime, this.start, this.meta );
}

}
11 changes: 11 additions & 0 deletions src/Functions.ts
Expand Up @@ -89,6 +89,17 @@ export class Functions
return typeof(input) !== 'undefined';
}

/**
* Determines whether the given input is defined and not null.
*
* @param input The variable to test.
* @return `true` if the variable is defined and not null, otherwise `false`.
*/
public static isValue(input: any): boolean
{
return input !== null && typeof(input) !== 'undefined';
}

/**
* Determines whether the given input appears to be a valid
* [[FrequencyValueEvery]].
Expand Down
168 changes: 168 additions & 0 deletions src/Iterator.ts
Expand Up @@ -312,6 +312,93 @@ export class Iterator<T>
return out;
}

/**
* Returns a new iterator that only returns a maximum number of items.
*
* @param amount The maximum number of items to return.
* @returns A new iterator which returns a maximum number of items.
*/
public take(amount: number): Iterator<T>
{
return new Iterator<T>(next =>
{
this.iterate((item, prev) =>
{
switch (next.act( item ))
{
case IteratorAction.Stop:
prev.stop();
break;
case IteratorAction.Remove:
prev.remove();
break;
}

if (--amount <= 0)
{
prev.stop();
}
});
});
}

/**
* Returns a new iterator that skips the given number of items from the items
* in this iterator.
*
* @param amount The number of items to skip.
* @returns A new iterator which skipped the given number of items.
*/
public skip(amount: number): Iterator<T>
{
return new Iterator<T>(next =>
{
let skipped: number = 0;

this.iterate((item, prev) =>
{
if (skipped >= amount)
{
switch (next.act( item ))
{
case IteratorAction.Stop:
prev.stop();
break;
case IteratorAction.Remove:
prev.remove();
break;
}
}

skipped++;
});
});
}

/**
* Returns a new iterator thats items are the items in this iterator followed
* by the items in the given iterators.
*
* @param iterators The iterators to append after this one.
* @returns A new iterator based on this iterator followed by the given.
*/
public append(...iterators: Iterator<T>[]): Iterator<T>
{
return Iterator.join<T>( this, ...iterators );
}

/**
* Returns a new iterator thats items are the items in the given iterators
* followed by the items in this iterator.
*
* @param iterators The iterators to prepend before this one.
* @returns A new iterator based on the given iterators followed by this.
*/
public prepend(...iterators: Iterator<T>[]): Iterator<T>
{
return Iterator.join<T>( ...iterators, this );
}

/**
* Removes items from the source that match certain criteria.
*
Expand All @@ -330,6 +417,42 @@ export class Iterator<T>
return this;
}

/**
* Returns an iterator which takes items from this iterator and presents them
* in reverse.
*
* @returns A new iterator with the items in this iterator in reverse.
*/
public reverse(): Iterator<T>
{
return new Iterator<T>(iterator =>
{
let items: T[] = this.list();
let removed: T[] = [];

for (let i = items.length - 1; i >= 0; i--)
{
let item: T = items[ i ];
let action: IteratorAction = iterator.act( item );

if (action === IteratorAction.Stop)
{
break;
}

if (action === IteratorAction.Remove)
{
removed.push( item );
}
}

if (removed.length > 0)
{
this.purge(item => removed.indexOf( item ) !== -1);
}
});
}

/**
* Reduces all the items in the source to a single value given the initial
* value and a function to convert an item and the current reduced value
Expand Down Expand Up @@ -531,5 +654,50 @@ export class Iterator<T>
});
}

/**
* Joins all the given iterators into a single iterator where the items
* returned are in the same order as passed to this function. If any items
* are removed from the returned iterator they will be removed from the given
* iterator if it supports removal.
*
* @param iterators The array of iterators to join as one.
* @returns A new iterator for the given iterators.
*/
public static join<T>(...iterators: Iterator<T>[]): Iterator<T>
{
return new Iterator<T>(parent =>
{
for (let child of iterators)
{
child.iterate((item, childIterator) =>
{
switch (parent.act( item ))
{
case IteratorAction.Remove:
childIterator.remove();
break;
case IteratorAction.Stop:
childIterator.stop();
break;
}
});

if (child.action === IteratorAction.Stop)
{
return;
}
}
});
}

/**
* Returns a new iterator with no items.
*
* @returns A new iterator with no items.
*/
public static empty<T>(): Iterator<T>
{
return new Iterator<T>(parent => {});
}

}

0 comments on commit 941b2e1

Please sign in to comment.