{"version":3,"file":"sntp-host.mjs","names":[],"sources":["../../src/hosts/sntp-host.ts"],"sourcesContent":["/* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD */\n/* SPDX-License-Identifier: Apache-2.0 */\n\n/**\n * In-memory BrookesiaHost for SNTP — Node/vitest only, not used on device.\n * Import: `@brookesia/service/hosts/sntp`\n */\n\nimport type { BrookesiaHost } from '../common/brookesia-host.ts';\nimport { serializeRpcError, serializeRpcResult } from '../common/rpc-json.ts';\nimport { SNTP_FUNCTIONS, SNTP_SERVICE_NAME } from '../sntp/sntp-client.ts';\nimport type { SntpState } from '../sntp/sntp-types.ts';\n\ntype SntpMockState = {\n  servers: string[];\n  timezone: string;\n  state: SntpState;\n  timeSynced: boolean;\n};\n\nlet nextHandle = 1;\nconst handles = new Map<number, SntpMockState>();\n\nfunction defaultState(): SntpMockState {\n  return {\n    servers: ['pool.ntp.org'],\n    timezone: 'UTC0',\n    state: 'Stopped',\n    timeSynced: false,\n  };\n}\n\nfunction getState(handle: number): SntpMockState {\n  const state = handles.get(handle);\n  if (!state) {\n    throw new Error(`SNTP memory host: invalid handle ${handle}`);\n  }\n  return state;\n}\n\nexport type SntpHostOptions = Partial<SntpMockState>;\n\nexport function createSntpHost(initial?: SntpHostOptions): BrookesiaHost {\n  const seed = { ...defaultState(), ...initial };\n\n  return {\n    service_available(name: string): boolean {\n      return name === SNTP_SERVICE_NAME;\n    },\n\n    start_service(name: string): number {\n      if (name !== SNTP_SERVICE_NAME) {\n        throw new Error(`SNTP memory host: unknown service ${name}`);\n      }\n      const handle = nextHandle++;\n      handles.set(handle, {\n        ...defaultState(),\n        servers: [...seed.servers],\n        timezone: seed.timezone,\n        state: seed.state,\n        timeSynced: seed.timeSynced,\n      });\n      return handle;\n    },\n\n    stop_service(handle: number): void {\n      handles.delete(handle);\n    },\n\n    call_function(handle: number, functionName: string, paramsJson: string): string {\n      const state = getState(handle);\n      const params = JSON.parse(paramsJson) as Record<string, unknown>;\n\n      try {\n        if (functionName === SNTP_FUNCTIONS.SetServers) {\n          state.servers = [...(params.Servers as string[])];\n          return serializeRpcResult();\n        }\n\n        if (functionName === SNTP_FUNCTIONS.SetTimezone) {\n          state.timezone = String(params.Timezone ?? '');\n          return serializeRpcResult();\n        }\n\n        if (functionName === SNTP_FUNCTIONS.Start) {\n          state.state = 'Syncing';\n          state.timeSynced = false;\n          state.state = 'Synced';\n          state.timeSynced = true;\n          return serializeRpcResult();\n        }\n\n        if (functionName === SNTP_FUNCTIONS.Stop) {\n          state.state = 'Stopped';\n          state.timeSynced = false;\n          return serializeRpcResult();\n        }\n\n        if (functionName === SNTP_FUNCTIONS.GetServers) {\n          return serializeRpcResult([...state.servers]);\n        }\n\n        if (functionName === SNTP_FUNCTIONS.GetTimezone) {\n          return serializeRpcResult(state.timezone);\n        }\n\n        if (functionName === SNTP_FUNCTIONS.GetState) {\n          return serializeRpcResult(state.state);\n        }\n\n        if (functionName === SNTP_FUNCTIONS.IsTimeSynced) {\n          return serializeRpcResult(state.timeSynced);\n        }\n\n        if (functionName === SNTP_FUNCTIONS.LoadData) {\n          return serializeRpcResult();\n        }\n\n        if (functionName === SNTP_FUNCTIONS.ResetData) {\n          Object.assign(state, defaultState());\n          return serializeRpcResult();\n        }\n\n        return serializeRpcError(`unknown function ${functionName}`);\n      } catch (err) {\n        const message = err instanceof Error ? err.message : String(err);\n        return serializeRpcError(message);\n      }\n    },\n  };\n}\n\nexport function resetSntpHostState(): void {\n  handles.clear();\n  nextHandle = 1;\n}\n"],"mappings":";;;AAoBA,IAAI,aAAa;AACjB,MAAM,0BAAU,IAAI,IAA2B;AAE/C,SAAS,eAA8B;CACrC,OAAO;EACL,SAAS,CAAC,cAAc;EACxB,UAAU;EACV,OAAO;EACP,YAAY;CACd;AACF;AAEA,SAAS,SAAS,QAA+B;CAC/C,MAAM,QAAQ,QAAQ,IAAI,MAAM;CAChC,IAAI,CAAC,OACH,MAAM,IAAI,MAAM,oCAAoC,QAAQ;CAE9D,OAAO;AACT;AAIA,SAAgB,eAAe,SAA0C;CACvE,MAAM,OAAO;EAAE,GAAG,aAAa;EAAG,GAAG;CAAQ;CAE7C,OAAO;EACL,kBAAkB,MAAuB;GACvC,OAAO,SAAS;EAClB;EAEA,cAAc,MAAsB;GAClC,IAAI,SAAA,QACF,MAAM,IAAI,MAAM,qCAAqC,MAAM;GAE7D,MAAM,SAAS;GACf,QAAQ,IAAI,QAAQ;IAClB,GAAG,aAAa;IAChB,SAAS,CAAC,GAAG,KAAK,OAAO;IACzB,UAAU,KAAK;IACf,OAAO,KAAK;IACZ,YAAY,KAAK;GACnB,CAAC;GACD,OAAO;EACT;EAEA,aAAa,QAAsB;GACjC,QAAQ,OAAO,MAAM;EACvB;EAEA,cAAc,QAAgB,cAAsB,YAA4B;GAC9E,MAAM,QAAQ,SAAS,MAAM;GAC7B,MAAM,SAAS,KAAK,MAAM,UAAU;GAEpC,IAAI;IACF,IAAI,iBAAiB,eAAe,YAAY;KAC9C,MAAM,UAAU,CAAC,GAAI,OAAO,OAAoB;KAChD,OAAO,mBAAmB;IAC5B;IAEA,IAAI,iBAAiB,eAAe,aAAa;KAC/C,MAAM,WAAW,OAAO,OAAO,YAAY,EAAE;KAC7C,OAAO,mBAAmB;IAC5B;IAEA,IAAI,iBAAiB,eAAe,OAAO;KACzC,MAAM,QAAQ;KACd,MAAM,aAAa;KACnB,MAAM,QAAQ;KACd,MAAM,aAAa;KACnB,OAAO,mBAAmB;IAC5B;IAEA,IAAI,iBAAiB,eAAe,MAAM;KACxC,MAAM,QAAQ;KACd,MAAM,aAAa;KACnB,OAAO,mBAAmB;IAC5B;IAEA,IAAI,iBAAiB,eAAe,YAClC,OAAO,mBAAmB,CAAC,GAAG,MAAM,OAAO,CAAC;IAG9C,IAAI,iBAAiB,eAAe,aAClC,OAAO,mBAAmB,MAAM,QAAQ;IAG1C,IAAI,iBAAiB,eAAe,UAClC,OAAO,mBAAmB,MAAM,KAAK;IAGvC,IAAI,iBAAiB,eAAe,cAClC,OAAO,mBAAmB,MAAM,UAAU;IAG5C,IAAI,iBAAiB,eAAe,UAClC,OAAO,mBAAmB;IAG5B,IAAI,iBAAiB,eAAe,WAAW;KAC7C,OAAO,OAAO,OAAO,aAAa,CAAC;KACnC,OAAO,mBAAmB;IAC5B;IAEA,OAAO,kBAAkB,oBAAoB,cAAc;GAC7D,SAAS,KAAK;IAEZ,OAAO,kBADS,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAC/B;GAClC;EACF;CACF;AACF;AAEA,SAAgB,qBAA2B;CACzC,QAAQ,MAAM;CACd,aAAa;AACf"}