-
Notifications
You must be signed in to change notification settings - Fork 48
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
load() and DOM APIs
- Loading branch information
Showing
22 changed files
with
1,567 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import {DomValue} from "./DomValue"; | ||
import {IonTypes} from "../Ion"; | ||
|
||
/** | ||
* Represents a blob[1] value in an Ion stream. | ||
* | ||
* [1] http://amzn.github.io/ion-docs/docs/spec.html#blob | ||
*/ | ||
export class Blob extends DomValue(Uint8Array, IonTypes.BLOB) { | ||
|
||
/** | ||
* Constructor. | ||
* @param data Raw, unsigned bytes to represent as a blob. | ||
* @param annotations An optional array of strings to associate with `data`. | ||
*/ | ||
constructor(data: Uint8Array, annotations: string[] = []) { | ||
super(data); | ||
this._setAnnotations(annotations); | ||
} | ||
|
||
uInt8ArrayValue(): Uint8Array { | ||
return this; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
import {IonTypes} from "../Ion"; | ||
import {DomValue} from "./DomValue"; | ||
|
||
/** | ||
* Represents a boolean[1] value in an Ion stream. | ||
* | ||
* Because this class extends Javascript's (big-B) Boolean data type, it is subject to the same | ||
* surprising behavior when used for control flow. | ||
* | ||
* From the Mozilla Developer Network documentation[2]: | ||
* | ||
* > Any object of which the value is not undefined or null, including a Boolean object | ||
* whose value is false, evaluates to true when passed to a conditional statement. | ||
* | ||
* var b = false; | ||
* if (b) { | ||
* // this code will NOT be executed | ||
* } | ||
* | ||
* b = new Boolean(false); | ||
* if (b) { | ||
* // this code WILL be executed | ||
* } | ||
* | ||
* [1] http://amzn.github.io/ion-docs/docs/spec.html#bool | ||
* [2] https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean#Description | ||
*/ | ||
export class Boolean extends DomValue(global.Boolean, IonTypes.BOOL) { | ||
|
||
/** | ||
* Constructor. | ||
* @param value The boolean value of the new instance. | ||
* @param annotations An optional array of strings to associate with `value`. | ||
*/ | ||
constructor(value: boolean, annotations: string[] = []) { | ||
super(value); | ||
this._setAnnotations(annotations); | ||
} | ||
|
||
booleanValue(): boolean { | ||
return this.valueOf() as boolean; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import {IonTypes} from "../Ion"; | ||
import {DomValue} from "./DomValue"; | ||
|
||
/** | ||
* Represents a clob[1] value in an Ion stream. | ||
* | ||
* [1] http://amzn.github.io/ion-docs/docs/spec.html#clob | ||
*/ | ||
export class Clob extends DomValue(Uint8Array, IonTypes.CLOB) { | ||
/** | ||
* Constructor. | ||
* @param bytes Raw, unsigned bytes to represent as a clob. | ||
* @param annotations An optional array of strings to associate with `bytes`. | ||
*/ | ||
constructor(bytes: Uint8Array, annotations: string[] = []) { | ||
super(bytes); | ||
this._setAnnotations(annotations); | ||
} | ||
|
||
uInt8ArrayValue(): Uint8Array { | ||
return this; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
import {DomValue} from "./DomValue"; | ||
import {IonTypes} from "../Ion"; | ||
import * as ion from "../Ion"; | ||
|
||
/** | ||
* Represents a decimal[1] value in an Ion stream. | ||
* | ||
* [1] http://amzn.github.io/ion-docs/docs/spec.html#decimal | ||
*/ | ||
export class Decimal extends DomValue(Number, IonTypes.DECIMAL) { | ||
private readonly _decimalValue: ion.Decimal; | ||
private readonly _numberValue: number; | ||
|
||
/** | ||
* Constructor. | ||
* @param value The numeric value to represent as a decimal. | ||
* @param annotations An optional array of strings to associate with `value`. | ||
*/ | ||
constructor(value: ion.Decimal, annotations: string[] = []) { | ||
super(...[value.getCoefficient(), value.getExponent(), value.isNegative()]); | ||
this._decimalValue = value; | ||
this._numberValue = value.numberValue(); | ||
this._setAnnotations(annotations); | ||
} | ||
|
||
numberValue(): number { | ||
return this._numberValue; | ||
} | ||
|
||
decimalValue(): ion.Decimal { | ||
return this._decimalValue; | ||
} | ||
|
||
toString(): string { | ||
return this._decimalValue.toString(); | ||
} | ||
|
||
valueOf(): number { | ||
return this._numberValue; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,135 @@ | ||
import {Decimal, IonType, Timestamp} from "../Ion"; | ||
import {PathElement, Value} from "./Value"; | ||
import JSBI from "jsbi"; | ||
|
||
/** | ||
* A type alias for the constructor signature required for mixins. | ||
*/ | ||
export type Constructor<T = {}> = new (...args: any[]) => T; | ||
|
||
/** | ||
* A mixin[1] that allows each DOM class to effectively extend two different parent classes: | ||
* 1. The corresponding native JS data type (dom.String extends String, dom.Integer extends Number, etc.) | ||
* 2. A new class constructed by the DomValue method which provides functionality common to all | ||
* DOM elements. This includes storing/accessing an Ion data type and annotations, as well as | ||
* convenience methods for converting from Ion data types to JS data types. | ||
* | ||
* [1] https://www.typescriptlang.org/docs/handbook/mixins.html | ||
* | ||
* @param BaseClass A parent type for the newly constructed class to extend. | ||
* @param ionType The Ion data type that will be associated with new instances of the constructed class. | ||
* @constructor | ||
*/ | ||
export function DomValue<Clazz extends Constructor>(BaseClass: Clazz, ionType: IonType) { | ||
return class extends BaseClass implements Value { | ||
_ionType: IonType; | ||
_ionAnnotations: string[]; | ||
|
||
/* TODO: | ||
* Ideally, this mixin's constructor would require subclasses to specify the desired annotations list | ||
* for the value being created as an argument. Something like: | ||
* constructor(annotations: string[], ...args: any[]) { | ||
* super(args); | ||
* this._setAnnotations(annotations); | ||
* } | ||
* Unfortunately, Typescript requires[1] that mixins have a single constructor which accepts a | ||
* single spread parameter. This means that we can't statically enforce this; callers would need | ||
* to "just know" to pass an annotations list as the first element of an arguments array. | ||
* For now, subclasses are expected to call `this._setAnnotations(...)` after the constructor completes. | ||
* This avoids the runtime costs that would be associated with the constant slicing/inspection of | ||
* values in the `...args` list to detect annotations. | ||
* | ||
* [1] https://github.com/Microsoft/TypeScript/issues/14126 | ||
*/ | ||
constructor(...args: any[]) { | ||
super(...args); | ||
this._ionType = ionType; | ||
this._ionAnnotations = []; | ||
// Setting the 'enumerable' attribute of these properties to `false` prevents them | ||
// from appearing in the iterators returned by Object.keys(), Object.entries(), etc. | ||
// This guarantees that users iterating over the fields of a struct or values in a list | ||
// will see only Values from the source data or that they have created themselves. | ||
Object.defineProperty(this, "_ionType", {enumerable: false}); | ||
Object.defineProperty(this, "_ionAnnotations", {enumerable: false}); | ||
} | ||
|
||
_unsupportedOperation<T extends Value>(functionName: string): never { | ||
throw new Error(`Value#${functionName}() is not supported by Ion type ${this.getType().name}`); | ||
} | ||
|
||
getType(): IonType { | ||
return this._ionType; | ||
} | ||
|
||
// Class expressions (like this mixin) cannot have private or protected methods. | ||
_setAnnotations(annotations: string[]) { | ||
this._ionAnnotations = annotations; | ||
} | ||
|
||
getAnnotations(): string[] { | ||
if (this._ionAnnotations === null) { | ||
return []; | ||
} | ||
return this._ionAnnotations; | ||
} | ||
|
||
isNull(): boolean { | ||
return false; | ||
} | ||
|
||
booleanValue(): boolean | null { | ||
this._unsupportedOperation('booleanValue'); | ||
} | ||
|
||
numberValue(): number | null { | ||
this._unsupportedOperation('numberValue'); | ||
} | ||
|
||
bigIntValue(): JSBI | null { | ||
this._unsupportedOperation('bigIntValue'); | ||
} | ||
|
||
decimalValue(): Decimal | null { | ||
this._unsupportedOperation('decimalValue'); | ||
} | ||
|
||
stringValue(): string | null { | ||
this._unsupportedOperation('stringValue'); | ||
} | ||
|
||
dateValue(): Date | null { | ||
this._unsupportedOperation('dateValue'); | ||
} | ||
|
||
timestampValue(): Timestamp | null { | ||
this._unsupportedOperation('timestampValue'); | ||
} | ||
|
||
uInt8ArrayValue(): Uint8Array | null { | ||
this._unsupportedOperation('uInt8ArrayValue'); | ||
} | ||
|
||
fieldNames(): string[] { | ||
this._unsupportedOperation('fieldNames'); | ||
} | ||
|
||
fields(): [string, Value][] { | ||
this._unsupportedOperation('fields'); | ||
} | ||
|
||
elements(): Value[] { | ||
this._unsupportedOperation('elements'); | ||
} | ||
|
||
get(...pathElements: PathElement[]): Value | null { | ||
this._unsupportedOperation('get'); | ||
} | ||
|
||
as<T extends Value>(ionValueType: Constructor<T>): T { | ||
if (this instanceof ionValueType) { | ||
return this as unknown as T; | ||
} | ||
throw new Error(`${this.constructor.name} is not an instance of ${ionValueType.name}`); | ||
} | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import {IonTypes} from "../Ion"; | ||
import {DomValue} from "./DomValue"; | ||
|
||
/** | ||
* Represents a float[1] value in an Ion stream. | ||
* | ||
* [1] http://amzn.github.io/ion-docs/docs/spec.html#float | ||
*/ | ||
export class Float extends DomValue(Number, IonTypes.FLOAT) { | ||
|
||
/** | ||
* Constructor. | ||
* @param value The numeric value to represent as a float. | ||
* @param annotations An optional array of strings to associate with `value`. | ||
*/ | ||
constructor(value: number, annotations: string[] = []) { | ||
super(value); | ||
this._setAnnotations(annotations); | ||
} | ||
|
||
public numberValue(): number { | ||
return +this.valueOf(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
import JSBI from "jsbi"; | ||
import {IonTypes} from "../Ion"; | ||
import {DomValue} from "./DomValue"; | ||
|
||
/** | ||
* Represents an integer value in an Ion stream. | ||
* | ||
* [1] http://amzn.github.io/ion-docs/docs/spec.html#int | ||
*/ | ||
export class Integer extends DomValue(Number, IonTypes.INT) { | ||
private _bigIntValue: JSBI | null; | ||
private _numberValue: number; | ||
|
||
/** | ||
* Constructor. | ||
* @param value The numeric value to represent as an integer. | ||
* @param annotations An optional array of strings to associate with `value`. | ||
*/ | ||
constructor(value: JSBI | number, annotations: string[] = []) { | ||
// If the provided value is a JS number, we will defer constructing a BigInt representation | ||
// of it until it's requested later by a call to bigIntValue(). | ||
if (typeof value === "number") { | ||
super(value); | ||
this._numberValue = value; | ||
this._bigIntValue = null; | ||
} else { | ||
let numberValue: number = JSBI.toNumber(value); | ||
super(numberValue); | ||
this._bigIntValue = value; | ||
this._numberValue = numberValue; | ||
} | ||
this._setAnnotations(annotations); | ||
} | ||
|
||
bigIntValue(): JSBI { | ||
if (this._bigIntValue === null) { | ||
this._bigIntValue = JSBI.BigInt(this.numberValue()); | ||
} | ||
return this._bigIntValue; | ||
} | ||
|
||
numberValue(): number { | ||
return this._numberValue; | ||
} | ||
|
||
toString(): string { | ||
if (this._bigIntValue === null) { | ||
return this._numberValue.toString(); | ||
} | ||
return this._bigIntValue.toString(); | ||
} | ||
|
||
valueOf() { | ||
return this.numberValue(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import {Value} from "./Value"; | ||
import {IonTypes} from "../Ion"; | ||
import {Sequence} from "./Sequence"; | ||
|
||
/** | ||
* Represents a list value in an Ion stream. | ||
* | ||
* [1] http://amzn.github.io/ion-docs/docs/spec.html#list | ||
*/ | ||
export class List extends Sequence(IonTypes.LIST) { | ||
/** | ||
* Constructor. | ||
* @param children Values that will be contained in the new list. | ||
* @param annotations An optional array of strings to associate with the items in `children`. | ||
*/ | ||
constructor(children: Value[], annotations: string[] = []) { | ||
super(children, annotations); | ||
} | ||
} |
Oops, something went wrong.