diff --git a/src/proxy.ts b/src/proxy.ts index e7d254c..7083a78 100644 --- a/src/proxy.ts +++ b/src/proxy.ts @@ -28,7 +28,7 @@ export class SheetProxy { this.working = new Working(sh.working); this.errors = new CellErrors(sh.errors); if (name) this._name = name; - this._id = sh.incrementProxyCount(); + this._id = sh.addProxy(); } // a Sheet has id 0, proxies > 0 @@ -182,6 +182,7 @@ export class SheetProxy { // @ts-expect-error conflict with overloaded definitions const cell = this._sheet.map(dependencies, computeFn, name, this, noFail); this._list.push(cell); + this._sheet.addProxyDependencies(this._id, dependencies); return cell as MapCell; } @@ -207,6 +208,7 @@ export class SheetProxy { noFail ); this._list.push(cell); + this._sheet.addProxyDependencies(this._id, dependencies); return cell; } diff --git a/src/sheet.ts b/src/sheet.ts index dfb4479..dbe20ea 100644 --- a/src/sheet.ts +++ b/src/sheet.ts @@ -113,6 +113,8 @@ export class Sheet { /** Cells that can be garbage collected */ private _gc: Set; + private _proxies: Graph; + /** * @param equality function comparing a new value with previous value for updates */ @@ -131,6 +133,8 @@ export class Sheet { this.working = new Working(); this.errors = new CellErrors(); this._gc = new Set(); + this._proxies = new Graph(); + this._proxies.addNode(0); } // a Sheet has id 0, proxies > 0 @@ -138,9 +142,22 @@ export class Sheet { return 0; } - incrementProxyCount() { + addProxy() { + // keeping 0 as original Sheet this[proxies]++; - return this[proxies]; // keeping 0 as original Sheet + const id = this[proxies]; + this._proxies.addNode(id); + return id; + } + + addProxyEdge(from: number, to: number) { + this._proxies.addEdge(from, to); + } + addProxyDependencies(id: number, deps: AnyCellArray) { + for (const dep of deps) + if (dep._proxy !== id) this.addProxyEdge(dep._proxy, id); + if (this._proxies.topologicalSort() === null) + this.debug(undefined, "proxy cycle", { proxy: id, deps }); } bless(id: number, name: string) {