@xframes/node 0.0.22 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CMakeLists.txt CHANGED
@@ -2,6 +2,8 @@ cmake_minimum_required(VERSION 3.15)
2
2
  cmake_policy(SET CMP0091 NEW)
3
3
  cmake_policy(SET CMP0042 NEW)
4
4
 
5
+ set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>DLL")
6
+
5
7
  if(NOT CMAKE_GENERATOR)
6
8
  set(CMAKE_GENERATOR "Ninja")
7
9
  endif()
@@ -15,6 +17,8 @@ if(NOT VCPKG_TARGET_TRIPLET)
15
17
  set(VCPKG_TARGET_TRIPLET "x64-osx")
16
18
  elseif(DEFINED ENV{ARM64_LINUX})
17
19
  set(VCPKG_TARGET_TRIPLET "arm64-linux")
20
+ elseif(DEFINED ENV{RISCV64_LINUX})
21
+ set(VCPKG_TARGET_TRIPLET "riscv64-linux")
18
22
  else()
19
23
  set(VCPKG_TARGET_TRIPLET "x64-linux")
20
24
  endif()
@@ -32,6 +36,56 @@ find_package(glfw3 CONFIG REQUIRED)
32
36
  find_package(ada CONFIG REQUIRED)
33
37
  find_package(Stb REQUIRED)
34
38
  find_package(fmt CONFIG REQUIRED)
39
+ find_package(JPEG REQUIRED)
40
+ find_package(PNG REQUIRED)
41
+ find_package(TIFF REQUIRED)
42
+ find_package(CURL REQUIRED)
43
+ find_package(nlohmann_json REQUIRED)
44
+ find_package(qjs CONFIG REQUIRED)
45
+ find_package(Lua REQUIRED)
46
+ find_package(sol2 CONFIG REQUIRED)
47
+
48
+ # --- Janet 3-stage bootstrap ---
49
+ set(JANET_ROOT "${DEPS}/janet")
50
+ set(JANET_SRC_DIR "${JANET_ROOT}/src")
51
+ file(GLOB JANET_CORE_SOURCES "${JANET_SRC_DIR}/core/*.c")
52
+ file(GLOB JANET_BOOT_SOURCES "${JANET_SRC_DIR}/boot/*.c")
53
+ set(JANET_NO_FLAGS JANET_NO_EV JANET_NO_FFI JANET_NO_NET JANET_NO_DYNAMIC_MODULES)
54
+
55
+ # Stage 1: bootstrap interpreter
56
+ add_executable(janet_boot ${JANET_CORE_SOURCES} ${JANET_BOOT_SOURCES})
57
+ target_include_directories(janet_boot PRIVATE "${JANET_SRC_DIR}/include" "${JANET_SRC_DIR}/conf")
58
+ target_compile_definitions(janet_boot PRIVATE JANET_BOOTSTRAP ${JANET_NO_FLAGS})
59
+ if(WIN32)
60
+ target_compile_definitions(janet_boot PRIVATE _CRT_SECURE_NO_WARNINGS)
61
+ target_link_libraries(janet_boot PRIVATE ws2_32)
62
+ endif()
63
+
64
+ # Stage 2: generate core image
65
+ set(JANET_IMAGE_FILE "${CMAKE_BINARY_DIR}/janet_core_image.c")
66
+ add_custom_command(
67
+ OUTPUT "${JANET_IMAGE_FILE}"
68
+ COMMAND ${CMAKE_COMMAND} -E env "$<TARGET_FILE:janet_boot>" "${JANET_ROOT}" image-only > "${JANET_IMAGE_FILE}"
69
+ DEPENDS janet_boot "${JANET_ROOT}/src/boot/boot.janet"
70
+ COMMENT "Generating Janet core image"
71
+ )
72
+
73
+ # Stage 3: static library (JANET_SINGLE_THREADED: janet_init sets thread-local VM;
74
+ # XFrames calls InitJanet on JS thread but Render on render thread)
75
+ add_library(janet_core STATIC ${JANET_CORE_SOURCES} "${JANET_IMAGE_FILE}")
76
+ target_include_directories(janet_core PUBLIC "${JANET_SRC_DIR}/include" "${JANET_SRC_DIR}/conf")
77
+ target_compile_definitions(janet_core PRIVATE ${JANET_NO_FLAGS} JANET_SINGLE_THREADED)
78
+ if(WIN32)
79
+ target_compile_definitions(janet_core PRIVATE _CRT_SECURE_NO_WARNINGS)
80
+ target_link_libraries(janet_core PRIVATE ws2_32)
81
+ endif()
82
+
83
+ # Auto-copy core image for WASM builds
84
+ add_custom_command(TARGET janet_core POST_BUILD
85
+ COMMAND ${CMAKE_COMMAND} -E make_directory "${CMAKE_CURRENT_SOURCE_DIR}/../../cpp/app/generated"
86
+ COMMAND ${CMAKE_COMMAND} -E copy_if_different "${JANET_IMAGE_FILE}" "${CMAKE_CURRENT_SOURCE_DIR}/../../cpp/app/generated/janet_core_image.c"
87
+ COMMENT "Copying Janet core image to app/generated/ for WASM"
88
+ )
35
89
 
36
90
  include_directories(${CMAKE_JS_INC})
37
91
 
@@ -39,6 +93,19 @@ file(GLOB YOGA_SRC CONFIGURE_DEPENDS
39
93
  ${DEPS}/yoga/yoga/*.cpp
40
94
  ${DEPS}/yoga/yoga/**/*.cpp)
41
95
 
96
+ file(GLOB LEPTONICA_SRC "${DEPS}/osm-static-map-generator/cpp/deps/leptonica/src/*.c")
97
+
98
+ # Generate endianness.h for leptonica (x64 is little-endian)
99
+ file(WRITE "${DEPS}/osm-static-map-generator/cpp/deps/leptonica/src/endianness.h" "#define L_LITTLE_ENDIAN\n")
100
+ add_compile_definitions(HAVE_LIBJPEG HAVE_LIBTIFF HAVE_LIBPNG NOMINMAX _USE_MATH_DEFINES)
101
+
102
+ set(OSM_STATIC_MAP_GENERATOR_SRC
103
+ ${DEPS}/osm-static-map-generator/cpp/shared.cpp
104
+ ${DEPS}/osm-static-map-generator/cpp/tiledownloader.cpp
105
+ ${DEPS}/osm-static-map-generator/cpp/mapgenerator.cpp
106
+ ${DEPS}/osm-static-map-generator/cpp/tilecache.cpp
107
+ )
108
+
42
109
  add_library(${PROJECT_NAME} SHARED
43
110
  ${DEPS}/css-color-parser-cpp/csscolorparser.hpp
44
111
  ${DEPS}/css-color-parser-cpp/csscolorparser.cpp
@@ -47,6 +114,7 @@ add_library(${PROJECT_NAME} SHARED
47
114
  ${DEPS}/imgui/imgui_draw.cpp
48
115
  ${DEPS}/imgui/imgui_widgets.cpp
49
116
  ${DEPS}/imgui/imgui_tables.cpp
117
+ ${DEPS}/imgui/misc/cpp/imgui_stdlib.cpp
50
118
  ${DEPS}/imgui/backends/imgui_impl_opengl3.cpp
51
119
  ${DEPS}/imgui/backends/imgui_impl_glfw.cpp
52
120
 
@@ -59,6 +127,7 @@ add_library(${PROJECT_NAME} SHARED
59
127
  ${APP}/src/color_helpers.cpp
60
128
  ${APP}/src/yoga_helpers.cpp
61
129
  ${APP}/src/imgui_helpers.cpp
130
+ ${APP}/src/disk_tile_cache.cpp
62
131
 
63
132
  ${APP}/src/element/layout_node.cpp
64
133
  ${APP}/src/element/element.cpp
@@ -72,6 +141,7 @@ add_library(${PROJECT_NAME} SHARED
72
141
 
73
142
  ${APP}/src/widget/button.cpp
74
143
  ${APP}/src/widget/checkbox.cpp
144
+ ${APP}/src/widget/color_picker.cpp
75
145
  ${APP}/src/widget/child.cpp
76
146
  ${APP}/src/widget/clipped_multi_line_text_renderer.cpp
77
147
  ${APP}/src/widget/collapsing_header.cpp
@@ -80,11 +150,19 @@ add_library(${PROJECT_NAME} SHARED
80
150
  ${APP}/src/widget/image.cpp
81
151
  ${APP}/src/widget/input_text.cpp
82
152
  ${APP}/src/widget/item_tooltip.cpp
153
+ ${APP}/src/widget/map_view.cpp
83
154
  ${APP}/src/widget/multi_slider.cpp
155
+ ${APP}/src/widget/plot_bar.cpp
84
156
  ${APP}/src/widget/plot_candlestick.cpp
157
+ ${APP}/src/widget/plot_histogram.cpp
158
+ ${APP}/src/widget/plot_heatmap.cpp
159
+ ${APP}/src/widget/plot_pie_chart.cpp
85
160
  ${APP}/src/widget/plot_line.cpp
161
+ ${APP}/src/widget/plot_scatter.cpp
86
162
  ${APP}/src/widget/separator.cpp
87
163
  ${APP}/src/widget/separator_text.cpp
164
+ ${APP}/src/widget/progress_bar.cpp
165
+ ${APP}/src/widget/color_indicator.cpp
88
166
  ${APP}/src/widget/slider.cpp
89
167
  ${APP}/src/widget/table.cpp
90
168
  ${APP}/src/widget/tabs.cpp
@@ -92,9 +170,15 @@ add_library(${PROJECT_NAME} SHARED
92
170
  ${APP}/src/widget/text_wrap.cpp
93
171
  ${APP}/src/widget/tree_node.cpp
94
172
  ${APP}/src/widget/window.cpp
173
+ ${APP}/src/widget/js_canvas.cpp
174
+ ${APP}/src/widget/lua_canvas.cpp
175
+ ${APP}/src/widget/janet_canvas.cpp
95
176
 
96
177
  ./src/xframes-node.cpp
97
178
 
179
+ ${OSM_STATIC_MAP_GENERATOR_SRC}
180
+ ${LEPTONICA_SRC}
181
+
98
182
  ${SOURCE_FILES}
99
183
  ${CMAKE_JS_SRC}
100
184
  )
@@ -104,9 +188,18 @@ target_link_libraries(${PROJECT_NAME}
104
188
  ${CMAKE_JS_LIB}
105
189
  ada::ada
106
190
  fmt::fmt
191
+ nlohmann_json::nlohmann_json
192
+ JPEG::JPEG
193
+ PNG::PNG
194
+ TIFF::TIFF
195
+ CURL::libcurl
107
196
 
108
197
  glfw
109
198
  OpenGL::GL
199
+ qjs
200
+ ${LUA_LIBRARIES}
201
+ sol2::sol2
202
+ janet_core
110
203
  )
111
204
 
112
205
  # Include Node-API wrappers
@@ -131,10 +224,16 @@ target_include_directories(${PROJECT_NAME} PRIVATE
131
224
  ${DEPS}/css-color-parser-cpp
132
225
  ${DEPS}/imgui
133
226
  ${DEPS}/imgui/backends
227
+ ${DEPS}/imgui/misc/cpp
134
228
  ${DEPS}/implot
135
229
  ${DEPS}/json/include
136
230
  ${DEPS}/yoga
137
231
  ${DEPS}/glfw/include
232
+ ${DEPS}/osm-static-map-generator/cpp
233
+ ${DEPS}/osm-static-map-generator/cpp/deps/leptonica/src
234
+ ${LUA_INCLUDE_DIR}
235
+ "${DEPS}/janet/src/include"
236
+ "${DEPS}/janet/src/conf"
138
237
  )
139
238
 
140
239
  # define NAPI_VERSION
package/README.md CHANGED
@@ -1,39 +1,107 @@
1
- # xframes for Node.js
1
+ # @xframes/node
2
2
 
3
- ## Building
3
+ DOM-free, GPU-accelerated desktop GUI development for Node.js — powered by [Dear ImGui](https://github.com/ocornut/imgui) and [Yoga Layout](https://www.yogalayout.dev/).
4
4
 
5
- ### Windows
5
+ Write React/TypeScript components that render as native desktop widgets with zero browser overhead.
6
6
 
7
- If a prebuilt module isn't found then you will need Visual Studio 2022
7
+ ## Quick Start
8
8
 
9
- ### WSL2 - Ubuntu 24.04
9
+ ```bash
10
+ npx create-xframes-node-app
11
+ cd my-app
12
+ npm start
13
+ ```
10
14
 
11
- You may need to run `export GALLIUM_DRIVER=d3d12` before starting the application to enable Direct3D 12 rendering support.
12
- This setting is required for proper GPU acceleration in WSL2 and needs to be set in each new terminal session.
13
- You can add this line to your ~/.bashrc to make it permanent.
15
+ ## Example
14
16
 
15
- ### Linux
17
+ ```tsx
18
+ import { resolve } from "path";
19
+ import * as React from "react";
20
+ import { render, XFrames } from "@xframes/node";
16
21
 
17
- If a prebuilt module isn't found then you will need gcc 13+ to build the project locally.
22
+ const fontDefs = {
23
+ defs: [{ name: "roboto-regular", sizes: [16, 18, 20, 24] }]
24
+ .map(({ name, sizes }) => sizes.map((size) => ({ name, size })))
25
+ .flat(),
26
+ };
18
27
 
19
- Ubuntu 24.04 dependencies:
28
+ const theme = { /* ... */ };
20
29
 
21
- `sudo apt install curl zip unzip tar build-essential cmake libglfw3 libglfw3-dev libxinerama-dev libxcursor-dev xorg-dev libglu1-mesa-dev pkg-config`
30
+ const App = () => (
31
+ <XFrames.Node root style={{ height: "100%" }}>
32
+ <XFrames.UnformattedText text="Hello, world" />
33
+ <XFrames.Button label="Click me" onClick={() => console.log("clicked")} />
34
+ </XFrames.Node>
35
+ );
22
36
 
23
- Fedora 41 dependencies:
37
+ render(App, resolve("./assets"), fontDefs, theme);
38
+ ```
24
39
 
25
- `sudo dnf install @development-tools gcc-c++ cmake glfw-devel`
40
+ ## Available Widgets
26
41
 
27
- Raspberry Pi OS
42
+ **Input**: Button, Checkbox, Combo, InputText, Slider, MultiSlider, ColorPicker
28
43
 
29
- `sudo apt install curl zip unzip tar build-essential cmake libglfw3 libglfw3-dev libxinerama-dev libxcursor-dev xorg-dev libglu1-mesa-dev pkg-config`
44
+ **Text**: BulletText, DisabledText, SeparatorText, TextWrap, UnformattedText
30
45
 
31
- You must set:
46
+ **Layout**: Node, Child, Group, DIWindow, Separator, TabBar, TabItem, CollapsingHeader, TreeNode, TreeView
32
47
 
33
- `export ARM64_LINUX=1`
48
+ **Data**: Table (sorting, filtering, column reorder/hide, context menus), PlotLine, PlotBar, PlotScatter, PlotHeatmap, PlotHistogram, PlotPieChart, PlotCandlestick
34
49
 
35
- We could not work out how to detect the correct architecture so, for convenience, in CMakeLists.txt we check for this ENV variable to be set.
50
+ **Canvas**: JsCanvas (QuickJS), LuaCanvas (Lua/Sol2), JanetCanvas (Janet) scripted 2D rendering with Canvas 2D API shim
36
51
 
37
- `export VCPKG_FORCE_SYSTEM_BINARIES=1`
52
+ **Other**: Image, ProgressBar, ColorIndicator, ClippedMultiLineTextRenderer, ItemTooltip
38
53
 
39
- It suppresses the downloading of CMake and Ninja and forces the use of the system binaries.
54
+ ## Key Features
55
+
56
+ - **React components** — familiar JSX syntax, hooks, refs, state management
57
+ - **Yoga flexbox layout** — the same layout engine used by React Native
58
+ - **Per-state styling** — base, hover, active, and disabled style variants
59
+ - **Imperative handles** — refs for Table, Plot widgets, InputText, and more
60
+ - **Font Awesome icons** — built-in icon support in tables and text
61
+ - **Scripted canvas rendering** — embed JavaScript, Lua, or Janet scripts for custom 2D drawing with an HTML5 Canvas 2D-style API
62
+ - **Interactive maps** — MapView widget with OpenStreetMap tiles, markers, polylines, and overlays
63
+ - **Theme system** — runtime theme switching via `patchStyle`
64
+ - **Prebuilt binaries** — `npm install` downloads platform-specific native addons (NAPI v9)
65
+
66
+ ## Platform Support
67
+
68
+ | Architecture | OS | Notes |
69
+ |---|---|---|
70
+ | x64-windows | Windows 11 | Works |
71
+ | x64-linux | WSL2 Ubuntu 24.04 | Set `export GALLIUM_DRIVER=d3d12` |
72
+ | x64-linux | Debian Trixie | Works |
73
+ | x64-linux | Ubuntu 22.04 / 24.04 | Works |
74
+ | arm64-linux | Raspberry Pi OS (Bookworm) | Works |
75
+
76
+ ## Building from Source
77
+
78
+ If a prebuilt binary isn't available for your platform, the native addon compiles from source during `npm install`. Requirements:
79
+
80
+ **Windows**: Visual Studio 2022
81
+
82
+ **Ubuntu 24.04**:
83
+ ```bash
84
+ sudo apt install curl zip unzip tar build-essential cmake libglfw3 libglfw3-dev libxinerama-dev libxcursor-dev xorg-dev libglu1-mesa-dev pkg-config
85
+ ```
86
+
87
+ **Fedora 41**:
88
+ ```bash
89
+ sudo dnf install @development-tools gcc-c++ cmake glfw-devel
90
+ ```
91
+
92
+ **Raspberry Pi OS**:
93
+ ```bash
94
+ sudo apt install curl zip unzip tar build-essential cmake libglfw3 libglfw3-dev libxinerama-dev libxcursor-dev xorg-dev libglu1-mesa-dev pkg-config
95
+ export ARM64_LINUX=1
96
+ export VCPKG_FORCE_SYSTEM_BINARIES=1
97
+ ```
98
+
99
+ ## Links
100
+
101
+ - [Documentation](https://xframes.dev)
102
+ - [GitHub](https://github.com/xframes-project/xframes)
103
+ - [Discord](https://discord.gg/Cbgcajdq)
104
+
105
+ ## License
106
+
107
+ MIT
package/dist/render.js CHANGED
@@ -49,7 +49,19 @@ const render = (EntryPointComponent, assetsBasePath, fontDefs, theme) => {
49
49
  value: "clicked",
50
50
  });
51
51
  };
52
- xframes.init(assetsBasePath, JSON.stringify(fontDefs), JSON.stringify(theme), onInit, onTextChange, onComboChange, onNumericValueChange, onBooleanValueChange, onMultiValueChange, onClick);
52
+ const onTableSort = (id, columnIndex, sortDirection) => {
53
+ const rootNodeID = id;
54
+ const topLevelType = "onSort";
55
+ const nativeEventParam = { columnIndex, sortDirection };
56
+ common_1.ReactNativePrivateInterface.nativeFabricUIManager.dispatchEvent(rootNodeID, topLevelType, nativeEventParam);
57
+ };
58
+ const onTableFilter = (id, columnIndex, filterText) => {
59
+ const rootNodeID = id;
60
+ const topLevelType = "onFilter";
61
+ const nativeEventParam = { columnIndex, filterText };
62
+ common_1.ReactNativePrivateInterface.nativeFabricUIManager.dispatchEvent(rootNodeID, topLevelType, nativeEventParam);
63
+ };
64
+ xframes.init(assetsBasePath, JSON.stringify(fontDefs), JSON.stringify(theme), onInit, onTextChange, onComboChange, onNumericValueChange, onBooleanValueChange, onMultiValueChange, onClick, onTableSort, onTableFilter);
53
65
  const widgetRegistrationService = new common_1.WidgetRegistrationService(xframes);
54
66
  common_1.ReactNativePrivateInterface.nativeFabricUIManager.init(xframes, widgetRegistrationService);
55
67
  let flag = true;
Binary file
Binary file
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xframes/node",
3
- "version": "0.0.22",
3
+ "version": "0.1.1",
4
4
  "description": "DOM-less, GPU-accelerated GUI development for Node.js",
5
5
  "main": "dist/index.js",
6
6
  "files": [
@@ -20,6 +20,8 @@
20
20
  },
21
21
  "scripts": {
22
22
  "install": "prebuild-install -t 9 -r napi --tag-prefix xframes-node- && npm run copy-artifacts-to-dist-folder",
23
+ "build:common": "cd ../common && npx tsup --format cjs --external react,react-dom",
24
+ "prestart": "npm run build:common && cpy --flat ../common/dist/*.* node_modules/@xframes/common/dist/",
23
25
  "start": "tsx ./src/index.tsx",
24
26
  "build:library": "rimraf ./dist && npm run tsc && npm run copy-artifacts-to-dist-folder",
25
27
  "tsc": "rimraf ./dist && tsc --project ./tsconfig-build.json",
@@ -66,11 +68,10 @@
66
68
  "whatwg-fetch": "^3.6.20"
67
69
  },
68
70
  "peerDependencies": {
69
- "@xframes/common": "^0.0.13",
71
+ "@xframes/common": "^0.1.0",
70
72
  "react": "^18.2.0"
71
73
  },
72
74
  "devDependencies": {
73
- "@alpacahq/alpaca-trade-api": "^3.1.2",
74
75
  "@babel/core": "^7.24.5",
75
76
  "@babel/plugin-proposal-class-properties": "^7.18.6",
76
77
  "@babel/plugin-transform-flow-strip-types": "^7.20.0",
@@ -81,8 +82,6 @@
81
82
  "@babel/preset-typescript": "^7.24.1",
82
83
  "@fortawesome/fontawesome-free": "^6.5.2",
83
84
  "@microsoft/api-extractor": "^7.43.4",
84
- "@react-rxjs/core": "^0.10.7",
85
- "@react-rxjs/utils": "^0.9.7",
86
85
  "@types/babel__core": "^7",
87
86
  "@types/babel__preset-env": "^7",
88
87
  "@types/invariant": "^2",
@@ -100,7 +99,7 @@
100
99
  "babel-plugin-syntax-hermes-parser": "0.21.0",
101
100
  "bindings": "^1.5.0",
102
101
  "clean-webpack-plugin": "^4.0.0",
103
- "cmake-js": "^7.3.0",
102
+ "cmake-js": "^8.0.0",
104
103
  "css-loader": "^7.1.1",
105
104
  "eslint": "^8.57.0",
106
105
  "eslint-plugin-react-hooks": "^4.6.0",
@@ -109,7 +108,7 @@
109
108
  "html-webpack-plugin": "^5.6.0",
110
109
  "inline-source-map": "^0.6.3",
111
110
  "mini-css-extract-plugin": "^2.9.0",
112
- "node-addon-api": "^8.2.1",
111
+ "node-addon-api": "^8.6.0",
113
112
  "prebuild": "^13.0.1",
114
113
  "react-native": "^0.74.1",
115
114
  "rimraf": "^5.0.6",
@@ -122,7 +121,6 @@
122
121
  "webpack": "^5.91.0",
123
122
  "webpack-cli": "^5.1.4",
124
123
  "webpack-dev-server": "^5.0.4",
125
- "yaml": "^2.4.3",
126
- "zustand": "^5.0.0-rc.2"
124
+ "yaml": "^2.4.3"
127
125
  }
128
- }
126
+ }
package/vcpkg.json CHANGED
@@ -6,6 +6,14 @@
6
6
  "ada-url",
7
7
  "fmt",
8
8
  "opengl-registry",
9
- "glfw3"
9
+ "glfw3",
10
+ "nlohmann-json",
11
+ "libjpeg-turbo",
12
+ "libpng",
13
+ "tiff",
14
+ "curl",
15
+ "quickjs-ng",
16
+ "lua",
17
+ "sol2"
10
18
  ]
11
19
  }