Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: climateinteractive/SDEverywhere
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: plugin-worker-v0.2.3
Choose a base ref
...
head repository: climateinteractive/SDEverywhere
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: plugin-worker-v0.2.4
Choose a head ref
Loading
Showing 407 changed files with 40,328 additions and 8,123 deletions.
43 changes: 27 additions & 16 deletions .github/workflows/build.yaml
Original file line number Diff line number Diff line change
@@ -14,6 +14,7 @@ on:
push:
branches-ignore:
- main
pull_request:

env:
EM_DIR: 'emsdk'
@@ -24,6 +25,14 @@ env:
jobs:
# The `build` job builds and tests all packages in the monorepo
build:
# We want to avoid redundant builds in the more common case where this workflow is running
# on a branch in the main SDEverywhere repository. For that case, we only care about "push"
# events. The "pull_request" events are only useful for contributions from external forks.
# Currently there is no way to detect or filter out forks in the `on: pull_request:` section
# above, so we use the following logic to filter at the job level. Only run the job if:
# - this is a "push" event for a branch in the main repository, OR
# - this is a "pull_request" event for an external fork
if: github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.pull_request.head.repo.fork)
runs-on: ${{ matrix.config.os }}
timeout-minutes: 20
strategy:
@@ -41,17 +50,17 @@ jobs:
git config --global core.eol lf
- name: Check out repo
uses: actions/checkout@v3
uses: actions/checkout@v4

- name: Install Node.js
uses: actions/setup-node@v3
uses: actions/setup-node@v4
with:
node-version: 16
node-version: 18

# The pnpm caching strategy in the following steps is based on:
# https://github.com/pnpm/action-setup#use-cache-to-reduce-installation-time
- name: Install pnpm
uses: pnpm/action-setup@v2.2.4
uses: pnpm/action-setup@v3.0.0
with:
version: 8

@@ -67,7 +76,7 @@ jobs:
run: echo "pnpm_cache_dir=$(pnpm store path)" >> $GITHUB_OUTPUT

- name: Enable pnpm cache
uses: actions/cache@v3
uses: actions/cache@v4
with:
path: ${{ steps.pnpm-cache.outputs.pnpm_cache_dir }}
key: pnpm-store-${{ runner.os }}-${{ hashFiles('**/pnpm-lock.yaml') }}
@@ -88,6 +97,7 @@ jobs:
# the other jobs (which cuts down on overall time to execute the workflow) because it
# only needs to build a subset of the packages in order to run the integration tests.
test_c:
if: github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.pull_request.head.repo.fork)
runs-on: ${{ matrix.config.os }}
timeout-minutes: 20
strategy:
@@ -105,17 +115,17 @@ jobs:
git config --global core.eol lf
- name: Check out repo
uses: actions/checkout@v3
uses: actions/checkout@v4

- name: Install Node.js
uses: actions/setup-node@v3
uses: actions/setup-node@v4
with:
node-version: 16
node-version: 18

# The pnpm caching strategy in the following steps is based on:
# https://github.com/pnpm/action-setup#use-cache-to-reduce-installation-time
- name: Install pnpm
uses: pnpm/action-setup@v2.2.4
uses: pnpm/action-setup@v3.0.0
with:
version: 8

@@ -131,7 +141,7 @@ jobs:
run: echo "pnpm_cache_dir=$(pnpm store path)" >> $GITHUB_OUTPUT

- name: Enable pnpm cache
uses: actions/cache@v3
uses: actions/cache@v4
with:
path: ${{ steps.pnpm-cache.outputs.pnpm_cache_dir }}
key: pnpm-store-${{ runner.os }}-${{ hashFiles('**/pnpm-lock.yaml') }}
@@ -152,6 +162,7 @@ jobs:
# the other jobs (which cuts down on overall time to execute the workflow) because it
# only needs to build a subset of the packages in order to run the integration tests.
test_js:
if: github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.pull_request.head.repo.fork)
runs-on: ${{ matrix.config.os }}
timeout-minutes: 20
strategy:
@@ -169,23 +180,23 @@ jobs:
git config --global core.eol lf
- name: Check out repo
uses: actions/checkout@v3
uses: actions/checkout@v4

- name: Enable Emscripten cache
uses: actions/cache@v3
uses: actions/cache@v4
with:
path: ${{env.EM_DIR}}
key: emsdk-app-${{env.EM_VERSION}}-${{env.EM_KEY}}

- name: Install Node.js
uses: actions/setup-node@v3
uses: actions/setup-node@v4
with:
node-version: 16
node-version: 18

# The pnpm caching strategy in the following steps is based on:
# https://github.com/pnpm/action-setup#use-cache-to-reduce-installation-time
- name: Install pnpm
uses: pnpm/action-setup@v2.2.4
uses: pnpm/action-setup@v3.0.0
with:
version: 8

@@ -201,7 +212,7 @@ jobs:
run: echo "pnpm_cache_dir=$(pnpm store path)" >> $GITHUB_OUTPUT

- name: Enable pnpm cache
uses: actions/cache@v3
uses: actions/cache@v4
with:
path: ${{ steps.pnpm-cache.outputs.pnpm_cache_dir }}
key: pnpm-store-${{ runner.os }}-${{ hashFiles('**/pnpm-lock.yaml') }}
18 changes: 8 additions & 10 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
@@ -18,7 +18,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Run release-please
uses: GoogleCloudPlatform/release-please-action@v3
uses: GoogleCloudPlatform/release-please-action@v4
id: release
with:
# Note that we need to use a custom token here because events triggered
@@ -27,21 +27,19 @@ jobs:
# release-please action to trigger the `build` workflow when it pushes
# to a `release-please` branch; using a custom token here makes it work.
token: ${{ secrets.GH_ACCESS_TOKEN }}
command: manifest
monorepo-tags: true

- name: Check out repo
uses: actions/checkout@v3
uses: actions/checkout@v4

- name: Install Node.js
uses: actions/setup-node@v3
uses: actions/setup-node@v4
with:
node-version: 16
node-version: 18

# The pnpm caching strategy in the following steps is based on:
# https://github.com/pnpm/action-setup#use-cache-to-reduce-installation-time
- name: Install pnpm
uses: pnpm/action-setup@v2
uses: pnpm/action-setup@v3
with:
version: 8

@@ -50,7 +48,7 @@ jobs:
run: echo "pnpm_cache_dir=$(pnpm store path)" >> $GITHUB_OUTPUT

- name: Enable pnpm cache
uses: actions/cache@v3
uses: actions/cache@v4
with:
path: ${{ steps.pnpm-cache.outputs.pnpm_cache_dir }}
key: pnpm-store-${{ runner.os }}-${{ hashFiles('**/pnpm-lock.yaml') }}
@@ -72,6 +70,6 @@ jobs:
echo "//registry.npmjs.org/:_authToken=${{ secrets.NPM_ACCESS_TOKEN }}" > ~/.npmrc
- name: Publish packages
if: ${{ steps.release.outputs.releases_created }}
if: ${{ steps.release.outputs.releases_created == 'true' }}
run: |
pnpm --workspace-concurrency=1 -r publish --access public
pnpm -r publish --access public
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Project files
models/**/build*
models/**/output*
models/**/compare
app_spec.json
removals.txt
.DS_Store
27 changes: 14 additions & 13 deletions .release-please-manifest.json
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
{
"packages/compile": "0.7.7",
"packages/cli": "0.7.11",
"packages/build": "0.3.2",
"packages/check-core": "0.1.1",
"packages/check-ui-shell": "0.2.3",
"packages/plugin-check": "0.3.4",
"packages/plugin-vite": "0.1.7",
"packages/plugin-wasm": "0.2.1",
"packages/plugin-worker": "0.2.3",
"packages/runtime": "0.2.2",
"packages/runtime-async": "0.2.2",
"packages/create": "0.2.4",
"packages/plugin-config": "0.2.2"
"packages/parse": "0.1.0",
"packages/compile": "0.7.18",
"packages/build": "0.3.5",
"packages/cli": "0.7.24",
"packages/check-core": "0.1.2",
"packages/check-ui-shell": "0.2.4",
"packages/plugin-check": "0.3.6",
"packages/plugin-config": "0.2.5",
"packages/plugin-vite": "0.1.9",
"packages/plugin-wasm": "0.2.4",
"packages/plugin-worker": "0.2.4",
"packages/runtime": "0.2.3",
"packages/runtime-async": "0.2.3",
"packages/create": "0.2.15"
}
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
The MIT License (MIT)

Copyright (c) 2016-2022 Todd Fincannon and Climate Interactive / New Venture Fund
Copyright (c) 2016-2024 Todd Fincannon and Climate Interactive / New Venture Fund

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
38 changes: 24 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
# SDEverywhere    ![](https://github.com/climateinteractive/SDEverywhere/actions/workflows/build.yaml/badge.svg)
# SDEverywhere    [![Build](https://github.com/climateinteractive/SDEverywhere/actions/workflows/release.yaml/badge.svg)](https://github.com/climateinteractive/SDEverywhere/actions/workflows/release.yaml)

[SDEverywhere](http://sdeverywhere.org/) is a collection of libraries and command line tools that help you transform a [System Dynamics](http://www.systemdynamics.org/what-is-system-dynamics/) model into C, JavaScript, and WebAssembly code.
[SDEverywhere](http://sdeverywhere.org/) is a collection of libraries and command line tools that help you improve the quality and expand the reach of a [System Dynamics](http://www.systemdynamics.org/what-is-system-dynamics/) model.
SDEverywhere allows for unit testing, continuous integration, the ability to compare model runs, and a toolchain to transform a model into C, JavaScript, and WebAssembly code.

Using SDEverywhere, you can deploy interactive System Dynamics models in mobile, desktop, and web apps for policymakers and the public.
Or you could perform model analysis using general-purpose languages, running the model as high-performance C code.
Using SDEverywhere, you can deploy interactive System Dynamics models on mobile, desktop, and the web for policymakers and the public.
Or you could perform model analysis using general-purpose languages, running the model as high-performance JavaScript or C code.

By following the ["Quick Start"](#quick-start) instructions below, within minutes you can turn a Vensim model like this:

@@ -19,7 +20,7 @@ By following the ["Quick Start"](#quick-start) instructions below, within minute
## Supported Platforms

The SDEverywhere tools can be used on on any computer running macOS, Windows, or Linux.
The libraries and code generated by SDEverywhere can be run in web browsers on almost any device (including phones and tablets) as well as on the server side (using C/C++ or WebAssembly).
The libraries and code generated by SDEverywhere can be run in web browsers on almost any device (including phones and tablets) as well as on the server side (using C/C++, JavaScript, and/or WebAssembly).

## Supported File Formats

@@ -45,7 +46,7 @@ https://github.com/climateinteractive/SDEverywhere/assets/438425/cd495776-5744-4

### Quality Checks and Comparisons

SDEverywhere includes extensive QA (quality assurance) tools that you can run locally on your machine as you develop your model or in the cloud in a continuous integration environment.
SDEverywhere includes extensive QA (quality assurance) tools that you can run as you develop your model, either locally on your machine or in the cloud in a continuous integration environment (or both).
There is support for two different kinds of tests:

- **_Checks:_** Check tests can be used to verify that your model behaves according to some guidelines (or conforms to your mental models). For example, you can have checks that verify that stocks are always positive, or that some output variable produces values that are close to historical reference data.
@@ -62,25 +63,25 @@ https://github.com/climateinteractive/SDEverywhere/assets/438425/b6f05b3f-f18a-4

## Core Functionality

At its core, SDEverywhere includes a [transpiler](https://en.wikipedia.org/wiki/Source-to-source_compiler) that can read a [Vensim](https://www.vensim.com/documentation/index.html?ref_language.htm) model and generate a high-performance version of that model in the C programming language.
At its core, SDEverywhere includes a [transpiler](https://en.wikipedia.org/wiki/Source-to-source_compiler) that can read a [Vensim](https://www.vensim.com/documentation/index.html?ref_language.htm) model and generate a high-performance version of that model as JavaScript or C code.

The [`sde`](./packages/cli) command line tool — in addition to generating C code — provides a plugin-based build system for extended functionality:
The [`sde`](./packages/cli) command line tool — in addition to generating JavaScript or C code — provides a plugin-based build system for extended functionality:

- [plugin-config](./packages/plugin-config) allows you to configure your model/library/app using CSV files
- [plugin-wasm](./packages/plugin-wasm) converts the generated C model into a fast WebAssembly module for use in a web browser or Node.js application
- [plugin-worker](./packages/plugin-worker) generates a Web Worker that can be used to run the WebAssembly model in a separate thread for improved user experience
- [plugin-wasm](./packages/plugin-wasm) converts a generated C model into a fast WebAssembly module for use in a web browser or Node.js application
- [plugin-worker](./packages/plugin-worker) generates a worker module that can be used to run your model in a separate thread for improved user experience
- [plugin-vite](./packages/plugin-vite) provides integration with [Vite](https://github.com/vitejs/vite) for developing a library or application around your generated model
- [plugin-check](./packages/plugin-check) allows for running QA checks and comparison tests on your model every time you make a change

Additionally, the [runtime](./packages/runtime) and [runtime-async](./packages/runtime-async) packages make it easy to interact with your generated WebAssembly model in a JavaScript- or TypeScript-based application.
Additionally, the [runtime](./packages/runtime) and [runtime-async](./packages/runtime-async) packages make it easy to interact with your generated model in a JavaScript- or TypeScript-based application.

For more details on all of these packages, refer to the ["Packages"](#packages) section below.

## Requirements

The SDEverywhere libraries and tools can be used on any computer running macOS, Windows, or Linux.

SDEverywhere requires [Node.js](https://nodejs.org) version 14 or later.
SDEverywhere requires [Node.js](https://nodejs.org) version 18 or later (the current LTS version 20 is recommended).
Node.js is a cross-platform runtime environment that allows for running JavaScript-based tools (like SDEverywhere) on macOS, Windows, and Linux computers.

Note: It is not necessary to have extensive knowledge of Node.js and JavaScript in order to use SDEverywhere, but a one-time download of Node.js is necessary to get started.
@@ -146,7 +147,7 @@ Please fork our code and contribute!
Here are some prominent current limitations:

- Sketch information, the visual representation of the model, is not converted.
- Only the most common [Vensim functions](https://www.vensim.com/documentation/index.html?20770.htm) are implemented.
- Only the most common [Vensim functions](https://github.com/climateinteractive/SDEverywhere/wiki/Supported-Vensim-Functions) are implemented.
- All models run using the Euler integrator.
- Strings are not supported.
- You must rewrite tabbed arrays as separate, non-apply-to-all variables.
@@ -295,6 +296,15 @@ Most users won't need to interact with these implementation packages directly, b
<a href="./packages/compile/CHANGELOG.md">Changelog</a>
</td>
</tr>
<tr>
<td><a href="./packages/parse">@sdeverywhere/parse</a> *</td>
<td><a href="https://www.npmjs.com/package/@sdeverywhere/parse"><img style="vertical-align:middle;" src="https://img.shields.io/npm/v/@sdeverywhere/parse.svg?label=%20"></a></td>
<td>
<a href="./packages/parse">Source</a>&nbsp;|&nbsp;
<a href="./packages/parse/README.md">Docs</a>&nbsp;|&nbsp;
<a href="./packages/parse/CHANGELOG.md">Changelog</a>
</td>
</tr>
<tr>
<td colspan="3"><em>`model-check` implementation</em></td>
</tr>
@@ -327,7 +337,7 @@ There is still much to contribute, for example:
- Enhance the C code generator to produce code for new language features now that you can parse them.
- Implement more Vensim functions. This is the easiest way to help out.
- Add support for the XMILE file format.
- Target languages other than C, such as R or Rust. (If you want Python, check out the excellent [PySD](https://github.com/JamesPHoughton/pysd)).
- Target languages other than JavaScript and C, such as R or Rust. (If you want Python, check out the excellent [PySD](https://github.com/JamesPHoughton/pysd)).

For more guidance on contributing to SDEverywhere, please consult the [wiki](https://github.com/climateinteractive/SDEverywhere/wiki).

2 changes: 1 addition & 1 deletion examples/hello-world/README.md
Original file line number Diff line number Diff line change
@@ -53,7 +53,7 @@ pnpm dev
pnpm build

# Open the generated report in a browser
pnpm serve
pnpm preview
```

## License
18 changes: 9 additions & 9 deletions examples/hello-world/package.json
Original file line number Diff line number Diff line change
@@ -5,17 +5,17 @@
"type": "module",
"scripts": {
"clean": "rm -rf ./sde-prep",
"build": "sde bundle",
"dev": "sde dev",
"save-baseline": "sde-check baseline --save",
"serve": "sirv ./sde-prep/check-report"
"build": "sde bundle",
"vite": "vite",
"preview": "vite preview --open --outDir ./sde-prep/check-report",
"save-baseline": "sde-check baseline --save"
},
"dependencies": {
"@sdeverywhere/build": "^0.3.0",
"@sdeverywhere/cli": "^0.7.6",
"@sdeverywhere/plugin-check": "^0.3.0",
"@sdeverywhere/plugin-wasm": "^0.2.0",
"@sdeverywhere/plugin-worker": "^0.2.0",
"sirv-cli": "^2.0.2"
"@sdeverywhere/build": "^0.3.4",
"@sdeverywhere/cli": "^0.7.23",
"@sdeverywhere/plugin-check": "^0.3.5",
"@sdeverywhere/plugin-worker": "^0.2.3",
"vite": "^4.4.9"
}
}
9 changes: 2 additions & 7 deletions examples/hello-world/sde.config.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { checkPlugin } from '@sdeverywhere/plugin-check'
import { wasmPlugin } from '@sdeverywhere/plugin-wasm'
import { workerPlugin } from '@sdeverywhere/plugin-worker'

export async function config() {
@@ -9,16 +8,12 @@ export async function config() {
modelSpec: async () => {
return {
inputs: [{ varName: 'Y', defaultValue: 0, minValue: -10, maxValue: 10 }],
outputs: [{ varName: 'Z' }],
datFiles: []
outputs: [{ varName: 'Z' }]
}
},

plugins: [
// Generate a `wasm-model.js` file containing the Wasm model
wasmPlugin(),

// Generate a `worker.js` file that runs the Wasm model in a worker
// Generate a `worker.js` file that runs the generated model in a worker
workerPlugin(),

// Run model check
1 change: 1 addition & 0 deletions examples/house-game/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
sde-prep
Loading