@figtreejs/core 0.0.1-alpha.1 → 0.0.1-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +2 -8874
- package/dist/index.d.ts +461 -233
- package/dist/index.mjs +4432 -6624
- package/package.json +7 -4
- package/src/bauble-makers/set-up-baubles.ts +1 -1
- package/src/components/baubles/clades/highlight.tsx +1 -1
- package/src/components/decorations/axis/polar-axis.tsx +1 -1
- package/src/components/decorations/axis/rectangular-axis.tsx +1 -1
- package/src/components/figtree/figtree.tsx +1 -1
- package/src/components/hoc/with-node.tsx +1 -1
- package/src/evo/tree/normalized-tree/immutable-tree-helpers.ts +2 -2
- package/src/evo/tree/normalized-tree/immutable-tree.test.ts +1 -1
- package/src/evo/tree/normalized-tree/immutable-tree.ts +3 -5
- package/src/evo/tree/parsers/annotation-parser.ts +6 -0
- package/src/evo/tree/parsers/newick-character-parser.ts +9 -1
- package/src/evo/tree/parsers/newick-parsing.ts +6 -0
- package/src/evo/tree/parsers/nexus-parsing.ts +8 -3
- package/src/evo/tree/parsers/parsing.test.ts +1 -1
- package/src/evo/tree/parsers/stream-reader/nexus-importer.ts +9 -2
- package/src/evo/tree/parsers/stream-reader/nexus-tokenizer.ts +6 -1
- package/src/evo/tree/taxa/helper-functions.ts +16 -2
- package/src/evo/tree/taxa/taxon.ts +41 -2
- package/src/evo/tree/traversals/preorder-traversal.ts +5 -0
- package/src/evo/tree/traversals/traversal-types.ts +3 -0
- package/src/evo/tree/tree-types.ts +259 -20
- package/src/index.ts +1 -1
- package/src/layouts/functional/radial-layout.ts +15 -11
- package/src/layouts/functional/rectangular-layout.ts +8 -1
- package/src/layouts/layout-interface.ts +0 -73
- package/src/path.helpers.ts +76 -59
- package/src/tests/clades/cartoon.test.tsx +1 -1
- package/src/tests/clades/highlight.test.tsx +1 -1
- package/src/tests/layouts/rectangularlayout.test.ts +1 -1
- package/src/tests/shapes/label.test.tsx +1 -1
- package/src/utils/dateUtils.ts +41 -0
- package/src/utils/index.ts +2 -0
- package/src/utils/maybe.ts +67 -0
- package/CHANGELOG.md +0 -17
- package/eslint.config.js +0 -9
- package/src/utils.ts +0 -57
- package/tsconfig.json +0 -12
- package/vite.config.ts +0 -34
- package/vitetest.config.ts +0 -11
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@figtreejs/core",
|
|
3
|
-
"version": "0.0.1-
|
|
3
|
+
"version": "0.0.1-beta.1",
|
|
4
4
|
"description": "A react component library for phylogenetic visualization and app building",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -19,6 +19,10 @@
|
|
|
19
19
|
"main": "./dist/index.cjs",
|
|
20
20
|
"module": "./dist/index.mjs",
|
|
21
21
|
"types": "./dist/index.d.ts",
|
|
22
|
+
"files": [
|
|
23
|
+
"./dist/*",
|
|
24
|
+
"./src/*"
|
|
25
|
+
],
|
|
22
26
|
"scripts": {
|
|
23
27
|
"build": "vite build",
|
|
24
28
|
"check-types": "tsc --noEmit",
|
|
@@ -37,7 +41,6 @@
|
|
|
37
41
|
]
|
|
38
42
|
},
|
|
39
43
|
"dependencies": {
|
|
40
|
-
"@figtreejs/maybe": "0.0.1-alpha.1",
|
|
41
44
|
"@react-spring/web": "^9.7.5",
|
|
42
45
|
"abs-svg-path": "^0.1.1",
|
|
43
46
|
"d3-array": "^3.2.4",
|
|
@@ -51,8 +54,8 @@
|
|
|
51
54
|
"uuid": "^13.0.0"
|
|
52
55
|
},
|
|
53
56
|
"devDependencies": {
|
|
54
|
-
"@figtreejs/eslint-config": "
|
|
55
|
-
"@figtreejs/typescript-config": "
|
|
57
|
+
"@figtreejs/eslint-config": "*",
|
|
58
|
+
"@figtreejs/typescript-config": "*",
|
|
56
59
|
"@microsoft/api-extractor": "^7.55.1",
|
|
57
60
|
"@testing-library/react": "^16.3.0",
|
|
58
61
|
"@types/abs-svg-path": "^0.1.3",
|
|
@@ -22,7 +22,7 @@ import type {
|
|
|
22
22
|
} from "./makers";
|
|
23
23
|
import { mapAttrsToProps, mapInteractionsToProps } from "./utils";
|
|
24
24
|
import type { Clade } from "../components/hoc/with-clades";
|
|
25
|
-
import { notNull } from "../utils";
|
|
25
|
+
import { notNull } from "../utils/maybe";
|
|
26
26
|
|
|
27
27
|
export type InternalBaubleOptions =
|
|
28
28
|
| InternalNodeOptions
|
|
@@ -5,7 +5,7 @@ import { withClades } from "../../hoc/with-clades";
|
|
|
5
5
|
|
|
6
6
|
import { BasePath, BaseRectangle } from "../shapes";
|
|
7
7
|
import type { PolarVertex, simplePolarVertex } from "../../../layouts/types";
|
|
8
|
-
import { notNull } from "../../../utils";
|
|
8
|
+
import { notNull } from "../../../utils/maybe";
|
|
9
9
|
import { ScaleContext } from "../../../context/scale-context";
|
|
10
10
|
import { layoutContext } from "../../../context/layout-context";
|
|
11
11
|
import { animatedContext } from "../../../context/aminated-context";
|
|
@@ -7,7 +7,7 @@ import { defaultAxisProps } from "./axis-types";
|
|
|
7
7
|
|
|
8
8
|
import { normalizeAngle } from "../../../store/polar-scale";
|
|
9
9
|
import type { dimensionType } from "../../figtree/figtree-types";
|
|
10
|
-
import { unNullify } from "../../../utils";
|
|
10
|
+
import { unNullify } from "../../../utils/maybe";
|
|
11
11
|
import { DimensionContext } from "../../../context/dimension-context";
|
|
12
12
|
import { ScaleContext } from "../../../context/scale-context";
|
|
13
13
|
import PolarAxisBars from "./polar-axis-bars";
|
|
@@ -9,7 +9,7 @@ import type {
|
|
|
9
9
|
} from "./axis-types";
|
|
10
10
|
import { defaultAxisProps } from "./axis-types";
|
|
11
11
|
import { makeAxisScale } from "./polar-axis";
|
|
12
|
-
import { unNullify } from "../../../utils";
|
|
12
|
+
import { unNullify } from "../../../utils/maybe";
|
|
13
13
|
import { DimensionContext } from "../../../context/dimension-context";
|
|
14
14
|
import { ScaleContext } from "../../../context/scale-context";
|
|
15
15
|
import RectangleAxisBars from "./rectangular-axis-bars";
|
|
@@ -4,7 +4,7 @@ import { defaultInternalLayoutOptions, rectangularLayout } from "../../layouts";
|
|
|
4
4
|
import { ImmutableTree } from "../../evo/tree";
|
|
5
5
|
import { getScale } from "../../store/store";
|
|
6
6
|
import { extent } from "d3-array";
|
|
7
|
-
import { unNullify } from "../../utils";
|
|
7
|
+
import { unNullify } from "../../utils/maybe";
|
|
8
8
|
import { Bauble } from "../baubles/bauble";
|
|
9
9
|
|
|
10
10
|
import { ScaleContext } from "../../context/scale-context";
|
|
@@ -8,7 +8,7 @@ import { layoutClass } from "../../layouts";
|
|
|
8
8
|
import { defaultNodeLabelData } from "../../store/store";
|
|
9
9
|
import type { PolarVertex } from "../../layouts/types";
|
|
10
10
|
import { textSafeDegrees } from "../../store/polar-scale";
|
|
11
|
-
import { unNullify } from "../../utils";
|
|
11
|
+
import { unNullify } from "../../utils/maybe";
|
|
12
12
|
|
|
13
13
|
//The goal here is now to take a shape components that accepts Attrs: number | string , x/y
|
|
14
14
|
// and return a component that takes a node / layout/ scale and attrs:number|string | function
|
|
@@ -6,8 +6,8 @@
|
|
|
6
6
|
* those can't be called by immer proxies.
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
import type { Maybe, Undefinable } from "
|
|
10
|
-
import {
|
|
9
|
+
import type { Maybe, Undefinable } from "../../../utils";
|
|
10
|
+
import { Nothing, Some, MaybeType } from "../../../utils";
|
|
11
11
|
import type { Annotation, NodeRef } from "../tree-types";
|
|
12
12
|
import type { ImmutableTree, nodeIndex, Node } from "./immutable-tree";
|
|
13
13
|
import type { Taxon } from "../taxa";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
//TODO test immutable tree include tests that check nodes to roots update as well.
|
|
2
2
|
|
|
3
|
-
import { notNull, u } from "../../../utils";
|
|
3
|
+
import { notNull, u } from "../../../utils/maybe";
|
|
4
4
|
import { ImmutableTree } from "./immutable-tree";
|
|
5
5
|
import { describe, it, expect } from "vitest";
|
|
6
6
|
|
|
@@ -28,7 +28,7 @@ import {
|
|
|
28
28
|
type Undefinable,
|
|
29
29
|
UnwrapErr,
|
|
30
30
|
type Maybe,
|
|
31
|
-
} from "
|
|
31
|
+
} from "../../../utils";
|
|
32
32
|
import {
|
|
33
33
|
maybeGetAnnotation,
|
|
34
34
|
maybeGetNode,
|
|
@@ -37,7 +37,7 @@ import {
|
|
|
37
37
|
maybeGetTaxon,
|
|
38
38
|
maybeGetTaxonFromNode,
|
|
39
39
|
} from "./immutable-tree-helpers";
|
|
40
|
-
import { notNull, unNullify } from "../../../utils";
|
|
40
|
+
import { notNull, unNullify } from "../../../utils/maybe";
|
|
41
41
|
import { v4 as uuidv4 } from "uuid";
|
|
42
42
|
|
|
43
43
|
export type nodeIndex = string | number | Taxon;
|
|
@@ -143,9 +143,7 @@ export class ImmutableTree implements Tree, TaxonSetInterface {
|
|
|
143
143
|
nexus: string,
|
|
144
144
|
options?: newickParsingOptions,
|
|
145
145
|
): ImmutableTree {
|
|
146
|
-
|
|
147
|
-
return parseNexus(tree, nexus, options);
|
|
148
|
-
// throw new Error("Nexus parsing not implemented")
|
|
146
|
+
return parseNexus(nexus, options);
|
|
149
147
|
}
|
|
150
148
|
static fromString(
|
|
151
149
|
string: string,
|
|
@@ -130,6 +130,12 @@ export function parseAnnotation(annotationString: string): ParsedAnnotationRaw {
|
|
|
130
130
|
return annotations;
|
|
131
131
|
}
|
|
132
132
|
|
|
133
|
+
/**
|
|
134
|
+
* Process an annotation value and return the possibly transformed value and
|
|
135
|
+
* figtreejs annotation type
|
|
136
|
+
* @param values RawAnnotationValue
|
|
137
|
+
* @returns ClassifiedValue {type: BaseAnnotationType, value: ValueOf<BaseAnnotationType>};
|
|
138
|
+
*/
|
|
133
139
|
export function processAnnotationValue(
|
|
134
140
|
values: RawAnnotationValue,
|
|
135
141
|
): ClassifiedValue {
|
|
@@ -3,7 +3,11 @@ import { TaxonSet } from "../taxa/taxon";
|
|
|
3
3
|
import type { NodeRef } from "../tree-types";
|
|
4
4
|
import { ImmutableTree } from "../normalized-tree/immutable-tree";
|
|
5
5
|
import { parseAnnotation } from "./annotation-parser";
|
|
6
|
-
import { notNull, unNullify } from "../../../utils";
|
|
6
|
+
import { notNull, unNullify } from "../../../utils/maybe";
|
|
7
|
+
/**
|
|
8
|
+
* A class that contains the logic for parsing newick strings.
|
|
9
|
+
* It the tokens of the string should be split as in
|
|
10
|
+
* /\s*('[^']+'|"[^"]+"|\[&[^[]+]|,|:|\)|\(|;)\s\*/
|
|
7
11
|
|
|
8
12
|
export class NewickCharacterParser {
|
|
9
13
|
done: boolean;
|
|
@@ -52,6 +56,10 @@ export class NewickCharacterParser {
|
|
|
52
56
|
return this.tree;
|
|
53
57
|
}
|
|
54
58
|
|
|
59
|
+
/**
|
|
60
|
+
* Parse the next token
|
|
61
|
+
* @param t token
|
|
62
|
+
*/
|
|
55
63
|
parseCharacter(t: string): void {
|
|
56
64
|
if (this.done) {
|
|
57
65
|
throw new Error("Parsing is done. We have seen a ';'");
|
|
@@ -2,6 +2,12 @@ import { NewickCharacterParser } from "./newick-character-parser";
|
|
|
2
2
|
import type { ImmutableTree, newickParsingOptions } from "..";
|
|
3
3
|
import { TaxonSet } from "..";
|
|
4
4
|
|
|
5
|
+
/**
|
|
6
|
+
* An internal function to parse a newick string.
|
|
7
|
+
* @param newick
|
|
8
|
+
* @param options
|
|
9
|
+
* @returns
|
|
10
|
+
*/
|
|
5
11
|
export function parseNewick(
|
|
6
12
|
newick: string,
|
|
7
13
|
options: newickParsingOptions = {},
|
|
@@ -1,12 +1,17 @@
|
|
|
1
1
|
/* eslint-disable */
|
|
2
2
|
import { ImmutableTree } from "../normalized-tree/immutable-tree";
|
|
3
|
+
import { newickParsingOptions } from "../tree-types";
|
|
3
4
|
import { parseNewick } from "./newick-parsing";
|
|
4
5
|
|
|
5
|
-
|
|
6
|
+
/**
|
|
7
|
+
* An internal helper function that parses the first tree in a nexus string
|
|
8
|
+
* @param nexus - The nexus string to be parsed.
|
|
9
|
+
* @param options - newickParsingOptions - parseAnnotations is set to true
|
|
10
|
+
* @returns
|
|
11
|
+
*/
|
|
6
12
|
export function parseNexus(
|
|
7
|
-
_tree: ImmutableTree,
|
|
8
13
|
nexus: string,
|
|
9
|
-
options = {},
|
|
14
|
+
options: newickParsingOptions = {},
|
|
10
15
|
): ImmutableTree {
|
|
11
16
|
// odd parts ensure we're not in a taxon label
|
|
12
17
|
//TODO make this parsing more robust
|
|
@@ -1,10 +1,14 @@
|
|
|
1
|
-
import { notNull } from "../../../../utils";
|
|
1
|
+
import { notNull } from "../../../../utils/maybe";
|
|
2
2
|
import type { ImmutableTree } from "../../normalized-tree";
|
|
3
3
|
import { TaxonSet } from "../../taxa/taxon";
|
|
4
4
|
|
|
5
5
|
import { NewickCharacterParser } from "../newick-character-parser";
|
|
6
6
|
import { newickDeliminators, nexusTokenizer } from "./nexus-tokenizer";
|
|
7
7
|
|
|
8
|
+
/**
|
|
9
|
+
* A nexus importing class that parses a stream and into an asynchronous
|
|
10
|
+
* iterator over trees.
|
|
11
|
+
*/
|
|
8
12
|
export class NexusImporter {
|
|
9
13
|
reader: ReadableStreamDefaultReader<string>;
|
|
10
14
|
taxonSet: TaxonSet;
|
|
@@ -27,7 +31,10 @@ export class NexusImporter {
|
|
|
27
31
|
this.currentBlock = undefined;
|
|
28
32
|
this.options = options;
|
|
29
33
|
}
|
|
30
|
-
|
|
34
|
+
/**
|
|
35
|
+
* The main public api.
|
|
36
|
+
* an asynchronous iterator over the trees provided by the stream
|
|
37
|
+
*/
|
|
31
38
|
async *getTrees(): AsyncIterableIterator<ImmutableTree> {
|
|
32
39
|
while (this.currentBlock !== "trees") {
|
|
33
40
|
await this.parseNextBlock();
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { notNull } from "../../../../utils";
|
|
1
|
+
import { notNull } from "../../../../utils/maybe";
|
|
2
2
|
|
|
3
3
|
export enum STATUS {
|
|
4
4
|
PARSING = "parsing",
|
|
@@ -7,6 +7,11 @@ export enum STATUS {
|
|
|
7
7
|
IN_COMMENT = "in comment",
|
|
8
8
|
}
|
|
9
9
|
|
|
10
|
+
/**
|
|
11
|
+
* A helper function that converts an incoming stream into tokens in
|
|
12
|
+
* a nexus file.
|
|
13
|
+
* @returns A pipe string tokenizer for use in a transform stream.
|
|
14
|
+
*/
|
|
10
15
|
export function nexusTokenizer() {
|
|
11
16
|
return {
|
|
12
17
|
lastChunk: "",
|
|
@@ -1,7 +1,14 @@
|
|
|
1
|
-
import type { Maybe, Undefinable } from "
|
|
2
|
-
import { Nothing, Some, MaybeType } from "
|
|
1
|
+
import type { Maybe, Undefinable } from "../../../utils";
|
|
2
|
+
import { Nothing, Some, MaybeType } from "../../../utils";
|
|
3
3
|
import type { Taxon, TaxonSetData } from "./taxon";
|
|
4
4
|
|
|
5
|
+
/**
|
|
6
|
+
* An internal maybe safe helper function for getting a taxon's name
|
|
7
|
+
* @param data - the underlying taxon set data.
|
|
8
|
+
* @param id
|
|
9
|
+
* @returns Maybe(name)
|
|
10
|
+
*/
|
|
11
|
+
|
|
5
12
|
export function maybeGetNameFromIndex(
|
|
6
13
|
data: TaxonSetData,
|
|
7
14
|
id: Maybe<number> | number,
|
|
@@ -23,6 +30,13 @@ export function maybeGetNameFromIndex(
|
|
|
23
30
|
return Some(name);
|
|
24
31
|
}
|
|
25
32
|
|
|
33
|
+
/**
|
|
34
|
+
* An internal maybe safe helper function for getting a taxon by it's name
|
|
35
|
+
* @param data - the underlying taxon set data.
|
|
36
|
+
* @param id
|
|
37
|
+
* @returns Maybe(taxon)
|
|
38
|
+
*/
|
|
39
|
+
|
|
26
40
|
export function maybeGetTaxonByName(
|
|
27
41
|
data: TaxonSetData,
|
|
28
42
|
id: Maybe<string> | string,
|
|
@@ -1,12 +1,23 @@
|
|
|
1
|
-
import { MaybeType } from "
|
|
1
|
+
import { MaybeType } from "../../../utils";
|
|
2
2
|
import { maybeGetNameFromIndex, maybeGetTaxonByName } from "./helper-functions";
|
|
3
3
|
|
|
4
|
+
/**
|
|
5
|
+
* A interface for taxon.
|
|
6
|
+
* There should only be one taxon per individual sampled.
|
|
7
|
+
* The taxon is meant to be synonymous with the individual and may be shared across multiple trees.
|
|
8
|
+
*/
|
|
4
9
|
export interface Taxon {
|
|
5
10
|
name: string;
|
|
6
11
|
number: number;
|
|
7
12
|
annotations: { [annotation: string]: string | string[] | number | number[] };
|
|
8
13
|
}
|
|
9
14
|
|
|
15
|
+
/**
|
|
16
|
+
* An internal helper function for constructing a new taxon.
|
|
17
|
+
* @param name - taxon name
|
|
18
|
+
* @param number - taxon number
|
|
19
|
+
* @returns
|
|
20
|
+
*/
|
|
10
21
|
function newTaxon(name: string, number: number): Taxon {
|
|
11
22
|
return {
|
|
12
23
|
name,
|
|
@@ -15,19 +26,47 @@ function newTaxon(name: string, number: number): Taxon {
|
|
|
15
26
|
};
|
|
16
27
|
}
|
|
17
28
|
|
|
29
|
+
/**
|
|
30
|
+
* An interface for a taxon set - a group of taxa in a tree.
|
|
31
|
+
*/
|
|
18
32
|
export interface TaxonSetInterface {
|
|
33
|
+
/**
|
|
34
|
+
* Add a taxon the the set
|
|
35
|
+
* @param name - Add a new taxon with this name
|
|
36
|
+
*/
|
|
19
37
|
addTaxon(name: string): TaxonSetInterface;
|
|
20
|
-
|
|
38
|
+
/**
|
|
39
|
+
* Get a taxon by it's number
|
|
40
|
+
* @param id -taxon number
|
|
41
|
+
*/
|
|
42
|
+
getTaxon(id: number): Taxon | undefined; // remove this undefined?
|
|
43
|
+
/**
|
|
44
|
+
* Get a taxon object by it's name.
|
|
45
|
+
* @param name -the taxon name
|
|
46
|
+
*/
|
|
21
47
|
getTaxonByName(name: string): Taxon;
|
|
48
|
+
/**
|
|
49
|
+
* Return the number of taxa in the set.
|
|
50
|
+
*/
|
|
22
51
|
getTaxonCount(): number;
|
|
52
|
+
/**
|
|
53
|
+
* Lock the taxa set. No taxa can be added or removed at this point. The population is fixed.
|
|
54
|
+
*/
|
|
23
55
|
lockTaxa(): TaxonSetInterface;
|
|
24
56
|
}
|
|
25
57
|
|
|
58
|
+
/**
|
|
59
|
+
* The interface for a taxon set internal data structure.
|
|
60
|
+
*/
|
|
26
61
|
export interface TaxonSetData {
|
|
27
62
|
allNames: string[];
|
|
28
63
|
byName: { [taxon: string]: Taxon };
|
|
29
64
|
finalized: boolean;
|
|
30
65
|
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* A concrete implementation of the taxonset interface
|
|
69
|
+
*/
|
|
31
70
|
export class TaxonSet implements TaxonSetInterface {
|
|
32
71
|
_data: TaxonSetData;
|
|
33
72
|
constructor(taxonSetData?: TaxonSetData) {
|
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
import type { Tree, NodeRef } from "../tree-types";
|
|
2
2
|
import type { TreeTraversal } from "./traversal-types";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* A class for a cached pre-order traversal.
|
|
6
|
+
* This needs to be revisited before it can be used.
|
|
7
|
+
*/
|
|
3
8
|
export class PreOrderTraversalCache implements TreeTraversal {
|
|
4
9
|
_forwardCache: Map<NodeRef, NodeRef>;
|
|
5
10
|
_reverseCache: Map<NodeRef, NodeRef>;
|