@sdeverywhere/runtime 0.2.6 → 0.2.7
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/README.md +1 -1
- package/dist/index.cjs +195 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +126 -7
- package/dist/index.d.ts +126 -7
- package/dist/index.js +194 -7
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -52,7 +52,7 @@ import loadGeneratedModel from './sde-prep/generated-model.js'
|
|
|
52
52
|
### 2. Initialize a `ModelRunner`
|
|
53
53
|
|
|
54
54
|
The next step is to create a `ModelRunner` instance, which simplifies
|
|
55
|
-
the process of running a
|
|
55
|
+
the process of running a generated model with a given set of inputs and
|
|
56
56
|
parsing the outputs.
|
|
57
57
|
The `ModelRunner` produces an `Outputs` instance that provides easy
|
|
58
58
|
access to time series data for each output variable in the model.
|
package/dist/index.cjs
CHANGED
|
@@ -58,6 +58,7 @@ __export(src_exports, {
|
|
|
58
58
|
MockWasmModule: () => MockWasmModule,
|
|
59
59
|
ModelListing: () => ModelListing,
|
|
60
60
|
ModelScheduler: () => ModelScheduler,
|
|
61
|
+
MultiContextModelScheduler: () => MultiContextModelScheduler,
|
|
61
62
|
Outputs: () => Outputs,
|
|
62
63
|
ReferencedRunModelParams: () => ReferencedRunModelParams,
|
|
63
64
|
Series: () => Series,
|
|
@@ -1906,7 +1907,7 @@ var ModelScheduler = class {
|
|
|
1906
1907
|
/** Whether a model run is in progress. */
|
|
1907
1908
|
this.runInProgress = false;
|
|
1908
1909
|
const afterSet = () => {
|
|
1909
|
-
this.
|
|
1910
|
+
this.runModelIfNeeded();
|
|
1910
1911
|
};
|
|
1911
1912
|
for (const userInput of userInputs) {
|
|
1912
1913
|
userInput.callbacks.onSet = afterSet;
|
|
@@ -1917,24 +1918,24 @@ var ModelScheduler = class {
|
|
|
1917
1918
|
}
|
|
1918
1919
|
}
|
|
1919
1920
|
/**
|
|
1920
|
-
* Schedule a
|
|
1921
|
+
* Schedule a model run (if not already pending). When the run is
|
|
1921
1922
|
* complete, save the outputs and call the `onOutputsChanged` callback.
|
|
1922
1923
|
*/
|
|
1923
|
-
|
|
1924
|
+
runModelIfNeeded() {
|
|
1924
1925
|
this.runNeeded = true;
|
|
1925
1926
|
if (this.runInProgress) {
|
|
1926
1927
|
return;
|
|
1927
1928
|
} else {
|
|
1928
1929
|
this.runInProgress = true;
|
|
1929
1930
|
setTimeout(() => {
|
|
1930
|
-
this.
|
|
1931
|
+
this.runModelNow();
|
|
1931
1932
|
}, 0);
|
|
1932
1933
|
}
|
|
1933
1934
|
}
|
|
1934
1935
|
/**
|
|
1935
|
-
* Run the
|
|
1936
|
+
* Run the model asynchronously using the current set of input values.
|
|
1936
1937
|
*/
|
|
1937
|
-
|
|
1938
|
+
runModelNow() {
|
|
1938
1939
|
return __async(this, null, function* () {
|
|
1939
1940
|
var _a;
|
|
1940
1941
|
for (let i = 0; i < this.userInputs.length; i++) {
|
|
@@ -1949,7 +1950,7 @@ var ModelScheduler = class {
|
|
|
1949
1950
|
if (this.runNeeded) {
|
|
1950
1951
|
this.runNeeded = false;
|
|
1951
1952
|
setTimeout(() => {
|
|
1952
|
-
this.
|
|
1953
|
+
this.runModelNow();
|
|
1953
1954
|
}, 0);
|
|
1954
1955
|
} else {
|
|
1955
1956
|
this.runNeeded = false;
|
|
@@ -1971,6 +1972,192 @@ function createSimpleInputValue(varId) {
|
|
|
1971
1972
|
};
|
|
1972
1973
|
return { varId, get, set, reset, callbacks: {} };
|
|
1973
1974
|
}
|
|
1975
|
+
|
|
1976
|
+
// src/model-scheduler/multi-context-model-scheduler.ts
|
|
1977
|
+
var MultiContextModelScheduler = class {
|
|
1978
|
+
/**
|
|
1979
|
+
* @param runner The model runner.
|
|
1980
|
+
* @param options Additional options for the scheduler.
|
|
1981
|
+
* @param options.initialOutputs An optional `Outputs` instance that will be reused
|
|
1982
|
+
* for the initial context. This is useful for saving memory when an `Outputs`
|
|
1983
|
+
* instance was already created for, e.g., a initial baseline/reference run.
|
|
1984
|
+
*/
|
|
1985
|
+
constructor(runner, options) {
|
|
1986
|
+
this.runner = runner;
|
|
1987
|
+
/** The contexts that hold distinct sets of inputs and outputs. */
|
|
1988
|
+
this.contexts = [];
|
|
1989
|
+
/** Whether a model run has been scheduled. */
|
|
1990
|
+
this.runNeeded = false;
|
|
1991
|
+
/** Whether a model run is in progress. */
|
|
1992
|
+
this.runInProgress = false;
|
|
1993
|
+
this.initialOutputs = options == null ? void 0 : options.initialOutputs;
|
|
1994
|
+
}
|
|
1995
|
+
/**
|
|
1996
|
+
* Return true if the scheduler has started any model runs.
|
|
1997
|
+
*/
|
|
1998
|
+
isStarted() {
|
|
1999
|
+
return this.initialOutputs === void 0;
|
|
2000
|
+
}
|
|
2001
|
+
/**
|
|
2002
|
+
* Add a new context that holds a distinct set of model inputs and outputs.
|
|
2003
|
+
* These inputs and outputs are kept separate from those in other contexts,
|
|
2004
|
+
* which allows an application to use the same underlying model to run with
|
|
2005
|
+
* multiple I/O contexts.
|
|
2006
|
+
*
|
|
2007
|
+
* Note that the contexts created before the first scheduled model run
|
|
2008
|
+
* will inherit the data from `initialOutputs` passed to the constructor,
|
|
2009
|
+
* but contexts created after that will initially have output values set
|
|
2010
|
+
* to zero.
|
|
2011
|
+
*
|
|
2012
|
+
* @param inputs The input values, in the same order as in the spec file passed to `sde`.
|
|
2013
|
+
* @param options Additional options for the context.
|
|
2014
|
+
* @param options.externalData Additional data that is external to the model outputs.
|
|
2015
|
+
* For example, this can contain data that was captured from an initial reference
|
|
2016
|
+
* run, or other static data that is displayed in graphs alongside the model
|
|
2017
|
+
* output data in graphs.
|
|
2018
|
+
*/
|
|
2019
|
+
addContext(inputs, options) {
|
|
2020
|
+
let outputs;
|
|
2021
|
+
if (this.initialOutputs !== void 0) {
|
|
2022
|
+
if (this.contexts.length === 0) {
|
|
2023
|
+
outputs = this.initialOutputs;
|
|
2024
|
+
} else {
|
|
2025
|
+
outputs = this.runner.createOutputs();
|
|
2026
|
+
for (const varId of outputs.varIds) {
|
|
2027
|
+
const series0 = this.initialOutputs.getSeriesForVar(varId);
|
|
2028
|
+
const series1 = outputs.getSeriesForVar(varId);
|
|
2029
|
+
for (let i = 0; i < series0.points.length; i++) {
|
|
2030
|
+
series1.points[i].y = series0.points[i].y;
|
|
2031
|
+
}
|
|
2032
|
+
}
|
|
2033
|
+
}
|
|
2034
|
+
} else {
|
|
2035
|
+
outputs = this.runner.createOutputs();
|
|
2036
|
+
}
|
|
2037
|
+
const context = new ModelContextImpl(inputs, outputs, options == null ? void 0 : options.externalData);
|
|
2038
|
+
const afterSet = () => {
|
|
2039
|
+
context.runNeeded = true;
|
|
2040
|
+
this.runModelIfNeeded();
|
|
2041
|
+
};
|
|
2042
|
+
for (const input of inputs) {
|
|
2043
|
+
input.callbacks.onSet = afterSet;
|
|
2044
|
+
}
|
|
2045
|
+
this.contexts.push(context);
|
|
2046
|
+
return context;
|
|
2047
|
+
}
|
|
2048
|
+
/**
|
|
2049
|
+
* Remove the given context from the set of contexts managed by the scheduler.
|
|
2050
|
+
*
|
|
2051
|
+
* @param context The context to remove.
|
|
2052
|
+
*/
|
|
2053
|
+
removeContext(context) {
|
|
2054
|
+
const index = this.contexts.findIndex((c) => c === context);
|
|
2055
|
+
if (index >= 0) {
|
|
2056
|
+
this.contexts.splice(index, 1);
|
|
2057
|
+
}
|
|
2058
|
+
}
|
|
2059
|
+
/**
|
|
2060
|
+
* Schedule a model run (if not already pending). When the run is
|
|
2061
|
+
* complete, save the outputs and call the `onOutputsChanged` callback.
|
|
2062
|
+
*/
|
|
2063
|
+
runModelIfNeeded() {
|
|
2064
|
+
this.runNeeded = true;
|
|
2065
|
+
if (this.runInProgress) {
|
|
2066
|
+
return;
|
|
2067
|
+
} else {
|
|
2068
|
+
this.runInProgress = true;
|
|
2069
|
+
setTimeout(() => {
|
|
2070
|
+
this.runModelNow();
|
|
2071
|
+
}, 0);
|
|
2072
|
+
}
|
|
2073
|
+
}
|
|
2074
|
+
/**
|
|
2075
|
+
* Run the model asynchronously for all relevant contexts.
|
|
2076
|
+
*/
|
|
2077
|
+
runModelNow() {
|
|
2078
|
+
return __async(this, null, function* () {
|
|
2079
|
+
this.initialOutputs = void 0;
|
|
2080
|
+
for (const context of this.contexts) {
|
|
2081
|
+
if (context.runNeeded) {
|
|
2082
|
+
context.runNeeded = false;
|
|
2083
|
+
yield this.runModelNowForContext(context);
|
|
2084
|
+
}
|
|
2085
|
+
}
|
|
2086
|
+
if (this.runNeeded) {
|
|
2087
|
+
this.runNeeded = false;
|
|
2088
|
+
setTimeout(() => {
|
|
2089
|
+
this.runModelNow();
|
|
2090
|
+
}, 0);
|
|
2091
|
+
} else {
|
|
2092
|
+
this.runNeeded = false;
|
|
2093
|
+
this.runInProgress = false;
|
|
2094
|
+
}
|
|
2095
|
+
});
|
|
2096
|
+
}
|
|
2097
|
+
/**
|
|
2098
|
+
* Run the model asynchronously using the current set of input values in the given context.
|
|
2099
|
+
*
|
|
2100
|
+
* @param context The context to use for the model run.
|
|
2101
|
+
*/
|
|
2102
|
+
runModelNowForContext(context) {
|
|
2103
|
+
return __async(this, null, function* () {
|
|
2104
|
+
var _a;
|
|
2105
|
+
if (this.currentInputs === void 0) {
|
|
2106
|
+
this.currentInputs = Array(context.inputsArray.length);
|
|
2107
|
+
}
|
|
2108
|
+
for (let i = 0; i < context.inputsArray.length; i++) {
|
|
2109
|
+
this.currentInputs[i] = context.inputsArray[i].get();
|
|
2110
|
+
}
|
|
2111
|
+
try {
|
|
2112
|
+
yield this.runner.runModel(this.currentInputs, context.outputs);
|
|
2113
|
+
(_a = context.onOutputsChanged) == null ? void 0 : _a.call(context);
|
|
2114
|
+
} catch (e) {
|
|
2115
|
+
console.error("ERROR: The scheduler encountered an error when running the model:", e);
|
|
2116
|
+
}
|
|
2117
|
+
});
|
|
2118
|
+
}
|
|
2119
|
+
};
|
|
2120
|
+
var ModelContextImpl = class {
|
|
2121
|
+
/**
|
|
2122
|
+
* @hidden This is intended for use by `MultiContextModelScheduler` only.
|
|
2123
|
+
*
|
|
2124
|
+
* @param inputs The input values, in the same order as in the spec file passed to `sde`.
|
|
2125
|
+
* @param outputs The structure into which the model outputs will be stored.
|
|
2126
|
+
* @param externalData Additional data that is external to the model outputs. For example, this can contain
|
|
2127
|
+
* data that was captured from an initial reference run, or other static data that is displayed in graphs
|
|
2128
|
+
* alongside the model output data in graphs.
|
|
2129
|
+
*/
|
|
2130
|
+
constructor(inputs, outputs, externalData) {
|
|
2131
|
+
this.externalData = externalData;
|
|
2132
|
+
/**
|
|
2133
|
+
* Whether a model run is needed for this context.
|
|
2134
|
+
* @hidden This is intended for use by `MultiContextModelScheduler` only.
|
|
2135
|
+
*/
|
|
2136
|
+
this.runNeeded = false;
|
|
2137
|
+
this.inputsArray = Array.from(inputs);
|
|
2138
|
+
this.outputs = outputs;
|
|
2139
|
+
}
|
|
2140
|
+
/**
|
|
2141
|
+
* Return the series data for the given model output variable or external
|
|
2142
|
+
* dataset.
|
|
2143
|
+
*
|
|
2144
|
+
* @param varId The ID of the output variable associated with the data.
|
|
2145
|
+
* @param sourceName The external data source name (e.g. "Ref"), or
|
|
2146
|
+
* undefined to use the latest model output data from this context.
|
|
2147
|
+
*/
|
|
2148
|
+
getSeriesForVar(varId, sourceName) {
|
|
2149
|
+
if (sourceName === void 0) {
|
|
2150
|
+
return this.outputs.getSeriesForVar(varId);
|
|
2151
|
+
} else {
|
|
2152
|
+
const dataForSource = this.externalData.get(sourceName);
|
|
2153
|
+
if (dataForSource !== void 0) {
|
|
2154
|
+
return dataForSource.get(varId);
|
|
2155
|
+
} else {
|
|
2156
|
+
return void 0;
|
|
2157
|
+
}
|
|
2158
|
+
}
|
|
2159
|
+
}
|
|
2160
|
+
};
|
|
1974
2161
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1975
2162
|
0 && (module.exports = {
|
|
1976
2163
|
BufferedRunModelParams,
|
|
@@ -1978,6 +2165,7 @@ function createSimpleInputValue(varId) {
|
|
|
1978
2165
|
MockWasmModule,
|
|
1979
2166
|
ModelListing,
|
|
1980
2167
|
ModelScheduler,
|
|
2168
|
+
MultiContextModelScheduler,
|
|
1981
2169
|
Outputs,
|
|
1982
2170
|
ReferencedRunModelParams,
|
|
1983
2171
|
Series,
|