@mikrojs/native 0.18.2 → 0.19.0-pr-352.20260829215534
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/CMakeLists.txt +25 -2
- package/include/mikrojs/mem.h +4 -0
- package/include/mikrojs/ota_client.h +3 -3
- package/include/mikrojs/platform.h +8 -0
- package/include/mikrojs/private.h +28 -0
- package/package.json +4 -5
- package/prebuilds/darwin-arm64/mikrojs.napi.node +0 -0
- package/prebuilds/linux-arm64/mikrojs.napi.node +0 -0
- package/prebuilds/linux-x64/mikrojs.napi.node +0 -0
- package/runtime/http/helpers.ts +5 -0
- package/runtime/internal.d.ts +41 -2
- package/runtime/ota/client.ts +4 -0
- package/runtime/ota/ota.ts +4 -0
- package/runtime/ota/types.ts +75 -0
- package/runtime/schema/schema.ts +25 -3
- package/runtime/schema/types.ts +193 -15
- package/runtime/sys/types.ts +11 -1
- package/runtime/test/test.ts +6 -2
- package/runtime/wifi/types.ts +3 -0
- package/scripts/gen-schema-fixtures.js +317 -0
- package/src/mem.cpp +83 -37
- package/src/mik_app_config.cpp +9 -1
- package/src/mik_http_client.cpp +1357 -0
- package/src/mik_ota_client.cpp +3 -3
- package/src/mik_repl.cpp +44 -5
- package/src/mik_schema.cpp +892 -0
- package/src/mik_sys.cpp +9 -1
- package/src/mik_wifi_client.cpp +742 -0
- package/src/mikrojs.cpp +34 -8
- package/src/modules.cpp +66 -0
- package/dist/runtime/schema/core.d.ts +0 -115
- package/dist/runtime/schema/core.d.ts.map +0 -1
- package/dist/runtime/schema/core.js +0 -259
- package/dist/runtime/schema/core.js.map +0 -1
- package/dist/runtime/schema/shared.d.ts +0 -54
- package/dist/runtime/schema/shared.d.ts.map +0 -1
- package/dist/runtime/schema/shared.js +0 -489
- package/dist/runtime/schema/shared.js.map +0 -1
- package/runtime/http/native.ts +0 -160
- package/runtime/http/request.ts +0 -25
- package/runtime/schema/core.ts +0 -539
- package/runtime/schema/shared.ts +0 -494
- package/runtime/wifi/wifi.ts +0 -191
package/CMakeLists.txt
CHANGED
|
@@ -43,7 +43,10 @@ set(MIKROJS_CORE_SOURCES
|
|
|
43
43
|
src/mik_text_encoding.cpp
|
|
44
44
|
src/mik_color.cpp
|
|
45
45
|
src/mik_abort.cpp
|
|
46
|
+
src/mik_http_client.cpp
|
|
47
|
+
src/mik_wifi_client.cpp
|
|
46
48
|
src/mik_cbor.cpp
|
|
49
|
+
src/mik_schema.cpp
|
|
47
50
|
src/mik_result.cpp
|
|
48
51
|
src/mik_console.cpp
|
|
49
52
|
src/mik_sys.cpp
|
|
@@ -88,7 +91,7 @@ endif()
|
|
|
88
91
|
include(cmake/mikrojs_bytecode.cmake)
|
|
89
92
|
mikrojs_generate_bytecode(
|
|
90
93
|
RUNTIME_DIR "${CMAKE_CURRENT_SOURCE_DIR}/runtime"
|
|
91
|
-
MODULES abort cbor env result schema fs
|
|
94
|
+
MODULES abort cbor env result schema fs i2c kv/nvs kv/rtc kv/shared module neopixel observable observable/lazy observable/operators ota ota/client ota/config pin pwm reader sleep spi sntp stdio stream sys test uart udp
|
|
92
95
|
MODULE_PREFIX "mikro"
|
|
93
96
|
SYMBOL_PREFIX "mikro"
|
|
94
97
|
TARGET gen_bytecode
|
|
@@ -194,6 +197,7 @@ if(BUILD_TESTING)
|
|
|
194
197
|
test/app_store_test.cpp
|
|
195
198
|
test/oom_test.cpp
|
|
196
199
|
test/oom_inject_test.cpp
|
|
200
|
+
test/mem_usable_size_test.cpp
|
|
197
201
|
test/fs_test.cpp
|
|
198
202
|
test/console_stdio_test.cpp
|
|
199
203
|
test/cbor_js_test.cpp
|
|
@@ -207,6 +211,8 @@ if(BUILD_TESTING)
|
|
|
207
211
|
test/stream_test.cpp
|
|
208
212
|
test/runtime_recycle_test.cpp
|
|
209
213
|
test/udp_test.cpp
|
|
214
|
+
test/http_client_test.cpp
|
|
215
|
+
test/wifi_client_test.cpp
|
|
210
216
|
test/observable_test.cpp
|
|
211
217
|
test/unhandled_rejection_test.cpp
|
|
212
218
|
test/ota_policy_test.cpp
|
|
@@ -214,6 +220,7 @@ if(BUILD_TESTING)
|
|
|
214
220
|
test/ota_config_test.cpp
|
|
215
221
|
test/ota_js_hooks_test.cpp
|
|
216
222
|
test/ota_wire_fixtures_test.cpp
|
|
223
|
+
test/schema_conformance_test.cpp
|
|
217
224
|
test/sys_codec_test.cpp
|
|
218
225
|
)
|
|
219
226
|
|
|
@@ -233,9 +240,25 @@ if(BUILD_TESTING)
|
|
|
233
240
|
)
|
|
234
241
|
add_dependencies(mikrojs_tests gen_checkin_fixtures)
|
|
235
242
|
|
|
243
|
+
# ── Schema conformance fixtures ──────────────────────────────────
|
|
244
|
+
# mikro/schema has two implementations: @mikrojs/schema (host) and
|
|
245
|
+
# src/mik_schema.cpp (device). The generator records what core.ts does and
|
|
246
|
+
# test/schema_conformance_test.cpp replays it through the native module.
|
|
247
|
+
# Always regenerated so the fixtures cannot lag core.ts.
|
|
248
|
+
set(_SCHEMA_FIXTURE_DIR "${CMAKE_CURRENT_BINARY_DIR}/gen/schema-fixtures")
|
|
249
|
+
add_custom_target(gen_schema_fixtures
|
|
250
|
+
COMMAND node "${CMAKE_CURRENT_SOURCE_DIR}/scripts/gen-schema-fixtures.js"
|
|
251
|
+
"${_SCHEMA_FIXTURE_DIR}"
|
|
252
|
+
COMMENT "Generating schema conformance fixtures from @mikrojs/schema"
|
|
253
|
+
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
|
|
254
|
+
VERBATIM
|
|
255
|
+
)
|
|
256
|
+
add_dependencies(mikrojs_tests gen_schema_fixtures)
|
|
257
|
+
|
|
236
258
|
target_link_libraries(mikrojs_tests PRIVATE mikrojs)
|
|
237
259
|
target_compile_definitions(mikrojs_tests PRIVATE
|
|
238
|
-
"MIK_CHECKIN_FIXTURE_DIR=\"${_CHECKIN_FIXTURE_DIR}\""
|
|
260
|
+
"MIK_CHECKIN_FIXTURE_DIR=\"${_CHECKIN_FIXTURE_DIR}\""
|
|
261
|
+
"MIK_SCHEMA_FIXTURE_DIR=\"${_SCHEMA_FIXTURE_DIR}\"")
|
|
239
262
|
target_include_directories(mikrojs_tests PRIVATE
|
|
240
263
|
"${CMAKE_CURRENT_SOURCE_DIR}/test"
|
|
241
264
|
"${CMAKE_CURRENT_SOURCE_DIR}/deps/nanocbor/include"
|
package/include/mikrojs/mem.h
CHANGED
|
@@ -36,4 +36,8 @@ void mik__oom_inject_fail_after(int64_t n);
|
|
|
36
36
|
/* Net live allocations across all mem.cpp allocators, for leak checks
|
|
37
37
|
* spanning an inject/recover cycle. */
|
|
38
38
|
int64_t mik__oom_inject_live_allocs(void);
|
|
39
|
+
/* Force the usable-size latch for hook-mode allocator tests: fn installs
|
|
40
|
+
* a fake platform hook, null restores header mode. Pointers must not
|
|
41
|
+
* cross a mode switch — the mode decides the allocation's offset. */
|
|
42
|
+
void mik__usable_size_latch_override(size_t (*fn)(const void* ptr));
|
|
39
43
|
#endif
|
|
@@ -178,9 +178,9 @@ public:
|
|
|
178
178
|
* un-enrolled device, which settles inline before Check() returns. */
|
|
179
179
|
void Check(const MIKOtaCheckOptions& options, MIKOtaCheckSink sink);
|
|
180
180
|
|
|
181
|
-
/* Start the free-running loop.
|
|
182
|
-
* device. At most one watch per client. */
|
|
183
|
-
|
|
181
|
+
/* Start the free-running loop. Returns false, with no loop started, on an
|
|
182
|
+
* un-enrolled device. At most one watch per client. */
|
|
183
|
+
bool Watch(const MIKOtaWatchOptions& options);
|
|
184
184
|
|
|
185
185
|
/* No further rounds, and the pending delay is cancelled. A round in flight
|
|
186
186
|
* still completes, but a build it stages no longer auto-restarts — it stays
|
|
@@ -53,6 +53,14 @@ typedef struct MIKPlatform {
|
|
|
53
53
|
/** PSRAM-targeted realloc. Grows or moves the allocation while keeping
|
|
54
54
|
* it in PSRAM. Same fallback rules as malloc_psram. */
|
|
55
55
|
void* (*realloc_psram)(void* ptr, size_t size);
|
|
56
|
+
/** Usable size of a live allocation made by this platform's allocators
|
|
57
|
+
* (malloc/calloc/realloc and the *_psram variants), as reported by
|
|
58
|
+
* libc malloc_usable_size / malloc_size or ESP-IDF's
|
|
59
|
+
* heap_caps_get_allocated_size. When provided, the runtime lets
|
|
60
|
+
* QuickJS account blocks by their real size instead of prepending a
|
|
61
|
+
* per-allocation size header (one word per live block). NULL keeps
|
|
62
|
+
* the header scheme. */
|
|
63
|
+
size_t (*malloc_usable_size)(const void* ptr);
|
|
56
64
|
bool (*get_fs_info)(const char* label, size_t* total, size_t* used);
|
|
57
65
|
void (*log)(int level, const char* tag, const char* fmt, ...);
|
|
58
66
|
int (*stdout_write)(const void* buf, size_t len);
|
|
@@ -115,6 +115,10 @@ struct MIKRuntime {
|
|
|
115
115
|
* mik__result_ok_void. Safe to share because Result is immutable by
|
|
116
116
|
* convention, and the singleton is frozen + non-extensible. */
|
|
117
117
|
JSValue result_ok_void_singleton;
|
|
118
|
+
/* Shared BodyConsumedError constructor for the native mikro/http/helpers
|
|
119
|
+
* module. Created lazily on first http module init, freed in
|
|
120
|
+
* MIK_FreeRuntime. */
|
|
121
|
+
JSValue http_body_consumed_ctor;
|
|
118
122
|
JSValue env_obj; /* Frozen object with env vars, set on import.meta.env */
|
|
119
123
|
struct {
|
|
120
124
|
JSValue on_data; /* JS callback for stdin data, JS_UNDEFINED when not listening */
|
|
@@ -255,9 +259,33 @@ std::string mik_inspect(JSContext* ctx, JSValue value, int depth = 2, bool color
|
|
|
255
259
|
bool show_hidden = false);
|
|
256
260
|
void mik__inspect_register(JSContext* ctx);
|
|
257
261
|
|
|
262
|
+
/* HTTP client modules mikro/http/helpers + mikro/http/request
|
|
263
|
+
* (mik_http_client.cpp). Loaded lazily via the C-module table in
|
|
264
|
+
* modules.cpp, not registered at runtime creation. */
|
|
265
|
+
JSModuleDef* mik__http_helpers_load(JSContext* ctx);
|
|
266
|
+
JSModuleDef* mik__http_request_load(JSContext* ctx);
|
|
267
|
+
|
|
268
|
+
/* Wifi client module mikro/wifi (mik_wifi_client.cpp), same lazy table. */
|
|
269
|
+
JSModuleDef* mik__wifi_client_load(JSContext* ctx);
|
|
270
|
+
|
|
271
|
+
/* Load `specifier` through the module loader on behalf of `importer` and
|
|
272
|
+
* return its namespace (modules.cpp). Honors virtual-module overrides. */
|
|
273
|
+
JSValue mik__load_module_ns(JSContext* ctx, const char* importer, const char* specifier,
|
|
274
|
+
bool require_evaluated);
|
|
275
|
+
|
|
276
|
+
/* Timer registry (timers.cpp) — direct scheduling for native callbacks that
|
|
277
|
+
* must not go through the JS setTimeout global. Schedule dups `func`. */
|
|
278
|
+
uint32_t MIK_Timer_Schedule(MIKTimers* timers, JSContext* ctx, JSValue func, int argc,
|
|
279
|
+
const JSValue* argv, int64_t timeout, bool is_interval, int64_t now);
|
|
280
|
+
bool MIK_Timer_UnSchedule(MIKTimers* timers, JSContext* ctx, uint32_t id);
|
|
281
|
+
|
|
258
282
|
/* CBOR module (mik_cbor.cpp) */
|
|
259
283
|
JSModuleDef* mik__cbor_init(JSContext* ctx);
|
|
260
284
|
|
|
285
|
+
/* Schema module (mik_schema.cpp). Registered lazily: the loader calls its
|
|
286
|
+
* init on first import of native:mikro/schema. */
|
|
287
|
+
void mik__schema_register(void);
|
|
288
|
+
|
|
261
289
|
/* Result module (mik_result.cpp) */
|
|
262
290
|
JSModuleDef* mik__result_init(JSContext* ctx);
|
|
263
291
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mikrojs/native",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.19.0-pr-352.20260829215534",
|
|
4
4
|
"description": "Mikro.js C++ runtime library and Node.js native addon",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"esp32",
|
|
@@ -70,8 +70,6 @@
|
|
|
70
70
|
"./runtime/reader/types": "./runtime/reader/types.ts",
|
|
71
71
|
"./runtime/result/native-result.node-shim": "./dist/runtime/result/native-result.node-shim.js",
|
|
72
72
|
"./runtime/result/types": "./runtime/result/types.ts",
|
|
73
|
-
"./runtime/schema/core": "./dist/runtime/schema/core.js",
|
|
74
|
-
"./runtime/schema/shared": "./dist/runtime/schema/shared.js",
|
|
75
73
|
"./runtime/schema/types": "./runtime/schema/types.ts",
|
|
76
74
|
"./runtime/sleep/types": "./runtime/sleep/types.ts",
|
|
77
75
|
"./runtime/sntp/types": "./runtime/sntp/types.ts",
|
|
@@ -88,14 +86,15 @@
|
|
|
88
86
|
"cmake-js": "^8.0.0",
|
|
89
87
|
"node-addon-api": "^8.7.0",
|
|
90
88
|
"node-gyp-build": "^4.8.4",
|
|
91
|
-
"@mikrojs/quickjs": "0.
|
|
89
|
+
"@mikrojs/quickjs": "0.19.0-pr-352.20260829215534+23027de"
|
|
92
90
|
},
|
|
93
91
|
"devDependencies": {
|
|
94
92
|
"@swc/core": "^1.15.30",
|
|
95
93
|
"@types/node": "^24.12.2",
|
|
96
94
|
"esbuild": "^0.28.0",
|
|
97
95
|
"terser": "^5.46.2",
|
|
98
|
-
"@mikrojs/registry": "0.
|
|
96
|
+
"@mikrojs/registry": "0.19.0-pr-352.20260829215534+23027de",
|
|
97
|
+
"@mikrojs/schema": "0.19.0-pr-352.20260829215534+23027de"
|
|
99
98
|
},
|
|
100
99
|
"engines": {
|
|
101
100
|
"node": ">=24.0.0"
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/runtime/http/helpers.ts
CHANGED
|
@@ -2,6 +2,11 @@
|
|
|
2
2
|
// `native:mikro/http`. Apps driving HTTP through a non-lwIP transport (e.g. an
|
|
3
3
|
// LTE modem over UART) implement the `Request` type directly and reuse
|
|
4
4
|
// `prepareBody` + `makeResponse` for the boring parts.
|
|
5
|
+
//
|
|
6
|
+
// On-device, `mikro/http/helpers` is the native C module in
|
|
7
|
+
// src/mik_http_client.cpp (behavior pinned by test/http_client_test.cpp).
|
|
8
|
+
// This TS source stays as the type surface and as the Node-side double for
|
|
9
|
+
// the http/server vitest suite.
|
|
5
10
|
|
|
6
11
|
import {err, ok} from 'mikro/result'
|
|
7
12
|
|
package/runtime/internal.d.ts
CHANGED
|
@@ -26,6 +26,34 @@ declare module 'native:mikro/cbor' {
|
|
|
26
26
|
export function decode(data: Uint8Array): Result<unknown, CborError>
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
+
declare module 'native:mikro/schema' {
|
|
30
|
+
import type * as S from '@mikrojs/native/runtime/schema/types'
|
|
31
|
+
/* typeof-aliased rather than re-exported: `export ... from` inside an
|
|
32
|
+
* ambient module declaration resolves to never, and writing the generic
|
|
33
|
+
* signatures out again here would be a third copy of the surface. */
|
|
34
|
+
export const string: typeof S.string
|
|
35
|
+
export const number: typeof S.number
|
|
36
|
+
export const boolean: typeof S.boolean
|
|
37
|
+
export const unknown: typeof S.unknown
|
|
38
|
+
export const literal: typeof S.literal
|
|
39
|
+
export const array: typeof S.array
|
|
40
|
+
export const object: typeof S.object
|
|
41
|
+
export const tuple: typeof S.tuple
|
|
42
|
+
export const optional: typeof S.optional
|
|
43
|
+
export const union: typeof S.union
|
|
44
|
+
export const enumOf: typeof S.enumOf
|
|
45
|
+
export const taggedUnion: typeof S.taggedUnion
|
|
46
|
+
export const applyDefaults: typeof S.applyDefaults
|
|
47
|
+
export const SchemaError: typeof S.SchemaError
|
|
48
|
+
/* The plain {ok, error} envelope core.ts's local err() builds, not a
|
|
49
|
+
* mikro/result Result: parse() in schema.ts wraps it. */
|
|
50
|
+
export function validate(
|
|
51
|
+
schema: S.Schema,
|
|
52
|
+
value: unknown,
|
|
53
|
+
path: string,
|
|
54
|
+
): {ok: false; error: S.SchemaError} | null
|
|
55
|
+
}
|
|
56
|
+
|
|
29
57
|
declare module 'native:mikro/result' {
|
|
30
58
|
import type {ErrResult, OkResult} from './result/types.js'
|
|
31
59
|
export function ok(): OkResult<void>
|
|
@@ -533,12 +561,21 @@ declare module 'native:mikro/udp' {
|
|
|
533
561
|
}
|
|
534
562
|
|
|
535
563
|
declare module 'native:mikro/ota_client' {
|
|
536
|
-
import type {
|
|
564
|
+
import type {Result} from 'mikro/result'
|
|
565
|
+
|
|
566
|
+
import type {
|
|
567
|
+
CheckOptions,
|
|
568
|
+
CheckResult,
|
|
569
|
+
NotEnrolledError,
|
|
570
|
+
Ota,
|
|
571
|
+
Watcher,
|
|
572
|
+
WatchOptions,
|
|
573
|
+
} from './ota/types.js'
|
|
537
574
|
|
|
538
575
|
// Backed by src/mik_ota_client.cpp, src/mik_ota_config.cpp and
|
|
539
576
|
// src/mik_ota_policy.cpp.
|
|
540
577
|
export function check(options?: CheckOptions): Promise<CheckResult>
|
|
541
|
-
export function watch(options?: WatchOptions): Watcher
|
|
578
|
+
export function watch(options?: WatchOptions): Result<Watcher, NotEnrolledError>
|
|
542
579
|
export function config(): unknown
|
|
543
580
|
|
|
544
581
|
// The mikro/ota policy surface.
|
|
@@ -549,6 +586,8 @@ declare module 'native:mikro/ota_client' {
|
|
|
549
586
|
export const parseConfig: Ota['parseConfig']
|
|
550
587
|
export const applyConfig: Ota['applyConfig']
|
|
551
588
|
export const configState: Ota['configState']
|
|
589
|
+
export const report: Ota['report']
|
|
590
|
+
export const settle: Ota['settle']
|
|
552
591
|
export const confirm: Ota['confirm']
|
|
553
592
|
export const revert: Ota['revert']
|
|
554
593
|
export const bearer: Ota['bearer']
|
package/runtime/ota/client.ts
CHANGED
|
@@ -14,6 +14,7 @@ export type {
|
|
|
14
14
|
CheckOptions,
|
|
15
15
|
CheckResult,
|
|
16
16
|
DeclineReason,
|
|
17
|
+
NotEnrolledError,
|
|
17
18
|
Teardown,
|
|
18
19
|
Watcher,
|
|
19
20
|
WatchOptions,
|
|
@@ -34,5 +35,8 @@ export const check = nativeCheck
|
|
|
34
35
|
* the device after staging a build. Use `beforeCheck` to bring the network up
|
|
35
36
|
* per round (its returned teardown runs after the round). Do not combine with
|
|
36
37
|
* `check()` — the two modes are alternatives, one per app.
|
|
38
|
+
*
|
|
39
|
+
* Returns the watcher as a Result: an un-enrolled device gets an
|
|
40
|
+
* `err({name: 'NotEnrolled'})` and no loop is started.
|
|
37
41
|
*/
|
|
38
42
|
export const watch = nativeWatch
|
package/runtime/ota/ota.ts
CHANGED
|
@@ -17,8 +17,10 @@ import {
|
|
|
17
17
|
parseOffer,
|
|
18
18
|
reconcile,
|
|
19
19
|
registry,
|
|
20
|
+
report,
|
|
20
21
|
revert,
|
|
21
22
|
running,
|
|
23
|
+
settle,
|
|
22
24
|
} from 'native:mikro/ota_client'
|
|
23
25
|
|
|
24
26
|
import type {Ota} from './types.js'
|
|
@@ -36,6 +38,8 @@ const ota: Ota = {
|
|
|
36
38
|
parseConfig,
|
|
37
39
|
applyConfig,
|
|
38
40
|
configState,
|
|
41
|
+
report,
|
|
42
|
+
settle,
|
|
39
43
|
}
|
|
40
44
|
|
|
41
45
|
export {ota}
|
package/runtime/ota/types.ts
CHANGED
|
@@ -197,6 +197,45 @@ export interface ConfigErrorReport {
|
|
|
197
197
|
message: string
|
|
198
198
|
}
|
|
199
199
|
|
|
200
|
+
/** The check-in body a device owes its registry, as `ota.report()` builds it.
|
|
201
|
+
* Field shapes match the wire, so a client (or the proxy behind it) can
|
|
202
|
+
* forward fields verbatim into `POST /api/v1/checkin`. */
|
|
203
|
+
export interface CheckinReport {
|
|
204
|
+
deviceId: string
|
|
205
|
+
/** Firmware version string. */
|
|
206
|
+
firmware: string
|
|
207
|
+
firmwareHash: string
|
|
208
|
+
/** QuickJS bytecode format version the running engine reads. */
|
|
209
|
+
bytecode: number
|
|
210
|
+
running: RunningBuild
|
|
211
|
+
/** The device-owned name pair: `[rev, name]`, or `[rev]` when never named
|
|
212
|
+
* or cleared. Sent every round so a lost response settles on the next
|
|
213
|
+
* check-in. */
|
|
214
|
+
name: [rev: number, name?: string]
|
|
215
|
+
/** Free bytes on the user partition. Absent when the platform cannot say. */
|
|
216
|
+
free?: number
|
|
217
|
+
/** Why a previous install failed. Present after a `reconcile()` that found
|
|
218
|
+
* one, until a `settle()` marks it delivered. */
|
|
219
|
+
lastInstall?: Diagnostic
|
|
220
|
+
/** The held document's rev to echo; see {@link ConfigState.rev}. */
|
|
221
|
+
configRev?: string
|
|
222
|
+
/** A rolled-back document to report; see {@link ConfigState.error}. */
|
|
223
|
+
configError?: ConfigErrorReport
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
/** What `ota.settle()` took from a completed check-in's response. */
|
|
227
|
+
export interface SettleOutcome {
|
|
228
|
+
/** A validated build offer, for the app's `applyOffer` call: the download
|
|
229
|
+
* is the one piece of the round that stays the app's. Absent when the
|
|
230
|
+
* response carried none. */
|
|
231
|
+
offer?: Offer
|
|
232
|
+
/** What the config delivery did, when the response carried a document.
|
|
233
|
+
* Only `'failed'` and `'invalid'` are worth logging; see {@link ConfigWrite}. */
|
|
234
|
+
config?: ConfigWrite
|
|
235
|
+
/** A name pair was adopted from the response (a clear counts). */
|
|
236
|
+
renamed: boolean
|
|
237
|
+
}
|
|
238
|
+
|
|
200
239
|
declare global {
|
|
201
240
|
/**
|
|
202
241
|
* Merge your app's config type into this interface (next to the schema
|
|
@@ -318,6 +357,37 @@ export interface Ota {
|
|
|
318
357
|
* re-served forever and nobody is told.
|
|
319
358
|
*/
|
|
320
359
|
configState(): ConfigState
|
|
360
|
+
/**
|
|
361
|
+
* The check-in body the device owes its registry, assembled: identity,
|
|
362
|
+
* `running()`, the name pair, free storage, the pending `lastInstall`
|
|
363
|
+
* report, and what `configState()` resolves. One call instead of gathering
|
|
364
|
+
* the fields by hand, and the same facts the built-in client sends.
|
|
365
|
+
*
|
|
366
|
+
* Call `reconcile()` first, on every boot: it is what surfaces the
|
|
367
|
+
* `lastInstall` report this reads (`settle()` marks it delivered).
|
|
368
|
+
*/
|
|
369
|
+
report(): CheckinReport
|
|
370
|
+
/**
|
|
371
|
+
* Take a COMPLETED check-in's response, whole: confirm the running trial
|
|
372
|
+
* and a read config document's trial (exactly `confirm()`), adopt a
|
|
373
|
+
* delivered name pair, store a delivered config document (exactly
|
|
374
|
+
* `applyConfig`, with `trialBoots`), and validate the offer fields (exactly
|
|
375
|
+
* `parseOffer(raw)`, with `allowInsecure`). An empty or null response is
|
|
376
|
+
* the registry's quiet round: nothing to deliver, and the confirm still
|
|
377
|
+
* happens, which is the point of calling. A response that is anything else,
|
|
378
|
+
* a string or a number, never decoded (a captive portal's HTML, a proxy's
|
|
379
|
+
* error page), so it is not a completed round: nothing settles, and the
|
|
380
|
+
* confirm does not run.
|
|
381
|
+
*
|
|
382
|
+
* Never call it on a failed request: a check-in that did not complete
|
|
383
|
+
* proves nothing about the running build, and settling it would keep
|
|
384
|
+
* exactly what rollback exists to catch.
|
|
385
|
+
*
|
|
386
|
+
* What stays the app's: the download (`applyOffer` with the returned
|
|
387
|
+
* offer), the restart after `'staged'`, and reading `ota.config()` in the
|
|
388
|
+
* same cycle so a delivered document's trial can settle.
|
|
389
|
+
*/
|
|
390
|
+
settle(raw: unknown, options?: {trialBoots?: number; allowInsecure?: boolean}): SettleOutcome
|
|
321
391
|
}
|
|
322
392
|
|
|
323
393
|
/** The `mikro/ota` singleton. The runtime value is provided by the on-device
|
|
@@ -398,6 +468,11 @@ export interface WatchOptions extends CheckOptions {
|
|
|
398
468
|
onConfig?(config: RegisteredConfig): void
|
|
399
469
|
}
|
|
400
470
|
|
|
471
|
+
/** `watch()` on a device with no enrollment pair (registry url + update key) in
|
|
472
|
+
* the system store. Permanent for this boot: enrollment is provisioned over
|
|
473
|
+
* the cable by `mikro ota enroll`, and a restart is what picks it up. */
|
|
474
|
+
export type NotEnrolledError = {name: 'NotEnrolled'; message: string}
|
|
475
|
+
|
|
401
476
|
export interface Watcher {
|
|
402
477
|
/** Prevent future rounds and cancel the pending sleep. An in-flight round
|
|
403
478
|
* completes, but a build it stages no longer auto-restarts: it stays armed
|
package/runtime/schema/schema.ts
CHANGED
|
@@ -1,30 +1,52 @@
|
|
|
1
|
+
/* mikro/schema. The constructors, the validator and applyDefaults are native
|
|
2
|
+
* (src/mik_schema.cpp); all this adds is the Result-returning parse(), which
|
|
3
|
+
* is the only part that needs mikro/result.
|
|
4
|
+
*
|
|
5
|
+
* @mikrojs/schema is the same DSL in TypeScript and is what the host
|
|
6
|
+
* runs (the CLI evaluating mikro.config.ts, the registry, vitest). The two are
|
|
7
|
+
* held together by scripts/gen-schema-fixtures.js and
|
|
8
|
+
* test/schema_conformance_test.cpp — change core.ts first, then mik_schema.cpp.
|
|
9
|
+
*
|
|
10
|
+
* validate() is deliberately not re-exported: parse() is the public entry, and
|
|
11
|
+
* that has been true since this module was bytecode. */
|
|
12
|
+
|
|
1
13
|
import {err, ok} from 'mikro/result'
|
|
14
|
+
import {validate} from 'native:mikro/schema'
|
|
2
15
|
|
|
3
16
|
import type {Result} from '../result/types.js'
|
|
4
|
-
import
|
|
17
|
+
import type {Infer, Schema, SchemaError} from './types.js'
|
|
5
18
|
|
|
6
19
|
export type {
|
|
20
|
+
ArrayOptions,
|
|
7
21
|
ArraySchema,
|
|
8
22
|
BooleanSchema,
|
|
9
23
|
DefaultOption,
|
|
24
|
+
DisplayOptions,
|
|
25
|
+
EnumEntry,
|
|
26
|
+
Format,
|
|
10
27
|
Infer,
|
|
11
28
|
InferRead,
|
|
12
29
|
LiteralSchema,
|
|
30
|
+
MaskableOptions,
|
|
31
|
+
NumberOptions,
|
|
13
32
|
NumberSchema,
|
|
14
33
|
ObjectSchema,
|
|
15
34
|
OptionalSchema,
|
|
16
35
|
ScalarOptions,
|
|
17
36
|
Schema,
|
|
37
|
+
StringOptions,
|
|
18
38
|
StringSchema,
|
|
19
39
|
TaggedUnionSchema,
|
|
20
40
|
TupleSchema,
|
|
21
41
|
UnionSchema,
|
|
42
|
+
Unit,
|
|
22
43
|
UnknownSchema,
|
|
23
|
-
} from './
|
|
44
|
+
} from './types.js'
|
|
24
45
|
export {
|
|
25
46
|
applyDefaults,
|
|
26
47
|
array,
|
|
27
48
|
boolean,
|
|
49
|
+
enumOf,
|
|
28
50
|
literal,
|
|
29
51
|
number,
|
|
30
52
|
object,
|
|
@@ -35,7 +57,7 @@ export {
|
|
|
35
57
|
tuple,
|
|
36
58
|
union,
|
|
37
59
|
unknown,
|
|
38
|
-
} from '
|
|
60
|
+
} from 'native:mikro/schema'
|
|
39
61
|
|
|
40
62
|
export function parse<S extends Schema>(schema: S, value: unknown): Result<Infer<S>, SchemaError> {
|
|
41
63
|
const result = validate(schema, value, '')
|