@ikalogic/at1000 0.5.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (86) hide show
  1. package/build/at1000-BGZGhgco.mjs +3 -0
  2. package/build/at1000-BGZGhgco.mjs.map +1 -0
  3. package/build/at1000-D9r6GCs0.cjs +3 -0
  4. package/build/at1000-D9r6GCs0.cjs.map +1 -0
  5. package/build/browser.cjs +1 -1
  6. package/build/browser.cjs.map +1 -1
  7. package/build/browser.d.cts +1 -1
  8. package/build/browser.d.mts +1 -1
  9. package/build/browser.mjs +1 -1
  10. package/build/browser.mjs.map +1 -1
  11. package/build/{com-B2R6yhB4.d.cts → com-XQjoTBdU.d.cts} +39 -39
  12. package/build/{com-B2R6yhB4.d.cts.map → com-XQjoTBdU.d.cts.map} +1 -1
  13. package/build/{com-B2R6yhB4.d.mts → com-XQjoTBdU.d.mts} +39 -39
  14. package/build/{com-B2R6yhB4.d.mts.map → com-XQjoTBdU.d.mts.map} +1 -1
  15. package/build/com.d.cts +1 -1
  16. package/build/com.d.mts +1 -1
  17. package/build/{events-zRq39ozC.d.cts → events-Cf7iAMZP.d.cts} +4 -3
  18. package/build/events-Cf7iAMZP.d.cts.map +1 -0
  19. package/build/{events-zRq39ozC.d.mts → events-Cf7iAMZP.d.mts} +4 -3
  20. package/build/events-Cf7iAMZP.d.mts.map +1 -0
  21. package/build/events.cjs +1 -1
  22. package/build/events.d.cts +1 -1
  23. package/build/events.d.mts +1 -1
  24. package/build/events.mjs +1 -1
  25. package/build/{gpio-xjqg-50L.d.cts → gpio-Bk1VEKYF.d.cts} +17 -7
  26. package/build/gpio-Bk1VEKYF.d.cts.map +1 -0
  27. package/build/{gpio-DThbC_mm.d.mts → gpio-bFe112uI.d.mts} +17 -7
  28. package/build/gpio-bFe112uI.d.mts.map +1 -0
  29. package/build/gpio.cjs.map +1 -1
  30. package/build/gpio.d.cts +1 -1
  31. package/build/gpio.d.mts +1 -1
  32. package/build/gpio.mjs.map +1 -1
  33. package/build/{hmi-6SM_R-VX.d.cts → hmi-B-potLdl.d.cts} +3 -3
  34. package/build/{hmi-6SM_R-VX.d.cts.map → hmi-B-potLdl.d.cts.map} +1 -1
  35. package/build/{hmi-6SM_R-VX.d.mts → hmi-B-potLdl.d.mts} +3 -3
  36. package/build/{hmi-6SM_R-VX.d.mts.map → hmi-B-potLdl.d.mts.map} +1 -1
  37. package/build/hmi.d.cts +1 -1
  38. package/build/hmi.d.mts +1 -1
  39. package/build/{at1000-Bk6QeH1q.d.cts → host-BCOEcUog.d.cts} +18 -16
  40. package/build/host-BCOEcUog.d.cts.map +1 -0
  41. package/build/{at1000-BG_IKvW8.d.mts → host-DJ8SAGMC.d.mts} +18 -16
  42. package/build/host-DJ8SAGMC.d.mts.map +1 -0
  43. package/build/management-BGrPAG5k.cjs +7 -0
  44. package/build/management-BGrPAG5k.cjs.map +1 -0
  45. package/build/management-CuI4cenF.mjs +7 -0
  46. package/build/management-CuI4cenF.mjs.map +1 -0
  47. package/build/management.cjs +1 -1
  48. package/build/management.d.cts +41 -25
  49. package/build/management.d.cts.map +1 -1
  50. package/build/management.d.mts +41 -25
  51. package/build/management.d.mts.map +1 -1
  52. package/build/management.mjs +1 -1
  53. package/build/node.cjs +1 -1
  54. package/build/node.cjs.map +1 -1
  55. package/build/node.d.cts +1 -1
  56. package/build/node.d.mts +1 -1
  57. package/build/node.mjs +1 -1
  58. package/build/node.mjs.map +1 -1
  59. package/build/package-CXtuh0C5.mjs +2 -0
  60. package/build/package-CXtuh0C5.mjs.map +1 -0
  61. package/build/{package-ByQuarMd.cjs → package-DDLRsahz.cjs} +2 -2
  62. package/build/package-DDLRsahz.cjs.map +1 -0
  63. package/build/{power-CUrqOTyE.d.cts → power-B8QFbKdP.d.cts} +9 -9
  64. package/build/{power-CUrqOTyE.d.cts.map → power-B8QFbKdP.d.cts.map} +1 -1
  65. package/build/{power-SmiM6n5O.d.mts → power-BZmXOJyK.d.mts} +9 -9
  66. package/build/{power-SmiM6n5O.d.mts.map → power-BZmXOJyK.d.mts.map} +1 -1
  67. package/build/power.cjs.map +1 -1
  68. package/build/power.d.cts +1 -1
  69. package/build/power.d.mts +1 -1
  70. package/build/power.mjs.map +1 -1
  71. package/build/session.cjs +1 -1
  72. package/build/session.mjs +1 -1
  73. package/package.json +5 -1
  74. package/build/at1000-BG_IKvW8.d.mts.map +0 -1
  75. package/build/at1000-BaJD2vC5.mjs +0 -8
  76. package/build/at1000-BaJD2vC5.mjs.map +0 -1
  77. package/build/at1000-Bk6QeH1q.d.cts.map +0 -1
  78. package/build/at1000-DuULyDOw.cjs +0 -8
  79. package/build/at1000-DuULyDOw.cjs.map +0 -1
  80. package/build/events-zRq39ozC.d.cts.map +0 -1
  81. package/build/events-zRq39ozC.d.mts.map +0 -1
  82. package/build/gpio-DThbC_mm.d.mts.map +0 -1
  83. package/build/gpio-xjqg-50L.d.cts.map +0 -1
  84. package/build/package-ByQuarMd.cjs.map +0 -1
  85. package/build/package-gaVXFnhN.mjs +0 -2
  86. package/build/package-gaVXFnhN.mjs.map +0 -1
@@ -0,0 +1,3 @@
1
+ import{ComApi as e,canConfig as t,canFrame as n,i2cConfig as r,rs232Config as i,rs485Config as a,spiConfig as o,uartConfig as s}from"./com.mjs";import{i as c,l,n as u,r as d,s as f,u as p}from"./management-CuI4cenF.mjs";import{GpioApi as m,analogInputConfiguration as h,analogOutputConfiguration as g,analogState as _,digitalInputConfiguration as v,digitalOutputConfiguration as y,digitalState as b,openDrainConfiguration as x,syncState as S}from"./gpio.mjs";import{HmiApi as C,color as w,internalKnobEvent as T,playbackConfiguration as E,progress as D,text as O}from"./hmi.mjs";import{PowerApi as k,dutState as A,usbState as j}from"./power.mjs";import{RelaysApi as M,relayState as N,states as P}from"./relays.mjs";import{up as F}from"up-fetch";import*as I from"valibot";const L=I.object({active:I.boolean(),kind:I.optional(I.picklist([`remote`,`project`])),label:I.optional(I.string()),project:I.optional(I.string()),since:I.optional(I.number())}),R=I.object({token:I.string()});async function z(e,t){let n=await fetch(`${e}/session/open`,{method:`POST`,body:JSON.stringify(t),headers:{"content-type":`application/json`},signal:AbortSignal.timeout(3e4)});if(n.status!==404&&n.status!==405)return n.ok||await X(n,`POST`),I.parse(R,await n.json()).token}var B=class{fetch;constructor(e){this.fetch=e}state(){return this.fetch(`/session/state`,{schema:L})}};const V=I.array(I.pipe(I.number(),I.integer(),I.minValue(0),I.maxValue(255))),H={"com.can_config":t,"com.rs232_config":i,"com.rs485_config":a,"com.spi_config":o,"com.i2c_config":r,"com.uart_config":s,"com.can_rx":I.array(n),"com.uart_rx":V,"com.rs232_rx":V,"com.rs485_rx":V,"gpio.state":I.union([b,_]),"gpio.config":I.union([h,g,v,y,x]),"gpio.sync":S,"hmi.text":O,"hmi.colors":w,"hmi.progress":I.optional(D),"hmi.play":E,"hmi.knob":T,"management.datetime":I.object({epoch_seconds:I.number()}),"management.calibration":d,"management.calibration_state":c,"management.project":f,"management.update_status":l,"power.dut":A,"power.usb":j,"relays.state":N,"relays.states":P,"session.state":L},U=[`com.reset`,`gpio.reset`,`hmi.clear`,`hmi.reset`,`power.reset`,`relays.reset`],W=I.object({type:I.string(),id:I.optional(I.pipe(I.number(),I.integer())),ts:I.number(),data:I.optional(I.unknown())}),G=5e3,K=(...e)=>console.debug(`[at1000:events]`,...e);var q=class{host;socket;listeners=new Map;stateListeners=new Set;shouldReconnect=!1;reconnectDelayMs=500;reconnectTimer;_connected=!1;connectPromise;constructor(e){this.host=e}get connected(){return this._connected}async connect(e){if(typeof WebSocket>`u`)throw Error(`WebSocket is not available in this runtime (Node >= 22, Bun, or a browser is required)`);if(!this._connected){this.connectPromise??=this.openSocket(e?.timeout??G);try{await this.connectPromise}finally{this.connectPromise=void 0}}}close(){this.shouldReconnect=!1,this.reconnectTimer!==void 0&&(clearTimeout(this.reconnectTimer),this.reconnectTimer=void 0);let e=this.socket;this.socket=void 0,e!==void 0&&e.close(),this.setConnected(!1)}on(e,t){let n=this.listeners.get(e);return n===void 0&&(n=new Set,this.listeners.set(e,n)),n.add(t),()=>{let n=this.listeners.get(e);n!==void 0&&(n.delete(t),n.size===0&&this.listeners.delete(e))}}onStateChange(e){return this.stateListeners.add(e),()=>{this.stateListeners.delete(e)}}openSocket(e){let{promise:t,resolve:n,reject:r}=Promise.withResolvers(),i=`ws://${p(this.host)}/v0/events`,a=new WebSocket(i);this.socket=a;let o=!1,s=setTimeout(()=>{o||(o=!0,a.close(),r(Error(`Timed out connecting to ${i}`)))},e);return a.onopen=()=>{this.socket!==a||o||(o=!0,clearTimeout(s),this.shouldReconnect=!0,this.reconnectDelayMs=500,this.setConnected(!0),K(`open`,i),n())},a.onmessage=e=>{this.socket===a&&this.handleMessage(e.data)},a.onerror=()=>{K(`error`,i),this.socket===a&&!o&&(o=!0,clearTimeout(s),r(Error(`Failed to connect to ${i}`)))},a.onclose=()=>{if(this.socket===a){if(K(`close`,i),clearTimeout(s),this.setConnected(!1),!o){o=!0,r(Error(`Connection to ${i} closed before opening`));return}this.shouldReconnect&&this.scheduleReconnect()}},t}scheduleReconnect(){if(!this.shouldReconnect||this.reconnectTimer!==void 0)return;let e=this.reconnectDelayMs;K(`reconnecting in`,e,`ms`),this.reconnectDelayMs=Math.min(this.reconnectDelayMs*2,8e3),this.reconnectTimer=setTimeout(()=>{this.reconnectTimer=void 0,this.shouldReconnect&&this.openSocket(G).catch(()=>{})},e)}handleMessage(e){if(typeof e!=`string`){K(`drop: non-string frame`);return}let t;try{t=JSON.parse(e)}catch{K(`drop: invalid JSON`,e);return}K(`recv`,t);let n=I.safeParse(W,t);if(!n.success){K(`drop: malformed envelope`,n.issues);return}let{type:r,id:i,ts:a}=n.output;if(r in H){let e=H[r],t=I.safeParse(e,n.output.data);if(!t.success){K(`drop: payload validation failed for`,r,t.issues);return}let o={type:r,id:i,ts:a,data:t.output};K(`dispatch`,r),this.emitTo(r,o),this.emitTo(`*`,o);return}if(U.includes(r)){let e={type:r,id:i,ts:a};K(`dispatch (dataless)`,r),this.emitTo(r,e),this.emitTo(`*`,e);return}K(`drop: unknown type`,r),this.emitTo(`*`,{type:r,id:i,ts:a,data:n.output.data})}emitTo(e,t){let n=this.listeners.get(e);if(n!==void 0)for(let e of n)try{e(t)}catch{}}setConnected(e){if(this._connected!==e){this._connected=e;for(let t of this.stateListeners)try{t(e)}catch{}}}},J=class extends Error{code;detail;suggestion;path;constructor(e){let t=e.suggestion.replace(/\n/g,`
2
+ `);super(`${e.message} (${e.code})\n Suggestion: ${t}\n Path: ${e.path}`),this.code=e.code,this.detail=e.message,this.suggestion=e.suggestion,this.path=e.path}};function Y(e){if(typeof e!=`object`||!e)return!1;let t=e;return[`code`,`message`,`suggestion`,`path`].every(e=>typeof t[e]==`string`)}async function X(e,t){let n,r=e.headers.get(`content-type`);try{n=r?.includes(`application/json`)?await e.json():await e.text()}catch{n=`Failed to parse response body`}throw Y(n)?new J(n):Error(`API request to ${t} ${e.url} failed with status ${e.status}: ${typeof n==`string`?n:JSON.stringify(n)}`)}var Z=class t{host;info;token;sessionSupported;fetch;com;hmi;gpio;management;power;relays;events;session;constructor(t,n,r,i=!0){this.host=t,this.info=n,this.token=r,this.sessionSupported=i,this.fetch=F(fetch,()=>({baseUrl:`http://${p(this.host)}/v0`,timeout:1e3,headers:this.token?{"X-AT1000-Session":this.token}:void 0,parseRejected:(e,t)=>X(e,t.method)})),this.com=new e(this.fetch),this.hmi=new C(this.fetch),this.gpio=new m(this.fetch,this.info),this.management=new u(this.fetch,this.host),this.power=new k(this.fetch,this.info),this.relays=new M(this.fetch),this.events=new q(this.host),this.session=new B(this.fetch)}async reset(){await this.com.reset(),await this.hmi.reset(),await this.gpio.reset(),await this.power.reset(),await this.relays.reset()}static async openBase(e,n,r){if(!e?.trim())throw Error(`No device address provided. Pass a host from findDevices() or findLocalDevice().`);let i=`http://${p(e)}/v0`,a=await new u(F(fetch,()=>({baseUrl:i,timeout:1e3,parseRejected:(e,t)=>X(e,t.method)})),e).info();if(n?.readonly)return new t(e,a);let o=await z(i,{kind:r?.kind??`remote`,label:n?.label??r?.defaultLabel,project:r?.project});return o===void 0?new t(e,a,void 0,!1):new t(e,a,o)}};export{B as a,q as i,J as n,z as o,X as r,L as s,Z as t};
3
+ //# sourceMappingURL=at1000-BGZGhgco.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"at1000-BGZGhgco.mjs","names":[],"sources":["../src/api/session.ts","../src/api/events.ts","../src/at1000.ts"],"sourcesContent":["import type { UpFetch } from 'up-fetch';\nimport * as v from 'valibot';\n\nimport { parseApiError } from '../at1000';\n\nexport const sessionState = v.object({\n active: v.boolean(),\n kind: v.optional(v.picklist(['remote', 'project'])),\n label: v.optional(v.string()),\n project: v.optional(v.string()),\n since: v.optional(v.number()),\n});\nexport type SessionState = v.InferOutput<typeof sessionState>;\n\n/** Body for `POST /v0/session/open`. */\nexport type SessionOpenBody = { kind: 'remote' | 'project'; label?: string; project?: string };\n\nconst openResponse = v.object({ token: v.string() });\n\n/**\n * Opens an exclusive session on the device (last-open-wins). Returns the minted\n * session token, or `undefined` when the server predates the session model.\n *\n * Deliberately uses a direct `fetch` (not the shared up-fetch client) so the\n * response status is inspectable before any structured-error handler throws:\n * pre-session servers answer the unmatched route with 404/405, which we degrade\n * to `undefined` rather than surface as a failure. A 30 s timeout (not the SDK\n * default 1 s) covers a remote-kind open synchronously stopping any running\n * project container; the host is already known-alive from the preceding info\n * probe, so the long timeout never hangs on dead hosts.\n */\nexport async function open_session(\n baseUrl: string,\n body: SessionOpenBody,\n): Promise<string | undefined> {\n const response = await fetch(`${baseUrl}/session/open`, {\n method: 'POST',\n body: JSON.stringify(body),\n headers: { 'content-type': 'application/json' },\n signal: AbortSignal.timeout(30_000),\n });\n\n if (response.status === 404 || response.status === 405) {\n return undefined; // legacy server without the session model\n }\n if (!response.ok) {\n await parseApiError(response, 'POST');\n }\n\n return v.parse(openResponse, await response.json()).token;\n}\n\n/** @hideconstructor */\nexport class SessionApi {\n constructor(private readonly fetch: UpFetch) {}\n\n /**\n * Reads the current device session state.\n * @returns The active holder (kind/label/project/since) or `{ active: false }`.\n */\n state(): Promise<SessionState> {\n return this.fetch('/session/state', { schema: sessionState });\n }\n}\n","import * as v from 'valibot';\n\nimport { format_host_for_url } from '../host';\nimport {\n canConfig,\n canFrame,\n i2cConfig,\n rs232Config,\n rs485Config,\n spiConfig,\n uartConfig,\n} from './com';\nimport {\n analogInputConfiguration,\n analogOutputConfiguration,\n analogState,\n digitalInputConfiguration,\n digitalOutputConfiguration,\n digitalState,\n openDrainConfiguration,\n syncState,\n} from './gpio';\nimport { color, internalKnobEvent, playbackConfiguration, progress, text } from './hmi';\nimport { calibrationData, calibrationState, projectEvent, updateStatus } from './management';\nimport { dutState, usbState } from './power';\nimport { relayState, states } from './relays';\nimport { sessionState } from './session';\n\n// Receive-side serial bytes. Distinct from com's `serialData`, whose string->bytes\n// transform is for request bodies; events deliver raw byte arrays.\nconst rxBytes = v.array(v.pipe(v.number(), v.integer(), v.minValue(0), v.maxValue(255)));\n\n// Schema for the `data` payload of each event, keyed by the wire `type` literal.\nconst eventDataSchemas = {\n 'com.can_config': canConfig,\n 'com.rs232_config': rs232Config,\n 'com.rs485_config': rs485Config,\n 'com.spi_config': spiConfig,\n 'com.i2c_config': i2cConfig,\n 'com.uart_config': uartConfig,\n 'com.can_rx': v.array(canFrame),\n 'com.uart_rx': rxBytes,\n 'com.rs232_rx': rxBytes,\n 'com.rs485_rx': rxBytes,\n 'gpio.state': v.union([digitalState, analogState]),\n 'gpio.config': v.union([\n analogInputConfiguration,\n analogOutputConfiguration,\n digitalInputConfiguration,\n digitalOutputConfiguration,\n openDrainConfiguration,\n ]),\n // Mirrors the glz::meta of gpio::sync_hold_state_t (apps/server/src/api/resources/gpio.hpp).\n 'gpio.sync': syncState,\n 'hmi.text': text,\n 'hmi.colors': color,\n // `data` absent (progress hidden) is accepted by v.optional.\n 'hmi.progress': v.optional(progress),\n 'hmi.play': playbackConfiguration,\n 'hmi.knob': internalKnobEvent,\n 'management.datetime': v.object({ epoch_seconds: v.number() }),\n 'management.calibration': calibrationData,\n 'management.calibration_state': calibrationState,\n 'management.project': projectEvent,\n 'management.update_status': updateStatus,\n 'power.dut': dutState,\n 'power.usb': usbState,\n 'relays.state': relayState,\n 'relays.states': states,\n 'session.state': sessionState,\n} as const;\n\nconst dataLessEvents = [\n 'com.reset',\n 'gpio.reset',\n 'hmi.clear',\n 'hmi.reset',\n 'power.reset',\n 'relays.reset',\n] as const;\n\nconst envelope = v.object({\n type: v.string(),\n id: v.optional(v.pipe(v.number(), v.integer())),\n ts: v.number(),\n data: v.optional(v.unknown()),\n});\n\ntype EventDataSchemas = typeof eventDataSchemas;\n\n/** Every event `type` literal the server can emit. */\nexport type EventType = keyof EventDataSchemas | (typeof dataLessEvents)[number];\n\ntype PayloadEvent = {\n [K in keyof EventDataSchemas]: {\n type: K;\n id?: number;\n ts: number;\n data: v.InferOutput<EventDataSchemas[K]>;\n };\n}[keyof EventDataSchemas];\n\ntype DataLessEvent = { type: (typeof dataLessEvents)[number]; id?: number; ts: number };\n\n/** A fully-typed device event for a known `type`. */\nexport type DeviceEvent = PayloadEvent | DataLessEvent;\n\n/**\n * Shape delivered to `'*'` listeners. Forward-compatible: a newer server may emit\n * a `type` this SDK does not model, surfaced here with an untyped `data`.\n */\nexport type AnyDeviceEvent = DeviceEvent | {\n type: string;\n id?: number;\n ts: number;\n data?: unknown;\n};\n\ntype EventListener = (event: AnyDeviceEvent) => void;\ntype StateListener = (connected: boolean) => void;\n\nconst reconnectBaseDelayMs = 500;\nconst reconnectMaxDelayMs = 8_000;\nconst defaultConnectTimeoutMs = 5_000;\n\nconst debugLog = (...args: unknown[]): void => console.debug('[at1000:events]', ...args);\n\n/** @hideconstructor */\nexport class EventsApi {\n private socket: WebSocket | undefined;\n private readonly listeners = new Map<string, Set<EventListener>>();\n private readonly stateListeners = new Set<StateListener>();\n private shouldReconnect = false;\n private reconnectDelayMs = reconnectBaseDelayMs;\n private reconnectTimer: ReturnType<typeof setTimeout> | undefined;\n private _connected = false;\n private connectPromise: Promise<void> | undefined;\n\n constructor(private readonly host: string) {}\n\n /** Whether the WebSocket is currently open. */\n get connected(): boolean {\n return this._connected;\n }\n\n /**\n * Open the event stream. Resolves once the socket is open, rejects on failure or\n * after `timeout` ms. A no-op while already connected. Auto-reconnect arms only\n * after the first successful open, so a failed initial `connect()` (e.g. old\n * firmware without `/v0/events`) rejects without scheduling retries.\n */\n async connect(options?: { timeout?: number }): Promise<void> {\n if (typeof WebSocket === 'undefined') {\n throw new Error(\n 'WebSocket is not available in this runtime (Node >= 22, Bun, or a browser is required)',\n );\n }\n if (this._connected) {\n return;\n }\n // Coalesce concurrent opens: the layout holder-banner effect and the\n // projects page both call connect() on the shared per-client socket. Without\n // this a second caller starts a second openSocket() that orphans the first\n // (leaked WS + a connect() that never settles). Reuse the in-flight open.\n this.connectPromise ??= this.openSocket(options?.timeout ?? defaultConnectTimeoutMs);\n try {\n await this.connectPromise;\n } finally {\n this.connectPromise = undefined;\n }\n }\n\n /** Close the stream and cancel any pending reconnect. */\n close(): void {\n this.shouldReconnect = false;\n if (this.reconnectTimer !== undefined) {\n clearTimeout(this.reconnectTimer);\n this.reconnectTimer = undefined;\n }\n const socket = this.socket;\n this.socket = undefined;\n if (socket !== undefined) {\n socket.close();\n }\n this.setConnected(false);\n }\n\n /**\n * Subscribe to an event `type`, or `'*'` for every event. Returns an unsubscribe\n * function. Listeners survive reconnects and are isolated: a throwing listener\n * does not break dispatch to the others.\n */\n on<T extends EventType>(\n type: T,\n listener: (event: Extract<DeviceEvent, { type: T }>) => void,\n ): () => void;\n on(type: '*', listener: (event: AnyDeviceEvent) => void): () => void;\n on(type: string, listener: (event: any) => void): () => void {\n let set = this.listeners.get(type);\n if (set === undefined) {\n set = new Set();\n this.listeners.set(type, set);\n }\n set.add(listener);\n return () => {\n const current = this.listeners.get(type);\n if (current === undefined) {\n return;\n }\n current.delete(listener);\n if (current.size === 0) {\n this.listeners.delete(type);\n }\n };\n }\n\n /** Subscribe to connection state changes. Returns an unsubscribe function. */\n onStateChange(listener: StateListener): () => void {\n this.stateListeners.add(listener);\n return () => {\n this.stateListeners.delete(listener);\n };\n }\n\n private openSocket(timeoutMs: number): Promise<void> {\n const { promise, resolve, reject } = Promise.withResolvers<void>();\n const url = `ws://${format_host_for_url(this.host)}/v0/events`;\n const socket = new WebSocket(url);\n this.socket = socket;\n\n let settled = false;\n const timer = setTimeout(() => {\n if (!settled) {\n settled = true;\n socket.close();\n reject(new Error(`Timed out connecting to ${url}`));\n }\n }, timeoutMs);\n\n socket.onopen = () => {\n if (this.socket !== socket || settled) {\n return;\n }\n settled = true;\n clearTimeout(timer);\n this.shouldReconnect = true;\n this.reconnectDelayMs = reconnectBaseDelayMs;\n this.setConnected(true);\n debugLog('open', url);\n resolve();\n };\n\n socket.onmessage = (event) => {\n if (this.socket === socket) {\n this.handleMessage(event.data);\n }\n };\n\n socket.onerror = () => {\n debugLog('error', url);\n if (this.socket === socket && !settled) {\n settled = true;\n clearTimeout(timer);\n reject(new Error(`Failed to connect to ${url}`));\n }\n };\n\n socket.onclose = () => {\n if (this.socket !== socket) {\n return;\n }\n debugLog('close', url);\n clearTimeout(timer);\n this.setConnected(false);\n if (!settled) {\n settled = true;\n reject(new Error(`Connection to ${url} closed before opening`));\n return;\n }\n if (this.shouldReconnect) {\n this.scheduleReconnect();\n }\n };\n\n return promise;\n }\n\n private scheduleReconnect(): void {\n if (!this.shouldReconnect || this.reconnectTimer !== undefined) {\n return;\n }\n const delay = this.reconnectDelayMs;\n debugLog('reconnecting in', delay, 'ms');\n this.reconnectDelayMs = Math.min(this.reconnectDelayMs * 2, reconnectMaxDelayMs);\n this.reconnectTimer = setTimeout(() => {\n this.reconnectTimer = undefined;\n if (!this.shouldReconnect) {\n return;\n }\n // A failed attempt rejects this promise; onclose then schedules the next retry.\n this.openSocket(defaultConnectTimeoutMs).catch(() => {});\n }, delay);\n }\n\n private handleMessage(data: unknown): void {\n if (typeof data !== 'string') {\n debugLog('drop: non-string frame');\n return;\n }\n let raw: unknown;\n try {\n raw = JSON.parse(data);\n } catch {\n debugLog('drop: invalid JSON', data);\n return;\n }\n\n debugLog('recv', raw);\n const parsed = v.safeParse(envelope, raw);\n if (!parsed.success) {\n debugLog('drop: malformed envelope', parsed.issues);\n return;\n }\n const { type, id, ts } = parsed.output;\n\n if (type in eventDataSchemas) {\n const schema = eventDataSchemas[type as keyof EventDataSchemas] as v.GenericSchema;\n const payload = v.safeParse(schema, parsed.output.data);\n if (!payload.success) {\n debugLog('drop: payload validation failed for', type, payload.issues);\n return;\n }\n const event: AnyDeviceEvent = { type, id, ts, data: payload.output };\n debugLog('dispatch', type);\n this.emitTo(type, event);\n this.emitTo('*', event);\n return;\n }\n\n if ((dataLessEvents as readonly string[]).includes(type)) {\n const event: AnyDeviceEvent = { type, id, ts };\n debugLog('dispatch (dataless)', type);\n this.emitTo(type, event);\n this.emitTo('*', event);\n return;\n }\n\n // Unknown type: deliver the raw envelope to '*' only (server may be newer).\n debugLog('drop: unknown type', type);\n this.emitTo('*', { type, id, ts, data: parsed.output.data });\n }\n\n private emitTo(key: string, event: AnyDeviceEvent): void {\n const set = this.listeners.get(key);\n if (set === undefined) {\n return;\n }\n for (const listener of set) {\n try {\n listener(event);\n } catch {\n // One throwing listener must not break dispatch to the others.\n }\n }\n }\n\n private setConnected(connected: boolean): void {\n if (this._connected === connected) {\n return;\n }\n this._connected = connected;\n for (const listener of this.stateListeners) {\n try {\n listener(connected);\n } catch {\n // Ignore throwing state listeners.\n }\n }\n }\n}\n","import { type UpFetch, up } from 'up-fetch';\n\nimport { ComApi } from './api/com';\nimport { EventsApi } from './api/events';\nimport { GpioApi } from './api/gpio';\nimport { HmiApi } from './api/hmi';\nimport { type Information, ManagementApi } from './api/management';\nimport { PowerApi } from './api/power';\nimport { RelaysApi } from './api/relays';\nimport { SessionApi, open_session } from './api/session';\nimport { format_host_for_url } from './host';\n\n/** Structured error thrown for AT1000 API responses carrying `{ code, message, suggestion, path }`. */\nexport class ApiError extends Error {\n readonly code: string;\n /** Raw human-readable server message (without code/suggestion/path). */\n readonly detail: string;\n readonly suggestion: string;\n readonly path: string;\n\n constructor(body: { code: string; message: string; suggestion: string; path: string }) {\n const formattedSuggestion = body.suggestion.replace(/\\n/g, '\\n ');\n super(\n `${body.message} (${body.code})\\n Suggestion: ${formattedSuggestion}\\n Path: ${body.path}`,\n );\n this.code = body.code;\n this.detail = body.message;\n this.suggestion = body.suggestion;\n this.path = body.path;\n }\n}\n\n/** Type guard for the AT1000 structured error body. */\nfunction isApiErrorBody(\n value: unknown,\n): value is { code: string; message: string; suggestion: string; path: string } {\n if (typeof value !== 'object' || value === null) {\n return false;\n }\n const record = value as Record<string, unknown>;\n return ['code', 'message', 'suggestion', 'path'].every((key) => typeof record[key] === 'string');\n}\n\n/**\n * Shared rejection handler for every AT1000 up-fetch client. Parses a structured\n * `{ code, message, suggestion, path }` body into an {@link ApiError}, otherwise\n * throws a generic error carrying the HTTP status. Written once so the per-client\n * factory and `open_session` share one code path.\n */\nexport async function parseApiError(response: Response, method: string): Promise<never> {\n let errorData: unknown;\n const contentType = response.headers.get('content-type');\n try {\n errorData = contentType?.includes('application/json')\n ? await response.json()\n : await response.text();\n } catch {\n errorData = 'Failed to parse response body';\n }\n\n if (isApiErrorBody(errorData)) {\n throw new ApiError(errorData);\n }\n\n throw new Error(\n `API request to ${method} ${response.url} failed with status ${response.status}: ${\n typeof errorData === 'string' ? errorData : JSON.stringify(errorData)\n }`,\n );\n}\n\n/** Options for opening a device. */\nexport interface OpenOptions {\n /** Open read-only: skip `session/open`, mint no token, send no session header. */\n readonly?: boolean;\n /** Human-readable holder label shown to other clients and on the front panel. */\n label?: string;\n}\n\n/** @hideconstructor */\nexport class AT1000Base {\n /**\n * IP address or hostname of the AT1000 device\n */\n public readonly host: string;\n /**\n * Device information\n */\n public readonly info: Information;\n /**\n * Session token minted by `open()`, or `undefined` for a read-only or legacy\n * (pre-session) client. Sent as the `X-AT1000-Session` header on every request.\n */\n public readonly token: string | undefined;\n /**\n * `false` only when a pre-session server was detected during an exclusive\n * `open()` (no `/v0/session/*` routes). Read-only opens never probe and report `true`.\n */\n public readonly sessionSupported: boolean;\n\n private fetch: UpFetch;\n /**\n * COM API\n */\n public readonly com: ComApi;\n /**\n * HMI API\n */\n public readonly hmi: HmiApi;\n /**\n * GPIO API\n */\n public readonly gpio: GpioApi;\n /**\n * Management API\n */\n public readonly management: ManagementApi;\n /**\n * Power management API\n */\n public readonly power: PowerApi;\n /**\n * Relays API\n */\n public readonly relays: RelaysApi;\n /**\n * Real-time events API (WebSocket). Call `events.connect()` then `events.on(...)`.\n */\n public readonly events: EventsApi;\n /**\n * Session API. Read the current holder via `session.state()`.\n */\n public readonly session: SessionApi;\n\n constructor(host: string, info: Information, token?: string, sessionSupported = true) {\n this.host = host;\n this.info = info;\n this.token = token;\n this.sessionSupported = sessionSupported;\n\n this.fetch = up(\n fetch,\n () => ({\n baseUrl: `http://${format_host_for_url(this.host)}/v0`,\n timeout: 1000,\n headers: this.token\n ? { 'X-AT1000-Session': this.token }\n : undefined,\n parseRejected: (response, request) => parseApiError(response, request.method),\n }),\n );\n\n this.com = new ComApi(this.fetch);\n this.hmi = new HmiApi(this.fetch);\n this.gpio = new GpioApi(this.fetch, this.info);\n this.management = new ManagementApi(this.fetch, this.host);\n this.power = new PowerApi(this.fetch, this.info);\n this.relays = new RelaysApi(this.fetch);\n this.events = new EventsApi(this.host);\n this.session = new SessionApi(this.fetch);\n }\n\n async reset() {\n await this.com.reset();\n await this.hmi.reset();\n await this.gpio.reset();\n await this.power.reset();\n await this.relays.reset();\n }\n\n protected static async openBase(\n host: string,\n options?: OpenOptions,\n session?: { kind: 'remote' | 'project'; project?: string; defaultLabel?: string },\n ): Promise<AT1000Base> {\n if (!host?.trim()) {\n throw new Error(\n 'No device address provided. Pass a host from findDevices() or findLocalDevice().',\n );\n }\n const base = `http://${format_host_for_url(host)}/v0`;\n\n // Re-fetch info to validate reachability (bare client, no session header yet).\n const bare = up(\n fetch,\n () => ({\n baseUrl: base,\n timeout: 1000,\n parseRejected: (response, request) =>\n parseApiError(response, request.method),\n }),\n );\n const info = await new ManagementApi(bare, host).info();\n\n if (options?.readonly) {\n return new AT1000Base(host, info);\n }\n\n const token = await open_session(base, {\n kind: session?.kind ?? 'remote',\n label: options?.label ?? session?.defaultLabel,\n project: session?.project,\n });\n // `undefined` => pre-session server: keep a working, tokenless client.\n return token === undefined\n ? new AT1000Base(host, info, undefined, false)\n : new AT1000Base(host, info, token);\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ const e=require("./rolldown-runtime-CMqjfN_6.cjs"),t=require("./com.cjs"),n=require("./management-BGrPAG5k.cjs"),r=require("./gpio.cjs"),i=require("./hmi.cjs"),a=require("./power.cjs"),o=require("./relays.cjs");let s=require("up-fetch"),c=require("valibot");c=e.t(c,1);const l=c.object({active:c.boolean(),kind:c.optional(c.picklist([`remote`,`project`])),label:c.optional(c.string()),project:c.optional(c.string()),since:c.optional(c.number())}),u=c.object({token:c.string()});async function d(e,t){let n=await fetch(`${e}/session/open`,{method:`POST`,body:JSON.stringify(t),headers:{"content-type":`application/json`},signal:AbortSignal.timeout(3e4)});if(n.status!==404&&n.status!==405)return n.ok||await S(n,`POST`),c.parse(u,await n.json()).token}var f=class{fetch;constructor(e){this.fetch=e}state(){return this.fetch(`/session/state`,{schema:l})}};const p=c.array(c.pipe(c.number(),c.integer(),c.minValue(0),c.maxValue(255))),m={"com.can_config":t.canConfig,"com.rs232_config":t.rs232Config,"com.rs485_config":t.rs485Config,"com.spi_config":t.spiConfig,"com.i2c_config":t.i2cConfig,"com.uart_config":t.uartConfig,"com.can_rx":c.array(t.canFrame),"com.uart_rx":p,"com.rs232_rx":p,"com.rs485_rx":p,"gpio.state":c.union([r.digitalState,r.analogState]),"gpio.config":c.union([r.analogInputConfiguration,r.analogOutputConfiguration,r.digitalInputConfiguration,r.digitalOutputConfiguration,r.openDrainConfiguration]),"gpio.sync":r.syncState,"hmi.text":i.text,"hmi.colors":i.color,"hmi.progress":c.optional(i.progress),"hmi.play":i.playbackConfiguration,"hmi.knob":i.internalKnobEvent,"management.datetime":c.object({epoch_seconds:c.number()}),"management.calibration":n.r,"management.calibration_state":n.i,"management.project":n.s,"management.update_status":n.l,"power.dut":a.dutState,"power.usb":a.usbState,"relays.state":o.relayState,"relays.states":o.states,"session.state":l},h=[`com.reset`,`gpio.reset`,`hmi.clear`,`hmi.reset`,`power.reset`,`relays.reset`],g=c.object({type:c.string(),id:c.optional(c.pipe(c.number(),c.integer())),ts:c.number(),data:c.optional(c.unknown())}),_=5e3,v=(...e)=>console.debug(`[at1000:events]`,...e);var y=class{host;socket;listeners=new Map;stateListeners=new Set;shouldReconnect=!1;reconnectDelayMs=500;reconnectTimer;_connected=!1;connectPromise;constructor(e){this.host=e}get connected(){return this._connected}async connect(e){if(typeof WebSocket>`u`)throw Error(`WebSocket is not available in this runtime (Node >= 22, Bun, or a browser is required)`);if(!this._connected){this.connectPromise??=this.openSocket(e?.timeout??_);try{await this.connectPromise}finally{this.connectPromise=void 0}}}close(){this.shouldReconnect=!1,this.reconnectTimer!==void 0&&(clearTimeout(this.reconnectTimer),this.reconnectTimer=void 0);let e=this.socket;this.socket=void 0,e!==void 0&&e.close(),this.setConnected(!1)}on(e,t){let n=this.listeners.get(e);return n===void 0&&(n=new Set,this.listeners.set(e,n)),n.add(t),()=>{let n=this.listeners.get(e);n!==void 0&&(n.delete(t),n.size===0&&this.listeners.delete(e))}}onStateChange(e){return this.stateListeners.add(e),()=>{this.stateListeners.delete(e)}}openSocket(e){let{promise:t,resolve:r,reject:i}=Promise.withResolvers(),a=`ws://${n.u(this.host)}/v0/events`,o=new WebSocket(a);this.socket=o;let s=!1,c=setTimeout(()=>{s||(s=!0,o.close(),i(Error(`Timed out connecting to ${a}`)))},e);return o.onopen=()=>{this.socket!==o||s||(s=!0,clearTimeout(c),this.shouldReconnect=!0,this.reconnectDelayMs=500,this.setConnected(!0),v(`open`,a),r())},o.onmessage=e=>{this.socket===o&&this.handleMessage(e.data)},o.onerror=()=>{v(`error`,a),this.socket===o&&!s&&(s=!0,clearTimeout(c),i(Error(`Failed to connect to ${a}`)))},o.onclose=()=>{if(this.socket===o){if(v(`close`,a),clearTimeout(c),this.setConnected(!1),!s){s=!0,i(Error(`Connection to ${a} closed before opening`));return}this.shouldReconnect&&this.scheduleReconnect()}},t}scheduleReconnect(){if(!this.shouldReconnect||this.reconnectTimer!==void 0)return;let e=this.reconnectDelayMs;v(`reconnecting in`,e,`ms`),this.reconnectDelayMs=Math.min(this.reconnectDelayMs*2,8e3),this.reconnectTimer=setTimeout(()=>{this.reconnectTimer=void 0,this.shouldReconnect&&this.openSocket(_).catch(()=>{})},e)}handleMessage(e){if(typeof e!=`string`){v(`drop: non-string frame`);return}let t;try{t=JSON.parse(e)}catch{v(`drop: invalid JSON`,e);return}v(`recv`,t);let n=c.safeParse(g,t);if(!n.success){v(`drop: malformed envelope`,n.issues);return}let{type:r,id:i,ts:a}=n.output;if(r in m){let e=m[r],t=c.safeParse(e,n.output.data);if(!t.success){v(`drop: payload validation failed for`,r,t.issues);return}let o={type:r,id:i,ts:a,data:t.output};v(`dispatch`,r),this.emitTo(r,o),this.emitTo(`*`,o);return}if(h.includes(r)){let e={type:r,id:i,ts:a};v(`dispatch (dataless)`,r),this.emitTo(r,e),this.emitTo(`*`,e);return}v(`drop: unknown type`,r),this.emitTo(`*`,{type:r,id:i,ts:a,data:n.output.data})}emitTo(e,t){let n=this.listeners.get(e);if(n!==void 0)for(let e of n)try{e(t)}catch{}}setConnected(e){if(this._connected!==e){this._connected=e;for(let t of this.stateListeners)try{t(e)}catch{}}}},b=class extends Error{code;detail;suggestion;path;constructor(e){let t=e.suggestion.replace(/\n/g,`
2
+ `);super(`${e.message} (${e.code})\n Suggestion: ${t}\n Path: ${e.path}`),this.code=e.code,this.detail=e.message,this.suggestion=e.suggestion,this.path=e.path}};function x(e){if(typeof e!=`object`||!e)return!1;let t=e;return[`code`,`message`,`suggestion`,`path`].every(e=>typeof t[e]==`string`)}async function S(e,t){let n,r=e.headers.get(`content-type`);try{n=r?.includes(`application/json`)?await e.json():await e.text()}catch{n=`Failed to parse response body`}throw x(n)?new b(n):Error(`API request to ${t} ${e.url} failed with status ${e.status}: ${typeof n==`string`?n:JSON.stringify(n)}`)}var C=class e{host;info;token;sessionSupported;fetch;com;hmi;gpio;management;power;relays;events;session;constructor(e,c,l,u=!0){this.host=e,this.info=c,this.token=l,this.sessionSupported=u,this.fetch=(0,s.up)(fetch,()=>({baseUrl:`http://${n.u(this.host)}/v0`,timeout:1e3,headers:this.token?{"X-AT1000-Session":this.token}:void 0,parseRejected:(e,t)=>S(e,t.method)})),this.com=new t.ComApi(this.fetch),this.hmi=new i.HmiApi(this.fetch),this.gpio=new r.GpioApi(this.fetch,this.info),this.management=new n.n(this.fetch,this.host),this.power=new a.PowerApi(this.fetch,this.info),this.relays=new o.RelaysApi(this.fetch),this.events=new y(this.host),this.session=new f(this.fetch)}async reset(){await this.com.reset(),await this.hmi.reset(),await this.gpio.reset(),await this.power.reset(),await this.relays.reset()}static async openBase(t,r,i){if(!t?.trim())throw Error(`No device address provided. Pass a host from findDevices() or findLocalDevice().`);let a=`http://${n.u(t)}/v0`,o=await new n.n((0,s.up)(fetch,()=>({baseUrl:a,timeout:1e3,parseRejected:(e,t)=>S(e,t.method)})),t).info();if(r?.readonly)return new e(t,o);let c=await d(a,{kind:i?.kind??`remote`,label:r?.label??i?.defaultLabel,project:i?.project});return c===void 0?new e(t,o,void 0,!1):new e(t,o,c)}};Object.defineProperty(exports,"a",{enumerable:!0,get:function(){return f}}),Object.defineProperty(exports,"i",{enumerable:!0,get:function(){return y}}),Object.defineProperty(exports,"n",{enumerable:!0,get:function(){return b}}),Object.defineProperty(exports,"o",{enumerable:!0,get:function(){return d}}),Object.defineProperty(exports,"r",{enumerable:!0,get:function(){return S}}),Object.defineProperty(exports,"s",{enumerable:!0,get:function(){return l}}),Object.defineProperty(exports,"t",{enumerable:!0,get:function(){return C}});
3
+ //# sourceMappingURL=at1000-D9r6GCs0.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"at1000-D9r6GCs0.cjs","names":["v","v","canConfig","rs232Config","rs485Config","spiConfig","i2cConfig","uartConfig","canFrame","digitalState","analogState","analogInputConfiguration","analogOutputConfiguration","digitalInputConfiguration","digitalOutputConfiguration","openDrainConfiguration","syncState","text","color","progress","playbackConfiguration","internalKnobEvent","calibrationData","calibrationState","projectEvent","updateStatus","dutState","usbState","relayState","states","format_host_for_url","format_host_for_url","ComApi","HmiApi","GpioApi","ManagementApi","PowerApi","RelaysApi"],"sources":["../src/api/session.ts","../src/api/events.ts","../src/at1000.ts"],"sourcesContent":["import type { UpFetch } from 'up-fetch';\nimport * as v from 'valibot';\n\nimport { parseApiError } from '../at1000';\n\nexport const sessionState = v.object({\n active: v.boolean(),\n kind: v.optional(v.picklist(['remote', 'project'])),\n label: v.optional(v.string()),\n project: v.optional(v.string()),\n since: v.optional(v.number()),\n});\nexport type SessionState = v.InferOutput<typeof sessionState>;\n\n/** Body for `POST /v0/session/open`. */\nexport type SessionOpenBody = { kind: 'remote' | 'project'; label?: string; project?: string };\n\nconst openResponse = v.object({ token: v.string() });\n\n/**\n * Opens an exclusive session on the device (last-open-wins). Returns the minted\n * session token, or `undefined` when the server predates the session model.\n *\n * Deliberately uses a direct `fetch` (not the shared up-fetch client) so the\n * response status is inspectable before any structured-error handler throws:\n * pre-session servers answer the unmatched route with 404/405, which we degrade\n * to `undefined` rather than surface as a failure. A 30 s timeout (not the SDK\n * default 1 s) covers a remote-kind open synchronously stopping any running\n * project container; the host is already known-alive from the preceding info\n * probe, so the long timeout never hangs on dead hosts.\n */\nexport async function open_session(\n baseUrl: string,\n body: SessionOpenBody,\n): Promise<string | undefined> {\n const response = await fetch(`${baseUrl}/session/open`, {\n method: 'POST',\n body: JSON.stringify(body),\n headers: { 'content-type': 'application/json' },\n signal: AbortSignal.timeout(30_000),\n });\n\n if (response.status === 404 || response.status === 405) {\n return undefined; // legacy server without the session model\n }\n if (!response.ok) {\n await parseApiError(response, 'POST');\n }\n\n return v.parse(openResponse, await response.json()).token;\n}\n\n/** @hideconstructor */\nexport class SessionApi {\n constructor(private readonly fetch: UpFetch) {}\n\n /**\n * Reads the current device session state.\n * @returns The active holder (kind/label/project/since) or `{ active: false }`.\n */\n state(): Promise<SessionState> {\n return this.fetch('/session/state', { schema: sessionState });\n }\n}\n","import * as v from 'valibot';\n\nimport { format_host_for_url } from '../host';\nimport {\n canConfig,\n canFrame,\n i2cConfig,\n rs232Config,\n rs485Config,\n spiConfig,\n uartConfig,\n} from './com';\nimport {\n analogInputConfiguration,\n analogOutputConfiguration,\n analogState,\n digitalInputConfiguration,\n digitalOutputConfiguration,\n digitalState,\n openDrainConfiguration,\n syncState,\n} from './gpio';\nimport { color, internalKnobEvent, playbackConfiguration, progress, text } from './hmi';\nimport { calibrationData, calibrationState, projectEvent, updateStatus } from './management';\nimport { dutState, usbState } from './power';\nimport { relayState, states } from './relays';\nimport { sessionState } from './session';\n\n// Receive-side serial bytes. Distinct from com's `serialData`, whose string->bytes\n// transform is for request bodies; events deliver raw byte arrays.\nconst rxBytes = v.array(v.pipe(v.number(), v.integer(), v.minValue(0), v.maxValue(255)));\n\n// Schema for the `data` payload of each event, keyed by the wire `type` literal.\nconst eventDataSchemas = {\n 'com.can_config': canConfig,\n 'com.rs232_config': rs232Config,\n 'com.rs485_config': rs485Config,\n 'com.spi_config': spiConfig,\n 'com.i2c_config': i2cConfig,\n 'com.uart_config': uartConfig,\n 'com.can_rx': v.array(canFrame),\n 'com.uart_rx': rxBytes,\n 'com.rs232_rx': rxBytes,\n 'com.rs485_rx': rxBytes,\n 'gpio.state': v.union([digitalState, analogState]),\n 'gpio.config': v.union([\n analogInputConfiguration,\n analogOutputConfiguration,\n digitalInputConfiguration,\n digitalOutputConfiguration,\n openDrainConfiguration,\n ]),\n // Mirrors the glz::meta of gpio::sync_hold_state_t (apps/server/src/api/resources/gpio.hpp).\n 'gpio.sync': syncState,\n 'hmi.text': text,\n 'hmi.colors': color,\n // `data` absent (progress hidden) is accepted by v.optional.\n 'hmi.progress': v.optional(progress),\n 'hmi.play': playbackConfiguration,\n 'hmi.knob': internalKnobEvent,\n 'management.datetime': v.object({ epoch_seconds: v.number() }),\n 'management.calibration': calibrationData,\n 'management.calibration_state': calibrationState,\n 'management.project': projectEvent,\n 'management.update_status': updateStatus,\n 'power.dut': dutState,\n 'power.usb': usbState,\n 'relays.state': relayState,\n 'relays.states': states,\n 'session.state': sessionState,\n} as const;\n\nconst dataLessEvents = [\n 'com.reset',\n 'gpio.reset',\n 'hmi.clear',\n 'hmi.reset',\n 'power.reset',\n 'relays.reset',\n] as const;\n\nconst envelope = v.object({\n type: v.string(),\n id: v.optional(v.pipe(v.number(), v.integer())),\n ts: v.number(),\n data: v.optional(v.unknown()),\n});\n\ntype EventDataSchemas = typeof eventDataSchemas;\n\n/** Every event `type` literal the server can emit. */\nexport type EventType = keyof EventDataSchemas | (typeof dataLessEvents)[number];\n\ntype PayloadEvent = {\n [K in keyof EventDataSchemas]: {\n type: K;\n id?: number;\n ts: number;\n data: v.InferOutput<EventDataSchemas[K]>;\n };\n}[keyof EventDataSchemas];\n\ntype DataLessEvent = { type: (typeof dataLessEvents)[number]; id?: number; ts: number };\n\n/** A fully-typed device event for a known `type`. */\nexport type DeviceEvent = PayloadEvent | DataLessEvent;\n\n/**\n * Shape delivered to `'*'` listeners. Forward-compatible: a newer server may emit\n * a `type` this SDK does not model, surfaced here with an untyped `data`.\n */\nexport type AnyDeviceEvent = DeviceEvent | {\n type: string;\n id?: number;\n ts: number;\n data?: unknown;\n};\n\ntype EventListener = (event: AnyDeviceEvent) => void;\ntype StateListener = (connected: boolean) => void;\n\nconst reconnectBaseDelayMs = 500;\nconst reconnectMaxDelayMs = 8_000;\nconst defaultConnectTimeoutMs = 5_000;\n\nconst debugLog = (...args: unknown[]): void => console.debug('[at1000:events]', ...args);\n\n/** @hideconstructor */\nexport class EventsApi {\n private socket: WebSocket | undefined;\n private readonly listeners = new Map<string, Set<EventListener>>();\n private readonly stateListeners = new Set<StateListener>();\n private shouldReconnect = false;\n private reconnectDelayMs = reconnectBaseDelayMs;\n private reconnectTimer: ReturnType<typeof setTimeout> | undefined;\n private _connected = false;\n private connectPromise: Promise<void> | undefined;\n\n constructor(private readonly host: string) {}\n\n /** Whether the WebSocket is currently open. */\n get connected(): boolean {\n return this._connected;\n }\n\n /**\n * Open the event stream. Resolves once the socket is open, rejects on failure or\n * after `timeout` ms. A no-op while already connected. Auto-reconnect arms only\n * after the first successful open, so a failed initial `connect()` (e.g. old\n * firmware without `/v0/events`) rejects without scheduling retries.\n */\n async connect(options?: { timeout?: number }): Promise<void> {\n if (typeof WebSocket === 'undefined') {\n throw new Error(\n 'WebSocket is not available in this runtime (Node >= 22, Bun, or a browser is required)',\n );\n }\n if (this._connected) {\n return;\n }\n // Coalesce concurrent opens: the layout holder-banner effect and the\n // projects page both call connect() on the shared per-client socket. Without\n // this a second caller starts a second openSocket() that orphans the first\n // (leaked WS + a connect() that never settles). Reuse the in-flight open.\n this.connectPromise ??= this.openSocket(options?.timeout ?? defaultConnectTimeoutMs);\n try {\n await this.connectPromise;\n } finally {\n this.connectPromise = undefined;\n }\n }\n\n /** Close the stream and cancel any pending reconnect. */\n close(): void {\n this.shouldReconnect = false;\n if (this.reconnectTimer !== undefined) {\n clearTimeout(this.reconnectTimer);\n this.reconnectTimer = undefined;\n }\n const socket = this.socket;\n this.socket = undefined;\n if (socket !== undefined) {\n socket.close();\n }\n this.setConnected(false);\n }\n\n /**\n * Subscribe to an event `type`, or `'*'` for every event. Returns an unsubscribe\n * function. Listeners survive reconnects and are isolated: a throwing listener\n * does not break dispatch to the others.\n */\n on<T extends EventType>(\n type: T,\n listener: (event: Extract<DeviceEvent, { type: T }>) => void,\n ): () => void;\n on(type: '*', listener: (event: AnyDeviceEvent) => void): () => void;\n on(type: string, listener: (event: any) => void): () => void {\n let set = this.listeners.get(type);\n if (set === undefined) {\n set = new Set();\n this.listeners.set(type, set);\n }\n set.add(listener);\n return () => {\n const current = this.listeners.get(type);\n if (current === undefined) {\n return;\n }\n current.delete(listener);\n if (current.size === 0) {\n this.listeners.delete(type);\n }\n };\n }\n\n /** Subscribe to connection state changes. Returns an unsubscribe function. */\n onStateChange(listener: StateListener): () => void {\n this.stateListeners.add(listener);\n return () => {\n this.stateListeners.delete(listener);\n };\n }\n\n private openSocket(timeoutMs: number): Promise<void> {\n const { promise, resolve, reject } = Promise.withResolvers<void>();\n const url = `ws://${format_host_for_url(this.host)}/v0/events`;\n const socket = new WebSocket(url);\n this.socket = socket;\n\n let settled = false;\n const timer = setTimeout(() => {\n if (!settled) {\n settled = true;\n socket.close();\n reject(new Error(`Timed out connecting to ${url}`));\n }\n }, timeoutMs);\n\n socket.onopen = () => {\n if (this.socket !== socket || settled) {\n return;\n }\n settled = true;\n clearTimeout(timer);\n this.shouldReconnect = true;\n this.reconnectDelayMs = reconnectBaseDelayMs;\n this.setConnected(true);\n debugLog('open', url);\n resolve();\n };\n\n socket.onmessage = (event) => {\n if (this.socket === socket) {\n this.handleMessage(event.data);\n }\n };\n\n socket.onerror = () => {\n debugLog('error', url);\n if (this.socket === socket && !settled) {\n settled = true;\n clearTimeout(timer);\n reject(new Error(`Failed to connect to ${url}`));\n }\n };\n\n socket.onclose = () => {\n if (this.socket !== socket) {\n return;\n }\n debugLog('close', url);\n clearTimeout(timer);\n this.setConnected(false);\n if (!settled) {\n settled = true;\n reject(new Error(`Connection to ${url} closed before opening`));\n return;\n }\n if (this.shouldReconnect) {\n this.scheduleReconnect();\n }\n };\n\n return promise;\n }\n\n private scheduleReconnect(): void {\n if (!this.shouldReconnect || this.reconnectTimer !== undefined) {\n return;\n }\n const delay = this.reconnectDelayMs;\n debugLog('reconnecting in', delay, 'ms');\n this.reconnectDelayMs = Math.min(this.reconnectDelayMs * 2, reconnectMaxDelayMs);\n this.reconnectTimer = setTimeout(() => {\n this.reconnectTimer = undefined;\n if (!this.shouldReconnect) {\n return;\n }\n // A failed attempt rejects this promise; onclose then schedules the next retry.\n this.openSocket(defaultConnectTimeoutMs).catch(() => {});\n }, delay);\n }\n\n private handleMessage(data: unknown): void {\n if (typeof data !== 'string') {\n debugLog('drop: non-string frame');\n return;\n }\n let raw: unknown;\n try {\n raw = JSON.parse(data);\n } catch {\n debugLog('drop: invalid JSON', data);\n return;\n }\n\n debugLog('recv', raw);\n const parsed = v.safeParse(envelope, raw);\n if (!parsed.success) {\n debugLog('drop: malformed envelope', parsed.issues);\n return;\n }\n const { type, id, ts } = parsed.output;\n\n if (type in eventDataSchemas) {\n const schema = eventDataSchemas[type as keyof EventDataSchemas] as v.GenericSchema;\n const payload = v.safeParse(schema, parsed.output.data);\n if (!payload.success) {\n debugLog('drop: payload validation failed for', type, payload.issues);\n return;\n }\n const event: AnyDeviceEvent = { type, id, ts, data: payload.output };\n debugLog('dispatch', type);\n this.emitTo(type, event);\n this.emitTo('*', event);\n return;\n }\n\n if ((dataLessEvents as readonly string[]).includes(type)) {\n const event: AnyDeviceEvent = { type, id, ts };\n debugLog('dispatch (dataless)', type);\n this.emitTo(type, event);\n this.emitTo('*', event);\n return;\n }\n\n // Unknown type: deliver the raw envelope to '*' only (server may be newer).\n debugLog('drop: unknown type', type);\n this.emitTo('*', { type, id, ts, data: parsed.output.data });\n }\n\n private emitTo(key: string, event: AnyDeviceEvent): void {\n const set = this.listeners.get(key);\n if (set === undefined) {\n return;\n }\n for (const listener of set) {\n try {\n listener(event);\n } catch {\n // One throwing listener must not break dispatch to the others.\n }\n }\n }\n\n private setConnected(connected: boolean): void {\n if (this._connected === connected) {\n return;\n }\n this._connected = connected;\n for (const listener of this.stateListeners) {\n try {\n listener(connected);\n } catch {\n // Ignore throwing state listeners.\n }\n }\n }\n}\n","import { type UpFetch, up } from 'up-fetch';\n\nimport { ComApi } from './api/com';\nimport { EventsApi } from './api/events';\nimport { GpioApi } from './api/gpio';\nimport { HmiApi } from './api/hmi';\nimport { type Information, ManagementApi } from './api/management';\nimport { PowerApi } from './api/power';\nimport { RelaysApi } from './api/relays';\nimport { SessionApi, open_session } from './api/session';\nimport { format_host_for_url } from './host';\n\n/** Structured error thrown for AT1000 API responses carrying `{ code, message, suggestion, path }`. */\nexport class ApiError extends Error {\n readonly code: string;\n /** Raw human-readable server message (without code/suggestion/path). */\n readonly detail: string;\n readonly suggestion: string;\n readonly path: string;\n\n constructor(body: { code: string; message: string; suggestion: string; path: string }) {\n const formattedSuggestion = body.suggestion.replace(/\\n/g, '\\n ');\n super(\n `${body.message} (${body.code})\\n Suggestion: ${formattedSuggestion}\\n Path: ${body.path}`,\n );\n this.code = body.code;\n this.detail = body.message;\n this.suggestion = body.suggestion;\n this.path = body.path;\n }\n}\n\n/** Type guard for the AT1000 structured error body. */\nfunction isApiErrorBody(\n value: unknown,\n): value is { code: string; message: string; suggestion: string; path: string } {\n if (typeof value !== 'object' || value === null) {\n return false;\n }\n const record = value as Record<string, unknown>;\n return ['code', 'message', 'suggestion', 'path'].every((key) => typeof record[key] === 'string');\n}\n\n/**\n * Shared rejection handler for every AT1000 up-fetch client. Parses a structured\n * `{ code, message, suggestion, path }` body into an {@link ApiError}, otherwise\n * throws a generic error carrying the HTTP status. Written once so the per-client\n * factory and `open_session` share one code path.\n */\nexport async function parseApiError(response: Response, method: string): Promise<never> {\n let errorData: unknown;\n const contentType = response.headers.get('content-type');\n try {\n errorData = contentType?.includes('application/json')\n ? await response.json()\n : await response.text();\n } catch {\n errorData = 'Failed to parse response body';\n }\n\n if (isApiErrorBody(errorData)) {\n throw new ApiError(errorData);\n }\n\n throw new Error(\n `API request to ${method} ${response.url} failed with status ${response.status}: ${\n typeof errorData === 'string' ? errorData : JSON.stringify(errorData)\n }`,\n );\n}\n\n/** Options for opening a device. */\nexport interface OpenOptions {\n /** Open read-only: skip `session/open`, mint no token, send no session header. */\n readonly?: boolean;\n /** Human-readable holder label shown to other clients and on the front panel. */\n label?: string;\n}\n\n/** @hideconstructor */\nexport class AT1000Base {\n /**\n * IP address or hostname of the AT1000 device\n */\n public readonly host: string;\n /**\n * Device information\n */\n public readonly info: Information;\n /**\n * Session token minted by `open()`, or `undefined` for a read-only or legacy\n * (pre-session) client. Sent as the `X-AT1000-Session` header on every request.\n */\n public readonly token: string | undefined;\n /**\n * `false` only when a pre-session server was detected during an exclusive\n * `open()` (no `/v0/session/*` routes). Read-only opens never probe and report `true`.\n */\n public readonly sessionSupported: boolean;\n\n private fetch: UpFetch;\n /**\n * COM API\n */\n public readonly com: ComApi;\n /**\n * HMI API\n */\n public readonly hmi: HmiApi;\n /**\n * GPIO API\n */\n public readonly gpio: GpioApi;\n /**\n * Management API\n */\n public readonly management: ManagementApi;\n /**\n * Power management API\n */\n public readonly power: PowerApi;\n /**\n * Relays API\n */\n public readonly relays: RelaysApi;\n /**\n * Real-time events API (WebSocket). Call `events.connect()` then `events.on(...)`.\n */\n public readonly events: EventsApi;\n /**\n * Session API. Read the current holder via `session.state()`.\n */\n public readonly session: SessionApi;\n\n constructor(host: string, info: Information, token?: string, sessionSupported = true) {\n this.host = host;\n this.info = info;\n this.token = token;\n this.sessionSupported = sessionSupported;\n\n this.fetch = up(\n fetch,\n () => ({\n baseUrl: `http://${format_host_for_url(this.host)}/v0`,\n timeout: 1000,\n headers: this.token\n ? { 'X-AT1000-Session': this.token }\n : undefined,\n parseRejected: (response, request) => parseApiError(response, request.method),\n }),\n );\n\n this.com = new ComApi(this.fetch);\n this.hmi = new HmiApi(this.fetch);\n this.gpio = new GpioApi(this.fetch, this.info);\n this.management = new ManagementApi(this.fetch, this.host);\n this.power = new PowerApi(this.fetch, this.info);\n this.relays = new RelaysApi(this.fetch);\n this.events = new EventsApi(this.host);\n this.session = new SessionApi(this.fetch);\n }\n\n async reset() {\n await this.com.reset();\n await this.hmi.reset();\n await this.gpio.reset();\n await this.power.reset();\n await this.relays.reset();\n }\n\n protected static async openBase(\n host: string,\n options?: OpenOptions,\n session?: { kind: 'remote' | 'project'; project?: string; defaultLabel?: string },\n ): Promise<AT1000Base> {\n if (!host?.trim()) {\n throw new Error(\n 'No device address provided. Pass a host from findDevices() or findLocalDevice().',\n );\n }\n const base = `http://${format_host_for_url(host)}/v0`;\n\n // Re-fetch info to validate reachability (bare client, no session header yet).\n const bare = up(\n fetch,\n () => ({\n baseUrl: base,\n timeout: 1000,\n parseRejected: (response, request) =>\n parseApiError(response, request.method),\n }),\n );\n const info = await new ManagementApi(bare, host).info();\n\n if (options?.readonly) {\n return new AT1000Base(host, info);\n }\n\n const token = await open_session(base, {\n kind: session?.kind ?? 'remote',\n label: options?.label ?? session?.defaultLabel,\n project: session?.project,\n });\n // `undefined` => pre-session server: keep a working, tokenless client.\n return token === undefined\n ? new AT1000Base(host, info, undefined, false)\n : new AT1000Base(host, info, token);\n }\n}\n"],"mappings":"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"}
package/build/browser.cjs CHANGED
@@ -1,2 +1,2 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./package-ByQuarMd.cjs"),t=require("./at1000-DuULyDOw.cjs");var n=class extends t.t{static apiVersion=e.t;static isStandalone(){return!1}static async open(e,n){return await t.t.openBase(e,n)}};exports.AT1000=n,exports.ApiError=t.n,exports.format_host_for_url=t.r,exports.host_without_port=t.i;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./package-DDLRsahz.cjs"),t=require("./management-BGrPAG5k.cjs"),n=require("./at1000-D9r6GCs0.cjs");var r=class extends n.t{static apiVersion=e.t;static isStandalone(){return!1}static async open(e,t){return await n.t.openBase(e,t)}};exports.AT1000=r,exports.ApiError=n.n,exports.format_host_for_url=t.u,exports.host_without_port=t.d;
2
2
  //# sourceMappingURL=browser.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"browser.cjs","names":["AT1000Base","version"],"sources":["../src/browser.ts"],"sourcesContent":["import { version } from '../package.json';\nimport { AT1000Base, type OpenOptions } from './at1000';\n\nexport type { ProjectTemplate } from './api/management';\nexport { ApiError } from './at1000';\nexport { format_host_for_url, host_without_port } from './at1000';\nexport type { OpenOptions } from './at1000';\n\n/** @hideconstructor */\nexport class AT1000 extends AT1000Base {\n static readonly apiVersion = version;\n\n /** The browser never runs on-device; standalone mode is unavailable. */\n static isStandalone(): boolean {\n return false;\n }\n\n /**\n * Opens a device, taking exclusive (remote-kind) access. The browser entry has\n * no in-container detection and no label default; the server falls back to the\n * client IP for the holder label.\n */\n static async open(host: string, options?: OpenOptions): Promise<AT1000> {\n // AT1000 adds no instance state over AT1000Base; the cast is the create-era convention.\n return (await AT1000Base.openBase(host, options)) as AT1000;\n }\n}\n"],"mappings":"gJASA,IAAa,EAAb,cAA4BA,EAAAA,CAAW,CACrC,OAAgB,WAAaC,EAAAA,EAG7B,OAAO,cAAwB,CAC7B,MAAO,EACT,CAOA,aAAa,KAAK,EAAc,EAAwC,CAEtE,OAAQ,MAAMD,EAAAA,EAAW,SAAS,EAAM,CAAO,CACjD,CACF"}
1
+ {"version":3,"file":"browser.cjs","names":["AT1000Base","version"],"sources":["../src/browser.ts"],"sourcesContent":["import { version } from '../package.json';\nimport { AT1000Base, type OpenOptions } from './at1000';\n\nexport type { ProjectTemplate } from './api/management';\nexport { ApiError } from './at1000';\nexport type { OpenOptions } from './at1000';\nexport { format_host_for_url, host_without_port } from './host';\n\n/** @hideconstructor */\nexport class AT1000 extends AT1000Base {\n static readonly apiVersion = version;\n\n /** The browser never runs on-device; standalone mode is unavailable. */\n static isStandalone(): boolean {\n return false;\n }\n\n /**\n * Opens a device, taking exclusive (remote-kind) access. The browser entry has\n * no in-container detection and no label default; the server falls back to the\n * client IP for the holder label.\n */\n static async open(host: string, options?: OpenOptions): Promise<AT1000> {\n // AT1000 adds no instance state over AT1000Base; the cast is the create-era convention.\n return (await AT1000Base.openBase(host, options)) as AT1000;\n }\n}\n"],"mappings":"uLASA,IAAa,EAAb,cAA4BA,EAAAA,CAAW,CACrC,OAAgB,WAAaC,EAAAA,EAG7B,OAAO,cAAwB,CAC7B,MAAO,EACT,CAOA,aAAa,KAAK,EAAc,EAAwC,CAEtE,OAAQ,MAAMD,EAAAA,EAAW,SAAS,EAAM,CAAO,CACjD,CACF"}
@@ -1,5 +1,5 @@
1
1
  import { ProjectTemplate } from "./management.cjs";
2
- import { a as host_without_port, i as format_host_for_url, n as ApiError, r as OpenOptions, t as AT1000Base } from "./at1000-Bk6QeH1q.cjs";
2
+ import { a as OpenOptions, i as ApiError, n as host_without_port, r as AT1000Base, t as format_host_for_url } from "./host-BCOEcUog.cjs";
3
3
  //#region src/browser.d.ts
4
4
  /** @hideconstructor */
5
5
  declare class AT1000 extends AT1000Base {
@@ -1,5 +1,5 @@
1
1
  import { ProjectTemplate } from "./management.mjs";
2
- import { a as host_without_port, i as format_host_for_url, n as ApiError, r as OpenOptions, t as AT1000Base } from "./at1000-BG_IKvW8.mjs";
2
+ import { a as OpenOptions, i as ApiError, n as host_without_port, r as AT1000Base, t as format_host_for_url } from "./host-DJ8SAGMC.mjs";
3
3
  //#region src/browser.d.ts
4
4
  /** @hideconstructor */
5
5
  declare class AT1000 extends AT1000Base {
package/build/browser.mjs CHANGED
@@ -1,2 +1,2 @@
1
- import{t as e}from"./package-gaVXFnhN.mjs";import{i as t,n,r,t as i}from"./at1000-BaJD2vC5.mjs";var a=class extends i{static apiVersion=e;static isStandalone(){return!1}static async open(e,t){return await i.openBase(e,t)}};export{a as AT1000,n as ApiError,r as format_host_for_url,t as host_without_port};
1
+ import{t as e}from"./package-CXtuh0C5.mjs";import{d as t,u as n}from"./management-CuI4cenF.mjs";import{n as r,t as i}from"./at1000-BGZGhgco.mjs";var a=class extends i{static apiVersion=e;static isStandalone(){return!1}static async open(e,t){return await i.openBase(e,t)}};export{a as AT1000,r as ApiError,n as format_host_for_url,t as host_without_port};
2
2
  //# sourceMappingURL=browser.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"browser.mjs","names":[],"sources":["../src/browser.ts"],"sourcesContent":["import { version } from '../package.json';\nimport { AT1000Base, type OpenOptions } from './at1000';\n\nexport type { ProjectTemplate } from './api/management';\nexport { ApiError } from './at1000';\nexport { format_host_for_url, host_without_port } from './at1000';\nexport type { OpenOptions } from './at1000';\n\n/** @hideconstructor */\nexport class AT1000 extends AT1000Base {\n static readonly apiVersion = version;\n\n /** The browser never runs on-device; standalone mode is unavailable. */\n static isStandalone(): boolean {\n return false;\n }\n\n /**\n * Opens a device, taking exclusive (remote-kind) access. The browser entry has\n * no in-container detection and no label default; the server falls back to the\n * client IP for the holder label.\n */\n static async open(host: string, options?: OpenOptions): Promise<AT1000> {\n // AT1000 adds no instance state over AT1000Base; the cast is the create-era convention.\n return (await AT1000Base.openBase(host, options)) as AT1000;\n }\n}\n"],"mappings":"gGASA,IAAa,EAAb,cAA4B,CAAW,CACrC,OAAgB,WAAa,EAG7B,OAAO,cAAwB,CAC7B,MAAO,EACT,CAOA,aAAa,KAAK,EAAc,EAAwC,CAEtE,OAAQ,MAAM,EAAW,SAAS,EAAM,CAAO,CACjD,CACF"}
1
+ {"version":3,"file":"browser.mjs","names":[],"sources":["../src/browser.ts"],"sourcesContent":["import { version } from '../package.json';\nimport { AT1000Base, type OpenOptions } from './at1000';\n\nexport type { ProjectTemplate } from './api/management';\nexport { ApiError } from './at1000';\nexport type { OpenOptions } from './at1000';\nexport { format_host_for_url, host_without_port } from './host';\n\n/** @hideconstructor */\nexport class AT1000 extends AT1000Base {\n static readonly apiVersion = version;\n\n /** The browser never runs on-device; standalone mode is unavailable. */\n static isStandalone(): boolean {\n return false;\n }\n\n /**\n * Opens a device, taking exclusive (remote-kind) access. The browser entry has\n * no in-container detection and no label default; the server falls back to the\n * client IP for the holder label.\n */\n static async open(host: string, options?: OpenOptions): Promise<AT1000> {\n // AT1000 adds no instance state over AT1000Base; the cast is the create-era convention.\n return (await AT1000Base.openBase(host, options)) as AT1000;\n }\n}\n"],"mappings":"iJASA,IAAa,EAAb,cAA4B,CAAW,CACrC,OAAgB,WAAa,EAG7B,OAAO,cAAwB,CAC7B,MAAO,EACT,CAOA,aAAa,KAAK,EAAc,EAAwC,CAEtE,OAAQ,MAAM,EAAW,SAAS,EAAM,CAAO,CACjD,CACF"}
@@ -44,7 +44,7 @@ declare const i2cTransactionRead: v.IntersectSchema<[Omit<v.ObjectSchema<{
44
44
  start?: boolean | undefined;
45
45
  stop?: boolean | undefined;
46
46
  nack_last_byte?: boolean | undefined;
47
- }, v.NumberIssue | v.BooleanIssue | v.ObjectIssue>;
47
+ }, v.BooleanIssue | v.NumberIssue | v.ObjectIssue>;
48
48
  readonly "~types"?: {
49
49
  readonly input: {
50
50
  address: number;
@@ -58,7 +58,7 @@ declare const i2cTransactionRead: v.IntersectSchema<[Omit<v.ObjectSchema<{
58
58
  stop?: boolean | undefined;
59
59
  nack_last_byte?: boolean | undefined;
60
60
  };
61
- readonly issue: v.NumberIssue | v.BooleanIssue | v.ObjectIssue;
61
+ readonly issue: v.BooleanIssue | v.NumberIssue | v.ObjectIssue;
62
62
  } | undefined;
63
63
  }, v.ObjectSchema<{
64
64
  readonly length: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.MinValueAction<number, 1, undefined>, v.MaxValueAction<number, 1024, undefined>]>;
@@ -92,7 +92,7 @@ declare const i2cTransactionWrite: v.IntersectSchema<[Omit<v.ObjectSchema<{
92
92
  start?: boolean | undefined;
93
93
  stop?: boolean | undefined;
94
94
  nack_last_byte?: boolean | undefined;
95
- }, v.NumberIssue | v.BooleanIssue | v.ObjectIssue>;
95
+ }, v.BooleanIssue | v.NumberIssue | v.ObjectIssue>;
96
96
  readonly "~types"?: {
97
97
  readonly input: {
98
98
  address: number;
@@ -106,7 +106,7 @@ declare const i2cTransactionWrite: v.IntersectSchema<[Omit<v.ObjectSchema<{
106
106
  stop?: boolean | undefined;
107
107
  nack_last_byte?: boolean | undefined;
108
108
  };
109
- readonly issue: v.NumberIssue | v.BooleanIssue | v.ObjectIssue;
109
+ readonly issue: v.BooleanIssue | v.NumberIssue | v.ObjectIssue;
110
110
  } | undefined;
111
111
  }, v.ObjectSchema<{
112
112
  readonly data: v.SchemaWithPipe<readonly [v.UnionSchema<[v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MaxLengthAction<string, 65536, undefined>]>, v.SchemaWithPipe<readonly [v.ArraySchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.MinValueAction<number, 0, undefined>, v.MaxValueAction<number, 255, undefined>]>, undefined>, v.MaxLengthAction<number[], 65536, undefined>]>], undefined>, v.TransformAction<string | number[], number[]>]>;
@@ -171,7 +171,7 @@ declare const canConfigPatch: Omit<v.ObjectSchema<{
171
171
  id: number;
172
172
  mask: number;
173
173
  } | undefined;
174
- }, v.NumberIssue | v.BooleanIssue | v.PicklistIssue | v.ObjectIssue>;
174
+ }, v.BooleanIssue | v.PicklistIssue | v.NumberIssue | v.ObjectIssue>;
175
175
  readonly "~types"?: {
176
176
  readonly input: {
177
177
  enabled?: boolean | undefined;
@@ -193,7 +193,7 @@ declare const canConfigPatch: Omit<v.ObjectSchema<{
193
193
  mask: number;
194
194
  } | undefined;
195
195
  };
196
- readonly issue: v.NumberIssue | v.BooleanIssue | v.PicklistIssue | v.ObjectIssue;
196
+ readonly issue: v.BooleanIssue | v.PicklistIssue | v.NumberIssue | v.ObjectIssue;
197
197
  } | undefined;
198
198
  };
199
199
  type CanConfigPatch = v.InferOutput<typeof canConfigPatch>;
@@ -245,7 +245,7 @@ declare const canEnableConfig: Omit<Omit<v.ObjectSchema<{
245
245
  id: number;
246
246
  mask: number;
247
247
  } | undefined;
248
- }, v.NumberIssue | v.BooleanIssue | v.PicklistIssue | v.ObjectIssue>;
248
+ }, v.BooleanIssue | v.PicklistIssue | v.NumberIssue | v.ObjectIssue>;
249
249
  readonly "~types"?: {
250
250
  readonly input: {
251
251
  enabled?: boolean | undefined;
@@ -267,7 +267,7 @@ declare const canEnableConfig: Omit<Omit<v.ObjectSchema<{
267
267
  mask: number;
268
268
  } | undefined;
269
269
  };
270
- readonly issue: v.NumberIssue | v.BooleanIssue | v.PicklistIssue | v.ObjectIssue;
270
+ readonly issue: v.BooleanIssue | v.PicklistIssue | v.NumberIssue | v.ObjectIssue;
271
271
  } | undefined;
272
272
  }, "~types" | "~run" | "~standard" | "entries"> & {
273
273
  readonly entries: Omit<{
@@ -305,7 +305,7 @@ declare const canEnableConfig: Omit<Omit<v.ObjectSchema<{
305
305
  mask: number;
306
306
  } | undefined;
307
307
  termination_resistors?: boolean | undefined;
308
- }, v.NumberIssue | v.BooleanIssue | v.PicklistIssue | v.ObjectIssue>;
308
+ }, v.BooleanIssue | v.PicklistIssue | v.NumberIssue | v.ObjectIssue>;
309
309
  readonly "~types"?: {
310
310
  readonly input: {
311
311
  baud_rate?: 5000 | 10000 | 20000 | 31250 | 33000 | 40000 | 50000 | 80000 | 83300 | 95000 | 100000 | 125000 | 200000 | 250000 | 500000 | 1000000 | undefined;
@@ -325,7 +325,7 @@ declare const canEnableConfig: Omit<Omit<v.ObjectSchema<{
325
325
  } | undefined;
326
326
  termination_resistors?: boolean | undefined;
327
327
  };
328
- readonly issue: v.NumberIssue | v.BooleanIssue | v.PicklistIssue | v.ObjectIssue;
328
+ readonly issue: v.BooleanIssue | v.PicklistIssue | v.NumberIssue | v.ObjectIssue;
329
329
  } | undefined;
330
330
  };
331
331
  type CanEnableConfig = v.InferOutput<typeof canEnableConfig>;
@@ -374,7 +374,7 @@ declare const rs232ConfigPatch: Omit<v.ObjectSchema<{
374
374
  data_bits?: number | undefined;
375
375
  stop_bits?: "1" | "2" | "1.5" | undefined;
376
376
  parity?: "none" | "odd" | "even" | "mark" | "space" | undefined;
377
- }, v.NumberIssue | v.BooleanIssue | v.MaxValueIssue<number, 8> | v.PicklistIssue | v.ObjectIssue | v.MinValueIssue<number, 50> | v.MaxValueIssue<number, 1000000> | v.MinValueIssue<number, 7>>;
377
+ }, v.BooleanIssue | v.PicklistIssue | v.NumberIssue | v.MaxValueIssue<number, 8> | v.ObjectIssue | v.MinValueIssue<number, 50> | v.MaxValueIssue<number, 1000000> | v.MinValueIssue<number, 7>>;
378
378
  readonly "~types"?: {
379
379
  readonly input: {
380
380
  enabled?: boolean | undefined;
@@ -390,7 +390,7 @@ declare const rs232ConfigPatch: Omit<v.ObjectSchema<{
390
390
  stop_bits?: "1" | "2" | "1.5" | undefined;
391
391
  parity?: "none" | "odd" | "even" | "mark" | "space" | undefined;
392
392
  };
393
- readonly issue: v.NumberIssue | v.BooleanIssue | v.MaxValueIssue<number, 8> | v.PicklistIssue | v.ObjectIssue | v.MinValueIssue<number, 50> | v.MaxValueIssue<number, 1000000> | v.MinValueIssue<number, 7>;
393
+ readonly issue: v.BooleanIssue | v.PicklistIssue | v.NumberIssue | v.MaxValueIssue<number, 8> | v.ObjectIssue | v.MinValueIssue<number, 50> | v.MaxValueIssue<number, 1000000> | v.MinValueIssue<number, 7>;
394
394
  } | undefined;
395
395
  };
396
396
  type Rs232ConfigPatch = v.InferOutput<typeof rs232ConfigPatch>;
@@ -427,7 +427,7 @@ declare const rs232EnableConfig: Omit<Omit<v.ObjectSchema<{
427
427
  data_bits?: number | undefined;
428
428
  stop_bits?: "1" | "2" | "1.5" | undefined;
429
429
  parity?: "none" | "odd" | "even" | "mark" | "space" | undefined;
430
- }, v.NumberIssue | v.BooleanIssue | v.MaxValueIssue<number, 8> | v.PicklistIssue | v.ObjectIssue | v.MinValueIssue<number, 50> | v.MaxValueIssue<number, 1000000> | v.MinValueIssue<number, 7>>;
430
+ }, v.BooleanIssue | v.PicklistIssue | v.NumberIssue | v.MaxValueIssue<number, 8> | v.ObjectIssue | v.MinValueIssue<number, 50> | v.MaxValueIssue<number, 1000000> | v.MinValueIssue<number, 7>>;
431
431
  readonly "~types"?: {
432
432
  readonly input: {
433
433
  enabled?: boolean | undefined;
@@ -443,7 +443,7 @@ declare const rs232EnableConfig: Omit<Omit<v.ObjectSchema<{
443
443
  stop_bits?: "1" | "2" | "1.5" | undefined;
444
444
  parity?: "none" | "odd" | "even" | "mark" | "space" | undefined;
445
445
  };
446
- readonly issue: v.NumberIssue | v.BooleanIssue | v.MaxValueIssue<number, 8> | v.PicklistIssue | v.ObjectIssue | v.MinValueIssue<number, 50> | v.MaxValueIssue<number, 1000000> | v.MinValueIssue<number, 7>;
446
+ readonly issue: v.BooleanIssue | v.PicklistIssue | v.NumberIssue | v.MaxValueIssue<number, 8> | v.ObjectIssue | v.MinValueIssue<number, 50> | v.MaxValueIssue<number, 1000000> | v.MinValueIssue<number, 7>;
447
447
  } | undefined;
448
448
  }, "~types" | "~run" | "~standard" | "entries"> & {
449
449
  readonly entries: Omit<{
@@ -469,7 +469,7 @@ declare const rs232EnableConfig: Omit<Omit<v.ObjectSchema<{
469
469
  data_bits?: number | undefined;
470
470
  stop_bits?: "1" | "2" | "1.5" | undefined;
471
471
  parity?: "none" | "odd" | "even" | "mark" | "space" | undefined;
472
- }, v.NumberIssue | v.MaxValueIssue<number, 8> | v.PicklistIssue | v.ObjectIssue | v.MinValueIssue<number, 50> | v.MaxValueIssue<number, 1000000> | v.MinValueIssue<number, 7>>;
472
+ }, v.PicklistIssue | v.NumberIssue | v.MaxValueIssue<number, 8> | v.ObjectIssue | v.MinValueIssue<number, 50> | v.MaxValueIssue<number, 1000000> | v.MinValueIssue<number, 7>>;
473
473
  readonly "~types"?: {
474
474
  readonly input: {
475
475
  baud_rate?: number | undefined;
@@ -483,7 +483,7 @@ declare const rs232EnableConfig: Omit<Omit<v.ObjectSchema<{
483
483
  stop_bits?: "1" | "2" | "1.5" | undefined;
484
484
  parity?: "none" | "odd" | "even" | "mark" | "space" | undefined;
485
485
  };
486
- readonly issue: v.NumberIssue | v.MaxValueIssue<number, 8> | v.PicklistIssue | v.ObjectIssue | v.MinValueIssue<number, 50> | v.MaxValueIssue<number, 1000000> | v.MinValueIssue<number, 7>;
486
+ readonly issue: v.PicklistIssue | v.NumberIssue | v.MaxValueIssue<number, 8> | v.ObjectIssue | v.MinValueIssue<number, 50> | v.MaxValueIssue<number, 1000000> | v.MinValueIssue<number, 7>;
487
487
  } | undefined;
488
488
  };
489
489
  type Rs232EnableConfig = v.InferOutput<typeof rs232EnableConfig>;
@@ -534,7 +534,7 @@ declare const rs485ConfigPatch: Omit<v.ObjectSchema<{
534
534
  stop_bits?: "1" | "2" | "1.5" | undefined;
535
535
  parity?: "none" | "odd" | "even" | "mark" | "space" | undefined;
536
536
  termination_resistors?: boolean | undefined;
537
- }, v.NumberIssue | v.BooleanIssue | v.MaxValueIssue<number, 8> | v.PicklistIssue | v.ObjectIssue | v.MinValueIssue<number, 7> | v.MinValueIssue<number, 300> | v.MaxValueIssue<number, 20000000>>;
537
+ }, v.BooleanIssue | v.PicklistIssue | v.NumberIssue | v.MaxValueIssue<number, 8> | v.ObjectIssue | v.MinValueIssue<number, 7> | v.MinValueIssue<number, 300> | v.MaxValueIssue<number, 20000000>>;
538
538
  readonly "~types"?: {
539
539
  readonly input: {
540
540
  enabled?: boolean | undefined;
@@ -552,7 +552,7 @@ declare const rs485ConfigPatch: Omit<v.ObjectSchema<{
552
552
  parity?: "none" | "odd" | "even" | "mark" | "space" | undefined;
553
553
  termination_resistors?: boolean | undefined;
554
554
  };
555
- readonly issue: v.NumberIssue | v.BooleanIssue | v.MaxValueIssue<number, 8> | v.PicklistIssue | v.ObjectIssue | v.MinValueIssue<number, 7> | v.MinValueIssue<number, 300> | v.MaxValueIssue<number, 20000000>;
555
+ readonly issue: v.BooleanIssue | v.PicklistIssue | v.NumberIssue | v.MaxValueIssue<number, 8> | v.ObjectIssue | v.MinValueIssue<number, 7> | v.MinValueIssue<number, 300> | v.MaxValueIssue<number, 20000000>;
556
556
  } | undefined;
557
557
  };
558
558
  type Rs485ConfigPatch = v.InferOutput<typeof rs485ConfigPatch>;
@@ -594,7 +594,7 @@ declare const rs485EnableConfig: Omit<Omit<v.ObjectSchema<{
594
594
  stop_bits?: "1" | "2" | "1.5" | undefined;
595
595
  parity?: "none" | "odd" | "even" | "mark" | "space" | undefined;
596
596
  termination_resistors?: boolean | undefined;
597
- }, v.NumberIssue | v.BooleanIssue | v.MaxValueIssue<number, 8> | v.PicklistIssue | v.ObjectIssue | v.MinValueIssue<number, 7> | v.MinValueIssue<number, 300> | v.MaxValueIssue<number, 20000000>>;
597
+ }, v.BooleanIssue | v.PicklistIssue | v.NumberIssue | v.MaxValueIssue<number, 8> | v.ObjectIssue | v.MinValueIssue<number, 7> | v.MinValueIssue<number, 300> | v.MaxValueIssue<number, 20000000>>;
598
598
  readonly "~types"?: {
599
599
  readonly input: {
600
600
  enabled?: boolean | undefined;
@@ -612,7 +612,7 @@ declare const rs485EnableConfig: Omit<Omit<v.ObjectSchema<{
612
612
  parity?: "none" | "odd" | "even" | "mark" | "space" | undefined;
613
613
  termination_resistors?: boolean | undefined;
614
614
  };
615
- readonly issue: v.NumberIssue | v.BooleanIssue | v.MaxValueIssue<number, 8> | v.PicklistIssue | v.ObjectIssue | v.MinValueIssue<number, 7> | v.MinValueIssue<number, 300> | v.MaxValueIssue<number, 20000000>;
615
+ readonly issue: v.BooleanIssue | v.PicklistIssue | v.NumberIssue | v.MaxValueIssue<number, 8> | v.ObjectIssue | v.MinValueIssue<number, 7> | v.MinValueIssue<number, 300> | v.MaxValueIssue<number, 20000000>;
616
616
  } | undefined;
617
617
  }, "~types" | "~run" | "~standard" | "entries"> & {
618
618
  readonly entries: Omit<{
@@ -642,7 +642,7 @@ declare const rs485EnableConfig: Omit<Omit<v.ObjectSchema<{
642
642
  data_bits?: number | undefined;
643
643
  stop_bits?: "1" | "2" | "1.5" | undefined;
644
644
  parity?: "none" | "odd" | "even" | "mark" | "space" | undefined;
645
- }, v.NumberIssue | v.BooleanIssue | v.MaxValueIssue<number, 8> | v.PicklistIssue | v.ObjectIssue | v.MinValueIssue<number, 7> | v.MinValueIssue<number, 300> | v.MaxValueIssue<number, 20000000>>;
645
+ }, v.BooleanIssue | v.PicklistIssue | v.NumberIssue | v.MaxValueIssue<number, 8> | v.ObjectIssue | v.MinValueIssue<number, 7> | v.MinValueIssue<number, 300> | v.MaxValueIssue<number, 20000000>>;
646
646
  readonly "~types"?: {
647
647
  readonly input: {
648
648
  baud_rate?: number | undefined;
@@ -658,7 +658,7 @@ declare const rs485EnableConfig: Omit<Omit<v.ObjectSchema<{
658
658
  stop_bits?: "1" | "2" | "1.5" | undefined;
659
659
  parity?: "none" | "odd" | "even" | "mark" | "space" | undefined;
660
660
  };
661
- readonly issue: v.NumberIssue | v.BooleanIssue | v.MaxValueIssue<number, 8> | v.PicklistIssue | v.ObjectIssue | v.MinValueIssue<number, 7> | v.MinValueIssue<number, 300> | v.MaxValueIssue<number, 20000000>;
661
+ readonly issue: v.BooleanIssue | v.PicklistIssue | v.NumberIssue | v.MaxValueIssue<number, 8> | v.ObjectIssue | v.MinValueIssue<number, 7> | v.MinValueIssue<number, 300> | v.MaxValueIssue<number, 20000000>;
662
662
  } | undefined;
663
663
  };
664
664
  type Rs485EnableConfig = v.InferOutput<typeof rs485EnableConfig>;
@@ -697,7 +697,7 @@ declare const spiConfigPatch: Omit<v.ObjectSchema<{
697
697
  baud_rate?: number | undefined;
698
698
  vcc?: number | undefined;
699
699
  mode?: number | undefined;
700
- }, v.NumberIssue | v.BooleanIssue | v.MinValueIssue<number, 0> | v.ObjectIssue | v.MinValueIssue<number, 300> | v.MaxValueIssue<number, 10000000> | v.MinValueIssue<number, 1.6> | v.MaxValueIssue<number, 5> | v.MaxValueIssue<number, 3>>;
700
+ }, v.BooleanIssue | v.NumberIssue | v.MinValueIssue<number, 0> | v.ObjectIssue | v.MinValueIssue<number, 300> | v.MaxValueIssue<number, 10000000> | v.MinValueIssue<number, 1.6> | v.MaxValueIssue<number, 5> | v.MaxValueIssue<number, 3>>;
701
701
  readonly "~types"?: {
702
702
  readonly input: {
703
703
  enabled?: boolean | undefined;
@@ -711,7 +711,7 @@ declare const spiConfigPatch: Omit<v.ObjectSchema<{
711
711
  vcc?: number | undefined;
712
712
  mode?: number | undefined;
713
713
  };
714
- readonly issue: v.NumberIssue | v.BooleanIssue | v.MinValueIssue<number, 0> | v.ObjectIssue | v.MinValueIssue<number, 300> | v.MaxValueIssue<number, 10000000> | v.MinValueIssue<number, 1.6> | v.MaxValueIssue<number, 5> | v.MaxValueIssue<number, 3>;
714
+ readonly issue: v.BooleanIssue | v.NumberIssue | v.MinValueIssue<number, 0> | v.ObjectIssue | v.MinValueIssue<number, 300> | v.MaxValueIssue<number, 10000000> | v.MinValueIssue<number, 1.6> | v.MaxValueIssue<number, 5> | v.MaxValueIssue<number, 3>;
715
715
  } | undefined;
716
716
  };
717
717
  type SpiConfigPatch = v.InferOutput<typeof spiConfigPatch>;
@@ -743,7 +743,7 @@ declare const spiEnableConfig: Omit<Omit<v.ObjectSchema<{
743
743
  baud_rate?: number | undefined;
744
744
  vcc?: number | undefined;
745
745
  mode?: number | undefined;
746
- }, v.NumberIssue | v.BooleanIssue | v.MinValueIssue<number, 0> | v.ObjectIssue | v.MinValueIssue<number, 300> | v.MaxValueIssue<number, 10000000> | v.MinValueIssue<number, 1.6> | v.MaxValueIssue<number, 5> | v.MaxValueIssue<number, 3>>;
746
+ }, v.BooleanIssue | v.NumberIssue | v.MinValueIssue<number, 0> | v.ObjectIssue | v.MinValueIssue<number, 300> | v.MaxValueIssue<number, 10000000> | v.MinValueIssue<number, 1.6> | v.MaxValueIssue<number, 5> | v.MaxValueIssue<number, 3>>;
747
747
  readonly "~types"?: {
748
748
  readonly input: {
749
749
  enabled?: boolean | undefined;
@@ -757,7 +757,7 @@ declare const spiEnableConfig: Omit<Omit<v.ObjectSchema<{
757
757
  vcc?: number | undefined;
758
758
  mode?: number | undefined;
759
759
  };
760
- readonly issue: v.NumberIssue | v.BooleanIssue | v.MinValueIssue<number, 0> | v.ObjectIssue | v.MinValueIssue<number, 300> | v.MaxValueIssue<number, 10000000> | v.MinValueIssue<number, 1.6> | v.MaxValueIssue<number, 5> | v.MaxValueIssue<number, 3>;
760
+ readonly issue: v.BooleanIssue | v.NumberIssue | v.MinValueIssue<number, 0> | v.ObjectIssue | v.MinValueIssue<number, 300> | v.MaxValueIssue<number, 10000000> | v.MinValueIssue<number, 1.6> | v.MaxValueIssue<number, 5> | v.MaxValueIssue<number, 3>;
761
761
  } | undefined;
762
762
  }, "~types" | "~run" | "~standard" | "entries"> & {
763
763
  readonly entries: Omit<{
@@ -824,7 +824,7 @@ declare const i2cConfigPatch: Omit<v.ObjectSchema<{
824
824
  enabled?: boolean | undefined;
825
825
  baud_rate?: 100000 | 1000000 | 400000 | undefined;
826
826
  vcc?: number | undefined;
827
- }, v.NumberIssue | v.BooleanIssue | v.PicklistIssue | v.ObjectIssue | v.MinValueIssue<number, 1.6> | v.MaxValueIssue<number, 5>>;
827
+ }, v.BooleanIssue | v.PicklistIssue | v.NumberIssue | v.ObjectIssue | v.MinValueIssue<number, 1.6> | v.MaxValueIssue<number, 5>>;
828
828
  readonly "~types"?: {
829
829
  readonly input: {
830
830
  enabled?: boolean | undefined;
@@ -836,7 +836,7 @@ declare const i2cConfigPatch: Omit<v.ObjectSchema<{
836
836
  baud_rate?: 100000 | 1000000 | 400000 | undefined;
837
837
  vcc?: number | undefined;
838
838
  };
839
- readonly issue: v.NumberIssue | v.BooleanIssue | v.PicklistIssue | v.ObjectIssue | v.MinValueIssue<number, 1.6> | v.MaxValueIssue<number, 5>;
839
+ readonly issue: v.BooleanIssue | v.PicklistIssue | v.NumberIssue | v.ObjectIssue | v.MinValueIssue<number, 1.6> | v.MaxValueIssue<number, 5>;
840
840
  } | undefined;
841
841
  };
842
842
  type I2cConfigPatch = v.InferOutput<typeof i2cConfigPatch>;
@@ -863,7 +863,7 @@ declare const i2cEnableConfig: Omit<Omit<v.ObjectSchema<{
863
863
  enabled?: boolean | undefined;
864
864
  baud_rate?: 100000 | 1000000 | 400000 | undefined;
865
865
  vcc?: number | undefined;
866
- }, v.NumberIssue | v.BooleanIssue | v.PicklistIssue | v.ObjectIssue | v.MinValueIssue<number, 1.6> | v.MaxValueIssue<number, 5>>;
866
+ }, v.BooleanIssue | v.PicklistIssue | v.NumberIssue | v.ObjectIssue | v.MinValueIssue<number, 1.6> | v.MaxValueIssue<number, 5>>;
867
867
  readonly "~types"?: {
868
868
  readonly input: {
869
869
  enabled?: boolean | undefined;
@@ -875,7 +875,7 @@ declare const i2cEnableConfig: Omit<Omit<v.ObjectSchema<{
875
875
  baud_rate?: 100000 | 1000000 | 400000 | undefined;
876
876
  vcc?: number | undefined;
877
877
  };
878
- readonly issue: v.NumberIssue | v.BooleanIssue | v.PicklistIssue | v.ObjectIssue | v.MinValueIssue<number, 1.6> | v.MaxValueIssue<number, 5>;
878
+ readonly issue: v.BooleanIssue | v.PicklistIssue | v.NumberIssue | v.ObjectIssue | v.MinValueIssue<number, 1.6> | v.MaxValueIssue<number, 5>;
879
879
  } | undefined;
880
880
  }, "~types" | "~run" | "~standard" | "entries"> & {
881
881
  readonly entries: Omit<{
@@ -893,7 +893,7 @@ declare const i2cEnableConfig: Omit<Omit<v.ObjectSchema<{
893
893
  readonly "~run": (dataset: v.UnknownDataset, config: v.Config<v.BaseIssue<unknown>>) => v.OutputDataset<{
894
894
  baud_rate?: 100000 | 1000000 | 400000 | undefined;
895
895
  vcc?: number | undefined;
896
- }, v.NumberIssue | v.PicklistIssue | v.ObjectIssue | v.MinValueIssue<number, 1.6> | v.MaxValueIssue<number, 5>>;
896
+ }, v.PicklistIssue | v.NumberIssue | v.ObjectIssue | v.MinValueIssue<number, 1.6> | v.MaxValueIssue<number, 5>>;
897
897
  readonly "~types"?: {
898
898
  readonly input: {
899
899
  baud_rate?: 100000 | 1000000 | 400000 | undefined;
@@ -903,7 +903,7 @@ declare const i2cEnableConfig: Omit<Omit<v.ObjectSchema<{
903
903
  baud_rate?: 100000 | 1000000 | 400000 | undefined;
904
904
  vcc?: number | undefined;
905
905
  };
906
- readonly issue: v.NumberIssue | v.PicklistIssue | v.ObjectIssue | v.MinValueIssue<number, 1.6> | v.MaxValueIssue<number, 5>;
906
+ readonly issue: v.PicklistIssue | v.NumberIssue | v.ObjectIssue | v.MinValueIssue<number, 1.6> | v.MaxValueIssue<number, 5>;
907
907
  } | undefined;
908
908
  };
909
909
  type I2cEnableConfig = v.InferOutput<typeof i2cEnableConfig>;
@@ -954,7 +954,7 @@ declare const uartConfigPatch: Omit<v.ObjectSchema<{
954
954
  data_bits?: number | undefined;
955
955
  stop_bits?: "1" | "2" | "1.5" | undefined;
956
956
  parity?: "none" | "odd" | "even" | "mark" | "space" | undefined;
957
- }, v.NumberIssue | v.BooleanIssue | v.MaxValueIssue<number, 8> | v.PicklistIssue | v.ObjectIssue | v.MinValueIssue<number, 7> | v.MinValueIssue<number, 300> | v.MinValueIssue<number, 1.6> | v.MaxValueIssue<number, 5> | v.MaxValueIssue<number, 12000000>>;
957
+ }, v.BooleanIssue | v.PicklistIssue | v.NumberIssue | v.MaxValueIssue<number, 8> | v.ObjectIssue | v.MinValueIssue<number, 7> | v.MinValueIssue<number, 300> | v.MinValueIssue<number, 1.6> | v.MaxValueIssue<number, 5> | v.MaxValueIssue<number, 12000000>>;
958
958
  readonly "~types"?: {
959
959
  readonly input: {
960
960
  enabled?: boolean | undefined;
@@ -972,7 +972,7 @@ declare const uartConfigPatch: Omit<v.ObjectSchema<{
972
972
  stop_bits?: "1" | "2" | "1.5" | undefined;
973
973
  parity?: "none" | "odd" | "even" | "mark" | "space" | undefined;
974
974
  };
975
- readonly issue: v.NumberIssue | v.BooleanIssue | v.MaxValueIssue<number, 8> | v.PicklistIssue | v.ObjectIssue | v.MinValueIssue<number, 7> | v.MinValueIssue<number, 300> | v.MinValueIssue<number, 1.6> | v.MaxValueIssue<number, 5> | v.MaxValueIssue<number, 12000000>;
975
+ readonly issue: v.BooleanIssue | v.PicklistIssue | v.NumberIssue | v.MaxValueIssue<number, 8> | v.ObjectIssue | v.MinValueIssue<number, 7> | v.MinValueIssue<number, 300> | v.MinValueIssue<number, 1.6> | v.MaxValueIssue<number, 5> | v.MaxValueIssue<number, 12000000>;
976
976
  } | undefined;
977
977
  };
978
978
  type UartConfigPatch = v.InferOutput<typeof uartConfigPatch>;
@@ -1014,7 +1014,7 @@ declare const uartEnableConfig: Omit<Omit<v.ObjectSchema<{
1014
1014
  data_bits?: number | undefined;
1015
1015
  stop_bits?: "1" | "2" | "1.5" | undefined;
1016
1016
  parity?: "none" | "odd" | "even" | "mark" | "space" | undefined;
1017
- }, v.NumberIssue | v.BooleanIssue | v.MaxValueIssue<number, 8> | v.PicklistIssue | v.ObjectIssue | v.MinValueIssue<number, 7> | v.MinValueIssue<number, 300> | v.MinValueIssue<number, 1.6> | v.MaxValueIssue<number, 5> | v.MaxValueIssue<number, 12000000>>;
1017
+ }, v.BooleanIssue | v.PicklistIssue | v.NumberIssue | v.MaxValueIssue<number, 8> | v.ObjectIssue | v.MinValueIssue<number, 7> | v.MinValueIssue<number, 300> | v.MinValueIssue<number, 1.6> | v.MaxValueIssue<number, 5> | v.MaxValueIssue<number, 12000000>>;
1018
1018
  readonly "~types"?: {
1019
1019
  readonly input: {
1020
1020
  enabled?: boolean | undefined;
@@ -1032,7 +1032,7 @@ declare const uartEnableConfig: Omit<Omit<v.ObjectSchema<{
1032
1032
  stop_bits?: "1" | "2" | "1.5" | undefined;
1033
1033
  parity?: "none" | "odd" | "even" | "mark" | "space" | undefined;
1034
1034
  };
1035
- readonly issue: v.NumberIssue | v.BooleanIssue | v.MaxValueIssue<number, 8> | v.PicklistIssue | v.ObjectIssue | v.MinValueIssue<number, 7> | v.MinValueIssue<number, 300> | v.MinValueIssue<number, 1.6> | v.MaxValueIssue<number, 5> | v.MaxValueIssue<number, 12000000>;
1035
+ readonly issue: v.BooleanIssue | v.PicklistIssue | v.NumberIssue | v.MaxValueIssue<number, 8> | v.ObjectIssue | v.MinValueIssue<number, 7> | v.MinValueIssue<number, 300> | v.MinValueIssue<number, 1.6> | v.MaxValueIssue<number, 5> | v.MaxValueIssue<number, 12000000>;
1036
1036
  } | undefined;
1037
1037
  }, "~types" | "~run" | "~standard" | "entries"> & {
1038
1038
  readonly entries: Omit<{
@@ -1062,7 +1062,7 @@ declare const uartEnableConfig: Omit<Omit<v.ObjectSchema<{
1062
1062
  stop_bits?: "1" | "2" | "1.5" | undefined;
1063
1063
  parity?: "none" | "odd" | "even" | "mark" | "space" | undefined;
1064
1064
  vcc?: number | undefined;
1065
- }, v.NumberIssue | v.MaxValueIssue<number, 8> | v.PicklistIssue | v.ObjectIssue | v.MinValueIssue<number, 7> | v.MinValueIssue<number, 300> | v.MinValueIssue<number, 1.6> | v.MaxValueIssue<number, 5> | v.MaxValueIssue<number, 12000000>>;
1065
+ }, v.PicklistIssue | v.NumberIssue | v.MaxValueIssue<number, 8> | v.ObjectIssue | v.MinValueIssue<number, 7> | v.MinValueIssue<number, 300> | v.MinValueIssue<number, 1.6> | v.MaxValueIssue<number, 5> | v.MaxValueIssue<number, 12000000>>;
1066
1066
  readonly "~types"?: {
1067
1067
  readonly input: {
1068
1068
  baud_rate?: number | undefined;
@@ -1078,7 +1078,7 @@ declare const uartEnableConfig: Omit<Omit<v.ObjectSchema<{
1078
1078
  parity?: "none" | "odd" | "even" | "mark" | "space" | undefined;
1079
1079
  vcc?: number | undefined;
1080
1080
  };
1081
- readonly issue: v.NumberIssue | v.MaxValueIssue<number, 8> | v.PicklistIssue | v.ObjectIssue | v.MinValueIssue<number, 7> | v.MinValueIssue<number, 300> | v.MinValueIssue<number, 1.6> | v.MaxValueIssue<number, 5> | v.MaxValueIssue<number, 12000000>;
1081
+ readonly issue: v.PicklistIssue | v.NumberIssue | v.MaxValueIssue<number, 8> | v.ObjectIssue | v.MinValueIssue<number, 7> | v.MinValueIssue<number, 300> | v.MinValueIssue<number, 1.6> | v.MaxValueIssue<number, 5> | v.MaxValueIssue<number, 12000000>;
1082
1082
  } | undefined;
1083
1083
  };
1084
1084
  type UartEnableConfig = v.InferOutput<typeof uartEnableConfig>;
@@ -1433,4 +1433,4 @@ declare class Uart {
1433
1433
  }
1434
1434
  //#endregion
1435
1435
  export { UartConfig as A, rs485Config as B, SerialParity as C, SpiConfigPatch as D, SpiConfig as E, UsbState as F, uartConfig as H, canConfig as I, canFrame as L, UartEnableConfig as M, UsbDevice as N, SpiEnableConfig as O, UsbInterface as P, i2cConfig as R, SerialDataInput as S, Spi as T, spiConfig as V, Rs485 as _, CanFrame as a, Rs485EnableConfig as b, ComUsb as c, I2cConfigPatch as d, I2cEnableConfig as f, Rs232EnableConfig as g, Rs232ConfigPatch as h, CanEnableConfig as i, UartConfigPatch as j, Uart as k, I2c as l, Rs232Config as m, CanConfig as n, CanFrameInput as o, Rs232 as p, CanConfigPatch as r, ComApi as s, Can as t, I2cConfig as u, Rs485Config as v, SerialStopBits as w, SerialData as x, Rs485ConfigPatch as y, rs232Config as z };
1436
- //# sourceMappingURL=com-B2R6yhB4.d.cts.map
1436
+ //# sourceMappingURL=com-XQjoTBdU.d.cts.map