@genome-spy/core 0.68.0 → 0.69.0
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/bundle/index.es.js +12108 -10682
- package/dist/bundle/index.js +119 -119
- package/dist/schema.json +6224 -6319
- package/dist/src/data/dataFlow.d.ts.map +1 -1
- package/dist/src/data/dataFlow.js +10 -0
- package/dist/src/data/flowNode.d.ts +25 -10
- package/dist/src/data/flowNode.d.ts.map +1 -1
- package/dist/src/data/flowNode.js +66 -13
- package/dist/src/data/flowTestUtils.d.ts +2 -2
- package/dist/src/data/flowTestUtils.d.ts.map +1 -1
- package/dist/src/data/flowTestUtils.js +5 -4
- package/dist/src/data/sources/dataSource.js +2 -2
- package/dist/src/data/sources/lazy/bigBedSource.d.ts.map +1 -1
- package/dist/src/data/sources/lazy/bigBedSource.js +11 -10
- package/dist/src/data/sources/lazy/bigWigSource.d.ts.map +1 -1
- package/dist/src/data/sources/lazy/bigWigSource.js +11 -10
- package/dist/src/data/sources/lazy/singleAxisWindowedSource.js +1 -1
- package/dist/src/data/sources/lazy/tabixSource.d.ts +0 -1
- package/dist/src/data/sources/lazy/tabixSource.d.ts.map +1 -1
- package/dist/src/data/sources/lazy/tabixSource.js +41 -11
- package/dist/src/data/sources/sequenceSource.d.ts.map +1 -1
- package/dist/src/data/sources/sequenceSource.js +5 -3
- package/dist/src/data/sources/urlSource.d.ts.map +1 -1
- package/dist/src/data/sources/urlSource.js +7 -3
- package/dist/src/data/transforms/filter.d.ts +4 -4
- package/dist/src/data/transforms/filter.d.ts.map +1 -1
- package/dist/src/data/transforms/filter.js +13 -7
- package/dist/src/data/transforms/filterScoredLabels.d.ts.map +1 -1
- package/dist/src/data/transforms/filterScoredLabels.js +11 -6
- package/dist/src/data/transforms/filterScoredLabels.test.d.ts +2 -0
- package/dist/src/data/transforms/filterScoredLabels.test.d.ts.map +1 -0
- package/dist/src/data/transforms/formula.d.ts +4 -4
- package/dist/src/data/transforms/formula.d.ts.map +1 -1
- package/dist/src/data/transforms/formula.js +12 -6
- package/dist/src/data/transforms/measureText.d.ts +2 -2
- package/dist/src/data/transforms/measureText.d.ts.map +1 -1
- package/dist/src/data/transforms/measureText.js +16 -12
- package/dist/src/data/transforms/transform.d.ts +2 -2
- package/dist/src/data/transforms/transform.d.ts.map +1 -1
- package/dist/src/data/transforms/transform.js +3 -3
- package/dist/src/encoder/accessor.d.ts +8 -4
- package/dist/src/encoder/accessor.d.ts.map +1 -1
- package/dist/src/encoder/accessor.js +10 -10
- package/dist/src/encoder/encoder.js +5 -5
- package/dist/src/genome/genome.d.ts +8 -0
- package/dist/src/genome/genome.d.ts.map +1 -1
- package/dist/src/genome/genome.js +16 -1
- package/dist/src/genomeSpy/inputBindingManager.js +1 -1
- package/dist/src/genomeSpy/interactionController.d.ts.map +1 -1
- package/dist/src/genomeSpy/interactionController.js +7 -1
- package/dist/src/genomeSpy.js +1 -1
- package/dist/src/gl/glslScaleGenerator.js +1 -1
- package/dist/src/marks/mark.d.ts.map +1 -1
- package/dist/src/marks/mark.js +22 -30
- package/dist/src/marks/point.d.ts.map +1 -1
- package/dist/src/marks/point.js +4 -6
- package/dist/src/paramRuntime/expressionCompiler.d.ts +7 -0
- package/dist/src/paramRuntime/expressionCompiler.d.ts.map +1 -0
- package/dist/src/paramRuntime/expressionCompiler.js +10 -0
- package/dist/src/paramRuntime/expressionRef.d.ts +20 -0
- package/dist/src/paramRuntime/expressionRef.d.ts.map +1 -0
- package/dist/src/paramRuntime/expressionRef.js +95 -0
- package/dist/src/paramRuntime/expressionRef.test.d.ts +2 -0
- package/dist/src/paramRuntime/expressionRef.test.d.ts.map +1 -0
- package/dist/src/paramRuntime/graphRuntime.d.ts +176 -0
- package/dist/src/paramRuntime/graphRuntime.d.ts.map +1 -0
- package/dist/src/paramRuntime/graphRuntime.js +628 -0
- package/dist/src/paramRuntime/graphRuntime.test.d.ts +2 -0
- package/dist/src/paramRuntime/graphRuntime.test.d.ts.map +1 -0
- package/dist/src/paramRuntime/index.d.ts +9 -0
- package/dist/src/paramRuntime/index.d.ts.map +1 -0
- package/dist/src/paramRuntime/index.js +8 -0
- package/dist/src/paramRuntime/lifecycleRegistry.d.ts +27 -0
- package/dist/src/paramRuntime/lifecycleRegistry.d.ts.map +1 -0
- package/dist/src/paramRuntime/lifecycleRegistry.js +54 -0
- package/dist/src/paramRuntime/paramRuntime.d.ts +165 -0
- package/dist/src/paramRuntime/paramRuntime.d.ts.map +1 -0
- package/dist/src/paramRuntime/paramRuntime.js +222 -0
- package/dist/src/paramRuntime/paramRuntime.test.d.ts +2 -0
- package/dist/src/paramRuntime/paramRuntime.test.d.ts.map +1 -0
- package/dist/src/paramRuntime/paramStore.d.ts +68 -0
- package/dist/src/paramRuntime/paramStore.d.ts.map +1 -0
- package/dist/src/paramRuntime/paramStore.js +148 -0
- package/dist/src/paramRuntime/paramStore.test.d.ts +2 -0
- package/dist/src/paramRuntime/paramStore.test.d.ts.map +1 -0
- package/dist/src/paramRuntime/paramUtils.d.ts +86 -0
- package/dist/src/paramRuntime/paramUtils.d.ts.map +1 -0
- package/dist/src/paramRuntime/paramUtils.js +272 -0
- package/dist/src/paramRuntime/selectionStore.d.ts +6 -0
- package/dist/src/paramRuntime/selectionStore.d.ts.map +1 -0
- package/dist/src/paramRuntime/selectionStore.js +13 -0
- package/dist/src/paramRuntime/types.d.ts +16 -0
- package/dist/src/paramRuntime/types.d.ts.map +1 -0
- package/dist/src/paramRuntime/types.js +25 -0
- package/dist/src/paramRuntime/viewParamRuntime.d.ts +164 -0
- package/dist/src/paramRuntime/viewParamRuntime.d.ts.map +1 -0
- package/dist/src/paramRuntime/viewParamRuntime.js +443 -0
- package/dist/src/scales/scaleInstanceManager.d.ts +6 -3
- package/dist/src/scales/scaleInstanceManager.d.ts.map +1 -1
- package/dist/src/scales/scaleInstanceManager.js +17 -11
- package/dist/src/scales/scaleResolution.d.ts +1 -0
- package/dist/src/scales/scaleResolution.d.ts.map +1 -1
- package/dist/src/scales/scaleResolution.js +7 -1
- package/dist/src/selection/selection.js +1 -1
- package/dist/src/spec/coreSchemaRoot.d.ts +53 -0
- package/dist/src/spec/root.d.ts +1 -1
- package/dist/src/spec/view.d.ts +114 -33
- package/dist/src/tooltip/dataTooltipHandler.d.ts +1 -1
- package/dist/src/tooltip/dataTooltipHandler.js +23 -32
- package/dist/src/tooltip/dataTooltipHandler.test.d.ts +2 -0
- package/dist/src/tooltip/dataTooltipHandler.test.d.ts.map +1 -0
- package/dist/src/tooltip/flattenDatumRows.d.ts +13 -0
- package/dist/src/tooltip/flattenDatumRows.d.ts.map +1 -0
- package/dist/src/tooltip/flattenDatumRows.js +47 -0
- package/dist/src/tooltip/flattenDatumRows.test.d.ts +2 -0
- package/dist/src/tooltip/flattenDatumRows.test.d.ts.map +1 -0
- package/dist/src/tooltip/refseqGeneTooltipHandler.d.ts +1 -1
- package/dist/src/tooltip/refseqGeneTooltipHandler.js +7 -1
- package/dist/src/tooltip/tooltipContext.d.ts +13 -0
- package/dist/src/tooltip/tooltipContext.d.ts.map +1 -0
- package/dist/src/tooltip/tooltipContext.js +543 -0
- package/dist/src/tooltip/tooltipContext.test.d.ts +2 -0
- package/dist/src/tooltip/tooltipContext.test.d.ts.map +1 -0
- package/dist/src/tooltip/tooltipHandler.d.ts +40 -1
- package/dist/src/tooltip/tooltipHandler.d.ts.map +1 -1
- package/dist/src/tooltip/tooltipHandler.ts +62 -1
- package/dist/src/types/encoder.d.ts +1 -1
- package/dist/src/utils/inputBinding.d.ts +10 -2
- package/dist/src/utils/inputBinding.d.ts.map +1 -1
- package/dist/src/utils/inputBinding.js +12 -3
- package/dist/src/view/flowBuilder.d.ts.map +1 -1
- package/dist/src/view/flowBuilder.js +12 -3
- package/dist/src/view/gridView/gridChild.d.ts.map +1 -1
- package/dist/src/view/gridView/gridChild.js +8 -3
- package/dist/src/view/gridView/selectionRect.d.ts +6 -10
- package/dist/src/view/gridView/selectionRect.d.ts.map +1 -1
- package/dist/src/view/gridView/selectionRect.js +3 -20
- package/dist/src/view/layerView.d.ts.map +1 -1
- package/dist/src/view/layerView.js +4 -2
- package/dist/src/view/multiscale.d.ts +35 -0
- package/dist/src/view/multiscale.d.ts.map +1 -0
- package/dist/src/view/multiscale.js +233 -0
- package/dist/src/view/multiscale.test.d.ts +2 -0
- package/dist/src/view/multiscale.test.d.ts.map +1 -0
- package/dist/src/view/unitView.d.ts.map +1 -1
- package/dist/src/view/unitView.js +10 -4
- package/dist/src/view/view.d.ts +5 -4
- package/dist/src/view/view.d.ts.map +1 -1
- package/dist/src/view/view.js +205 -28
- package/dist/src/view/viewFactory.d.ts +0 -12
- package/dist/src/view/viewFactory.d.ts.map +1 -1
- package/dist/src/view/viewFactory.js +35 -24
- package/dist/src/view/viewParamRuntime.test.d.ts +2 -0
- package/dist/src/view/viewParamRuntime.test.d.ts.map +1 -0
- package/dist/src/view/viewSelectors.d.ts.map +1 -1
- package/dist/src/view/viewSelectors.js +8 -5
- package/package.json +3 -3
- package/dist/src/spec/sampleView.d.ts +0 -197
- package/dist/src/view/paramMediator.d.ts +0 -168
- package/dist/src/view/paramMediator.d.ts.map +0 -1
- package/dist/src/view/paramMediator.js +0 -545
- package/dist/src/view/paramMediator.test.d.ts +0 -2
- package/dist/src/view/paramMediator.test.d.ts.map +0 -1
package/dist/src/marks/mark.js
CHANGED
|
@@ -48,7 +48,10 @@ import coalesceProperties from "../utils/propertyCoalescer.js";
|
|
|
48
48
|
import { isScalar } from "../utils/variableTools.js";
|
|
49
49
|
import { InternMap } from "internmap";
|
|
50
50
|
import ViewError from "../view/viewError.js";
|
|
51
|
-
import {
|
|
51
|
+
import {
|
|
52
|
+
isExprRef,
|
|
53
|
+
validateParameterName,
|
|
54
|
+
} from "../paramRuntime/paramUtils.js";
|
|
52
55
|
import { UNIQUE_ID_KEY } from "../data/transforms/identifier.js";
|
|
53
56
|
import {
|
|
54
57
|
isIntervalSelection,
|
|
@@ -95,11 +98,6 @@ export default class Mark {
|
|
|
95
98
|
*/
|
|
96
99
|
#callAfterShaderCompilation = [];
|
|
97
100
|
|
|
98
|
-
/**
|
|
99
|
-
* @type {{expr: import("../view/paramMediator.js").ExprRefFunction, listener: () => void}[]}
|
|
100
|
-
*/
|
|
101
|
-
#exprListeners = [];
|
|
102
|
-
|
|
103
101
|
/**
|
|
104
102
|
* @param {import("../view/unitView.js").default} unitView
|
|
105
103
|
*/
|
|
@@ -304,13 +302,13 @@ export default class Mark {
|
|
|
304
302
|
for (const key of props) {
|
|
305
303
|
const prop = this.properties[key];
|
|
306
304
|
if (prop && isExprRef(prop)) {
|
|
307
|
-
const fn = this.unitView.
|
|
308
|
-
prop.expr
|
|
305
|
+
const fn = this.unitView.paramRuntime.watchExpression(
|
|
306
|
+
prop.expr,
|
|
307
|
+
() => {
|
|
308
|
+
this.updateGraphicsData();
|
|
309
|
+
this.unitView.context.animator.requestRender();
|
|
310
|
+
}
|
|
309
311
|
);
|
|
310
|
-
fn.addListener(() => {
|
|
311
|
-
this.updateGraphicsData();
|
|
312
|
-
this.unitView.context.animator.requestRender();
|
|
313
|
-
});
|
|
314
312
|
// @ts-ignore
|
|
315
313
|
if (!channels.includes(key)) {
|
|
316
314
|
Object.defineProperty(exprProps, key, {
|
|
@@ -487,8 +485,8 @@ export default class Mark {
|
|
|
487
485
|
|
|
488
486
|
for (const predicate of paramPredicates) {
|
|
489
487
|
const param = predicate.param;
|
|
490
|
-
const
|
|
491
|
-
const selection =
|
|
488
|
+
const paramRuntime = this.unitView.paramRuntime;
|
|
489
|
+
const selection = paramRuntime.findValue(param);
|
|
492
490
|
|
|
493
491
|
// The selection is supposed to have an empty value at this point
|
|
494
492
|
// so that we can figure out the type of the selection.
|
|
@@ -546,7 +544,7 @@ export default class Mark {
|
|
|
546
544
|
|
|
547
545
|
this.selectionTextureOps.push(() => {
|
|
548
546
|
// Texture is set in the prepareRender method
|
|
549
|
-
const selection =
|
|
547
|
+
const selection = paramRuntime.getValue(param);
|
|
550
548
|
const texture = selectionTextures.get(selection);
|
|
551
549
|
if (!texture) {
|
|
552
550
|
throw new Error(
|
|
@@ -569,11 +567,10 @@ export default class Mark {
|
|
|
569
567
|
// Create the initial texture
|
|
570
568
|
glHelper.createSelectionTexture(selection);
|
|
571
569
|
|
|
572
|
-
|
|
573
|
-
fn.addListener(() => {
|
|
570
|
+
paramRuntime.watchExpression(param, () => {
|
|
574
571
|
const selection =
|
|
575
572
|
/** @type {import("../types/selectionTypes.js").MultiPointSelection} */ (
|
|
576
|
-
|
|
573
|
+
paramRuntime.getValue(param)
|
|
577
574
|
);
|
|
578
575
|
glHelper.createSelectionTexture(selection);
|
|
579
576
|
this.getContext().animator.requestRender();
|
|
@@ -1044,15 +1041,14 @@ export default class Mark {
|
|
|
1044
1041
|
};
|
|
1045
1042
|
|
|
1046
1043
|
if (isExprRef(propValue)) {
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
);
|
|
1050
|
-
|
|
1044
|
+
/** @type {import("../paramRuntime/types.js").ExprRefFunction} */
|
|
1045
|
+
let fn;
|
|
1051
1046
|
const set = () => setter(adjuster(fn(null)));
|
|
1047
|
+
fn = this.unitView.paramRuntime.watchExpression(
|
|
1048
|
+
propValue.expr,
|
|
1049
|
+
set
|
|
1050
|
+
);
|
|
1052
1051
|
|
|
1053
|
-
// Register a listener ...
|
|
1054
|
-
fn.addListener(set);
|
|
1055
|
-
this.#exprListeners.push({ expr: fn, listener: set });
|
|
1056
1052
|
// ... and set the initial value
|
|
1057
1053
|
set();
|
|
1058
1054
|
} else {
|
|
@@ -1097,10 +1093,6 @@ export default class Mark {
|
|
|
1097
1093
|
}
|
|
1098
1094
|
|
|
1099
1095
|
dispose() {
|
|
1100
|
-
for (const { expr, listener } of this.#exprListeners) {
|
|
1101
|
-
expr.removeListener(listener);
|
|
1102
|
-
}
|
|
1103
|
-
this.#exprListeners.length = 0;
|
|
1104
1096
|
this.deleteGraphicsData();
|
|
1105
1097
|
}
|
|
1106
1098
|
|
|
@@ -1177,7 +1169,7 @@ export default class Mark {
|
|
|
1177
1169
|
isPickingParticipant() {
|
|
1178
1170
|
if (
|
|
1179
1171
|
this.properties.tooltip === null &&
|
|
1180
|
-
!this.unitView.
|
|
1172
|
+
!this.unitView.paramRuntime.hasPointSelections()
|
|
1181
1173
|
) {
|
|
1182
1174
|
// Disabled
|
|
1183
1175
|
return false;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"point.d.ts","sourceRoot":"","sources":["../../../src/marks/point.js"],"names":[],"mappings":"AAmBA;;GAEG;AACH;IAGI;;OAEG;IACH,sBAFW,OAAO,qBAAqB,EAAE,OAAO,
|
|
1
|
+
{"version":3,"file":"point.d.ts","sourceRoot":"","sources":["../../../src/marks/point.js"],"names":[],"mappings":"AAmBA;;GAEG;AACH;IAGI;;OAEG;IACH,sBAFW,OAAO,qBAAqB,EAAE,OAAO,EAiD/C;IA0EO,iDAMC;IAkET,+BAkBC;;CAgDJ;iBApRgB,WAAW"}
|
package/dist/src/marks/point.js
CHANGED
|
@@ -10,7 +10,7 @@ import FRAGMENT_SHADER from "./point.fragment.glsl.js";
|
|
|
10
10
|
import COMMON_SHADER from "./point.common.glsl.js";
|
|
11
11
|
|
|
12
12
|
import Mark from "./mark.js";
|
|
13
|
-
import { isExprRef } from "../
|
|
13
|
+
import { isExprRef } from "../paramRuntime/paramUtils.js";
|
|
14
14
|
import { sampleIterable } from "../data/transforms/sample.js";
|
|
15
15
|
import { fixFill, fixStroke } from "./markUtils.js";
|
|
16
16
|
|
|
@@ -58,11 +58,9 @@ export default class PointMark extends Mark {
|
|
|
58
58
|
const szf = this.properties.semanticZoomFraction;
|
|
59
59
|
if (szf != null) {
|
|
60
60
|
if (isExprRef(szf)) {
|
|
61
|
-
const fn = this.unitView.
|
|
62
|
-
szf.expr
|
|
63
|
-
|
|
64
|
-
fn.addListener(() =>
|
|
65
|
-
this.getContext().animator.requestRender()
|
|
61
|
+
const fn = this.unitView.paramRuntime.watchExpression(
|
|
62
|
+
szf.expr,
|
|
63
|
+
() => this.getContext().animator.requestRender()
|
|
66
64
|
);
|
|
67
65
|
this.#semanticZoomFraction = fn;
|
|
68
66
|
} else {
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @param {string} expr
|
|
3
|
+
* @param {Record<string, any>} [globalObject]
|
|
4
|
+
* @returns {import("../utils/expression.js").ExpressionFunction}
|
|
5
|
+
*/
|
|
6
|
+
export function compileExpression(expr: string, globalObject?: Record<string, any>): import("../utils/expression.js").ExpressionFunction;
|
|
7
|
+
//# sourceMappingURL=expressionCompiler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"expressionCompiler.d.ts","sourceRoot":"","sources":["../../../src/paramRuntime/expressionCompiler.js"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,wCAJW,MAAM,iBACN,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GACjB,OAAO,wBAAwB,EAAE,kBAAkB,CAI/D"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import createFunction from "../utils/expression.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @param {string} expr
|
|
5
|
+
* @param {Record<string, any>} [globalObject]
|
|
6
|
+
* @returns {import("../utils/expression.js").ExpressionFunction}
|
|
7
|
+
*/
|
|
8
|
+
export function compileExpression(expr, globalObject = {}) {
|
|
9
|
+
return createFunction(expr, globalObject);
|
|
10
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @typedef {{
|
|
3
|
+
* expression: import("./types.js").ExprRefFunction,
|
|
4
|
+
* dependencies: import("./types.js").ParamRef<any>[]
|
|
5
|
+
* }} BoundExpression
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Binds expression globals to parameter refs in a specific scope and equips the
|
|
9
|
+
* resulting expression function with listener lifecycle helpers.
|
|
10
|
+
*
|
|
11
|
+
* @param {string} expr
|
|
12
|
+
* @param {(name: string) => import("./types.js").ParamRef<any> | undefined} resolve
|
|
13
|
+
* @returns {BoundExpression}
|
|
14
|
+
*/
|
|
15
|
+
export function bindExpression(expr: string, resolve: (name: string) => import("./types.js").ParamRef<any> | undefined): BoundExpression;
|
|
16
|
+
export type BoundExpression = {
|
|
17
|
+
expression: import("./types.js").ExprRefFunction;
|
|
18
|
+
dependencies: import("./types.js").ParamRef<any>[];
|
|
19
|
+
};
|
|
20
|
+
//# sourceMappingURL=expressionRef.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"expressionRef.d.ts","sourceRoot":"","sources":["../../../src/paramRuntime/expressionRef.js"],"names":[],"mappings":"AAEA;;;;;GAKG;AAEH;;;;;;;GAOG;AACH,qCAJW,MAAM,WACN,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,YAAY,EAAE,QAAQ,CAAC,GAAG,CAAC,GAAG,SAAS,GAC9D,eAAe,CA+E3B;8BA3FY;IACR,UAAU,EAAE,OAAO,YAAY,EAAE,eAAe,CAAC;IACjD,YAAY,EAAE,OAAO,YAAY,EAAE,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAA;CACnD"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { compileExpression } from "./expressionCompiler.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @typedef {{
|
|
5
|
+
* expression: import("./types.js").ExprRefFunction,
|
|
6
|
+
* dependencies: import("./types.js").ParamRef<any>[]
|
|
7
|
+
* }} BoundExpression
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Binds expression globals to parameter refs in a specific scope and equips the
|
|
12
|
+
* resulting expression function with listener lifecycle helpers.
|
|
13
|
+
*
|
|
14
|
+
* @param {string} expr
|
|
15
|
+
* @param {(name: string) => import("./types.js").ParamRef<any> | undefined} resolve
|
|
16
|
+
* @returns {BoundExpression}
|
|
17
|
+
*/
|
|
18
|
+
export function bindExpression(expr, resolve) {
|
|
19
|
+
const globalObject = {};
|
|
20
|
+
|
|
21
|
+
/** @type {import("./types.js").ExprRefFunction} */
|
|
22
|
+
const expression = /** @type {any} */ (
|
|
23
|
+
compileExpression(expr, globalObject)
|
|
24
|
+
);
|
|
25
|
+
|
|
26
|
+
/** @type {Map<string, import("./types.js").ParamRef<any>>} */
|
|
27
|
+
const refsForParams = new Map();
|
|
28
|
+
|
|
29
|
+
for (const globalName of expression.globals) {
|
|
30
|
+
if (refsForParams.has(globalName)) {
|
|
31
|
+
continue;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const ref = resolve(globalName);
|
|
35
|
+
if (!ref) {
|
|
36
|
+
throw new Error(
|
|
37
|
+
'Unknown variable "' + globalName + '" in expression: ' + expr
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
refsForParams.set(globalName, ref);
|
|
42
|
+
|
|
43
|
+
Object.defineProperty(globalObject, globalName, {
|
|
44
|
+
enumerable: true,
|
|
45
|
+
get() {
|
|
46
|
+
return ref.get();
|
|
47
|
+
},
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/** @type {Set<() => void>} */
|
|
52
|
+
const activeSubscriptions = new Set();
|
|
53
|
+
|
|
54
|
+
expression.subscribe = (listener) => {
|
|
55
|
+
/** @type {(() => void)[]} */
|
|
56
|
+
const disposers = [];
|
|
57
|
+
for (const ref of refsForParams.values()) {
|
|
58
|
+
disposers.push(ref.subscribe(listener));
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
let active = true;
|
|
62
|
+
const unsubscribe = () => {
|
|
63
|
+
if (!active) {
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
active = false;
|
|
67
|
+
activeSubscriptions.delete(unsubscribe);
|
|
68
|
+
disposers.forEach((dispose) => dispose());
|
|
69
|
+
};
|
|
70
|
+
activeSubscriptions.add(unsubscribe);
|
|
71
|
+
|
|
72
|
+
return unsubscribe;
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
expression.invalidate = () => {
|
|
76
|
+
for (const unsubscribe of activeSubscriptions) {
|
|
77
|
+
unsubscribe();
|
|
78
|
+
}
|
|
79
|
+
activeSubscriptions.clear();
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
// Include dependency identities to avoid collisions between structurally
|
|
83
|
+
// identical expressions in different scopes.
|
|
84
|
+
expression.identifier = () =>
|
|
85
|
+
expression.code +
|
|
86
|
+
"|" +
|
|
87
|
+
Array.from(refsForParams.values())
|
|
88
|
+
.map((ref) => ref.id)
|
|
89
|
+
.join(",");
|
|
90
|
+
|
|
91
|
+
return {
|
|
92
|
+
expression,
|
|
93
|
+
dependencies: Array.from(refsForParams.values()),
|
|
94
|
+
};
|
|
95
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"expressionRef.test.d.ts","sourceRoot":"","sources":["../../../src/paramRuntime/expressionRef.test.js"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Low-level reactive DAG runtime for parameter propagation.
|
|
3
|
+
*
|
|
4
|
+
* `GraphRuntime` is the scheduling engine behind `ParamRuntime`. It owns:
|
|
5
|
+
* 1. Writable source nodes (`base` and `selection`).
|
|
6
|
+
* 2. Derived/computed nodes with explicit dependencies.
|
|
7
|
+
* 3. Side-effect nodes that run after computed stabilization.
|
|
8
|
+
* 4. Transaction-aware batching and deterministic topological flushing.
|
|
9
|
+
*
|
|
10
|
+
* Typical usage:
|
|
11
|
+
* 1. Create writable refs using `createWritable(...)`.
|
|
12
|
+
* 2. Build derived refs with `computed(...)` from existing refs.
|
|
13
|
+
* 3. Attach side effects with `effect(...)` when external work is needed.
|
|
14
|
+
* 4. Batch writes with `runInTransaction(...)` when multiple updates belong to
|
|
15
|
+
* one logical state transition.
|
|
16
|
+
* 5. Await `whenPropagated(...)` when callers need a "graph is settled" barrier.
|
|
17
|
+
*
|
|
18
|
+
* Notes:
|
|
19
|
+
* 1. This class is intended for runtime internals; most call sites should use
|
|
20
|
+
* `ParamRuntime` / `ViewParamRuntime`.
|
|
21
|
+
* 2. Equality is referential (`!==`), so object writes must use new identities
|
|
22
|
+
* to trigger propagation.
|
|
23
|
+
*/
|
|
24
|
+
export default class GraphRuntime {
|
|
25
|
+
/**
|
|
26
|
+
* Creates a graph runtime.
|
|
27
|
+
*
|
|
28
|
+
* @param {object} [options]
|
|
29
|
+
* @param {import("./lifecycleRegistry.js").default} [options.lifecycleRegistry]
|
|
30
|
+
* Optional lifecycle owner registry. When provided, all created nodes
|
|
31
|
+
* are bound to owners and disposed automatically on owner disposal.
|
|
32
|
+
*/
|
|
33
|
+
constructor(options?: {
|
|
34
|
+
lifecycleRegistry?: import("./lifecycleRegistry.js").default;
|
|
35
|
+
});
|
|
36
|
+
/**
|
|
37
|
+
* Registers a writable source node and returns a writable param ref.
|
|
38
|
+
*
|
|
39
|
+
* Write semantics:
|
|
40
|
+
* 1. A write triggers propagation only when `value !== currentValue`.
|
|
41
|
+
* 2. If `options.notify` is `false`, local listeners are not notified and
|
|
42
|
+
* downstream scheduling is skipped for writes to this ref.
|
|
43
|
+
* 3. Writing to a disposed ref throws.
|
|
44
|
+
*
|
|
45
|
+
* Lifecycle:
|
|
46
|
+
* 1. The node is owner-bound via `ownerId`.
|
|
47
|
+
* 2. Owner disposal marks the node disposed and clears listeners.
|
|
48
|
+
*
|
|
49
|
+
* @template T
|
|
50
|
+
* @param {string} ownerId
|
|
51
|
+
* @param {string} name
|
|
52
|
+
* @param {"base" | "selection"} kind
|
|
53
|
+
* @param {T} initialValue
|
|
54
|
+
* @param {{ notify?: boolean }} [options]
|
|
55
|
+
* @returns {import("./types.js").WritableParamRef<T>}
|
|
56
|
+
*/
|
|
57
|
+
createWritable<T>(ownerId: string, name: string, kind: "base" | "selection", initialValue: T, options?: {
|
|
58
|
+
notify?: boolean;
|
|
59
|
+
}): import("./types.js").WritableParamRef<T>;
|
|
60
|
+
/**
|
|
61
|
+
* Registers a derived node whose value is computed from dependencies.
|
|
62
|
+
*
|
|
63
|
+
* Compute semantics:
|
|
64
|
+
* 1. Initial value is computed eagerly at registration time.
|
|
65
|
+
* 2. On dependency changes, recomputation is queued (deduplicated per flush).
|
|
66
|
+
* 3. Downstream listeners are notified only if computed value identity changes.
|
|
67
|
+
*
|
|
68
|
+
* Lifecycle:
|
|
69
|
+
* 1. Dependency subscriptions are created immediately.
|
|
70
|
+
* 2. Owner disposal unsubscribes dependencies and detaches the node.
|
|
71
|
+
*
|
|
72
|
+
* @template T
|
|
73
|
+
* @param {string} ownerId
|
|
74
|
+
* @param {string} name
|
|
75
|
+
* @param {import("./types.js").ParamRef<any>[]} deps
|
|
76
|
+
* @param {() => T} fn
|
|
77
|
+
* @returns {import("./types.js").ParamRef<T>}
|
|
78
|
+
*/
|
|
79
|
+
computed<T>(ownerId: string, name: string, deps: import("./types.js").ParamRef<any>[], fn: () => T): import("./types.js").ParamRef<T>;
|
|
80
|
+
/**
|
|
81
|
+
* Registers an effect node that runs after computed propagation.
|
|
82
|
+
*
|
|
83
|
+
* Effect semantics:
|
|
84
|
+
* 1. Effect callbacks are queued on dependency changes.
|
|
85
|
+
* 2. Effects run after computed nodes for the same flush epoch.
|
|
86
|
+
* 3. Multiple dependency changes before a flush coalesce to one queued run.
|
|
87
|
+
*
|
|
88
|
+
* @param {string} ownerId
|
|
89
|
+
* @param {import("./types.js").ParamRef<any>[]} deps
|
|
90
|
+
* @param {() => void} fn
|
|
91
|
+
* @returns {() => void} explicit disposer for manual teardown
|
|
92
|
+
*/
|
|
93
|
+
effect(ownerId: string, deps: import("./types.js").ParamRef<any>[], fn: () => void): () => void;
|
|
94
|
+
/**
|
|
95
|
+
* Runs `fn` as an atomic update transaction for this runtime graph.
|
|
96
|
+
*
|
|
97
|
+
* Transaction intent:
|
|
98
|
+
* 1. Batch multiple source writes so downstream computeds/effects observe
|
|
99
|
+
* the final state for the batch, not each intermediate write.
|
|
100
|
+
* 2. Defer scheduling/flush until the outermost transaction exits.
|
|
101
|
+
* 3. Preserve deterministic propagation order by running one flush pass
|
|
102
|
+
* after the transaction boundary.
|
|
103
|
+
*
|
|
104
|
+
* Semantics:
|
|
105
|
+
* 1. Nested transactions are supported via depth counting.
|
|
106
|
+
* 2. Only the outermost transaction exit triggers scheduling.
|
|
107
|
+
* 3. If `fn` throws, the error is rethrown after transaction depth is
|
|
108
|
+
* restored; pending propagation is still scheduled from `finally`.
|
|
109
|
+
* 4. The scheduled flush runs in a microtask (`queueMicrotask`) after the
|
|
110
|
+
* outermost transaction exits.
|
|
111
|
+
* 5. This method does not force immediate synchronous propagation. Use
|
|
112
|
+
* `flushNow()` when the caller explicitly requires immediate flushing.
|
|
113
|
+
*
|
|
114
|
+
* @template T
|
|
115
|
+
* @param {() => T} fn
|
|
116
|
+
* @returns {T}
|
|
117
|
+
*/
|
|
118
|
+
runInTransaction<T>(fn: () => T): T;
|
|
119
|
+
/**
|
|
120
|
+
* Flushes currently queued computed/effect work immediately.
|
|
121
|
+
*
|
|
122
|
+
* Behavior:
|
|
123
|
+
* 1. No-op if called while a transaction is open.
|
|
124
|
+
* 2. No-op during re-entrant flush calls.
|
|
125
|
+
* 3. Runs computeds first, then effects, until the graph reaches a fixed
|
|
126
|
+
* point for the current queued work.
|
|
127
|
+
*/
|
|
128
|
+
flushNow(): void;
|
|
129
|
+
/**
|
|
130
|
+
* Returns a promise that resolves when currently pending graph propagation
|
|
131
|
+
* has completed (computed queue and effect queue are settled).
|
|
132
|
+
*
|
|
133
|
+
* This is a synchronization barrier for reactive propagation only. It does
|
|
134
|
+
* not include animation/time-based convergence semantics.
|
|
135
|
+
*
|
|
136
|
+
* @param {{ signal?: AbortSignal, timeoutMs?: number }} [options]
|
|
137
|
+
* Optional cancellation/timeout controls for waiting callers.
|
|
138
|
+
* @returns {Promise<void>}
|
|
139
|
+
*/
|
|
140
|
+
whenPropagated(options?: {
|
|
141
|
+
signal?: AbortSignal;
|
|
142
|
+
timeoutMs?: number;
|
|
143
|
+
}): Promise<void>;
|
|
144
|
+
#private;
|
|
145
|
+
}
|
|
146
|
+
export type SubscribeFn = (listener: () => void) => () => void;
|
|
147
|
+
export type RuntimeNodeBase = {
|
|
148
|
+
id: string;
|
|
149
|
+
rank: number;
|
|
150
|
+
disposed: boolean;
|
|
151
|
+
listeners: Set<() => void>;
|
|
152
|
+
subscribe: SubscribeFn;
|
|
153
|
+
};
|
|
154
|
+
export type WritableNode<T> = RuntimeNodeBase & {
|
|
155
|
+
value: T;
|
|
156
|
+
kind: "base" | "selection";
|
|
157
|
+
name: string;
|
|
158
|
+
};
|
|
159
|
+
export type ComputedNode<T> = RuntimeNodeBase & {
|
|
160
|
+
value: T;
|
|
161
|
+
kind: "derived";
|
|
162
|
+
name: string;
|
|
163
|
+
fn: () => T;
|
|
164
|
+
};
|
|
165
|
+
export type EffectNode = {
|
|
166
|
+
id: string;
|
|
167
|
+
rank: number;
|
|
168
|
+
disposed: boolean;
|
|
169
|
+
fn: () => void;
|
|
170
|
+
};
|
|
171
|
+
/**
|
|
172
|
+
* @param {import("./types.js").ParamRef<any>} ref
|
|
173
|
+
* @returns {RuntimeNodeBase}
|
|
174
|
+
*/
|
|
175
|
+
export function getNode(ref: import("./types.js").ParamRef<any>): RuntimeNodeBase;
|
|
176
|
+
//# sourceMappingURL=graphRuntime.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graphRuntime.d.ts","sourceRoot":"","sources":["../../../src/paramRuntime/graphRuntime.js"],"names":[],"mappings":"AAoIA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH;IA6BI;;;;;;;OAOG;IACH,sBAJG;QAA2D,iBAAiB,GAApE,OAAO,wBAAwB,EAAE,OAAO;KAGlD,EAGA;IAED;;;;;;;;;;;;;;;;;;;;OAoBG;IACH,eARa,CAAC,WACH,MAAM,QACN,MAAM,QACN,MAAM,GAAG,WAAW,gBACpB,CAAC,YACD;QAAE,MAAM,CAAC,EAAE,OAAO,CAAA;KAAE,GAClB,OAAO,YAAY,EAAE,gBAAgB,CAAC,CAAC,CAAC,CAwDpD;IAED;;;;;;;;;;;;;;;;;;OAkBG;IACH,SAPa,CAAC,WACH,MAAM,QACN,MAAM,QACN,OAAO,YAAY,EAAE,QAAQ,CAAC,GAAG,CAAC,EAAE,MACpC,MAAM,CAAC,GACL,OAAO,YAAY,EAAE,QAAQ,CAAC,CAAC,CAAC,CAuD5C;IAED;;;;;;;;;;;;OAYG;IACH,gBALW,MAAM,QACN,OAAO,YAAY,EAAE,QAAQ,CAAC,GAAG,CAAC,EAAE,MACpC,MAAM,IAAI,GACR,MAAM,IAAI,CAwCtB;IAED;;;;;;;;;;;;;;;;;;;;;;;OAuBG;IACH,iBAJa,CAAC,MACH,MAAM,CAAC,GACL,CAAC,CAYb;IAED;;;;;;;;OAQG;IACH,iBA8CC;IAED;;;;;;;;;;OAUG;IACH,yBAJW;QAAE,MAAM,CAAC,EAAE,WAAW,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,GAE1C,OAAO,CAAC,IAAI,CAAC,CAgDzB;;CA2EJ;0BA3mBY,CAAC,QAAQ,EAAE,MAAM,IAAI,KAAK,MAAM,IAAI;8BAEpC;IACR,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,OAAO,CAAC;IAClB,SAAS,EAAE,GAAG,CAAC,MAAM,IAAI,CAAC,CAAC;IAC3B,SAAS,EAAE,WAAW,CAAA;CACvB;yBAIS,CAAC,IACD,eAAe,GAAG;IAC1B,KAAK,EAAE,CAAC,CAAC;IACT,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;IAC3B,IAAI,EAAE,MAAM,CAAA;CACb;yBAIS,CAAC,IACD,eAAe,GAAG;IAC1B,KAAK,EAAE,CAAC,CAAC;IACT,IAAI,EAAE,SAAS,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC,CAAA;CACZ;yBAIS;IACR,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,OAAO,CAAC;IAClB,EAAE,EAAE,MAAM,IAAI,CAAA;CACf;AAgEJ;;;GAGG;AACH,6BAHW,OAAO,YAAY,EAAE,QAAQ,CAAC,GAAG,CAAC,GAChC,eAAe,CAa3B"}
|