@mikrojs/native 0.0.7
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 +198 -0
- package/LICENSE +21 -0
- package/README.md +49 -0
- package/cmake/mikrojs_bytecode.cmake +146 -0
- package/cmake.js +22 -0
- package/dist/index.d.ts +52 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +132 -0
- package/dist/index.js.map +1 -0
- package/dist/types.d.ts +43 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/include/byteorder_apple.h +11 -0
- package/include/byteorder_windows.h +12 -0
- package/include/mikrojs/cbor_helpers.h +24 -0
- package/include/mikrojs/cutils_wrap.h +59 -0
- package/include/mikrojs/errors.h +144 -0
- package/include/mikrojs/mem.h +11 -0
- package/include/mikrojs/mik_color.h +32 -0
- package/include/mikrojs/mikrojs.h +331 -0
- package/include/mikrojs/platform.h +82 -0
- package/include/mikrojs/private.h +281 -0
- package/include/mikrojs/utils.h +125 -0
- package/package.json +100 -0
- 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/ble/ble.ts +231 -0
- package/runtime/ble/types.ts +194 -0
- package/runtime/ble/uuid.ts +89 -0
- package/runtime/ble/validators.ts +61 -0
- package/runtime/cbor/cbor.ts +1 -0
- package/runtime/cbor/types.ts +8 -0
- package/runtime/console/types.ts +50 -0
- package/runtime/env/env.ts +17 -0
- package/runtime/env/types.ts +12 -0
- package/runtime/format/types.ts +4 -0
- package/runtime/fs/fs.ts +93 -0
- package/runtime/fs/types.ts +92 -0
- package/runtime/globals.d.ts +87 -0
- package/runtime/http/helpers.ts +222 -0
- package/runtime/http/native.ts +151 -0
- package/runtime/http/request.ts +25 -0
- package/runtime/i2c/i2c.ts +35 -0
- package/runtime/i2c/types.ts +55 -0
- package/runtime/inspect/types.ts +10 -0
- package/runtime/internal.d.ts +456 -0
- package/runtime/kv/nvs.ts +17 -0
- package/runtime/kv/rtc.ts +17 -0
- package/runtime/kv/shared.ts +107 -0
- package/runtime/kv/types.ts +150 -0
- package/runtime/neopixel/neopixel.ts +38 -0
- package/runtime/neopixel/types.ts +27 -0
- package/runtime/pin/pin.ts +51 -0
- package/runtime/pin/types.ts +49 -0
- package/runtime/pwm/pwm.ts +32 -0
- package/runtime/pwm/types.ts +29 -0
- package/runtime/reader/reader.ts +167 -0
- package/runtime/reader/types.ts +34 -0
- package/runtime/result/native-result.node-shim.ts +44 -0
- package/runtime/result/result.ts +26 -0
- package/runtime/result/types.ts +60 -0
- package/runtime/schema/schema.ts +321 -0
- package/runtime/schema/types.ts +152 -0
- package/runtime/sleep/sleep.ts +14 -0
- package/runtime/sleep/types.ts +44 -0
- package/runtime/sntp/sntp.ts +54 -0
- package/runtime/sntp/types.ts +38 -0
- package/runtime/spi/spi.ts +31 -0
- package/runtime/spi/types.ts +42 -0
- package/runtime/stdio/stdio.ts +44 -0
- package/runtime/stdio/types.ts +22 -0
- package/runtime/stream/stream.ts +150 -0
- package/runtime/stream/types.ts +47 -0
- package/runtime/sys/sys.ts +90 -0
- package/runtime/sys/types.ts +131 -0
- package/runtime/test/test.ts +595 -0
- package/runtime/test/types.ts +97 -0
- package/runtime/uart/types.ts +75 -0
- package/runtime/uart/uart.ts +51 -0
- package/runtime/wifi/types.ts +156 -0
- package/runtime/wifi/wifi.ts +208 -0
- package/scripts/bundle-runtime.js +149 -0
- package/scripts/compare-minifiers.js +189 -0
- package/scripts/compile-bytecode.sh +38 -0
- package/scripts/copy-prebuild.js +20 -0
- package/scripts/generate-symbol-map.js +146 -0
- package/src/builtins.cpp +82 -0
- package/src/cutils_compat.c +38 -0
- package/src/eval_bytecode.cpp +42 -0
- package/src/fs.cpp +878 -0
- package/src/mem.cpp +63 -0
- package/src/mik_abort.cpp +160 -0
- package/src/mik_app_config.cpp +358 -0
- package/src/mik_cbor.cpp +334 -0
- package/src/mik_color.cpp +46 -0
- package/src/mik_console.cpp +422 -0
- package/src/mik_inspect.cpp +850 -0
- package/src/mik_repl.cpp +1122 -0
- package/src/mik_result.cpp +344 -0
- package/src/mik_stdio.cpp +147 -0
- package/src/mik_sys.cpp +239 -0
- package/src/mik_text_encoding.cpp +443 -0
- package/src/mikrojs.cpp +942 -0
- package/src/modules.cpp +944 -0
- package/src/platform_posix.cpp +134 -0
- package/src/timers.cpp +208 -0
- package/src/utils.cpp +173 -0
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import * as native from 'native:i2c'
|
|
2
|
+
|
|
3
|
+
import type {Result} from '../result/types.js'
|
|
4
|
+
import type {I2c as PlatformI2c, I2cError, I2cOptions} from './types.js'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* @public
|
|
8
|
+
*/
|
|
9
|
+
export class I2c implements PlatformI2c {
|
|
10
|
+
#native: native.I2c
|
|
11
|
+
|
|
12
|
+
constructor(busNo: 0 | 1, options?: I2cOptions) {
|
|
13
|
+
this.#native = new native.I2c(busNo, options)
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
begin(): Result<void, I2cError> {
|
|
17
|
+
return this.#native.begin()
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
end(): Result<void, I2cError> {
|
|
21
|
+
return this.#native.end()
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
scan(): Result<Uint8Array, I2cError> {
|
|
25
|
+
return this.#native.scan()
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
write(address: number, data: Uint8Array, stop?: boolean): Result<void, I2cError> {
|
|
29
|
+
return this.#native.write(address, data, stop)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
read(address: number, bytes: number): Result<Uint8Array, I2cError> {
|
|
33
|
+
return this.#native.read(address, bytes)
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type {Result} from '../result/types.js'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @public
|
|
5
|
+
*/
|
|
6
|
+
export interface I2cBaseOptions {
|
|
7
|
+
freq?: number
|
|
8
|
+
timeout?: number
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* @public
|
|
13
|
+
*/
|
|
14
|
+
export interface I2cOptionsWithPins extends I2cBaseOptions {
|
|
15
|
+
sda: number
|
|
16
|
+
scl: number
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* @public
|
|
21
|
+
*/
|
|
22
|
+
export type I2cOptions = I2cBaseOptions | I2cOptionsWithPins
|
|
23
|
+
|
|
24
|
+
export type I2cError =
|
|
25
|
+
| {name: 'BusInitFailed'; message: string}
|
|
26
|
+
| {name: 'BusDeinitFailed'; message: string}
|
|
27
|
+
| {name: 'NotStarted'}
|
|
28
|
+
| {name: 'MissingPins'}
|
|
29
|
+
| {name: 'AddDeviceFailed'; message: string}
|
|
30
|
+
| {name: 'WriteFailed'; message: string}
|
|
31
|
+
| {name: 'WriteTooLarge'}
|
|
32
|
+
| {name: 'ReadFailed'; message: string}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* @public
|
|
36
|
+
*/
|
|
37
|
+
export declare const I2c: {
|
|
38
|
+
prototype: I2c
|
|
39
|
+
new (busNo: 0 | 1, options?: I2cOptions): I2c
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* @public
|
|
44
|
+
*/
|
|
45
|
+
export interface I2c {
|
|
46
|
+
begin(): Result<void, I2cError>
|
|
47
|
+
|
|
48
|
+
end(): Result<void, I2cError>
|
|
49
|
+
|
|
50
|
+
read(address: number, bytes: number): Result<Uint8Array, I2cError>
|
|
51
|
+
|
|
52
|
+
write(address: number, data: Uint8Array, stop?: boolean): Result<void, I2cError>
|
|
53
|
+
|
|
54
|
+
scan(): Result<Uint8Array, I2cError>
|
|
55
|
+
}
|
|
@@ -0,0 +1,456 @@
|
|
|
1
|
+
// Native C modules provided by the firmware, not importable by user scripts
|
|
2
|
+
|
|
3
|
+
type NR<T> = {ok: true; value: T} | {ok: false; error: {code: number; message: string}}
|
|
4
|
+
|
|
5
|
+
// Internal shared runtime modules. Registered as builtins so sibling bundles
|
|
6
|
+
// can reference them at runtime to dedupe shared code, but not exposed via
|
|
7
|
+
// the public `mikrojs/*` subpath exports so user apps can't accidentally
|
|
8
|
+
// import them. Keep these in sync with the MODULES list in the firmware +
|
|
9
|
+
// @mikrojs/native CMakeLists.
|
|
10
|
+
declare module 'mikrojs/kv/shared' {
|
|
11
|
+
export {KVError, makeCreateValue, type NativeKvFns} from './kv/shared.js'
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
declare module 'native:cbor' {
|
|
15
|
+
import type {CborError} from '@mikrojs/native/runtime/cbor/types'
|
|
16
|
+
import type {Result} from 'mikrojs/result'
|
|
17
|
+
export function encode(value: unknown): Result<Uint8Array, CborError>
|
|
18
|
+
export function decode(data: Uint8Array): Result<unknown, CborError>
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
declare module 'native:result' {
|
|
22
|
+
import type {ErrResult, OkResult} from './result/types.js'
|
|
23
|
+
export function ok(): OkResult<void>
|
|
24
|
+
export function ok<T>(value: T): OkResult<T>
|
|
25
|
+
export function err<E>(error: E): ErrResult<E>
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
declare module 'native:sys' {
|
|
29
|
+
import type {JsMemoryUsage} from './sys/types.js'
|
|
30
|
+
export function evalScript(code: string): Promise<{value: unknown}>
|
|
31
|
+
export function memoryUsage(): {
|
|
32
|
+
heapUsed: number
|
|
33
|
+
heapTotal: number
|
|
34
|
+
systemFree: number
|
|
35
|
+
systemMinFree: number
|
|
36
|
+
systemTotal: number
|
|
37
|
+
systemLargestFree: number
|
|
38
|
+
}
|
|
39
|
+
export function jsMemoryUsage(): JsMemoryUsage
|
|
40
|
+
export function gc(): void
|
|
41
|
+
export function activeTimers(): number
|
|
42
|
+
export function setTime(millisSinceEpoch: number): void
|
|
43
|
+
export function uptime(): {boot: number; rtc: number}
|
|
44
|
+
export function restart(): never
|
|
45
|
+
export const version: string
|
|
46
|
+
export const board: {
|
|
47
|
+
name: string
|
|
48
|
+
chip: string
|
|
49
|
+
cores: number
|
|
50
|
+
revision: number
|
|
51
|
+
features: string[]
|
|
52
|
+
flash: number
|
|
53
|
+
psram: number
|
|
54
|
+
}
|
|
55
|
+
export const firmware: {hash: string; date: string; idfVersion: string | undefined}
|
|
56
|
+
export const deviceId: string
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
declare module 'native:fs' {
|
|
60
|
+
import type {DirEntry, FSError, MkdirOptions, StatResult, WriteFileOptions} from './fs/types.js'
|
|
61
|
+
import type {Result} from './result/types.js'
|
|
62
|
+
|
|
63
|
+
export interface FileHandle {
|
|
64
|
+
/** Reads up to `size` bytes. Value is `undefined` at EOF. */
|
|
65
|
+
read(size: number): Result<Uint8Array | undefined, FSError>
|
|
66
|
+
write(data: Uint8Array | string): Result<number, FSError>
|
|
67
|
+
seek(offset: number, whence?: 'start' | 'current' | 'end'): Result<number, FSError>
|
|
68
|
+
close(): Result<void, FSError>
|
|
69
|
+
stat(): Result<StatResult, FSError>
|
|
70
|
+
readonly path: string
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export type OpenMode = 'r' | 'w' | 'a' | 'r+' | 'w+' | 'a+'
|
|
74
|
+
|
|
75
|
+
export function open(path: string, mode?: OpenMode): Result<FileHandle, FSError>
|
|
76
|
+
export function readFile(path: string): Result<Uint8Array, FSError>
|
|
77
|
+
export function readFile(path: string, encoding: 'utf-8'): Result<string, FSError>
|
|
78
|
+
export function writeFile(
|
|
79
|
+
path: string,
|
|
80
|
+
contents: string,
|
|
81
|
+
options?: WriteFileOptions,
|
|
82
|
+
): Result<void, FSError>
|
|
83
|
+
export function writeFile(
|
|
84
|
+
path: string,
|
|
85
|
+
contents: Uint8Array,
|
|
86
|
+
options?: WriteFileOptions,
|
|
87
|
+
): Result<void, FSError>
|
|
88
|
+
export function stat(path: string): Result<StatResult, FSError>
|
|
89
|
+
export function readDir(path: string): Result<DirEntry[], FSError>
|
|
90
|
+
export function unlink(path: string): Result<void, FSError>
|
|
91
|
+
export function rename(from: string, to: string): Result<void, FSError>
|
|
92
|
+
export function mkdir(path: string, options?: MkdirOptions): Result<void, FSError>
|
|
93
|
+
export function rmdir(path: string): Result<void, FSError>
|
|
94
|
+
export function exists(path: string): boolean
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
declare module 'native:stdio' {
|
|
98
|
+
export const stdout: {
|
|
99
|
+
write(output: Uint8Array | string): boolean
|
|
100
|
+
flush(): void
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export const stdin: {
|
|
104
|
+
read(): undefined | Uint8Array
|
|
105
|
+
setHandler(handler: (data: Uint8Array) => void): void
|
|
106
|
+
clearHandler(): void
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
declare module 'native:pin' {
|
|
111
|
+
import type {PinError} from '@mikrojs/native/runtime/pin/types'
|
|
112
|
+
import type {Result} from 'mikrojs/result'
|
|
113
|
+
export type PinMode = 0x01 | 0x03 | 0x05
|
|
114
|
+
export function pinMode(pin: number, value: PinMode): Result<void, PinError>
|
|
115
|
+
export function digitalWrite(pin: number, value: 0 | 1): Result<void, PinError>
|
|
116
|
+
export function digitalRead(pin: number): number
|
|
117
|
+
// attenuation: 0=0dB, 1=2.5dB, 2=6dB, 3=11dB
|
|
118
|
+
export function analogRead(pin: number, attenuation: number): Result<number, PinError>
|
|
119
|
+
export function analogReadMillivolts(pin: number, attenuation: number): Result<number, PinError>
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
declare module 'native:sleep' {
|
|
123
|
+
import type {SleepError} from '@mikrojs/native/runtime/sleep/types'
|
|
124
|
+
import type {Result} from 'mikrojs/result'
|
|
125
|
+
|
|
126
|
+
export function deepSleep(ms: number): never
|
|
127
|
+
export function lightSleep(ms: number): Result<void, SleepError>
|
|
128
|
+
export function getWakeupCause(): string
|
|
129
|
+
export function enableTimerWakeup(us: number): Result<void, SleepError>
|
|
130
|
+
export function enableGpioWakeup(pin: number, level: number): Result<void, SleepError>
|
|
131
|
+
export function enableExt0Wakeup(pin: number, level: number): Result<void, SleepError>
|
|
132
|
+
export function enableExt1Wakeup(pinMask: number, mode: number): Result<void, SleepError>
|
|
133
|
+
export function disableWakeupSource(source?: string): Result<void, SleepError>
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
declare module 'native:http' {
|
|
137
|
+
import type {RequestError} from 'mikrojs/http/helpers'
|
|
138
|
+
import type {Result} from 'mikrojs/result'
|
|
139
|
+
|
|
140
|
+
import type {ErrResult} from './result/types.js'
|
|
141
|
+
type HeadersMsg = {status: number; headers: [string, string][]}
|
|
142
|
+
export type HttpMessage =
|
|
143
|
+
| {kind: 'chunk'; data: Uint8Array}
|
|
144
|
+
| {kind: 'end'}
|
|
145
|
+
| {kind: 'error'; cancelled: boolean; message: string}
|
|
146
|
+
export type HttpRequestStart =
|
|
147
|
+
| {ok: true; id: number; headers: Promise<Result<HeadersMsg, RequestError>>}
|
|
148
|
+
| ErrResult<RequestError>
|
|
149
|
+
export function request(
|
|
150
|
+
url: string,
|
|
151
|
+
options?: {method?: string; body?: Uint8Array; headers?: [string, string][]},
|
|
152
|
+
): HttpRequestStart
|
|
153
|
+
export function nextMessage(id: number): Promise<HttpMessage>
|
|
154
|
+
export function cancel(id: number): void
|
|
155
|
+
export function pendingCount(): number
|
|
156
|
+
}
|
|
157
|
+
declare module 'native:i2c' {
|
|
158
|
+
import type {I2cError} from '@mikrojs/native/runtime/i2c/types'
|
|
159
|
+
import type {Result} from 'mikrojs/result'
|
|
160
|
+
|
|
161
|
+
export interface I2cBaseOptions {
|
|
162
|
+
freq?: number
|
|
163
|
+
timeout?: number
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
export interface I2cOptionsWithPins extends I2cBaseOptions {
|
|
167
|
+
sda: number
|
|
168
|
+
scl: number
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
export type I2cOptions = I2cBaseOptions | I2cOptionsWithPins
|
|
172
|
+
export declare const I2c: {
|
|
173
|
+
prototype: I2c
|
|
174
|
+
new (busNo: 0 | 1, options?: I2cOptions): I2c
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
export interface I2c {
|
|
178
|
+
begin(): Result<void, I2cError>
|
|
179
|
+
|
|
180
|
+
end(): Result<void, I2cError>
|
|
181
|
+
|
|
182
|
+
read(address: number, bytes: number): Result<Uint8Array, I2cError>
|
|
183
|
+
|
|
184
|
+
write(address: number, data: Uint8Array, stop?: boolean): Result<void, I2cError>
|
|
185
|
+
|
|
186
|
+
scan(): Result<Uint8Array, I2cError>
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
declare module 'native:spi' {
|
|
190
|
+
import type {SpiError} from '@mikrojs/native/runtime/spi/types'
|
|
191
|
+
import type {Result} from 'mikrojs/result'
|
|
192
|
+
|
|
193
|
+
export interface SpiOptions {
|
|
194
|
+
clk: number
|
|
195
|
+
mosi: number
|
|
196
|
+
miso?: number
|
|
197
|
+
cs?: number
|
|
198
|
+
freq?: number
|
|
199
|
+
mode?: 0 | 1 | 2 | 3
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
export declare const Spi: {
|
|
203
|
+
prototype: Spi
|
|
204
|
+
new (hostNo: 1 | 2, options: SpiOptions): Spi
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
export interface Spi {
|
|
208
|
+
begin(): Result<void, SpiError>
|
|
209
|
+
|
|
210
|
+
end(): Result<void, SpiError>
|
|
211
|
+
|
|
212
|
+
transfer(data: Uint8Array): Result<Uint8Array, SpiError>
|
|
213
|
+
|
|
214
|
+
write(data: Uint8Array): Result<void, SpiError>
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
declare module 'native:sntp' {
|
|
219
|
+
import type {SntpError} from '@mikrojs/native/runtime/sntp/types'
|
|
220
|
+
import type {Result} from 'mikrojs/result'
|
|
221
|
+
/**
|
|
222
|
+
* Native errors: the outer Result covers init/config failures (InitFailed);
|
|
223
|
+
* the inner Result on resolve covers post-start errors (Cancelled).
|
|
224
|
+
* `Timeout` is owned by the JS-side Promise racer in mikrojs/sntp, not
|
|
225
|
+
* emitted by native.
|
|
226
|
+
*/
|
|
227
|
+
export function sync(
|
|
228
|
+
servers: string[],
|
|
229
|
+
timezone: string,
|
|
230
|
+
background: boolean,
|
|
231
|
+
): Result<Promise<Result<{time: number}, SntpError>>, SntpError>
|
|
232
|
+
export function stop(): void
|
|
233
|
+
export function setTimezone(tz: string): void
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
declare module 'native:rtc' {
|
|
237
|
+
type NRV = {ok: true} | {ok: false; error: {code: number; message: string}}
|
|
238
|
+
export function set(key: string, value: unknown): NRV
|
|
239
|
+
export function get(key: string): unknown
|
|
240
|
+
export function remove(key: string): boolean
|
|
241
|
+
export function clear(): void
|
|
242
|
+
export function info(): {used: number; total: number; entries: number}
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
declare module 'native:nvs_kv' {
|
|
246
|
+
type NRV = {ok: true} | {ok: false; error: {code: number; message: string}}
|
|
247
|
+
export function set(key: string, value: unknown): NRV
|
|
248
|
+
export function get(key: string): unknown
|
|
249
|
+
export function remove(key: string): boolean
|
|
250
|
+
export function clear(): void
|
|
251
|
+
export function info(): {entries: number; used: number; total: number; free: number}
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
declare module 'native:pwm' {
|
|
255
|
+
import type {PwmError} from '@mikrojs/native/runtime/pwm/types'
|
|
256
|
+
import type {Result} from 'mikrojs/result'
|
|
257
|
+
|
|
258
|
+
export declare const Pwm: {
|
|
259
|
+
prototype: Pwm
|
|
260
|
+
new (pin: number, freq: number, duty: number): Pwm
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
export interface Pwm {
|
|
264
|
+
duty(value?: number): Result<number, PwmError>
|
|
265
|
+
freq(value?: number): Result<number, PwmError>
|
|
266
|
+
fade(target: number, durationMs: number): Result<Promise<void>, PwmError>
|
|
267
|
+
end(): Result<void, PwmError>
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
declare module 'native:neopixel' {
|
|
272
|
+
import type {NeoPixelError} from '@mikrojs/native/runtime/neopixel/types'
|
|
273
|
+
import type {Result} from 'mikrojs/result'
|
|
274
|
+
|
|
275
|
+
export declare const NeoPixel: {
|
|
276
|
+
prototype: NeoPixel
|
|
277
|
+
new (pin: number, numLeds: number, bytesPerLed: number): NeoPixel
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
export interface NeoPixel {
|
|
281
|
+
setPixel(index: number, r: number, g: number, b: number, w: number): Result<void, NeoPixelError>
|
|
282
|
+
fill(r: number, g: number, b: number, w: number): Result<void, NeoPixelError>
|
|
283
|
+
show(): Result<void, NeoPixelError>
|
|
284
|
+
clear(): Result<void, NeoPixelError>
|
|
285
|
+
end(): Result<void, NeoPixelError>
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
declare module 'native:uart' {
|
|
290
|
+
import type {UartError} from '@mikrojs/native/runtime/uart/types'
|
|
291
|
+
import type {Result} from 'mikrojs/result'
|
|
292
|
+
|
|
293
|
+
export interface UartOptions {
|
|
294
|
+
tx?: number
|
|
295
|
+
rx?: number
|
|
296
|
+
baudRate: number
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
export declare const Uart: {
|
|
300
|
+
prototype: Uart
|
|
301
|
+
new (port: number, options: UartOptions): Uart
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
export interface Uart {
|
|
305
|
+
begin(): Result<void, UartError>
|
|
306
|
+
|
|
307
|
+
end(): Result<void, UartError>
|
|
308
|
+
|
|
309
|
+
write(data: Uint8Array): Result<void, UartError>
|
|
310
|
+
|
|
311
|
+
read(): Result<
|
|
312
|
+
{
|
|
313
|
+
next(): Promise<IteratorResult<Uint8Array>>
|
|
314
|
+
return(): Promise<IteratorResult<Uint8Array>>
|
|
315
|
+
},
|
|
316
|
+
UartError
|
|
317
|
+
>
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
declare module 'native:ble' {
|
|
322
|
+
import type {BleError} from '@mikrojs/native/runtime/ble/types'
|
|
323
|
+
import type {Result} from 'mikrojs/result'
|
|
324
|
+
|
|
325
|
+
type R<T> = Result<T, BleError>
|
|
326
|
+
|
|
327
|
+
export interface CharacteristicNative {
|
|
328
|
+
uuid: string
|
|
329
|
+
properties: number // bitmask
|
|
330
|
+
value?: Uint8Array
|
|
331
|
+
onWrite?: (value: Uint8Array) => void
|
|
332
|
+
writeMode?: string
|
|
333
|
+
security?: string
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
export interface ServiceNative {
|
|
337
|
+
uuid: string
|
|
338
|
+
characteristics: CharacteristicNative[]
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
export interface AdvertiseOptionsNative {
|
|
342
|
+
name?: string
|
|
343
|
+
connectable?: boolean
|
|
344
|
+
services?: ServiceNative[]
|
|
345
|
+
interval?: {min: number; max: number}
|
|
346
|
+
includeTxPower?: boolean
|
|
347
|
+
manufacturerData?: Uint8Array
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
export interface Ble {
|
|
351
|
+
getName(): string
|
|
352
|
+
setName(name: string): R<void>
|
|
353
|
+
getAddress(): R<string>
|
|
354
|
+
|
|
355
|
+
getTxPower(): R<number>
|
|
356
|
+
setTxPower(dbm: number): R<void>
|
|
357
|
+
|
|
358
|
+
advertise(options: AdvertiseOptionsNative): R<void>
|
|
359
|
+
stopAdvertising(): R<void>
|
|
360
|
+
stop(): R<void>
|
|
361
|
+
|
|
362
|
+
setValue(serviceUuid: string, characteristicUuid: string, value: Uint8Array): R<void>
|
|
363
|
+
notify(serviceUuid: string, characteristicUuid: string, value: Uint8Array): R<void>
|
|
364
|
+
|
|
365
|
+
on(event: string, listener: (...args: unknown[]) => void): void
|
|
366
|
+
off(event: string, listener: (...args: unknown[]) => void): void
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
export declare const Ble: {
|
|
370
|
+
prototype: Ble
|
|
371
|
+
new (): Ble
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
declare module 'native:wifi' {
|
|
376
|
+
import type {WifiError} from '@mikrojs/native/runtime/wifi/types'
|
|
377
|
+
import type {Result} from 'mikrojs/result'
|
|
378
|
+
|
|
379
|
+
type R<T> = Result<T, WifiError>
|
|
380
|
+
|
|
381
|
+
export interface Wifi {
|
|
382
|
+
connect(
|
|
383
|
+
ssid: string,
|
|
384
|
+
passphrase: string,
|
|
385
|
+
): R<Promise<R<{ip: string; netmask: string; gateway: string}>>>
|
|
386
|
+
disconnect(): R<void>
|
|
387
|
+
rssi(): R<number>
|
|
388
|
+
ip(): string
|
|
389
|
+
status(): number
|
|
390
|
+
scan(opts?: {ssid?: string; channel?: number; passive?: boolean}): R<
|
|
391
|
+
Promise<
|
|
392
|
+
R<
|
|
393
|
+
{
|
|
394
|
+
ssid: string
|
|
395
|
+
bssid: string
|
|
396
|
+
channel: number
|
|
397
|
+
rssi: number
|
|
398
|
+
authMode: string
|
|
399
|
+
hidden: boolean
|
|
400
|
+
}[]
|
|
401
|
+
>
|
|
402
|
+
>
|
|
403
|
+
>
|
|
404
|
+
on(event: string, listener: (...args: unknown[]) => void): void
|
|
405
|
+
off(event: string, listener: (...args: unknown[]) => void): void
|
|
406
|
+
|
|
407
|
+
// Network config
|
|
408
|
+
mac(): R<string>
|
|
409
|
+
getHostname(): string | undefined
|
|
410
|
+
setHostname(hostname: string): R<void>
|
|
411
|
+
getIpConfig(): R<{ip: string; netmask: string; gateway: string; dns: string} | undefined>
|
|
412
|
+
setIpConfig(opts: {
|
|
413
|
+
ip?: string
|
|
414
|
+
netmask?: string
|
|
415
|
+
gateway?: string
|
|
416
|
+
dns?: string
|
|
417
|
+
dhcp?: boolean
|
|
418
|
+
}): R<void>
|
|
419
|
+
|
|
420
|
+
// AP mode
|
|
421
|
+
apStart(opts: {
|
|
422
|
+
ssid: string
|
|
423
|
+
passphrase?: string
|
|
424
|
+
authMode?: string
|
|
425
|
+
channel?: number
|
|
426
|
+
hidden?: boolean
|
|
427
|
+
maxConnections?: number
|
|
428
|
+
}): R<void>
|
|
429
|
+
apStop(): R<void>
|
|
430
|
+
apIsActive(): boolean
|
|
431
|
+
apIp(): string | undefined
|
|
432
|
+
apStations(): {mac: string; rssi: number}[]
|
|
433
|
+
|
|
434
|
+
// TX power & RSSI threshold
|
|
435
|
+
getTxPower(): R<number>
|
|
436
|
+
setTxPower(dbm: number): R<void>
|
|
437
|
+
getRssiThreshold(): number
|
|
438
|
+
setRssiThreshold(threshold: number): R<void>
|
|
439
|
+
|
|
440
|
+
// AP extras
|
|
441
|
+
apDeauthStation(mac: string): R<void>
|
|
442
|
+
apGetInactiveTimeout(): R<number>
|
|
443
|
+
apSetInactiveTimeout(seconds: number): R<void>
|
|
444
|
+
|
|
445
|
+
// Power management & misc
|
|
446
|
+
getPowerSave(): string
|
|
447
|
+
setPowerSave(mode: string): R<void>
|
|
448
|
+
getCountry(): string | undefined
|
|
449
|
+
setCountry(cc: string): R<void>
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
export declare const Wifi: {
|
|
453
|
+
prototype: Wifi
|
|
454
|
+
new (): Wifi
|
|
455
|
+
}
|
|
456
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import {KVError, makeCreateValue} from 'mikrojs/kv/shared'
|
|
2
|
+
import {clear, get, info, remove, set} from 'native:nvs_kv'
|
|
3
|
+
|
|
4
|
+
import type {NvsStorage} from './types.js'
|
|
5
|
+
|
|
6
|
+
// Loaded in isolation: this file avoids `native:rtc`, so apps importing
|
|
7
|
+
// `mikrojs/kv/nvs` directly don't pay for the RTC backend. `KVError` and
|
|
8
|
+
// `makeCreateValue` come from the shared bytecode module at runtime so
|
|
9
|
+
// they aren't duplicated across nvs.js and rtc.js.
|
|
10
|
+
|
|
11
|
+
export {KVError}
|
|
12
|
+
|
|
13
|
+
export const nvsStorage = {
|
|
14
|
+
createValue: makeCreateValue({get, set, remove, clear, info}),
|
|
15
|
+
clear,
|
|
16
|
+
info,
|
|
17
|
+
} as NvsStorage
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import {KVError, makeCreateValue} from 'mikrojs/kv/shared'
|
|
2
|
+
import {clear, get, info, remove, set} from 'native:rtc'
|
|
3
|
+
|
|
4
|
+
import type {RtcStorage} from './types.js'
|
|
5
|
+
|
|
6
|
+
// Loaded in isolation: this file avoids `native:nvs_kv`, so apps importing
|
|
7
|
+
// `mikrojs/kv/rtc` directly don't pay for the NVS backend. `KVError` and
|
|
8
|
+
// `makeCreateValue` come from the shared bytecode module at runtime so
|
|
9
|
+
// they aren't duplicated across nvs.js and rtc.js.
|
|
10
|
+
|
|
11
|
+
export {KVError}
|
|
12
|
+
|
|
13
|
+
export const rtcStorage = {
|
|
14
|
+
createValue: makeCreateValue({get, set, remove, clear, info}),
|
|
15
|
+
clear,
|
|
16
|
+
info,
|
|
17
|
+
} as RtcStorage
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import {defineError, err, ok} from 'mikrojs/result'
|
|
2
|
+
// Typed loosely to avoid deep type instantiation from Infer<S> in parse's generics.
|
|
3
|
+
// Type safety is provided by the storage interface overloads in types.ts.
|
|
4
|
+
import {parse as _parse} from 'mikrojs/schema'
|
|
5
|
+
|
|
6
|
+
import type {NativeError} from '../result/types.js'
|
|
7
|
+
|
|
8
|
+
type ParseResult = {ok: true; value: unknown} | {ok: false; error: {message: string; path: string}}
|
|
9
|
+
const parse = _parse as unknown as (schema: unknown, value: unknown) => ParseResult
|
|
10
|
+
|
|
11
|
+
export const KVError = defineError('KVError', {
|
|
12
|
+
StorageFull: (message: string) => ({message}),
|
|
13
|
+
EncodeFailed: (message: string) => ({message}),
|
|
14
|
+
WriteFailed: (message: string) => ({message}),
|
|
15
|
+
ValidationFailed: (message: string, path: string) => ({message, path}),
|
|
16
|
+
})
|
|
17
|
+
|
|
18
|
+
/* Error codes from errors.h (MIK_ERR_BASE + 0xD0..0xD4) */
|
|
19
|
+
const KV_INVALID_KEY = 0x80d0
|
|
20
|
+
const KV_ENCODE = 0x80d1
|
|
21
|
+
const KV_TOO_LARGE = 0x80d2
|
|
22
|
+
const KV_STORAGE_FULL = 0x80d3
|
|
23
|
+
const KV_WRITE = 0x80d4
|
|
24
|
+
|
|
25
|
+
type NativeResult = {ok: true} | {ok: false; error: NativeError}
|
|
26
|
+
|
|
27
|
+
export type NativeKvFns = {
|
|
28
|
+
get: (key: string) => unknown
|
|
29
|
+
set: (key: string, value: unknown) => NativeResult
|
|
30
|
+
remove: (key: string) => boolean
|
|
31
|
+
clear: () => void
|
|
32
|
+
info: () => unknown
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function mapKvError(e: NativeError) {
|
|
36
|
+
switch (e.code) {
|
|
37
|
+
case KV_STORAGE_FULL:
|
|
38
|
+
case KV_TOO_LARGE:
|
|
39
|
+
return KVError.StorageFull(e.message)
|
|
40
|
+
case KV_ENCODE:
|
|
41
|
+
case KV_INVALID_KEY:
|
|
42
|
+
return KVError.EncodeFailed(e.message)
|
|
43
|
+
case KV_WRITE:
|
|
44
|
+
return KVError.WriteFailed(e.message)
|
|
45
|
+
default:
|
|
46
|
+
throw new Error(`unexpected native kv error: code=0x${e.code.toString(16)}`)
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export function makeCreateValue(native: NativeKvFns) {
|
|
51
|
+
return function createValue(key: string, options?: any): any {
|
|
52
|
+
const schema = options?.schema
|
|
53
|
+
const initialValue = options?.initialValue
|
|
54
|
+
const hasInitialValue = options !== undefined && 'initialValue' in options
|
|
55
|
+
const onReadError = options?.onReadError ?? (() => undefined)
|
|
56
|
+
|
|
57
|
+
function doGet(): unknown {
|
|
58
|
+
try {
|
|
59
|
+
const v = native.get(key)
|
|
60
|
+
if (v === undefined) return hasInitialValue ? initialValue : undefined
|
|
61
|
+
if (schema) {
|
|
62
|
+
const result = parse(schema, v)
|
|
63
|
+
if (!result.ok) {
|
|
64
|
+
// Schema mismatch: data decoded fine, don't delete it
|
|
65
|
+
return onReadError(result.error)
|
|
66
|
+
}
|
|
67
|
+
return result.value
|
|
68
|
+
}
|
|
69
|
+
return v
|
|
70
|
+
} catch (e) {
|
|
71
|
+
// Decode failure: corrupt data, delete it
|
|
72
|
+
native.remove(key)
|
|
73
|
+
const fallback = onReadError(e)
|
|
74
|
+
if (fallback !== undefined) native.set(key, fallback)
|
|
75
|
+
return fallback
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function doSet(value: unknown) {
|
|
80
|
+
if (value === undefined) {
|
|
81
|
+
native.remove(key)
|
|
82
|
+
return ok(undefined)
|
|
83
|
+
}
|
|
84
|
+
if (schema) {
|
|
85
|
+
const result = parse(schema, value)
|
|
86
|
+
if (!result.ok) {
|
|
87
|
+
return err(KVError.ValidationFailed(result.error.message, result.error.path))
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
const result = native.set(key, value)
|
|
91
|
+
if (!result.ok) return err(mapKvError(result.error))
|
|
92
|
+
return ok(value)
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
return {
|
|
96
|
+
get: doGet,
|
|
97
|
+
set: doSet,
|
|
98
|
+
update(updater: (value: any) => any) {
|
|
99
|
+
return doSet(updater(doGet()))
|
|
100
|
+
},
|
|
101
|
+
delete() {
|
|
102
|
+
const removed = native.remove(key)
|
|
103
|
+
return removed ? ok() : err(KVError.WriteFailed(`failed to delete key "${key}"`))
|
|
104
|
+
},
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|