Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
07e4c78417 |
@@ -28,7 +28,12 @@ title-bar controls). The rules that matter most:
|
|||||||
ship inside the module folder** (zero deps is the norm). **Everything the
|
ship inside the module folder** (zero deps is the norm). **Everything the
|
||||||
module does runs inside its server entry** — no helper scripts, companion
|
module does runs inside its server entry** — no helper scripts, companion
|
||||||
programs or daemons the operator starts by hand; a listener or decoder is
|
programs or daemons the operator starts by hand; a listener or decoder is
|
||||||
started in `init()` and stopped in `stop()`. Declare `"proddash": ">=x.y.z"`
|
started in `init()` and stopped in `stop()`. **A native helper ships
|
||||||
|
prebuilt inside the module folder for Apple silicon macOS and 64-bit
|
||||||
|
Windows** (`bin/<name>-macos-arm64`, `bin/<name>-win-x64.exe`, source and
|
||||||
|
build script under `native/`); nothing is ever compiled on the machine
|
||||||
|
running ProdDash, and a missing binary means the feature reports itself
|
||||||
|
off, not a broken module. Declare `"proddash": ">=x.y.z"`
|
||||||
and bump the module's `version` on every change.
|
and bump the module's `version` on every change.
|
||||||
- Browsers never call upstream services directly; the module's server routes
|
- Browsers never call upstream services directly; the module's server routes
|
||||||
proxy everything (no CORS, secrets stay server-side).
|
proxy everything (no CORS, secrets stay server-side).
|
||||||
|
|||||||
+68
-1
@@ -28,7 +28,10 @@ people running the booth depend on them.
|
|||||||
ProdDash. If your feature needs a listener, a decoder or a worker, your
|
ProdDash. If your feature needs a listener, a decoder or a worker, your
|
||||||
server entry owns it: start it in `init()`, stop it in `stop()`, report
|
server entry owns it: start it in `init()`, stop it in `stop()`, report
|
||||||
it in `health()`. A child process the module itself spawns and supervises
|
it in `health()`. A child process the module itself spawns and supervises
|
||||||
is fine; a program someone launches by hand is not.
|
is fine; a program someone launches by hand is not. **A native helper —
|
||||||
|
anything that is not JavaScript — ships prebuilt inside the module folder,
|
||||||
|
for Apple silicon macOS and 64-bit Windows; nothing is ever compiled on
|
||||||
|
the machine running ProdDash** (see "Native helpers" below).
|
||||||
4. **Declare the ProdDash version you need** (`"proddash": ">=1.1.0"` in the
|
4. **Declare the ProdDash version you need** (`"proddash": ">=1.1.0"` in the
|
||||||
manifest) and **bump your own `version`** whenever you change the module.
|
manifest) and **bump your own `version`** whenever you change the module.
|
||||||
The admin page refuses to install a module whose requirement the running
|
The admin page refuses to install a module whose requirement the running
|
||||||
@@ -83,6 +86,10 @@ modules/<id>/
|
|||||||
├── module.json manifest (required)
|
├── module.json manifest (required)
|
||||||
├── client.js ES module, client entry (required)
|
├── client.js ES module, client entry (required)
|
||||||
├── server.js server entry (optional — only if you need server code)
|
├── server.js server entry (optional — only if you need server code)
|
||||||
|
├── bin/ native helpers, prebuilt per platform (only if you need one)
|
||||||
|
│ ├── <name>-macos-arm64
|
||||||
|
│ └── <name>-win-x64.exe
|
||||||
|
├── native/ their source and the script that builds every bin/ file
|
||||||
└── ... assets (css, images…) served statically at /modules/<id>/
|
└── ... assets (css, images…) served statically at /modules/<id>/
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -97,6 +104,66 @@ the newer version runs. **Uninstall** in the admin page removes an installed
|
|||||||
module's files (a bundled one is hidden instead, since its folder belongs to
|
module's files (a bundled one is hidden instead, since its folder belongs to
|
||||||
the app); its settings are kept for a later reinstall.
|
the app); its settings are kept for a later reinstall.
|
||||||
|
|
||||||
|
### Native helpers
|
||||||
|
|
||||||
|
Some features need a program JavaScript cannot be: reading an audio input,
|
||||||
|
decoding timecode, measuring sound. Rule 3 says the module owns that program;
|
||||||
|
this section says how it ships: **already built, for every platform it runs
|
||||||
|
on, inside the module folder.** The machine running ProdDash is a packaged
|
||||||
|
app or the Windows bundle plus modules from the admin page's catalog. It has
|
||||||
|
no compiler and never will — the catalog delivers exactly the folder that is
|
||||||
|
in the repo, so the binaries live in git next to the code.
|
||||||
|
|
||||||
|
- **Platforms.** Apple silicon macOS and 64-bit Windows are required. Intel
|
||||||
|
macOS is welcome but optional. One file per platform in `bin/`, named for
|
||||||
|
what it is:
|
||||||
|
|
||||||
|
| Platform | File |
|
||||||
|
| --- | --- |
|
||||||
|
| macOS, Apple silicon | `bin/<name>-macos-arm64` |
|
||||||
|
| Windows, 64-bit | `bin/<name>-win-x64.exe` |
|
||||||
|
| macOS, Intel (optional) | `bin/<name>-macos-x86_64` |
|
||||||
|
|
||||||
|
- **Pick it at runtime, and cope without it.** Choose by `process.platform`
|
||||||
|
and `process.arch`; when there is no file for this machine, the feature
|
||||||
|
says so — in `health()` and in the tile's `setStatus` — and everything else
|
||||||
|
in the module keeps working. Never try to build it, never look for a copy
|
||||||
|
elsewhere on the machine, never tell the operator to install anything.
|
||||||
|
|
||||||
|
```js
|
||||||
|
const HELPERS = {
|
||||||
|
darwin: { arm64: 'ltc-capture-macos-arm64', x64: 'ltc-capture-macos-x86_64' },
|
||||||
|
win32: { x64: 'ltc-capture-win-x64.exe' },
|
||||||
|
};
|
||||||
|
const name = HELPERS[process.platform]?.[process.arch];
|
||||||
|
const helper = name ? path.join(__dirname, 'bin', name) : '';
|
||||||
|
if (!helper || !fs.existsSync(helper)) {
|
||||||
|
// Timecode is off on this platform. Say it once, keep the clock running.
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
- **One contract, any language.** Every platform's binary speaks the same
|
||||||
|
command line and output format, so `server.js` has one code path. What is
|
||||||
|
behind it is your choice per platform — Swift against CoreAudio on macOS,
|
||||||
|
C#, C or Rust on Windows — the module does not care.
|
||||||
|
- **Source and build beside it.** Keep the source under `native/` with one
|
||||||
|
script that produces every `bin/` file from a checkout, so any binary can be
|
||||||
|
rebuilt from what is committed. A helper that cannot be rebuilt does not
|
||||||
|
ship.
|
||||||
|
- **Bump the module version whenever a binary changes**, like any other
|
||||||
|
file — that is how installs learn about it.
|
||||||
|
- **Keep them lean.** Optimised builds, no debug symbols, a few megabytes at
|
||||||
|
most: the catalog fetches the whole repo as one archive, capped at 80 MB.
|
||||||
|
- **Signing.** Apple silicon refuses unsigned code, so sign the macOS binary
|
||||||
|
— Developer ID when you have it, ad-hoc at least. Windows needs nothing:
|
||||||
|
files the app writes carry no download mark, so SmartScreen never sees
|
||||||
|
them. Permissions come from the launcher (see "Permissions macOS has to
|
||||||
|
grant"), not from the binary.
|
||||||
|
|
||||||
|
A helper that ends up existing for one platform only is an exception made
|
||||||
|
on purpose, not a default: say so in the module's README and in the health
|
||||||
|
line, so a Windows booth knows why the feature is off.
|
||||||
|
|
||||||
## module.json
|
## module.json
|
||||||
|
|
||||||
```json
|
```json
|
||||||
|
|||||||
Reference in New Issue
Block a user