• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

TEN-framework / ten-framework / 22890412256

10 Mar 2026 06:39AM UTC coverage: 58.714%. First build
22890412256

Pull #2097

github

web-flow
Merge d59ff8d41 into 65bd8cf55
Pull Request #2097: feat: support sync_stop_before_deinit in graph

165 of 236 new or added lines in 15 files covered. (69.92%)

53334 of 90837 relevant lines covered (58.71%)

877495.58 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

11.59
/core/src/ten_runtime/binding/nodejs/native/msg/cmd/start_graph_cmd.c
1
//
2
// Copyright © 2025 Agora
3
// This file is part of TEN Framework, an open source project.
4
// Licensed under the Apache License, Version 2.0, with certain conditions.
5
// Refer to the "LICENSE" file in the root directory for more information.
6
//
7
#include "include_internal/ten_runtime/binding/nodejs/common/common.h"
8
#include "include_internal/ten_runtime/binding/nodejs/error/error.h"
9
#include "include_internal/ten_runtime/binding/nodejs/msg/cmd/cmd.h"
10
#include "js_native_api.h"
11
#include "ten_runtime/msg/cmd/start_graph/cmd.h"
12
#include "ten_utils/macro/mark.h"
13
#include "ten_utils/macro/memory.h"
14

15
static napi_ref js_cmd_constructor_ref = NULL;  // NOLINT
16

17
static napi_value ten_nodejs_cmd_start_graph_register_class(
18
    napi_env env, napi_callback_info info) {
3✔
19
  const size_t argc = 1;
3✔
20
  napi_value args[argc];  // Cmd constructor
3✔
21
  if (!ten_nodejs_get_js_func_args(env, info, args, argc)) {
3✔
22
    napi_fatal_error(NULL, NAPI_AUTO_LENGTH,
×
23
                     "Incorrect number of parameters passed.",
×
24
                     NAPI_AUTO_LENGTH);
×
25
    TEN_ASSERT(0, "Should not happen.");
×
26
    return NULL;
×
27
  }
×
28

29
  napi_status status =
3✔
30
      napi_create_reference(env, args[0], 1, &js_cmd_constructor_ref);
3✔
31
  if (status != napi_ok) {
3✔
32
    napi_fatal_error(NULL, NAPI_AUTO_LENGTH,
×
33
                     "Failed to create JS reference to JS Cmd constructor.",
×
34
                     NAPI_AUTO_LENGTH);
×
35
    TEN_ASSERT(0, "Failed to create JS reference to JS Cmd constructor: %d",
×
36
               status);
×
37
  }
×
38

39
  return js_undefined(env);
3✔
40
}
3✔
41

42
static void ten_nodejs_cmd_destroy(ten_nodejs_cmd_t *self) {
×
43
  TEN_ASSERT(self, "Should not happen.");
×
44

45
  ten_nodejs_msg_deinit(&self->msg);
×
46

47
  TEN_FREE(self);
×
48
}
×
49

50
static void ten_nodejs_cmd_finalize(napi_env env, void *data,
51
                                    TEN_UNUSED void *hint) {
×
52
  ten_nodejs_cmd_t *cmd_bridge = data;
×
53
  TEN_ASSERT(cmd_bridge, "Should not happen.");
×
54

55
  napi_delete_reference(env, cmd_bridge->msg.bridge.js_instance_ref);
×
56

57
  ten_nodejs_cmd_destroy(cmd_bridge);
×
58
}
×
59

60
static napi_value ten_nodejs_cmd_start_graph_create(napi_env env,
61
                                                    napi_callback_info info) {
×
62
  const size_t argc = 1;
×
63
  napi_value args[argc];  // this
×
64
  if (!ten_nodejs_get_js_func_args(env, info, args, argc)) {
×
65
    napi_fatal_error(NULL, NAPI_AUTO_LENGTH,
×
66
                     "Incorrect number of parameters passed.",
×
67
                     NAPI_AUTO_LENGTH);
×
68
    TEN_ASSERT(0, "Should not happen.");
×
69
  }
×
70

71
  ten_shared_ptr_t *c_cmd = ten_cmd_start_graph_create();
×
72
  TEN_ASSERT(c_cmd, "Failed to create cmd.");
×
73

74
  ten_nodejs_cmd_t *cmd_bridge = TEN_MALLOC(sizeof(ten_nodejs_cmd_t));
×
75
  TEN_ASSERT(cmd_bridge, "Failed to allocate memory.");
×
76

77
  ten_nodejs_msg_init_from_c_msg(&cmd_bridge->msg, c_cmd);
×
78
  // Decrement the reference count of c_cmd to indicate that the JS cmd takes
79
  // the full ownership of this c_cmd, in other words, when the JS cmd is
80
  // finalized, its C cmd would be destroyed, too.
81
  ten_shared_ptr_destroy(c_cmd);
×
82

83
  napi_status status =
×
84
      napi_wrap(env, args[0], cmd_bridge, ten_nodejs_cmd_finalize, NULL,
×
85
                &cmd_bridge->msg.bridge.js_instance_ref);
×
86
  if (status != napi_ok) {
×
87
    napi_fatal_error(NULL, NAPI_AUTO_LENGTH, "Failed to wrap JS Cmd object.",
×
88
                     NAPI_AUTO_LENGTH);
×
89
    TEN_ASSERT(0, "Failed to wrap JS Cmd object: %d", status);
×
90
  }
×
91

92
  return js_undefined(env);
×
93
}
×
94

95
static napi_value ten_nodejs_cmd_start_graph_set_predefined_graph_name(
96
    napi_env env, napi_callback_info info) {
×
97
  const size_t argc = 2;
×
98
  napi_value args[argc];  // this, predefined_graph_name
×
99
  if (!ten_nodejs_get_js_func_args(env, info, args, argc)) {
×
100
    napi_fatal_error(NULL, NAPI_AUTO_LENGTH,
×
101
                     "Incorrect number of parameters passed.",
×
102
                     NAPI_AUTO_LENGTH);
×
103
    TEN_ASSERT(0, "Should not happen.");
×
104
    return js_undefined(env);
×
105
  }
×
106

107
  ten_nodejs_cmd_t *cmd_bridge = NULL;
×
108
  napi_status status = napi_unwrap(env, args[0], (void **)&cmd_bridge);
×
109
  RETURN_UNDEFINED_IF_NAPI_FAIL(status == napi_ok && cmd_bridge != NULL,
×
110
                                "Failed to get cmd bridge: %d", status);
×
111
  TEN_ASSERT(cmd_bridge, "Should not happen.");
×
112

113
  ten_string_t predefined_graph_name;
×
114
  TEN_STRING_INIT(predefined_graph_name);
×
115

116
  bool rc = ten_nodejs_get_str_from_js(env, args[1], &predefined_graph_name);
×
117
  RETURN_UNDEFINED_IF_NAPI_FAIL(rc, "Failed to get predefined graph name",
×
118
                                NULL);
×
119

120
  ten_error_t err;
×
121
  TEN_ERROR_INIT(err);
×
122

123
  bool result = ten_cmd_start_graph_set_predefined_graph_name(
×
124
      cmd_bridge->msg.msg, ten_string_get_raw_str(&predefined_graph_name),
×
125
      &err);
×
126

127
  ten_string_deinit(&predefined_graph_name);
×
128

129
  napi_value js_error = NULL;
×
130
  if (!result) {
×
131
    js_error = ten_nodejs_error_wrap(env, &err);
×
132
    ASSERT_IF_NAPI_FAIL(js_error, "Failed to create JS error", NULL);
×
133
  }
×
134

135
  ten_error_deinit(&err);
×
136

137
  return js_error ? js_error : js_undefined(env);
×
138
}
×
139

140
static napi_value ten_nodejs_cmd_start_graph_set_graph_from_json_str(
141
    napi_env env, napi_callback_info info) {
×
142
  const size_t argc = 2;
×
143
  napi_value args[argc];  // this, json_str
×
144
  if (!ten_nodejs_get_js_func_args(env, info, args, argc)) {
×
145
    napi_fatal_error(NULL, NAPI_AUTO_LENGTH,
×
146
                     "Incorrect number of parameters passed.",
×
147
                     NAPI_AUTO_LENGTH);
×
148
    TEN_ASSERT(0, "Should not happen.");
×
149
    return js_undefined(env);
×
150
  }
×
151

152
  ten_nodejs_cmd_t *cmd_bridge = NULL;
×
153
  napi_status status = napi_unwrap(env, args[0], (void **)&cmd_bridge);
×
154
  RETURN_UNDEFINED_IF_NAPI_FAIL(status == napi_ok && cmd_bridge != NULL,
×
155
                                "Failed to get cmd bridge: %d", status);
×
156
  TEN_ASSERT(cmd_bridge, "Should not happen.");
×
157

158
  ten_string_t json_str;
×
159
  TEN_STRING_INIT(json_str);
×
160

161
  bool rc = ten_nodejs_get_str_from_js(env, args[1], &json_str);
×
162
  RETURN_UNDEFINED_IF_NAPI_FAIL(rc, "Failed to get JSON string", NULL);
×
163

164
  ten_error_t err;
×
165
  TEN_ERROR_INIT(err);
×
166

167
  bool result = ten_cmd_start_graph_set_graph_from_json_str(
×
168
      cmd_bridge->msg.msg, ten_string_get_raw_str(&json_str), &err);
×
169

170
  ten_string_deinit(&json_str);
×
171

172
  napi_value js_error = NULL;
×
173
  if (!result) {
×
174
    js_error = ten_nodejs_error_wrap(env, &err);
×
175
    ASSERT_IF_NAPI_FAIL(js_error, "Failed to create JS error", NULL);
×
176
  }
×
177

178
  ten_error_deinit(&err);
×
179

180
  return js_error ? js_error : js_undefined(env);
×
181
}
×
182

183
static napi_value ten_nodejs_cmd_start_graph_set_sync_stop_before_deinit(
NEW
184
    napi_env env, napi_callback_info info) {
×
NEW
185
  const size_t argc = 2;
×
NEW
186
  napi_value args[argc];  // this, sync_stop_before_deinit
×
NEW
187
  if (!ten_nodejs_get_js_func_args(env, info, args, argc)) {
×
NEW
188
    napi_fatal_error(NULL, NAPI_AUTO_LENGTH,
×
NEW
189
                     "Incorrect number of parameters passed.",
×
NEW
190
                     NAPI_AUTO_LENGTH);
×
NEW
191
    TEN_ASSERT(0, "Should not happen.");
×
NEW
192
    return js_undefined(env);
×
NEW
193
  }
×
194

NEW
195
  ten_nodejs_cmd_t *cmd_bridge = NULL;
×
NEW
196
  napi_status status = napi_unwrap(env, args[0], (void **)&cmd_bridge);
×
NEW
197
  RETURN_UNDEFINED_IF_NAPI_FAIL(status == napi_ok && cmd_bridge != NULL,
×
NEW
198
                                "Failed to get cmd bridge: %d", status);
×
NEW
199
  TEN_ASSERT(cmd_bridge, "Should not happen.");
×
200

NEW
201
  bool sync_stop_before_deinit = false;
×
NEW
202
  status = napi_get_value_bool(env, args[1], &sync_stop_before_deinit);
×
NEW
203
  RETURN_UNDEFINED_IF_NAPI_FAIL(status == napi_ok,
×
NEW
204
                                "Failed to get bool value: %d", status);
×
205

NEW
206
  ten_error_t err;
×
NEW
207
  TEN_ERROR_INIT(err);
×
208

NEW
209
  bool result = ten_cmd_start_graph_set_sync_stop_before_deinit(
×
NEW
210
      cmd_bridge->msg.msg, sync_stop_before_deinit, &err);
×
211

NEW
212
  napi_value js_error = NULL;
×
NEW
213
  if (!result) {
×
NEW
214
    js_error = ten_nodejs_error_wrap(env, &err);
×
NEW
215
    ASSERT_IF_NAPI_FAIL(js_error, "Failed to create JS error", NULL);
×
NEW
216
  }
×
217

NEW
218
  ten_error_deinit(&err);
×
219

NEW
220
  return js_error ? js_error : js_undefined(env);
×
NEW
221
}
×
222

223
napi_value ten_nodejs_cmd_start_graph_module_init(napi_env env,
224
                                                  napi_value exports) {
3✔
225
  EXPORT_FUNC(env, exports, ten_nodejs_cmd_start_graph_register_class);
3✔
226
  EXPORT_FUNC(env, exports, ten_nodejs_cmd_start_graph_create);
3✔
227
  EXPORT_FUNC(env, exports,
3✔
228
              ten_nodejs_cmd_start_graph_set_predefined_graph_name);
3✔
229
  EXPORT_FUNC(env, exports, ten_nodejs_cmd_start_graph_set_graph_from_json_str);
3✔
230
  EXPORT_FUNC(env, exports,
3✔
231
              ten_nodejs_cmd_start_graph_set_sync_stop_before_deinit);
3✔
232

233
  return exports;
3✔
234
}
3✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc