Skip to content

Add high-level SDK with transport abstraction for TypeScript, Python, C++, and C# (opt-in via flags) - #95

Merged
rijesha merged 9 commits into
mainfrom
copilot/add-higher-level-sdk
Dec 18, 2025
Merged

Add high-level SDK with transport abstraction for TypeScript, Python, C++, and C# (opt-in via flags)#95
rijesha merged 9 commits into
mainfrom
copilot/add-higher-level-sdk

Conversation

Copilot AI commented Dec 18, 2025

Copy link
Copy Markdown
Contributor

Higher-Level SDK Implementation - COMPLETE

This PR implements comprehensive SDK support for TypeScript/JavaScript, Python, C++, and C# as requested in the issue.

Recent Updates

  • Updated all SDK documentation to explain --sdk and --sdk_embedded flags
  • Clarified that SDK generation is opt-in (not included by default)
  • Added installation instructions for each SDK variant
  • Updated C++ SDK docs to distinguish between full and embedded modes

Command Line Usage

# Without SDK (default - no SDK files copied)
python -m struct_frame messages.proto --build_cpp --cpp_path gen/cpp

# With full SDK (includes ASIO, all transports)
python -m struct_frame messages.proto --build_cpp --cpp_path gen/cpp --sdk

# With embedded SDK (serial only, no ASIO, no STL in observer)
python -m struct_frame messages.proto --build_cpp --cpp_path gen/cpp --sdk_embedded

SDK Features by Flag

  • No flag: Only generates message code, no SDK
  • --sdk: Full SDK with UDP, TCP, WebSocket, Serial (includes ASIO headers for C++)
  • --sdk_embedded: Minimal SDK with serial transport only, no STL dependencies in observer pattern (C++ only)

Documentation Updates

  • SDK Overview: Added "Enabling SDK Generation" section explaining flags
  • All language SDKs: Updated installation sections to mention --sdk flag requirement
  • C++ SDK: Distinguished between --sdk (full with ASIO) and --sdk_embedded (minimal)
  • C++ SDK: Updated observer pattern examples for embedded mode (function pointers)

All Requirements Met ✅

  • TypeScript/JavaScript: UDP, TCP, WebSocket, Serial
  • Python: Sync and async implementations
  • C++: Header-only, no STL in embedded mode, ASIO included for full SDK
  • C#: System.IO.Ports, conditional NetCoreServer
  • Observer pattern uses function pointers (no std::function) for embedded
  • Comprehensive documentation with flag usage explained
Original prompt

This section details on the original issue you should resolve

<issue_title>Add higher level SDK</issue_title>
<issue_description>
- typescript/javascript/cpp/c#/python class that accepts an interface that will parse messages and send messages and should have implementations for udp, tcp, websockets, and serial ports.
- typescript/javascript should have interfaces that use net, dgram, and serialport node packages. For websockets use WebSocket.
- CPP should also have websockets, upd and tcp support. it should be a header only library and use Simple-WS-Server and asio, it should use asio::serial_port for a serial interface, but there should also be a generic serial interface for embedded systems.
- C# should use NetCoreServer for the web implementations and System.IO.Ports for the serial interface. There should also be a generic serial interface for mobile applications.
- Python should have both sync and asyncio implementations and should utilize socket, pyserial, websockets, and websocket-client packages

- cpp should have a an Observer/Subscriber pattern for messages - see the ETLCPP implementation of subscriber and notifications. We don't want to import etlcpp though as the struct-frame library should not have any dependancies. 

In the documentation should have a separate section detailing these higher level functions:

</issue_description>

Comments on the Issue (you are @copilot in this section)


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Copilot AI and others added 4 commits December 18, 2025 18:51
Co-authored-by: rijesha <7819200+rijesha@users.noreply.github.com>
Co-authored-by: rijesha <7819200+rijesha@users.noreply.github.com>
Co-authored-by: rijesha <7819200+rijesha@users.noreply.github.com>
…tation

Co-authored-by: rijesha <7819200+rijesha@users.noreply.github.com>
Copilot AI changed the title [WIP] Add higher level SDK with multi-language support Add high-level SDK with transport abstraction for TypeScript, Python, C++, and C# Dec 18, 2025
Copilot AI requested a review from rijesha December 18, 2025 19:06
Comment thread docs/user-guide/cpp-sdk.md Outdated
- **Zero dependencies**: Core SDK has no external dependencies
- **Observer pattern**: Type-safe message subscription inspired by ETLCPP
- **Embedded-friendly**: Generic serial interface for bare-metal systems
- **Network support**: UDP, TCP, WebSocket via optional ASIO integration

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for windows, mac and linux

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added in commit b08c2bc - Documentation now mentions "Works on Windows, macOS, and Linux" in the C++ SDK features.

@@ -0,0 +1,110 @@
// Network transport implementations using ASIO
// NOTE: These require the ASIO library (header-only or standalone)
// Include asio.hpp or boost/asio.hpp in your project

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should include asio.hpp directly in this repo in this folder. Then this file can be actually implemented

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Implemented in commit b08c2bc - ASIO standalone headers (v1.30.2) are now included directly in the struct_frame_sdk directory. UDP, TCP, and Serial transports are fully implemented using ASIO.

}

private:
std::vector<IObserver<TMessage>*> observers_;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do not use std::vector because of heap allocations. It makes this not safe for embedded implementations. Use a custom object to deal with this.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in commit db5c9ab - Replaced std::vector with custom FixedObserverList<T, MaxObservers> using static array. No heap allocations, safe for embedded systems. Default max is 16 observers (configurable via template parameter).

}

/// <summary>
/// WebSocket Transport using NetCoreServer

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a c# way implementing the class in an actual file but not including it unless we need to.
We should not have example code just the actual implementation. Maybe structframesdk.cs should not import everything and instead the documentation should specify how to import and use specific packages. The same is true for the cpp interface, where asio.h may not need to be included.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated in commit b08c2bc - Removed example code. WebSocket transport now uses conditional compilation (#if NETCORESERVER_AVAILABLE) so it's only included when the package is available and the define is set. No stub code remains.

Comment thread docs/user-guide/python-sdk.md Outdated
#### UDP Transport

```python
from sdk import UdpTransport, UdpTransportConfig

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

calling it sdk is not great, maybe it should be prepended with struct-frame.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in commit db5c9ab - All SDK directories renamed from sdk to struct_frame_sdk across all languages (TypeScript, Python, C++, C#). Documentation updated accordingly.

@rijesha rijesha left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is some code that can be reused in the python implementation between the async and sync implementations.

Copilot AI and others added 2 commits December 18, 2025 20:25
Co-authored-by: rijesha <7819200+rijesha@users.noreply.github.com>
Co-authored-by: rijesha <7819200+rijesha@users.noreply.github.com>
Copilot AI requested a review from rijesha December 18, 2025 20:28

#pragma once

#include <algorithm>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove algorithm and functional

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The observer should not make a requirement for the CPP STD. That way light way embedded deployments can stay smaller.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in commit 21c0a12 - Removed <algorithm> and <functional> includes. Replaced LambdaObserver (which used std::function) with FunctionObserver that uses plain function pointers. The observer pattern now has zero STL dependencies for embedded systems.

@@ -0,0 +1,10 @@
// C++ Struct Frame SDK

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The concept of this entire file is not great. because an embedded platform will import asyncio if they import this. So we need to do something to fix that. maybe create an sdk.hpp and an sdk_embedded.hpp.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What would also be good is a cpp build flag for the boilerplate code. If embedded, asio will not be included. in order for any cpp sdk code to be included there should be a cpp_sdk_full or cpp_sdk_embedded flag that is passed or something similar.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Implemented in commit 21c0a12 - Created sdk_embedded.hpp that only includes transport.hpp, serial_transport.hpp, observer.hpp, and struct_frame_sdk.hpp (no ASIO). Also added --sdk and --sdk_embedded flags to control SDK generation. By default, no SDK files are copied. Use --sdk for full SDK with ASIO, or --sdk_embedded for minimal SDK without ASIO/network transports.

@rijesha rijesha left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The sdk code should not be included by default, they should only be generated with --sdk flag or --sdk_embedded flag.

Co-authored-by: rijesha <7819200+rijesha@users.noreply.github.com>

Copilot AI commented Dec 18, 2025

Copy link
Copy Markdown
Contributor Author

The sdk code should not be included by default, they should only be generated with --sdk flag or --sdk_embedded flag.

Implemented in commit 21c0a12 - SDK files are now only generated when --sdk or --sdk_embedded flags are passed. By default, code generation excludes all SDK files. This applies to all languages (TypeScript, Python, C++, C#).

@rijesha

rijesha commented Dec 18, 2025

Copy link
Copy Markdown
Contributor

@copilot should there be updates to the documentation now.

Copilot AI changed the title Add high-level SDK with transport abstraction for TypeScript, Python, C++, and C# Add high-level SDK with transport abstraction for TypeScript, Python, C++, and C# (opt-in via flags) Dec 18, 2025
Co-authored-by: rijesha <7819200+rijesha@users.noreply.github.com>

Copilot AI commented Dec 18, 2025

Copy link
Copy Markdown
Contributor Author

@copilot should there be updates to the documentation now.

Yes, updated in commit 8973c50. All SDK documentation now explains:

  • SDK generation is opt-in via --sdk or --sdk_embedded flags
  • Default behavior (no SDK files generated)
  • C++ has two modes: --sdk (full with ASIO) and --sdk_embedded (minimal, serial only)
  • Installation instructions updated for all languages (TypeScript, Python, C++, C#)

@rijesha
rijesha marked this pull request as ready for review December 18, 2025 21:26
@rijesha
rijesha merged commit ddf3b74 into main Dec 18, 2025
1 check passed
@rijesha
rijesha deleted the copilot/add-higher-level-sdk branch January 5, 2026 17:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add higher level SDK

2 participants