Members

(constant) ComparisonModes

Comparison modes for two ranges. When comparing two ranges, you can compare any combination of range starts and ends. The enumeration is setup as a bitset, so you can identify which of a/b is start/end:

  • bits 0 (LSb) and 1 indicate a and b respectively
  • a value of 0 or 1 indicates start or end of range respectively
Properties
NameTypeDescription
START0b00

Comparing the starts of two ranges

END0b11

Comparing the ends of two ranges

START_END0b10

Comparing the start (a) to the end (b) of a single range

END_START0b01

Comparing the end (a) to the start (b) of two ranges. This compares the gap between two ranges. If the range type supports merging adjacent ranges, it should return -0 (negative zero) if a comes before b but the gap is zero.

(constant) DateFloorNormType

This is the same as DateFloorType, but where the range bounds have been normalized to always be inclusive. This can be easier to work with, and omits the extra logic needed to handle exclusive bounds.

This uses IntNormType internally as a base type.

Implements

(constant) DateFloorType

This is similar to DateType, but where fractions of a time unit are ignored. This supports second, minute, hour, and day time units. Each of these is accessible as DateType.Second, etc. As an example, new Date("2023-06-08T01:33:59.380Z"), would be treated as the following for each time unit:

  • second: 2023-06-08T01:33:59Z
  • minute: 2023-06-08T01:33:00Z
  • hour: 2023-06-08T01:00:00Z
  • day: 2023-06-08T00:00:00Z

Note that the implicit conversion is done in UTC, using JavaScript's Date object. This means:

  • Local timezone information is not factored into DateType.Day.
  • Some unusual timezones have a daylight savings offset of 30 minutes, rather than a whole hour. DateType.Hour wouldn't account for this.
  • Leap seconds are not factored into DateType.minute.

In all other cases, conversion is unaffected by locality.

The time unit defines the smallest interval between two dates. For example, if using DateType.Hour, the following ranges could be merged via RangeGroup#normalize:

[new Date("09:30 1/15"), new Date("14:00 1/15")]
[new Date("15:59 1/15"), new Date("16:00 1/15")]

You can think of ranges as indicating occupancy within a time span. For example, with hour being the time unit, the following range:

[new Date("06:59 1/15"), new Date("08:00 1/15")]

occupies hours 6 (for one second), 7 (for the full hour), and 8 (infinitesimally).

This uses IntType internally as a base type.

Implements

(constant) DateNormType

This is the same as DateType, but where the range bounds have been normalized to always be inclusive. This can be easier to work with, and omits the extra logic needed to handle exclusive bounds.

This uses IntNormType as its base type.

Implements

(constant) DateType

Implementation of RangeType for JavaScript Date objects. Internally, this type is represented as an IntType operating on the Date's numeric millisecond value (the Unix timestamp). Hence, the following ranges would get merged by RangeGroup#normalize:

[new Date(0), new Date(10)]
[new Date(11), new Date(20)]

The RangeType.size method will give you the duration of the range in milliseconds. *

Implements

(constant) FloatNormType

This is similar to RealType, but assuming a discrete, floating point representation. The bounds are normalized to always be inclusive. This can be easier to work with, and omits the extra logic needed to handle exclusive bounds.

True real numbers cannot be normalized: e.g. for the half-open interval [.25,4.75), you cannot represent the value that is infinitely close, but not equal to 4.75. However, for finite representations like floating point, you can normalize to the next closest representable number: e.g. 4.74999952316 for a 32 bit float. This is the kind of normalization this type performs.

Normalization uses typed arrays and BigInt to get the binary representation of a number as a floating point, meaning possibly less browser support than RealType. While the logic for handling exclusive bounds is ommitted, the RangeType.compare method needs to perform extra calculations to determine floating point adjacency; so the type is likely slower for typical use cases.

Unlike RealType, an RangeType.iterate implementation is provided, which iterates through every representable floating point number in the range. The RangeType.sample implementation bears the same caveat however, in that we cannot map [0,1) to any floating point range.

Implements

(constant) IntNormType

This is the same as IntType, but where the range bounds have been normalized to always be inclusive. This can be easier to work with, and omits the extra logic needed to handle exclusive bounds. For example, (0,5) would be normalized on creation to be [1,4] instead.

Implements

(constant) IntType

Implementation of RangeType for integer values. You can use this to implement any discrete RangeType, so long as you can map the values to the domain of integers.

Inputs for this type are coerced to numbers prior to calculations.

Implements

(constant) RealType

Implementation of RangeType for real values. You can use this to implement any continuous RangeType, so long as you can map them to the domain of reals. In reality the operations will be using floating point arithmetic. However the assumptions made by the RangeType.compare method for this type are that each value is a point on a continuous number line.

No RangeType.iterate implementation is provided, as it represents a continuous type.

The builtin RangeType.sample method is not perfect. Firstly, we cannot map [0,1) to any floating point range, e.g. we can only sample half of the values in [-1,1]. Exclusion is only handled properly when the end, and only end, is exclusive. This matches the exclusion of the input [0,1). If the end is inclusive, it won't ever get sampled. If the start is exclusive, it could get falsely sampled. For accurate handling of exclusion, you can consider using the FloatNormType instead. Another alternative would be to write your own sampler which resamples if the value is exclusive (e.g. perhaps returning null and looping elsewhere until non-null).

Inputs for this type are coerced to numbers prior to calculations.

Implements

(constant) UnicodeNormType

This is the same as UnicodeType, but where the range bounds have been normalized to always be inclusive. This can be easier to work with, and omits the extra logic needed to handle exclusive bounds.

This uses IntNormType internally for operations on codepoints.

Implements

(constant) UnicodeType

Implementation of RangeType for unicode codepoints. This also supports a fixed string prefix to the codepoint, which is used to accomodate string ranges in a limited fashion. String ranges are used to encode a set of strings, as opposed to single characters. See the StringRange documentation for more details on this topic.

Ranges are compared by the number of codepoints first (e.g. the string length in UTF-32 encoding), then by their prefix, then by their final codepoint. Distances are always infinite unless the two strings have the same length and prefix.

To create a valid Range, the following must be true of Range#start and Range#end:

  • the UTF-32 string length must be equal
  • all but the last codepoint must be equal (the prefixes)
  • the last codepoint of Range#end should be greater or equal

Like all other builtin types, for performance no validation is performed when you call RangeType.setStart or RangeType.setEnd. As strings can be more tricky to work with (e.g. the unicode string length is not immediately obvious with grapheme clusters), you can call UnicodeType.validate(range) -> bool to double check if a range is valid. This is simply transforming the result of UnicodeType.compare to a boolean.

This uses IntType internally for operations on codepoints.

Implements