@casadi/casadi-reader 0.0.0-poc → 0.2.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/CHANGELOG.md +25 -0
- package/NOTICE +4 -4
- package/README.md +160 -240
- package/bin/casadi-reader.js +12 -6
- package/dist/index.js +10352 -624
- package/package.json +4 -5
- package/dist/operations.js +0 -352
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# 0.2.0
|
|
2
|
+
|
|
3
|
+
- Generate JavaScript, Python, C/C++, MATLAB and Julia readers from the compact serialization scheme, with language-specific runtime templates.
|
|
4
|
+
- Decode MX/SX expression vectors and their ordered dependencies, in ordinary and debug files.
|
|
5
|
+
- Refresh serializer layouts, including irregular nonzero assignments and finite differences.
|
|
6
|
+
- Preserve typed fields and shared references for generic Function property inspection.
|
|
7
|
+
- Remove structural `offset` and `byteLength` fields; keep `root` and `roots`. Lazy byte payload handles retain their I/O metadata.
|
|
8
|
+
- Use explicit layout calls instead of runtime inheritance resolution.
|
|
9
|
+
|
|
10
|
+
Breaking change: structural records no longer expose byte spans. npm publication remains JavaScript-only; the other language readers are available as source.
|
|
11
|
+
|
|
12
|
+
# 0.1.0
|
|
13
|
+
|
|
14
|
+
- Replace MX graph interpretation with a schema-driven structural reader.
|
|
15
|
+
- Read typed fields, inline structures, maps, shared references and byte ranges.
|
|
16
|
+
- Validate ordinary and debug serialization with the same generated layouts.
|
|
17
|
+
- Add SX, nested SX/MX calls, ONNX-backed function and additional MX fixtures.
|
|
18
|
+
- Defer byte payload decoding and File/Blob payload I/O.
|
|
19
|
+
- Move operation labels, mapping reconstruction and MX graph normalization to casadi-viz.
|
|
20
|
+
|
|
21
|
+
Breaking changes from 0.0.0-poc: `decodeCasadi` now returns
|
|
22
|
+
`casadi_serialization`, not `casadi_json`. Prefer `decode` and `open`.
|
|
23
|
+
The `/operations` export is removed. Raw Resource streams use
|
|
24
|
+
`decode(text, {type: 'Resource'})` or `open(file, {type: 'Resource'})`.
|
|
25
|
+
Other language prototypes remain deferred.
|
package/NOTICE
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
casadi-reader's implementation is licensed under the MIT License (LICENSE).
|
|
2
2
|
|
|
3
|
-
The vendored schemes/serialization_scheme.json contains
|
|
4
|
-
|
|
3
|
+
The vendored schemes/serialization_scheme.json contains decoding metadata derived
|
|
4
|
+
from CasADi 3.8.1, https://github.com/casadi/casadi. The upstream sources
|
|
5
5
|
retain CasADi's LGPL-3.0-or-later license; they are not relicensed by this
|
|
6
6
|
repository's MIT License. License texts are in LICENSES/.
|
|
7
7
|
|
|
@@ -11,7 +11,7 @@ Copyright (C) 2010-2023 Joel Andersson, Joris Gillis, Moritz Diehl,
|
|
|
11
11
|
Copyright (C) 2011-2014 Greg Horn
|
|
12
12
|
Additional source-file notices remain available in the referenced CasADi tree.
|
|
13
13
|
|
|
14
|
-
The published reader runtime assets contain generated
|
|
15
|
-
|
|
14
|
+
The published reader runtime assets contain generated decoding metadata.
|
|
15
|
+
Neither these assets nor the vendored scheme contains serializer source bodies. The full scheme is included in
|
|
16
16
|
this source repository and Python source distributions as a generation/test
|
|
17
17
|
input; it is not needed by the installed readers.
|
package/README.md
CHANGED
|
@@ -1,273 +1,193 @@
|
|
|
1
|
-
# casadi-reader
|
|
2
|
-
|
|
3
|
-
Inspect `.casadi` files without installing or loading CasADi. One repository
|
|
4
|
-
provides JavaScript/npm, Python/PyPI, C++, C, MATLAB and Julia interfaces.
|
|
5
|
-
The current development focus is the **npm package**. The other language
|
|
6
|
-
interfaces are experimental and deferred. This is not yet a published npm release.
|
|
7
|
-
Files are inspected, never evaluated; no archives are extracted.
|
|
8
|
-
|
|
9
|
-
| Interface | Implementation | Runtime dependencies |
|
|
10
|
-
| --- | --- | --- |
|
|
11
|
-
| `@casadi/casadi-reader` (npm) | Standalone JavaScript | None; Node 22+ or browser ESM |
|
|
12
|
-
| `casadi-reader` (PyPI) | Standalone Python | None; Python 3.9+ |
|
|
13
|
-
| C++ | Native reader, RAII `Document` | C++ standard library |
|
|
14
|
-
| C | C ABI over the native reader | Same native library |
|
|
15
|
-
| MATLAB | MATLAB package and MEX | Native reader compiled into the MEX |
|
|
16
|
-
| Julia `CasadiReader` | Julia package calling the C ABI | Standalone native library, JSON.jl |
|
|
17
|
-
|
|
18
|
-
All interfaces use the same object-table JSON contract and fixtures. The three
|
|
19
|
-
reader implementations use source assets generated from the vendored scheme.
|
|
20
|
-
MATLAB and Julia do not launch Python, Node or a subprocess to decode files.
|
|
21
|
-
|
|
22
|
-
## Python
|
|
23
|
-
|
|
24
|
-
Install locally with `pip install .` (the distribution declares no runtime
|
|
25
|
-
requirements):
|
|
26
|
-
|
|
27
|
-
```python
|
|
28
|
-
from casadi_reader import read_casadi, read_resource, to_json
|
|
29
|
-
|
|
30
|
-
graph = read_casadi('model.casadi')
|
|
31
|
-
print(to_json(graph, indent=2))
|
|
32
|
-
|
|
33
|
-
resource = read_resource('resource.casadi', lazy=True)
|
|
34
|
-
blob = resource['resource']['blob']
|
|
35
|
-
try:
|
|
36
|
-
first_bytes = blob.read(0, 64)
|
|
37
|
-
finally:
|
|
38
|
-
blob.close()
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
File input uses a read-only memory map. Lazy payloads keep that mapping alive;
|
|
42
|
-
metadata and requested slices are decoded, without allocating the whole archive.
|
|
43
|
-
`loads(text)` and `loads_resource(text, lazy=True)` also accept encoded strings.
|
|
44
|
-
The CLI is `casadi-reader [--resource] [--lazy] input.casadi [output.json]`, or
|
|
45
|
-
`python -m casadi_reader ...`.
|
|
46
|
-
|
|
47
|
-
## JavaScript
|
|
48
|
-
|
|
49
|
-
Install locally with `npm install /path/to/casadi-reader`:
|
|
1
|
+
# @casadi/casadi-reader
|
|
50
2
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
const graph = readCasadi(await file.text());
|
|
54
|
-
const {resource} = decodeResource(resourceStreamText, {lazy: true});
|
|
55
|
-
const firstBytes = resource.blob.read(0, 64); // Uint8Array
|
|
56
|
-
|
|
57
|
-
// File/Blob input also defers reading the encoded payload:
|
|
58
|
-
const opened = await openResource(resourceFile, {lazy: true});
|
|
59
|
-
const bytes = await opened.resource.blob.read(0, 64);
|
|
60
|
-
```
|
|
3
|
+
Read CasADi serialization into typed fields, values, containers and shared
|
|
4
|
+
references, without installing CasADi or loading its plugins.
|
|
61
5
|
|
|
62
|
-
The
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
`<script type="module">`; no import map or bundler is required. `VERSION` is a
|
|
67
|
-
placeholder: this prototype has not been published.
|
|
6
|
+
The reader does not interpret SX/MX instructions, name mathematical operations,
|
|
7
|
+
reconstruct entry mappings, or build visualization graphs. Those tasks belong
|
|
8
|
+
in [casadi-viz](https://github.com/casadi/casadi-viz). An ONNX-backed function is
|
|
9
|
+
read as serialized configuration and model bytes; the reader never runs ONNX.
|
|
68
10
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
whitespace. An application installing both CLIs should use the explicit module
|
|
73
|
-
or Node entry point to avoid the common `casadi-reader` executable name.
|
|
11
|
+
JavaScript, Python, C, C++, MATLAB and Julia expose the same structural document
|
|
12
|
+
contract. C and C++ share a native engine; MATLAB and Julia bind that engine.
|
|
13
|
+
Only JavaScript packaging and publishing are currently enabled in CI.
|
|
74
14
|
|
|
75
|
-
##
|
|
15
|
+
## API
|
|
76
16
|
|
|
77
|
-
|
|
17
|
+
```js
|
|
18
|
+
import {decode, open} from '@casadi/casadi-reader';
|
|
78
19
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
cmake --install build --prefix /your/prefix
|
|
20
|
+
const document = decode(serializedText);
|
|
21
|
+
const fromFile = await open(file, {lazy: true}); // browser File/Blob
|
|
22
|
+
const root = document.objects[document.root];
|
|
23
|
+
console.log(root.type, root.fields);
|
|
84
24
|
```
|
|
85
25
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
`<casadi_reader/reader.hpp>` and `<casadi_reader/reader.h>`.
|
|
26
|
+
`decode()` accepts encoded `.casadi` text. `open()` accepts a File/Blob.
|
|
27
|
+
`decodeCasadi` remains an alias for `decode`; both return structural documents.
|
|
89
28
|
|
|
90
|
-
|
|
91
|
-
casadi_reader::Document graph("model.casadi");
|
|
92
|
-
std::string json = graph.json();
|
|
93
|
-
casadi_reader::Document resource("resource.casadi", true, true);
|
|
94
|
-
auto bytes = resource.read_blob(0, 0, 64);
|
|
95
|
-
```
|
|
29
|
+
The output is ordinary JavaScript data:
|
|
96
30
|
|
|
97
|
-
```
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
31
|
+
```js
|
|
32
|
+
{
|
|
33
|
+
format: 'casadi_serialization',
|
|
34
|
+
version: 1,
|
|
35
|
+
serializationProtocol: 3,
|
|
36
|
+
root: 8,
|
|
37
|
+
roots: [{$ref: 8}],
|
|
38
|
+
objects: [
|
|
39
|
+
// ... shared objects ...
|
|
40
|
+
{
|
|
41
|
+
type: 'Function',
|
|
42
|
+
fields: [
|
|
43
|
+
{name: 'Function::null', type: 'bool', value: false},
|
|
44
|
+
// Serialized field order and duplicate field names are preserved.
|
|
45
|
+
],
|
|
46
|
+
layouts: ['MXFunction::serialize_body', /* base layouts ... */]
|
|
47
|
+
}
|
|
48
|
+
]
|
|
105
49
|
}
|
|
106
50
|
```
|
|
107
51
|
|
|
108
|
-
The
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
52
|
+
The example's indices are illustrative. `$ref` values are
|
|
53
|
+
zero-based indices into `objects`. Shared definitions appear once, even when
|
|
54
|
+
referenced by several functions. Inline structures have their own `type` and
|
|
55
|
+
`fields`. Vectors are arrays, pairs are two-element arrays, and maps are
|
|
56
|
+
`{$map: [[key, value], ...]}` so arbitrary key types and field order survive.
|
|
57
|
+
Repeated serializer fields remain repeated entries, not overwritten properties.
|
|
58
|
+
64-bit integers outside JavaScript's exact range use `{$integer: "..."}`;
|
|
59
|
+
nonfinite floating-point values use `{$float: "..."}`. Records and fields contain no source byte ranges.
|
|
113
60
|
|
|
114
|
-
|
|
61
|
+
A file can contain several roots; `roots` retains them in order. `root` is a
|
|
62
|
+
convenience index for a single shared-object root, otherwise null.
|
|
115
63
|
|
|
116
|
-
|
|
117
|
-
cmake -S . -B build -DCASADI_READER_MATLAB=ON
|
|
118
|
-
cmake --build build
|
|
119
|
-
```
|
|
64
|
+
## Lazy bytes
|
|
120
65
|
|
|
121
|
-
```
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
cleanup = onCleanup(@() delete(document));
|
|
127
|
-
metadata = document.data();
|
|
128
|
-
bytes = document.readBlob(1, 0, 64);
|
|
66
|
+
```js
|
|
67
|
+
const document = await open(resourceFile, {type: 'Resource', lazy: true});
|
|
68
|
+
const root = document.objects[document.root];
|
|
69
|
+
const blob = root.fields.find(f => f.name === 'ZipMemResource::blob').value;
|
|
70
|
+
const firstBytes = await blob.read(0, 64);
|
|
129
71
|
```
|
|
130
72
|
|
|
131
|
-
`
|
|
132
|
-
|
|
133
|
-
|
|
73
|
+
`type` selects a raw `SerializingStream` root instead of FileSerializer framing.
|
|
74
|
+
Resource streams use the same archive representation embedded inside FMUs;
|
|
75
|
+
complete saved FMU functions are not yet a validated layout family.
|
|
134
76
|
|
|
135
|
-
|
|
77
|
+
Lazy byte handles expose `offset`, `byteLength` and `read(offset, length)`.
|
|
78
|
+
Text-input reads are synchronous; File/Blob reads are asynchronous. JSON output
|
|
79
|
+
contains a small descriptor and requires the original source to retrieve bytes.
|
|
136
80
|
|
|
137
|
-
|
|
81
|
+
Opaque streams are deferred in lazy mode. Large serialized strings are also
|
|
82
|
+
deferred (default `lazyThreshold: 65536` bytes). Smaller strings are decoded as
|
|
83
|
+
UTF-8 where possible; other strings retain their bytes as `{$bytes: [...]}` in
|
|
84
|
+
eager mode or a lazy byte handle in lazy mode. No archive extraction occurs.
|
|
138
85
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
86
|
+
Lazy File/Blob opening loads metadata pages and skips payload pages by their
|
|
87
|
+
declared lengths. It requires unpadded encoded files, as emitted by CasADi.
|
|
88
|
+
Text input accepts surrounding whitespace but necessarily retains the supplied
|
|
89
|
+
encoded string. Graph fields and containers are currently eager; lazy mode
|
|
90
|
+
specifically concerns opaque byte payloads.
|
|
142
91
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
92
|
+
## Browser and CLI
|
|
93
|
+
|
|
94
|
+
Published packages contain bundled browser ESM with the layout data embedded.
|
|
95
|
+
They do not fetch or parse the source scheme JSON at runtime. A browser can
|
|
96
|
+
import a pinned `https://unpkg.com/@casadi/casadi-reader@VERSION/dist/index.js`
|
|
97
|
+
from a module script without a bundler or an import map.
|
|
98
|
+
|
|
99
|
+
```sh
|
|
100
|
+
npx @casadi/casadi-reader model.casadi model.json
|
|
101
|
+
# Or, for a raw Resource stream:
|
|
102
|
+
npx @casadi/casadi-reader --type Resource --lazy resource.casadi
|
|
153
103
|
```
|
|
154
104
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
The fixtures come from CasADi 3.8.1 default `Function.save()` files: MX arithmetic,
|
|
191
|
-
sparse matrices, gathers, slices and entry assignments. Supported layouts are
|
|
192
|
-
ProtoFunction 2, FunctionInternal 8, XFunction 1, MXFunction 3, little-endian
|
|
193
|
-
protocol 3. Unsupported operations/layouts fail explicitly. SX functions, nested
|
|
194
|
-
function calls, plugins, JIT, nonempty option/cache dictionaries and debug
|
|
195
|
-
serialization are outside this prototype. It is not a general reader for every
|
|
196
|
-
CasADi file or version, nor a hardened untrusted-file service.
|
|
197
|
-
|
|
198
|
-
Resource entry points accept a **raw SerializingStream containing one Resource**.
|
|
199
|
-
This tests the embedded ZIP representation used by FMUs, but **does not yet read
|
|
200
|
-
an entire saved FmuFunction**. No FMU is loaded or executed.
|
|
201
|
-
|
|
202
|
-
## Scheme, tests and packaging
|
|
203
|
-
|
|
204
|
-
`schemes/serialization_scheme.json` vendors CasADi's checked-in
|
|
205
|
-
`misc/serialization_scheme.json`. It is a source-derived serializer index and
|
|
206
|
-
named-field contract, **not a complete executable deserialization grammar**.
|
|
207
|
-
`scripts/generate-reader-assets.py` consumes this JSON and emits three checked-in
|
|
208
|
-
source assets: `src/scheme.js`, `python/casadi_reader/_scheme.py`, and
|
|
209
|
-
`native/src/scheme.hpp`. These contain runtime protocol constants, operation IDs
|
|
210
|
-
and class versions, omitting the C++ source index. Supported positional layouts
|
|
211
|
-
are still implemented explicitly in the readers.
|
|
212
|
-
|
|
213
|
-
`npm run build` regenerates the assets and bundles the JavaScript. `npm pack`
|
|
214
|
-
runs that build automatically. Python packages contain the generated Python
|
|
215
|
-
module, so neither Python nor JavaScript parses the scheme JSON at runtime.
|
|
216
|
-
Build tools are development dependencies only.
|
|
217
|
-
|
|
218
|
-
CI checks `npm run check:generated` **before** rebuilding, rejecting stale
|
|
219
|
-
committed assets. The initial CI builds and tests the npm package and produces its tarball. A browser test serves the extracted npm tarball
|
|
220
|
-
over HTTP and checks that decoding needs one JavaScript request and no scheme
|
|
221
|
-
JSON request. CI uploads build artifacts; it does not publish packages.
|
|
105
|
+
There are no runtime dependencies. Building the npm package needs Node 22+,
|
|
106
|
+
Python 3.9+ and the development dependencies in package-lock.json.
|
|
107
|
+
|
|
108
|
+
## Scheme and coverage
|
|
109
|
+
|
|
110
|
+
CasADi's `misc/generate_serialization_scheme.py` produces the vendored
|
|
111
|
+
`schemes/serialization_scheme.json`: decoding rules and validation metadata,
|
|
112
|
+
without source bodies, pack expressions, source locations or extraction offsets.
|
|
113
|
+
Field bindings are retained only when decoding expressions can reference them.
|
|
114
|
+
`npm run generate` generates all six readers. The generic engines
|
|
115
|
+
execute field, base-layout, repetition, condition and discriminator instructions;
|
|
116
|
+
they contain no SX/MX-specific decoding methods. A small `Generator` base class
|
|
117
|
+
and language subclasses in `scripts/reader_generators.py` emit scheme data and
|
|
118
|
+
copy runtime templates from `scripts/templates`. Edit templates, then regenerate.
|
|
119
|
+
Use `--scheme PATH --output-root DIR` with `scripts/generate-reader-assets.py`
|
|
120
|
+
to generate readers for another extracted scheme without changing this checkout.
|
|
121
|
+
|
|
122
|
+
The extractor includes inline serializers, inheritance and tensor metadata
|
|
123
|
+
helpers. Inherited serializers and template aliases are explicit layouts with
|
|
124
|
+
call instructions; readers perform no C++ inheritance lookup. It derives operation dispatch families from CasADi's native dispatcher
|
|
125
|
+
and plugin registrations from the source. No mathematical evaluation occurs.
|
|
126
|
+
|
|
127
|
+
Coverage is still experimental. Native plain/debug fixture pairs validate MX,
|
|
128
|
+
SX, nested calls, mappings, constants, ONNX-backed functions and Resource streams.
|
|
129
|
+
The debug files independently check serialized field names and primitive tags;
|
|
130
|
+
ordinary undecorated files use the same layouts. Tests also exercise a new
|
|
131
|
+
function discriminator supplied entirely as layout data.
|
|
132
|
+
|
|
133
|
+
This is **not yet a guarantee that every CasADi class/version can be read**.
|
|
134
|
+
Unsupported lowering, missing field types, absent layouts and unknown
|
|
135
|
+
discriminators fail explicitly. Current fixtures target the CasADi 3.8.1 source
|
|
136
|
+
snapshot, little-endian protocol 3. Expanding coverage belongs in the scheme
|
|
137
|
+
extractor and fixtures, not mathematical interpretation in the reader. Advanced
|
|
138
|
+
consumers can supply a compiled schema through `decode(text, {scheme})`.
|
|
222
139
|
|
|
223
140
|
```sh
|
|
224
|
-
node scripts/vendor-scheme.mjs ../serialization-scheme/misc/serialization_scheme.json
|
|
225
|
-
python scripts/generate-reader-assets.py
|
|
226
141
|
npm ci
|
|
227
142
|
npm run check:generated
|
|
228
143
|
npm test
|
|
229
144
|
npm run test:browser
|
|
230
|
-
PYTHONPATH=python python -m unittest discover -s python/tests -v
|
|
231
|
-
CASADI_READER_LIBRARY="$PWD/build/libcasadi_reader.so" julia --project=julia julia/test/runtests.jl
|
|
232
|
-
```
|
|
233
|
-
|
|
234
|
-
Set `CASADI_READER_NATIVE` to the native CLI to enable Python/native agreement
|
|
235
|
-
tests. Python tests also compare JavaScript when Node is available. Native CasADi
|
|
236
|
-
is used only to regenerate fixtures (`scripts/generate-fixtures.py` and
|
|
237
|
-
`scripts/generate-resource-fixture.cpp`), never to run the readers. Tests check
|
|
238
|
-
native graph/metadata oracles and deferred 16 MiB payload access.
|
|
239
|
-
|
|
240
|
-
Create unpublished artifacts with:
|
|
241
|
-
|
|
242
|
-
```sh
|
|
243
|
-
python -m build
|
|
244
145
|
npm pack
|
|
245
|
-
python scripts/package-bindings.py --output dist --mex build/matlab/casadi_reader_mex.mexa64
|
|
246
146
|
```
|
|
247
147
|
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
148
|
+
CI rejects stale generated assets before rebuilding. Browser tests serve the
|
|
149
|
+
extracted npm tarball over HTTP and verify one JavaScript request with no scheme
|
|
150
|
+
JSON or CasADi runtime request. Native CasADi is used only when regenerating the
|
|
151
|
+
fixtures, via `scripts/generate-fixtures.py` and the Resource fixture generator.
|
|
152
|
+
|
|
153
|
+
## Other languages
|
|
154
|
+
|
|
155
|
+
Python is dependency-free: `PYTHONPATH=python python3 -m casadi_reader model.casadi`.
|
|
156
|
+
`casadi_reader.read_casadi(path)` returns the same typed records as JavaScript;
|
|
157
|
+
`to_json(document)` makes them portable to the viewer. Use `lazy=True` for byte
|
|
158
|
+
handles and keep their source open while reading them.
|
|
159
|
+
|
|
160
|
+
Build the standalone native library and CLI using the root `CMakeLists.txt`.
|
|
161
|
+
C uses `cr_open_type` for files or `cr_decode` for copied encoded input;
|
|
162
|
+
`cr_json` exposes the structural JSON, valid until `cr_close`.
|
|
163
|
+
C++ wraps this lifetime in `casadi_reader::Document`. Both accept an optional
|
|
164
|
+
raw root type, such as `Resource`. Lazy byte access checks ranges and requires
|
|
165
|
+
an open document. The native engine limits collection/eager byte counts to one
|
|
166
|
+
million, nesting to 256, and input size to 1 GiB; larger opaque payloads can use
|
|
167
|
+
lazy mode within the file limit.
|
|
168
|
+
|
|
169
|
+
MATLAB uses `casadi_reader.read(path)` or a `casadi_reader.Document` for lazy
|
|
170
|
+
bytes; compile `matlab/casadi_reader_mex.cpp` with the native engine.
|
|
171
|
+
Julia uses `CasadiReader.read_casadi(path)` or `Document(path; lazy=true)` and
|
|
172
|
+
loads the native library through `CASADI_READER_LIBRARY`.
|
|
173
|
+
|
|
174
|
+
`python/tests/test_reader.py` compares every field against JavaScript
|
|
175
|
+
on all plain/debug fixtures, and also checks the native CLI when
|
|
176
|
+
`CASADI_READER_NATIVE` points to it. `scripts/test-bindings.py` runs the same
|
|
177
|
+
fixture comparisons in MATLAB/Julia; see its `--help` for local paths. Native
|
|
178
|
+
`native/tests/api.c` exercises the C ABI, copied input and lazy payload bounds.
|
|
179
|
+
These local language tests do not add language packaging to CI.
|
|
180
|
+
|
|
181
|
+
## Publishing
|
|
182
|
+
|
|
183
|
+
`publish.yml` publishes on a published GitHub release, after tests. The release
|
|
184
|
+
tag must equal `v` plus the package version. Prereleases use npm's `next` tag;
|
|
185
|
+
stable versions use `latest`.
|
|
186
|
+
|
|
187
|
+
The npm Trusted Publisher configuration is GitHub organization `casadi`,
|
|
188
|
+
repository `casadi-reader`, workflow `publish.yml`, with no environment name and
|
|
189
|
+
with direct `npm publish` allowed. Publishing uses OIDC and provenance, with no
|
|
190
|
+
npm token secret. See [npm's documentation](https://docs.npmjs.com/trusted-publishers/).
|
|
191
|
+
|
|
192
|
+
The reader implementation is MIT licensed. The vendored scheme is derived from
|
|
193
|
+
CasADi; upstream attribution and license texts are retained in NOTICE and LICENSES.
|
package/bin/casadi-reader.js
CHANGED
|
@@ -1,11 +1,17 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {readFile,writeFile} from 'node:fs/promises';
|
|
3
|
-
import {
|
|
3
|
+
import {decode} from '../dist/index.js';
|
|
4
4
|
try {
|
|
5
|
-
const args=process.argv.slice(2),options={
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
5
|
+
const args=process.argv.slice(2),options={};const positional=[];
|
|
6
|
+
for(let i=0;i<args.length;i++){
|
|
7
|
+
if(args[i]==='--lazy')options.lazy=true;
|
|
8
|
+
else if(args[i]==='--type') {if(!args[i+1])throw Error('Missing --type value');options.type=args[++i];}
|
|
9
|
+
else if(args[i]==='--resource')options.type='Resource';
|
|
10
|
+
else if(args[i].startsWith('--'))throw Error('Unknown option '+args[i]);
|
|
11
|
+
else positional.push(args[i]);
|
|
12
|
+
}
|
|
13
|
+
const [input,output,...extra]=positional;
|
|
14
|
+
if(!input||extra.length)throw Error('Usage: casadi-reader [--lazy] [--type TYPE] INPUT [OUTPUT.json]');
|
|
15
|
+
const json=JSON.stringify(decode(await readFile(input,'utf8'),options),null,2)+'\n';
|
|
10
16
|
if(output)await writeFile(output,json);else process.stdout.write(json);
|
|
11
17
|
}catch(error){console.error(error.message);process.exitCode=1;}
|