@mikrojs/native 0.20.1 → 0.21.0-next.20260913195055

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.
Files changed (56) hide show
  1. package/CMakeLists.txt +3 -1
  2. package/cmake/mikrojs_bytecode.cmake +1 -1
  3. package/dist/index.d.ts +1 -1
  4. package/dist/index.js +1 -1
  5. package/dist/runtime/result/native-result.node-shim.js.map +1 -1
  6. package/dist/runtime/result/types.d.ts +5 -5
  7. package/dist/runtime/result/types.d.ts.map +1 -1
  8. package/dist/types.d.ts +1 -1
  9. package/dist/types.d.ts.map +1 -1
  10. package/include/mikrojs/mikrojs.h +26 -2
  11. package/include/mikrojs/ota_env.h +8 -6
  12. package/include/mikrojs/ota_policy.h +16 -0
  13. package/include/mikrojs/private.h +13 -0
  14. package/include/mikrojs/utils.h +24 -0
  15. package/package.json +10 -10
  16. package/prebuilds/darwin-arm64/mikrojs.napi.node +0 -0
  17. package/prebuilds/linux-arm64/mikrojs.napi.node +0 -0
  18. package/prebuilds/linux-x64/mikrojs.napi.node +0 -0
  19. package/runtime/gpio/types.ts +116 -0
  20. package/runtime/i2c/types.ts +25 -31
  21. package/runtime/i2s/types.ts +23 -12
  22. package/runtime/internal.d.ts +1 -174
  23. package/runtime/kv/shared.ts +13 -11
  24. package/runtime/neopixel/types.ts +24 -6
  25. package/runtime/observable/native-observable.node-shim.ts +73 -37
  26. package/runtime/observable/native-operators.node-shim.ts +417 -0
  27. package/runtime/observable/observable.ts +76 -1
  28. package/runtime/observable/operators.ts +156 -89
  29. package/runtime/observable/types.ts +61 -6
  30. package/runtime/pwm/types.ts +31 -11
  31. package/runtime/result/native-result.node-shim.ts +1 -1
  32. package/runtime/result/types.ts +5 -5
  33. package/runtime/sleep/types.ts +10 -8
  34. package/runtime/spi/types.ts +16 -14
  35. package/runtime/uart/types.ts +27 -15
  36. package/src/gpio_claim.cpp +63 -0
  37. package/src/mik_abort.cpp +1 -2
  38. package/src/mik_console.cpp +192 -115
  39. package/src/mik_http_client.cpp +3 -14
  40. package/src/mik_inspect.cpp +86 -9
  41. package/src/mik_observable.cpp +1028 -80
  42. package/src/mik_ota_client.cpp +5 -2
  43. package/src/mik_ota_policy.cpp +65 -18
  44. package/src/mik_result.cpp +10 -9
  45. package/src/mikrojs.cpp +26 -13
  46. package/src/modules.cpp +17 -6
  47. package/src/timers.cpp +6 -2
  48. package/src/utils.cpp +106 -0
  49. package/runtime/i2c/i2c.ts +0 -35
  50. package/runtime/i2s/i2s.ts +0 -46
  51. package/runtime/neopixel/neopixel.ts +0 -38
  52. package/runtime/pin/pin.ts +0 -51
  53. package/runtime/pin/types.ts +0 -49
  54. package/runtime/pwm/pwm.ts +0 -32
  55. package/runtime/spi/spi.ts +0 -31
  56. package/runtime/uart/uart.ts +0 -52
package/CMakeLists.txt CHANGED
@@ -62,6 +62,7 @@ set(MIKROJS_CORE_SOURCES
62
62
  src/mik_ota_client.cpp
63
63
  src/mik_sys_codec.cpp
64
64
  src/mik_watchdog.cpp
65
+ src/gpio_claim.cpp
65
66
  )
66
67
 
67
68
  add_library(mikrojs STATIC
@@ -92,7 +93,7 @@ endif()
92
93
  include(cmake/mikrojs_bytecode.cmake)
93
94
  mikrojs_generate_bytecode(
94
95
  RUNTIME_DIR "${CMAKE_CURRENT_SOURCE_DIR}/runtime"
95
- 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 watchdog
96
+ MODULES abort cbor env result schema fs kv/nvs kv/rtc kv/shared module observable observable/lazy ota ota/client ota/config reader sleep sntp stdio stream sys test udp watchdog
96
97
  MODULE_PREFIX "mikro"
97
98
  SYMBOL_PREFIX "mikro"
98
99
  TARGET gen_bytecode
@@ -224,6 +225,7 @@ if(BUILD_TESTING)
224
225
  test/schema_conformance_test.cpp
225
226
  test/sys_codec_test.cpp
226
227
  test/watchdog_test.cpp
228
+ test/gpio_claim_test.cpp
227
229
  )
228
230
 
229
231
  # ── Check-in wire fixtures ───────────────────────────────────────
@@ -7,7 +7,7 @@
7
7
  # mikrojs_generate_bytecode(
8
8
  # RUNTIME_DIR <path> # Directory containing <mod>/<mod>.ts files
9
9
  # MODULES <mod1> <mod2> # Module names to compile
10
- # MODULE_PREFIX <prefix> # Module name prefix (e.g. "mikro" -> "mikro/pin")
10
+ # MODULE_PREFIX <prefix> # Module name prefix (e.g. "mikro" -> "mikro/gpio")
11
11
  # SYMBOL_PREFIX <prefix> # C symbol prefix (e.g. "mikrojs" -> "mikrojs_pin_bytecode")
12
12
  # TARGET <name> # Custom target name (default: gen_bytecode)
13
13
  # WORKING_DIRECTORY <dir> # Working dir for esbuild (default: CMAKE_CURRENT_SOURCE_DIR)
package/dist/index.d.ts CHANGED
@@ -32,7 +32,7 @@ export declare class MikroRuntime {
32
32
  * Useful for stripping TypeScript types from .ts files. */
33
33
  setPreprocessor(fn: (filename: string, source: string) => string | undefined): void;
34
34
  /** Set a synchronous RPC handler called from QuickJS via native:mikro/host.call().
35
- * The handler receives a method name (e.g. 'pin.pinMode') and JSON-encoded args,
35
+ * The handler receives a method name (e.g. 'http.fetch') and JSON-encoded args,
36
36
  * and must return a JSON-encoded result string (or a Promise of one for async). */
37
37
  setRpcHandler(handler: (method: string, argsJson: string) => string | Promise<string>): void;
38
38
  /** Enable per-module memory profiling. Must be called before any module loads
package/dist/index.js CHANGED
@@ -79,7 +79,7 @@ export class MikroRuntime {
79
79
  this.native.setPreprocessor(fn);
80
80
  }
81
81
  /** Set a synchronous RPC handler called from QuickJS via native:mikro/host.call().
82
- * The handler receives a method name (e.g. 'pin.pinMode') and JSON-encoded args,
82
+ * The handler receives a method name (e.g. 'http.fetch') and JSON-encoded args,
83
83
  * and must return a JSON-encoded result string (or a Promise of one for async). */
84
84
  setRpcHandler(handler) {
85
85
  this.native.setRpcHandler(handler);
@@ -1 +1 @@
1
- {"version":3,"file":"native-result.node-shim.js","sourceRoot":"","sources":["../../../runtime/result/native-result.node-shim.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,uEAAuE;AAEvE,MAAM,KAAK,GAAG;IACZ,GAAG,CAAwD,EAA2B;QACpF,OAAO,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;IAC5C,CAAC;IACD,MAAM,CAAwD,EAA2B;QACvF,OAAO,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAA;IAC7C,CAAC;IACD,OAAO,CAAwD,EAA2B;QACxF,OAAO,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;IACxC,CAAC;IACD,KAAK,CAEH,QAAqE;QAErE,OAAO,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;IACrE,CAAC;IACD,SAAS,CAAwD,YAAqB;QACpF,OAAO,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,YAAY,CAAA;IAC5C,CAAC;IACD,OAAO,CAAwD,OAAe;QAC5E,IAAI,IAAI,CAAC,EAAE;YAAE,OAAO,IAAI,CAAC,KAAK,CAAA;QAC9B,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,OAAO,CAAC,CAAA;QAChC,KAAK,CAAC,IAAI,GAAG,YAAY,CACxB;QAAC,KAAmC,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAA;QACxD,MAAM,KAAK,CAAA;IACb,CAAC;CACF,CAAA;AAED,MAAM,UAAU,EAAE,CAAC,KAAe;IAChC,MAAM,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;IAC9B,CAAC,CAAC,EAAE,GAAG,IAAI,CAAA;IACX,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC;QAAE,CAAC,CAAC,KAAK,GAAG,KAAK,CAAA;IACzC,OAAO,CAAC,CAAA;AACV,CAAC;AAED,MAAM,UAAU,GAAG,CAAC,KAAc;IAChC,MAAM,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;IAC9B,CAAC,CAAC,EAAE,GAAG,KAAK,CAAA;IACZ,CAAC,CAAC,KAAK,GAAG,KAAK,CAAA;IACf,OAAO,CAAC,CAAA;AACV,CAAC"}
1
+ {"version":3,"file":"native-result.node-shim.js","sourceRoot":"","sources":["../../../runtime/result/native-result.node-shim.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,uEAAuE;AAEvE,MAAM,KAAK,GAAG;IACZ,GAAG,CAAwD,EAA2B;QACpF,OAAO,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;IAC5C,CAAC;IACD,MAAM,CAAwD,EAA2B;QACvF,OAAO,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAA;IAC7C,CAAC;IACD,OAAO,CAAwD,EAA2B;QACxF,OAAO,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;IACxC,CAAC;IACD,KAAK,CAEH,QAAqE;QAErE,OAAO,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;IACrE,CAAC;IACD,SAAS,CAAwD,YAAqB;QACpF,OAAO,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,YAAY,CAAA;IAC5C,CAAC;IACD,OAAO,CAAwD,OAAgB;QAC7E,IAAI,IAAI,CAAC,EAAE;YAAE,OAAO,IAAI,CAAC,KAAK,CAAA;QAC9B,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,OAAO,CAAC,CAAA;QAChC,KAAK,CAAC,IAAI,GAAG,YAAY,CACxB;QAAC,KAAmC,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAA;QACxD,MAAM,KAAK,CAAA;IACb,CAAC;CACF,CAAA;AAED,MAAM,UAAU,EAAE,CAAC,KAAe;IAChC,MAAM,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;IAC9B,CAAC,CAAC,EAAE,GAAG,IAAI,CAAA;IACX,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC;QAAE,CAAC,CAAC,KAAK,GAAG,KAAK,CAAA;IACzC,OAAO,CAAC,CAAA;AACV,CAAC;AAED,MAAM,UAAU,GAAG,CAAC,KAAc;IAChC,MAAM,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;IAC9B,CAAC,CAAC,EAAE,GAAG,KAAK,CAAA;IACZ,CAAC,CAAC,KAAK,GAAG,KAAK,CAAA;IACf,OAAO,CAAC,CAAA;AACV,CAAC"}
@@ -1,5 +1,5 @@
1
1
  export declare class PanicError extends Error {
2
- constructor(message: string, options?: {
2
+ constructor(message?: string, options?: {
3
3
  cause?: unknown;
4
4
  });
5
5
  }
@@ -16,8 +16,8 @@ export interface OkResult<T> {
16
16
  }): A;
17
17
  /** Get the value, or return the default if this is an Err. */
18
18
  orDefault<D>(defaultValue: D): T | D;
19
- /** Get the value, or panic with the given message if this is an Err. */
20
- orPanic(message: string): T;
19
+ /** Get the value, or panic if this is an Err. The error is included as cause. */
20
+ orPanic(message?: string): T;
21
21
  }
22
22
  export interface ErrResult<E> {
23
23
  readonly ok: false;
@@ -32,8 +32,8 @@ export interface ErrResult<E> {
32
32
  }): B;
33
33
  /** Return the default value since this is an Err. */
34
34
  orDefault<D>(defaultValue: D): D;
35
- /** Always panics with the given message since this is an Err. The error is included as cause. */
36
- orPanic(message: string): never;
35
+ /** Always panics since this is an Err. The error is included as cause. */
36
+ orPanic(message?: string): never;
37
37
  }
38
38
  export type Result<T, E> = OkResult<T> | ErrResult<E>;
39
39
  export declare function ok(): OkResult<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../runtime/result/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../runtime/result/types.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,OAAO,OAAO,UAAW,SAAQ,KAAK;gBAC/B,OAAO,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAC,KAAK,CAAC,EAAE,OAAO,CAAA;KAAC;CAC1D;AAED,MAAM,WAAW,QAAQ,CAAC,CAAC;IACzB,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAA;IACjB,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAA;IACjB,QAAQ,CAAC,KAAK,CAAC,EAAE,KAAK,CAAA;IACtB,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAA;IACxC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAA;IAC/C,OAAO,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;IAC3D,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,QAAQ,EAAE;QAAC,EAAE,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,CAAC;QAAC,GAAG,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,CAAC,CAAA;KAAC,GAAG,CAAC,CAAA;IACzE,8DAA8D;IAC9D,SAAS,CAAC,CAAC,EAAE,YAAY,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;IACpC,iFAAiF;IACjF,OAAO,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,CAAC,CAAA;CAC7B;AAED,MAAM,WAAW,SAAS,CAAC,CAAC;IAC1B,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAA;IAClB,QAAQ,CAAC,KAAK,CAAC,EAAE,KAAK,CAAA;IACtB,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAA;IACjB,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,CAAA;IAC7C,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,CAAA;IAC5C,OAAO,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,CAAA;IAC/D,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,QAAQ,EAAE;QAAC,EAAE,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,CAAC,CAAC;QAAC,GAAG,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,CAAA;KAAC,GAAG,CAAC,CAAA;IACzE,qDAAqD;IACrD,SAAS,CAAC,CAAC,EAAE,YAAY,EAAE,CAAC,GAAG,CAAC,CAAA;IAChC,0EAA0E;IAC1E,OAAO,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,KAAK,CAAA;CACjC;AAED,MAAM,MAAM,MAAM,CAAC,CAAC,EAAE,CAAC,IAAI,QAAQ,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,CAAA;AAErD,MAAM,CAAC,OAAO,UAAU,EAAE,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAA;AAC5C,MAAM,CAAC,OAAO,UAAU,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAA;AAEpD,MAAM,CAAC,OAAO,UAAU,GAAG,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,CAAA;AAEtD,MAAM,CAAC,OAAO,UAAU,UAAU,CAAC,CAAC,SAAS;IAAC,IAAI,EAAE,MAAM,CAAA;CAAC,EAAE,CAAC,EAC5D,KAAK,EAAE,CAAC,EACR,QAAQ,EAAE;KAAE,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC,EAAE;QAAC,IAAI,EAAE,CAAC,CAAA;KAAC,CAAC,KAAK,CAAC;CAAC,GAChE,CAAC,CAAA;AAEJ,4DAA4D;AAC5D,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CACxB"}
package/dist/types.d.ts CHANGED
@@ -6,7 +6,7 @@ export interface MikroRuntimeOptions {
6
6
  fsLimit?: number;
7
7
  fsReadMax?: number;
8
8
  env?: Record<string, string>;
9
- /** Virtual module sources to register, keyed by module name (e.g. 'native:mikro/pin'). */
9
+ /** Virtual module sources to register, keyed by module name (e.g. 'native:mikro/sleep'). */
10
10
  modules?: Record<string, string>;
11
11
  }
12
12
  export interface HostMessage {
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../addon/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC5B,0FAA0F;IAC1F,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CACjC;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;CACb;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAA;IACZ,UAAU,EAAE,MAAM,CAAA;IAClB,KAAK,EAAE,MAAM,CAAA;CACd;AAED,MAAM,WAAW,kBAAkB;IACjC,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,GAAG,IAAI,CAAA;IACpD,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1D,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAA;IAC5C,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;IACrB,QAAQ,IAAI,MAAM,CAAA;IAClB,IAAI,IAAI,IAAI,CAAA;IACZ,OAAO,IAAI,IAAI,CAAA;IACf,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;IACxD,aAAa,IAAI,WAAW,EAAE,CAAA;IAC9B,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;IAC7C,eAAe,CAAC,EAAE,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,GAAG,IAAI,CAAA;IACnF,aAAa,CAAC,OAAO,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,GAAG,IAAI,CAAA;IAC5F,eAAe,IAAI,IAAI,CAAA;IACvB,UAAU,IAAI,YAAY,EAAE,CAAA;IAC5B,kBAAkB,IAAI,MAAM,CAAA;IAC5B,WAAW,IAAI;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAC,CAAA;IACpD,EAAE,IAAI,IAAI,CAAA;IACV,iBAAiB,IAAI,IAAI,CAAA;IACzB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAA;CAC9D;AAED,MAAM,WAAW,cAAc;IAC7B,YAAY,EAAE,KAAK,OAAO,CAAC,EAAE,mBAAmB,KAAK,kBAAkB,CAAA;IACvE,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAA;IACjC,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,CAAA;IACjF,UAAU,CACR,IAAI,EAAE,OAAO,EACb,OAAO,CAAC,EAAE;QAAC,aAAa,CAAC,EAAE,OAAO,CAAA;KAAC,GAClC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAC,GAAG,SAAS,CAAA;CAC7D"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../addon/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC5B,4FAA4F;IAC5F,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CACjC;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;CACb;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAA;IACZ,UAAU,EAAE,MAAM,CAAA;IAClB,KAAK,EAAE,MAAM,CAAA;CACd;AAED,MAAM,WAAW,kBAAkB;IACjC,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,GAAG,IAAI,CAAA;IACpD,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1D,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAA;IAC5C,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;IACrB,QAAQ,IAAI,MAAM,CAAA;IAClB,IAAI,IAAI,IAAI,CAAA;IACZ,OAAO,IAAI,IAAI,CAAA;IACf,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;IACxD,aAAa,IAAI,WAAW,EAAE,CAAA;IAC9B,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;IAC7C,eAAe,CAAC,EAAE,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,GAAG,IAAI,CAAA;IACnF,aAAa,CAAC,OAAO,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,GAAG,IAAI,CAAA;IAC5F,eAAe,IAAI,IAAI,CAAA;IACvB,UAAU,IAAI,YAAY,EAAE,CAAA;IAC5B,kBAAkB,IAAI,MAAM,CAAA;IAC5B,WAAW,IAAI;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAC,CAAA;IACpD,EAAE,IAAI,IAAI,CAAA;IACV,iBAAiB,IAAI,IAAI,CAAA;IACzB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAA;CAC9D;AAED,MAAM,WAAW,cAAc;IAC7B,YAAY,EAAE,KAAK,OAAO,CAAC,EAAE,mBAAmB,KAAK,kBAAkB,CAAA;IACvE,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAA;IACjC,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,CAAA;IACjF,UAAU,CACR,IAAI,EAAE,OAAO,EACb,OAAO,CAAC,EAAE;QAAC,aAAa,CAAC,EAAE,OAAO,CAAA;KAAC,GAClC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAC,GAAG,SAAS,CAAA;CAC7D"}
@@ -93,7 +93,9 @@ void MIK_FreeRuntime(MIKRuntime* mik_rt);
93
93
  * -EINVAL runtime or entry is null/empty
94
94
  * -ENOENT entry (and its .bjs variant) not on disk
95
95
  * -EFAULT module evaluation threw
96
- * Emits no diagnostic output callers decide whether and how to log. */
96
+ * A synchronous throw (a missing import, a syntax error) is reported like an
97
+ * uncaught exception found by MIK_Loop: error handler, dump, MIK_Stop. A
98
+ * rejected eval promise is reported by the next loop's rejection flush. */
97
99
  int MIK_RunEntry(MIKRuntime* mik_rt, const char* entry);
98
100
 
99
101
  /* MIK_RunEntry variant that, on -EFAULT, copies the thrown exception's
@@ -265,7 +267,7 @@ int MIK_ReserveModuleSlot(void);
265
267
  typedef JSModuleDef* (*MIKModuleInitFn)(JSContext* ctx);
266
268
 
267
269
  typedef struct mik_module_desc_t {
268
- const char* name; /* module name, e.g. "native:mikro/pin" */
270
+ const char* name; /* module name, e.g. "native:mikro/sleep" */
269
271
  MIKModuleInitFn init; /* called on first import; returns the JSModuleDef */
270
272
  MIKLoopConsumeFn consume; /* event loop consumer (nullable) */
271
273
  MIKLoopDestroyFn destroy; /* cleanup on shutdown (nullable) */
@@ -290,6 +292,7 @@ extern mik_module_desc_t* mik__module_registry_head;
290
292
  #define MIK__REQUIRE_NATIVE_NS(name_) MIK__REQUIRE_PREFIX(name_, "native:" MIK_PACKAGE_NAME "/")
291
293
  #define MIK__REQUIRE_BUILTIN_NS(name_) MIK__REQUIRE_PREFIX(name_, MIK_PACKAGE_NAME "/")
292
294
  #else
295
+ #define MIK__REQUIRE_PREFIX(name_, prefix_) static_assert(true, "")
293
296
  #define MIK__REQUIRE_NATIVE_NS(name_) static_assert(true, "")
294
297
  #define MIK__REQUIRE_BUILTIN_NS(name_) static_assert(true, "")
295
298
  #endif
@@ -298,6 +301,14 @@ extern mik_module_desc_t* mik__module_registry_head;
298
301
  * via -u flags (static symbols in static libraries get stripped). */
299
302
  #define MIK_REGISTER_MODULE(id, name_, init_, consume_, destroy_) \
300
303
  MIK__REQUIRE_NATIVE_NS(name_); \
304
+ MIK__MODULE_DESC(id, name_, init_, consume_, destroy_)
305
+ /* A platform C module under its public mikro/ name (mikro/gpio on ESP-IDF), for
306
+ * modules with no bytecode layer. Core runtime only. */
307
+ #define MIK__REGISTER_PUBLIC_MODULE(id, name_, init_, consume_, destroy_) \
308
+ MIK__REQUIRE_BUILTIN_NS(name_); \
309
+ MIK__REQUIRE_PREFIX(name_, "mikro/"); \
310
+ MIK__MODULE_DESC(id, name_, init_, consume_, destroy_)
311
+ #define MIK__MODULE_DESC(id, name_, init_, consume_, destroy_) \
301
312
  mik_module_desc_t mik__mod_desc_##id = { \
302
313
  name_, init_, consume_, destroy_, NULL}; \
303
314
  static void __attribute__((constructor)) mik__register_mod_##id(void) { \
@@ -437,6 +448,19 @@ void MIK_ProtocolServeLoop(void);
437
448
  * and call MIK_ProtocolServeLoop() again. */
438
449
  void MIK_ProtocolExit(void);
439
450
 
451
+ /* Exclusive GPIO claims, shared by every module and driver that configures a
452
+ * GPIO pin. MIK_ClaimGpio returns false when the GPIO is already held. `owner`
453
+ * must be a non-null static string, such as a class name ("Pwm"); it is
454
+ * reported to the app in GpioInUse errors, and a NULL owner claims and
455
+ * releases nothing. Numbers outside 0..63, such as -1 for an unused bus role,
456
+ * are not tracked: the claim succeeds and release does nothing. Release only
457
+ * frees a GPIO held under the same owner string, so a stale release cannot
458
+ * free another module's claim (two instances of one class share an owner). */
459
+ bool MIK_ClaimGpio(int gpio, const char* owner);
460
+ void MIK_ReleaseGpio(int gpio, const char* owner);
461
+ /* The current owner of `gpio`, or NULL when it is free. */
462
+ const char* MIK_GpioOwner(int gpio);
463
+
440
464
  #ifdef __cplusplus
441
465
  }
442
466
  #endif
@@ -146,13 +146,15 @@ struct MIKOtaEnv {
146
146
  MIKOtaKvStatus (*kv_get_blob)(void* opaque, const char* key, uint8_t* out_buf,
147
147
  size_t* inout_len);
148
148
  bool (*kv_set_blob)(void* opaque, const char* key, const uint8_t* data, size_t len);
149
- /* NOTE: the string and integer getters are still two-valued. Their callers
150
- * (the retry-budget store) read a failure as absence, which hands the budget
151
- * back a boot early. Same class of bug as the blob case above; worth the same
152
- * treatment when the policy's error handling is revisited. */
153
- bool (*kv_get_str)(void* opaque, const char* key, char* out_buf, size_t max_len);
149
+ /* Same contract as kv_get_blob: absent and failed are different answers.
150
+ * The retry budget lives behind these two, and every fallback a caller
151
+ * would pick for "absent" grants the device more than it has earned: an
152
+ * unspent budget, a url that looks new, no bad build on record. Stored
153
+ * bytes that do not decode report MIK_OTA_KV_ERROR too: garbage is not
154
+ * absence either. */
155
+ MIKOtaKvStatus (*kv_get_str)(void* opaque, const char* key, char* out_buf, size_t max_len);
154
156
  bool (*kv_set_str)(void* opaque, const char* key, const char* val);
155
- bool (*kv_get_i32)(void* opaque, const char* key, int32_t* out_val);
157
+ MIKOtaKvStatus (*kv_get_i32)(void* opaque, const char* key, int32_t* out_val);
156
158
  bool (*kv_set_i32)(void* opaque, const char* key, int32_t val);
157
159
  bool (*kv_remove)(void* opaque, const char* key);
158
160
 
@@ -92,8 +92,24 @@ public:
92
92
  void SetDecline(const MIKOtaDeclineRecord& record);
93
93
  void ClearDecline();
94
94
 
95
+ /* True once any read on this store has failed (as opposed to finding the
96
+ * key absent). Each getter has to answer with something, and the honest
97
+ * fallback for an unreadable key is the same everywhere: nothing stored.
98
+ * That reads as an unspent budget, a url that never matched, no abandoned
99
+ * build, every one of them more permission than the device has earned.
100
+ * Callers that are about to widen what the device may do consult this
101
+ * instead, and do nothing on an unreadable store; the next boot re-reads
102
+ * the real values. Latches for the life of one policy operation, which is
103
+ * how long a store lives. */
104
+ bool ReadFailed() const { return read_failed_; }
105
+
95
106
  private:
107
+ /* Runs every read through one place so the latch cannot be forgotten. */
108
+ MIKOtaKvStatus ReadStr(const char* key, char* out, size_t max_len) const;
109
+ MIKOtaKvStatus ReadI32(const char* key, int32_t* out) const;
110
+
96
111
  const MIKOtaEnv* env_;
112
+ mutable bool read_failed_ = false;
97
113
  };
98
114
 
99
115
  /* Validate untrusted offer fields into a well-formed MIKOtaOffer */
@@ -310,6 +310,19 @@ JSModuleDef* mik__udp_init(JSContext* ctx);
310
310
  /* Observable module (mik_observable.cpp) */
311
311
  JSModuleDef* mik__observable_init(JSContext* ctx);
312
312
  void mik__observable_dispatch_free(struct MIKRuntime* mik_rt);
313
+ /* mikro/observable/operators, loaded lazily through the C-module table. */
314
+ JSModuleDef* mik__observable_operators_load(JSContext* ctx);
315
+ /* Builds the same {observable, next, complete} triple as Observable.withEmitters(),
316
+ * for C modules that expose event streams. Returns -1 with an exception pending;
317
+ * on success the caller owns all three values. */
318
+ int mik__observable_multicast_new(JSContext* ctx, JSValue* observable, JSValue* next,
319
+ JSValue* complete);
320
+
321
+ /* GPIO claims (gpio_claim.cpp). Claims every GPIO for `owner`; on the first one
322
+ * already held, releases those claimed so far and returns an err Result
323
+ * carrying GpioInUse {name, owner, message}. Returns JS_UNDEFINED on success. */
324
+ JSValue mik__claim_gpios(JSContext* ctx, const int* gpios, int count, const char* owner);
325
+ void mik__release_gpios(const int* gpios, int count, const char* owner);
313
326
 
314
327
  /* Watchdog (mik_watchdog.cpp). */
315
328
  /* Start a fresh blocking budget: top of each MIK_Loop pass, eval entry
@@ -73,6 +73,30 @@ void mik_call_handler(JSContext* ctx, JSValue func, int argc, JSValue* argv);
73
73
  * tag on the device and silent by default, so lines that precede a reboot
74
74
  * (watchdog lines, panic actions) go through here instead. */
75
75
  void mik__print_error_line(const char* fmt, ...) __attribute__((format(printf, 1, 2)));
76
+ /* The Symbol.asyncIterator atom; quickjs.h does not expose the well-known
77
+ * symbols. The caller frees it with JS_FreeAtom. */
78
+ JSAtom mik__async_iterator_atom(JSContext* ctx);
79
+ /* Prints "<owner> <id>: <call> after end(); the handle no longer owns the <resource>"
80
+ * once per handle; `warned` is the handle's flag. */
81
+ void mik__warn_after_end(bool* warned, const char* owner, int id, const char* call,
82
+ const char* resource);
83
+
84
+ /* Argument readers for handle factories and methods. Each returns -1 with a
85
+ * TypeError pending: an integer rejects NaN and fractions (a number accepts
86
+ * both), a missing optional value leaves *out unchanged, and options may be
87
+ * undefined unless required. */
88
+ int mik__to_int_arg(JSContext* ctx, JSValueConst v, const char* name, int32_t* out);
89
+ int mik__to_number_arg(JSContext* ctx, JSValueConst v, const char* name, double* out);
90
+ /* Reads a Uint8Array (or ArrayBuffer) without copying; returns nullptr with a
91
+ * TypeError pending. */
92
+ uint8_t* mik__bytes_arg(JSContext* ctx, JSValueConst v, const char* name, size_t* len);
93
+ int mik__options_arg(JSContext* ctx, int argc, JSValueConst* argv, int index, bool required,
94
+ JSValueConst* out);
95
+ int mik__int_option(JSContext* ctx, JSValueConst options, const char* name, bool required,
96
+ int32_t* out);
97
+ int mik__number_option(JSContext* ctx, JSValueConst options, const char* name, bool required,
98
+ double* out);
99
+ int mik__bool_option(JSContext* ctx, JSValueConst options, const char* name, bool* out);
76
100
  void mik_dump_error(JSContext* ctx);
77
101
  void mik_dump_error1(JSContext* ctx, JSValue exception_val);
78
102
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mikrojs/native",
3
- "version": "0.20.1",
3
+ "version": "0.21.0-next.20260913195055",
4
4
  "description": "Mikro.js C++ runtime library and Node.js native addon",
5
5
  "keywords": [
6
6
  "esp32",
@@ -65,7 +65,7 @@
65
65
  "./runtime/observable/operators": "./runtime/observable/operators.ts",
66
66
  "./runtime/observable/types": "./runtime/observable/types.ts",
67
67
  "./runtime/ota/types": "./runtime/ota/types.ts",
68
- "./runtime/pin/types": "./runtime/pin/types.ts",
68
+ "./runtime/gpio/types": "./runtime/gpio/types.ts",
69
69
  "./runtime/pwm/types": "./runtime/pwm/types.ts",
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",
@@ -84,18 +84,18 @@
84
84
  "./runtime/wifi/types": "./runtime/wifi/types.ts"
85
85
  },
86
86
  "dependencies": {
87
+ "@mikrojs/quickjs": "0.21.0-next.20260913195055+2dfdbd6",
87
88
  "cmake-js": "^8.0.0",
88
- "node-addon-api": "^8.7.0",
89
- "node-gyp-build": "^4.8.4",
90
- "@mikrojs/quickjs": "0.20.1"
89
+ "node-addon-api": "^8.9.2",
90
+ "node-gyp-build": "^4.8.4"
91
91
  },
92
92
  "devDependencies": {
93
- "@swc/core": "^1.15.30",
93
+ "@mikrojs/registry": "0.21.0-next.20260913195055+2dfdbd6",
94
+ "@mikrojs/schema": "0.21.0-next.20260913195055+2dfdbd6",
95
+ "@swc/core": "^1.16.2",
94
96
  "@types/node": "^24.12.2",
95
- "esbuild": "^0.28.0",
96
- "terser": "^5.46.2",
97
- "@mikrojs/registry": "0.20.1",
98
- "@mikrojs/schema": "0.20.1"
97
+ "esbuild": "^0.28.2",
98
+ "terser": "^5.51.2"
99
99
  },
100
100
  "engines": {
101
101
  "node": ">=24.0.0"
@@ -0,0 +1,116 @@
1
+ /* mikro/gpio, declared here and implemented in C (mik_gpio.cpp). Each handle
2
+ * type has a factory of the same name that claims the GPIO pin, configures it
3
+ * and returns a Result. A GPIO pin has one owner at a time across every module. */
4
+
5
+ import type {Observable} from '../observable/types.js'
6
+ import type {Result} from '../result/types.js'
7
+
8
+ /**
9
+ * ADC attenuation setting, controls the measurable voltage range.
10
+ * - `'0db'`: 0 to 750 mV
11
+ * - `'2.5db'`: 0 to 1050 mV
12
+ * - `'6db'`: 0 to 1300 mV
13
+ * - `'11db'`: 0 to 2500 mV (default)
14
+ */
15
+ export type Attenuation = '0db' | '2.5db' | '6db' | '11db'
16
+
17
+ /** The electrical level of a pin: 0 is low, 1 is high. */
18
+ export type Level = 0 | 1
19
+
20
+ export interface DigitalOutOptions {
21
+ /** Level applied before the pin becomes an output. Defaults to `0`. */
22
+ initial?: Level
23
+ }
24
+
25
+ export interface DigitalInOptions {
26
+ /** Internal pull resistor. Defaults to `'none'`. Input-only GPIOs (ESP32 GPIO 34 to 39)
27
+ * have none, so `'up'` or `'down'` there returns `InvalidGpio`. */
28
+ pull?: 'up' | 'down' | 'none'
29
+ }
30
+
31
+ export interface AnalogInOptions {
32
+ /** ADC attenuation. Defaults to `'11db'`. */
33
+ attenuation?: Attenuation
34
+ }
35
+
36
+ /** The GPIO pin is held by another handle, peripheral or the console. */
37
+ export type GpioInUse = {name: 'GpioInUse'; owner: string; message: string}
38
+
39
+ export type GpioError =
40
+ | GpioInUse
41
+ | {name: 'InvalidGpio'; message: string}
42
+ | {name: 'ConfigFailed'; message: string}
43
+ | {name: 'ReadFailed'; message: string}
44
+ | {name: 'CalibrationUnavailable'}
45
+
46
+ /**
47
+ * @public
48
+ */
49
+ export interface GpioPin {
50
+ /** The GPIO number. */
51
+ readonly gpio: number
52
+ /** Releases the GPIO pin. Calling it again does nothing. Afterwards writes do nothing and reads
53
+ * still read the pin; the first such call prints a warning. */
54
+ end(): void
55
+ }
56
+
57
+ /**
58
+ * @public
59
+ */
60
+ export interface DigitalOut extends GpioPin {
61
+ /** Drives the pin low (0) or high (1). Does nothing after `end()`. */
62
+ write(level: Level): void
63
+ }
64
+
65
+ /**
66
+ * @public
67
+ */
68
+ export interface DigitalIn extends GpioPin {
69
+ /** The pin's current level. Still reads the pin after `end()`. */
70
+ read(): Level
71
+ /**
72
+ * Level changes. Edges within one event loop pass are combined, so
73
+ * each value differs from the previous one. Filter bounces with
74
+ * `debounceTime` followed by `distinctUntilChanged()`, since a short bounce
75
+ * can return to the level it started from. Reading this keeps the handle
76
+ * alive until `end()`, which completes the stream.
77
+ */
78
+ readonly onChange: Observable<Level>
79
+ }
80
+
81
+ /**
82
+ * @public
83
+ */
84
+ export interface AnalogIn extends GpioPin {
85
+ /** Raw 12-bit reading, 0 to 4095. Still reads the pin after `end()`. */
86
+ read(): Result<number, GpioError>
87
+ /** Calibrated reading in millivolts. */
88
+ readMillivolts(): Result<number, GpioError>
89
+ }
90
+
91
+ /**
92
+ * Claims a GPIO pin as a digital output.
93
+ * @public
94
+ */
95
+ export declare function DigitalOut(
96
+ gpio: number,
97
+ options?: DigitalOutOptions,
98
+ ): Result<DigitalOut, GpioError>
99
+
100
+ /**
101
+ * Claims a GPIO pin as a digital input.
102
+ * @public
103
+ */
104
+ export declare function DigitalIn(
105
+ gpio: number,
106
+ options?: DigitalInOptions,
107
+ ): Result<DigitalIn, GpioError>
108
+
109
+ /**
110
+ * Claims a GPIO pin as an analog input on ADC1.
111
+ * @public
112
+ */
113
+ export declare function AnalogIn(
114
+ gpio: number,
115
+ options?: AnalogInOptions,
116
+ ): Result<AnalogIn, GpioError>
@@ -1,55 +1,49 @@
1
- import type {Result} from '../result/types.js'
1
+ /* mikro/i2c, declared here and implemented in C (mik_i2c.cpp). */
2
2
 
3
- /**
4
- * @public
5
- */
6
- export interface I2cBaseOptions {
7
- freq?: number
8
- timeout?: number
9
- }
3
+ import type {GpioInUse} from '../gpio/types.js'
4
+ import type {Result} from '../result/types.js'
10
5
 
11
6
  /**
12
7
  * @public
13
8
  */
14
- export interface I2cOptionsWithPins extends I2cBaseOptions {
9
+ export interface I2cOptions {
15
10
  sda: number
16
11
  scl: number
12
+ /** Clock frequency in Hz. Defaults to 100000. */
13
+ freq?: number
14
+ /** Timeout per operation in ms. Defaults to 100. */
15
+ timeout?: number
17
16
  }
18
17
 
19
- /**
20
- * @public
21
- */
22
- export type I2cOptions = I2cBaseOptions | I2cOptionsWithPins
23
-
24
18
  export type I2cError =
19
+ | GpioInUse
20
+ | {name: 'InvalidGpio'; message: string}
21
+ | {name: 'InvalidParam'; message: string}
25
22
  | {name: 'BusInitFailed'; message: string}
26
- | {name: 'BusDeinitFailed'; message: string}
27
- | {name: 'NotStarted'}
28
- | {name: 'MissingPins'}
29
23
  | {name: 'AddDeviceFailed'; message: string}
30
24
  | {name: 'WriteFailed'; message: string}
31
25
  | {name: 'WriteTooLarge'}
32
26
  | {name: 'ReadFailed'; message: string}
33
27
 
34
- /**
35
- * @public
36
- */
37
- export declare const I2c: {
38
- prototype: I2c
39
- new (busNo: 0 | 1, options?: I2cOptions): I2c
40
- }
41
-
42
28
  /**
43
29
  * @public
44
30
  */
45
31
  export interface I2c {
46
- begin(): Result<void, I2cError>
47
-
48
- end(): Result<void, I2cError>
49
-
32
+ /** Reads `bytes` bytes from the device at `address`. */
50
33
  read(address: number, bytes: number): Result<Uint8Array, I2cError>
51
-
34
+ /** Writes `data` to the device at `address`. Pass `stop: false` to follow with a read that
35
+ * uses a repeated start. */
52
36
  write(address: number, data: Uint8Array, stop?: boolean): Result<void, I2cError>
53
-
37
+ /** Addresses that answered a probe. */
54
38
  scan(): Result<Uint8Array, I2cError>
39
+ /** Deletes the bus and releases its GPIO pins. Calling it again does nothing. Afterwards
40
+ * `write()` does nothing and reads return an empty array; the first such call prints a
41
+ * warning. */
42
+ end(): void
55
43
  }
44
+
45
+ /**
46
+ * Claims the pins and starts an I2C bus on a controller.
47
+ * @public
48
+ */
49
+ export declare function I2c(bus: number, options: I2cOptions): Result<I2c, I2cError>
@@ -1,3 +1,6 @@
1
+ /* mikro/i2s, declared here and implemented in C (mik_i2s.cpp). */
2
+
3
+ import type {GpioInUse} from '../gpio/types.js'
1
4
  import type {Result} from '../result/types.js'
2
5
 
3
6
  /**
@@ -57,7 +60,7 @@ export interface I2sStdTxRxOptions extends I2sStdBaseOptions {
57
60
 
58
61
  /**
59
62
  * PDM is receive-only and chip-dependent (classic ESP32 and S3 support it; some
60
- * C/H-series targets do not). On unsupported chips `begin()` returns
63
+ * C/H-series targets do not). On unsupported chips `I2s()` returns
61
64
  * `ChannelInitFailed`.
62
65
  *
63
66
  * @public
@@ -80,11 +83,12 @@ export interface I2sPdmRxOptions {
80
83
  * @public
81
84
  */
82
85
  export type I2sError =
86
+ | GpioInUse
87
+ | {name: 'InvalidGpio'; message: string}
83
88
  | {name: 'ChannelInitFailed'; message: string}
84
89
  | {name: 'InvalidParam'; message: string}
85
90
  | {name: 'WriteFailed'; message: string}
86
91
  | {name: 'ReadFailed'; message: string}
87
- | {name: 'NotStarted'}
88
92
  | {name: 'QueueFull'}
89
93
  | {name: 'NoRxPin'}
90
94
  | {name: 'NoTxPin'}
@@ -122,18 +126,25 @@ export interface I2sRx {
122
126
  /**
123
127
  * @public
124
128
  */
125
- export interface I2sBase {
126
- begin(): Result<void, I2sError>
127
- end(): Result<void, I2sError>
129
+ export interface I2s {
130
+ /**
131
+ * Stops the DMA, deletes the channels and releases the GPIO pins. Queued
132
+ * writes resolve with `ok()`. Calling it again does nothing. Afterwards
133
+ * `write()` resolves `ok()` and `capture()` returns an empty array; the first
134
+ * such call prints a warning.
135
+ */
136
+ end(): void
128
137
  }
129
138
 
130
139
  /**
140
+ * Claims the pins and starts I2S channels on a controller. Direction follows
141
+ * the pins: `dout` enables `write()`, `din` enables `capture()`.
131
142
  * @public
132
143
  */
133
- export declare const I2s: {
134
- prototype: I2sBase
135
- new (port: number, options: I2sStdTxRxOptions): I2sBase & I2sTx & I2sRx
136
- new (port: number, options: I2sStdTxOptions): I2sBase & I2sTx
137
- new (port: number, options: I2sStdRxOptions): I2sBase & I2sRx
138
- new (port: number, options: I2sPdmRxOptions): I2sBase & I2sRx
139
- }
144
+ export declare function I2s(
145
+ port: number,
146
+ options: I2sStdTxRxOptions,
147
+ ): Result<I2s & I2sTx & I2sRx, I2sError>
148
+ export declare function I2s(port: number, options: I2sStdTxOptions): Result<I2s & I2sTx, I2sError>
149
+ export declare function I2s(port: number, options: I2sStdRxOptions): Result<I2s & I2sRx, I2sError>
150
+ export declare function I2s(port: number, options: I2sPdmRxOptions): Result<I2s & I2sRx, I2sError>