diff --git a/README.md b/README.md
index 4886b0197..0573ebfe1 100644
--- a/README.md
+++ b/README.md
@@ -22,6 +22,8 @@
---
+> 🚀 **We're hiring!** Join HyperFormula team as a **Senior Software Engineer**. [See the role and apply](https://handsontable.traffit.com/public/an/4b09e1395bf8ea42ef86db4c4657992c2f48673d).
+
HyperFormula is a headless spreadsheet built in TypeScript, serving as both a parser and evaluator of spreadsheet formulas. It can be integrated into your browser or utilized as a service with Node.js as your back-end technology.
## What HyperFormula can be used for?
diff --git a/docs/.vuepress/components/HiringBanner.vue b/docs/.vuepress/components/HiringBanner.vue
new file mode 100644
index 000000000..55207e6f5
--- /dev/null
+++ b/docs/.vuepress/components/HiringBanner.vue
@@ -0,0 +1,87 @@
+
+
+
+
+
+
+
diff --git a/docs/.vuepress/config.js b/docs/.vuepress/config.js
index 6e95cc8a9..eecf3aa24 100644
--- a/docs/.vuepress/config.js
+++ b/docs/.vuepress/config.js
@@ -11,6 +11,7 @@ const searchPattern = new RegExp('^/api', 'i');
module.exports = {
title: 'HyperFormula (v' + HyperFormula.version + ')',
description: 'HyperFormula is an open-source, high-performance calculation engine for spreadsheets and web applications.',
+ globalUIComponents: ['HiringBanner'],
head: [
// Import HF (required for the examples)
[ 'script', { src: 'https://cdn.jsdelivr.net/npm/hyperformula/dist/hyperformula.full.min.js' } ],
@@ -40,7 +41,7 @@ module.exports = {
new Sentry.Replay({
maskAllText: false,
blockAllMedia: false,
- }),
+ }),
],
});
};
diff --git a/src/DependencyGraph/EmptyCellVertex.ts b/src/DependencyGraph/EmptyCellVertex.ts
index 99bbfa766..7daccc72e 100644
--- a/src/DependencyGraph/EmptyCellVertex.ts
+++ b/src/DependencyGraph/EmptyCellVertex.ts
@@ -9,6 +9,8 @@ import {EmptyValue, EmptyValueType} from '../interpreter/InterpreterValue'
* Represents singleton vertex bound to all empty cells
*/
export class EmptyCellVertex {
+ public _graphId?: number
+
constructor() {}
/**
diff --git a/src/DependencyGraph/FormulaVertex.ts b/src/DependencyGraph/FormulaVertex.ts
index cf1c02161..a6c38b6b6 100644
--- a/src/DependencyGraph/FormulaVertex.ts
+++ b/src/DependencyGraph/FormulaVertex.ts
@@ -16,6 +16,8 @@ import {Ast} from '../parser'
import {ColumnsSpan, RowsSpan} from '../Span'
export abstract class FormulaVertex {
+ public _graphId?: number
+
protected constructor(
protected formula: Ast,
protected cellAddress: SimpleCellAddress,
diff --git a/src/DependencyGraph/Graph.ts b/src/DependencyGraph/Graph.ts
index 60c5f3487..4aceca92b 100644
--- a/src/DependencyGraph/Graph.ts
+++ b/src/DependencyGraph/Graph.ts
@@ -18,7 +18,7 @@ export type DependencyQuery = (vertex: Node) => [(SimpleCellAddress | Simp
* Idea for performance improvement:
* - use Set[] instead of NodeId[][] for edgesSparseArray
*/
-export class Graph {
+export class Graph {
/**
* A sparse array. The value nodesSparseArray[n] exists if and only if node n is in the graph.
* @private
@@ -32,12 +32,6 @@ export class Graph {
*/
private edgesSparseArray: NodeId[][] = []
- /**
- * A mapping from node to its id. The value nodesIds.get(node) exists if and only if node is in the graph.
- * @private
- */
- private nodesIds: Map = new Map()
-
/**
* A ProcessableValue object.
* @private
@@ -78,7 +72,7 @@ export class Graph {
* @param node - node to check
*/
public hasNode(node: Node): boolean {
- return this.nodesIds.has(node)
+ return node._graphId !== undefined
}
/**
@@ -137,7 +131,7 @@ export class Graph {
* @param node - a node to be added
*/
public addNodeAndReturnId(node: Node): NodeId {
- const idOfExistingNode = this.nodesIds.get(node)
+ const idOfExistingNode = node._graphId
if (idOfExistingNode !== undefined) {
return idOfExistingNode
@@ -148,7 +142,7 @@ export class Graph {
this.nodesSparseArray[newId] = node
this.edgesSparseArray[newId] = []
- this.nodesIds.set(node, newId)
+ node._graphId = newId
return newId
}
@@ -183,7 +177,7 @@ export class Graph {
* Removes node from graph
*/
public removeNode(node: Node): [(SimpleCellAddress | SimpleCellRange), Node][] {
- const id = this.getNodeId(node)
+ const id = node._graphId
if (id === undefined) {
throw this.missingNodeError(node)
@@ -199,7 +193,7 @@ export class Graph {
delete this.nodesSparseArray[id]
delete this.edgesSparseArray[id]
this.infiniteRangeIds.delete(id)
- this.nodesIds.delete(node)
+ node._graphId = undefined
return dependencies
}
@@ -368,14 +362,14 @@ export class Graph {
* Returns the internal id of a node.
*/
public getNodeId(node: Node): NodeId | undefined {
- return this.nodesIds.get(node)
+ return node._graphId
}
/**
*
*/
private getNodeIdIfNotNumber(node: Node | NodeId): NodeId | undefined {
- return typeof node === 'number' ? node : this.nodesIds.get(node)
+ return typeof node === 'number' ? node : node._graphId
}
/**
diff --git a/src/DependencyGraph/ParsingErrorVertex.ts b/src/DependencyGraph/ParsingErrorVertex.ts
index b8535869c..6e7b036c5 100644
--- a/src/DependencyGraph/ParsingErrorVertex.ts
+++ b/src/DependencyGraph/ParsingErrorVertex.ts
@@ -10,6 +10,8 @@ import {ParsingError} from '../parser/Ast'
* Represents a cell that contains a parsing error.
*/
export class ParsingErrorVertex {
+ public _graphId?: number
+
/**
* Constructor
*/
diff --git a/src/DependencyGraph/RangeVertex.ts b/src/DependencyGraph/RangeVertex.ts
index b64e1187d..cd0ef5b00 100644
--- a/src/DependencyGraph/RangeVertex.ts
+++ b/src/DependencyGraph/RangeVertex.ts
@@ -16,6 +16,7 @@ export type CriterionCache = Map
* Represents vertex bound to range
*/
export class RangeVertex {
+ public _graphId?: number
public bruteForce: boolean
/** Cache for associative aggregate functions. */
private functionCache: Map
diff --git a/src/DependencyGraph/ValueCellVertex.ts b/src/DependencyGraph/ValueCellVertex.ts
index 5e4d7e329..2c1d8c7f9 100644
--- a/src/DependencyGraph/ValueCellVertex.ts
+++ b/src/DependencyGraph/ValueCellVertex.ts
@@ -18,6 +18,8 @@ export interface RawAndParsedValue {
* Represents vertex which keeps static cell value
*/
export class ValueCellVertex {
+ public _graphId?: number
+
/** Static cell value. */
constructor(private parsedValue: ValueCellVertexValue, private rawValue: RawCellContent) {
}