tranfi 0.1.2 → 0.2.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/LICENSE +177 -0
- package/NOTICE +8 -0
- package/README.md +443 -51
- package/app/assets/{index-pDFMluyz.js → index-BIAIKnrp.js} +1 -1
- package/app/index.html +1 -1
- package/binding.gyp +55 -3
- package/csrc/arena.c +7 -5
- package/csrc/batch.c +818 -71
- package/csrc/buffer.c +84 -8
- package/csrc/cJSON.c +262 -19
- package/csrc/cJSON.h +17 -1
- package/csrc/codec_csv.c +1074 -181
- package/csrc/codec_jsonl.c +830 -118
- package/csrc/codec_table.c +108 -78
- package/csrc/codec_text.c +286 -68
- package/csrc/compiler.c +31 -3
- package/csrc/config.h +21 -0
- package/csrc/dsl.c +4722 -485
- package/csrc/expr.c +363 -55
- package/csrc/expr.h +2 -0
- package/csrc/internal.h +316 -27
- package/csrc/ir.c +65 -18
- package/csrc/ir.h +41 -0
- package/csrc/ir_schema.c +20 -5
- package/csrc/ir_serialize.c +68 -6
- package/csrc/ir_sql.c +796 -185
- package/csrc/ir_validate.c +462 -6
- package/csrc/json_path.c +210 -0
- package/csrc/main.c +879 -30
- package/csrc/memory_estimate.c +477 -0
- package/csrc/op_acf.c +171 -21
- package/csrc/op_across.c +477 -0
- package/csrc/op_anomaly.c +167 -32
- package/csrc/op_assert.c +761 -0
- package/csrc/op_bin.c +168 -29
- package/csrc/op_cast.c +383 -55
- package/csrc/op_clip.c +30 -19
- package/csrc/op_date_trunc.c +208 -34
- package/csrc/op_datetime.c +259 -77
- package/csrc/op_derive.c +65 -97
- package/csrc/op_diff.c +146 -30
- package/csrc/op_ewma.c +149 -30
- package/csrc/op_explode.c +124 -26
- package/csrc/op_fill_down.c +125 -53
- package/csrc/op_fill_null.c +176 -31
- package/csrc/op_filter.c +89 -40
- package/csrc/op_frequency.c +571 -43
- package/csrc/op_grep.c +36 -18
- package/csrc/op_group_agg.c +1790 -119
- package/csrc/op_hash.c +48 -15
- package/csrc/op_head.c +21 -86
- package/csrc/op_interpolate.c +268 -62
- package/csrc/op_join.c +2700 -182
- package/csrc/op_json_extract.c +227 -0
- package/csrc/op_json_filter.c +384 -0
- package/csrc/op_json_flatten.c +293 -0
- package/csrc/op_json_schema.c +503 -0
- package/csrc/op_label_encode.c +328 -53
- package/csrc/op_lag.c +181 -0
- package/csrc/op_lead.c +141 -89
- package/csrc/op_normalize.c +363 -79
- package/csrc/op_onehot.c +345 -73
- package/csrc/op_pivot.c +1546 -162
- package/csrc/op_quarantine.c +189 -0
- package/csrc/op_registry.c +2062 -166
- package/csrc/op_rename.c +41 -50
- package/csrc/op_replace.c +270 -118
- package/csrc/op_rleid.c +297 -0
- package/csrc/op_rowid.c +559 -0
- package/csrc/op_sample.c +80 -23
- package/csrc/op_schema.c +1341 -0
- package/csrc/op_schema_infer.c +252 -0
- package/csrc/op_select.c +265 -65
- package/csrc/op_set.c +3449 -0
- package/csrc/op_skip.c +30 -87
- package/csrc/op_sort.c +670 -124
- package/csrc/op_source_name.c +120 -0
- package/csrc/op_split.c +65 -28
- package/csrc/op_split_data.c +41 -9
- package/csrc/op_stack.c +178 -222
- package/csrc/op_stats.c +206 -110
- package/csrc/op_step.c +217 -55
- package/csrc/op_tail.c +21 -12
- package/csrc/op_tee.c +338 -0
- package/csrc/op_top.c +260 -53
- package/csrc/op_trim.c +48 -19
- package/csrc/op_unique.c +1193 -150
- package/csrc/op_unpivot.c +100 -66
- package/csrc/op_validate.c +601 -24
- package/csrc/op_window.c +492 -51
- package/csrc/path_policy.c +85 -0
- package/csrc/pipeline.c +872 -99
- package/csrc/recipes.c +3 -1
- package/csrc/report.c +73 -30
- package/csrc/selector.c +1097 -0
- package/csrc/size_utils.c +352 -0
- package/csrc/spill.c +317 -0
- package/csrc/spill.h +21 -0
- package/csrc/tranfi.h +169 -1
- package/csrc/transform.h +209 -0
- package/csrc/transform_api.c +2237 -0
- package/csrc/transform_categorical.c +923 -0
- package/csrc/transform_internal.h +472 -0
- package/csrc/transform_json.c +3812 -0
- package/csrc/transform_numeric.c +1966 -0
- package/csrc/transform_sha256.c +154 -0
- package/csrc/transform_wasm.h +162 -0
- package/csrc/transform_wasm_api.c +1373 -0
- package/csrc/wasm_api.c +70 -9
- package/napi_api.c +219 -11
- package/napi_transform.c +1648 -0
- package/napi_transform.h +8 -0
- package/package.json +27 -11
- package/scripts/install-native.js +76 -0
- package/scripts/prepack.js +64 -0
- package/scripts/sync-csrc.js +23 -0
- package/src/cli.js +81 -41
- package/src/engines/duckdb.js +45 -12
- package/src/index.js +661 -42
- package/src/memory_policy.js +411 -0
- package/src/native.js +1 -5
- package/src/pipeline.js +454 -31
- package/src/recipe_json.js +80 -0
- package/src/server.js +10 -8
- package/src/transform.js +403 -0
- package/src/transform_error.js +10 -0
- package/src/wasm.js +6 -4
- package/wasm/index.js +498 -10
- package/wasm/tranfi_core.js +0 -0
- package/wasm/transform.js +1156 -0
- package/wasm/worker.js +786 -0
- package/csrc/plan.c +0 -206
package/csrc/wasm_api.c
CHANGED
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
#endif
|
|
11
11
|
|
|
12
12
|
#include "tranfi.h"
|
|
13
|
+
#include "internal.h"
|
|
13
14
|
#include "dsl.h"
|
|
14
15
|
#include "recipes.h"
|
|
15
16
|
#include <stdlib.h>
|
|
@@ -34,15 +35,35 @@ static tf_pipeline *get_handle(int h) {
|
|
|
34
35
|
return handles[h];
|
|
35
36
|
}
|
|
36
37
|
|
|
38
|
+
static int wasm_validate_buffer(const void *ptr, int len, const char *what) {
|
|
39
|
+
if (len < 0) {
|
|
40
|
+
tf_set_last_error(what ? what : "invalid WASM buffer length");
|
|
41
|
+
return 0;
|
|
42
|
+
}
|
|
43
|
+
if (len > 0 && !ptr) {
|
|
44
|
+
tf_set_last_error(what ? what : "invalid WASM buffer pointer");
|
|
45
|
+
return 0;
|
|
46
|
+
}
|
|
47
|
+
return 1;
|
|
48
|
+
}
|
|
49
|
+
|
|
37
50
|
#ifdef __EMSCRIPTEN__
|
|
38
51
|
#define EXPORT EMSCRIPTEN_KEEPALIVE
|
|
39
52
|
#else
|
|
40
53
|
#define EXPORT
|
|
41
54
|
#endif
|
|
42
55
|
|
|
43
|
-
|
|
44
|
-
int
|
|
45
|
-
|
|
56
|
+
static int wasm_pipeline_create_policy(const char *json, int len,
|
|
57
|
+
int allow_fs, int allow_spill,
|
|
58
|
+
int allow_rules_file, const char *workspace_root) {
|
|
59
|
+
if (!wasm_validate_buffer(json, len, "invalid WASM plan buffer")) return -1;
|
|
60
|
+
tf_host_policy policy = {0};
|
|
61
|
+
policy.allow_fs = allow_fs != 0;
|
|
62
|
+
policy.allow_spill = allow_spill != 0;
|
|
63
|
+
policy.allow_rules_file = allow_rules_file != 0;
|
|
64
|
+
policy.allow_blocking = true;
|
|
65
|
+
policy.workspace_root = workspace_root && workspace_root[0] ? workspace_root : NULL;
|
|
66
|
+
tf_pipeline *p = tf_pipeline_create_with_host_policy(json, (size_t)len, &policy);
|
|
46
67
|
if (!p) return -1;
|
|
47
68
|
int h = alloc_handle(p);
|
|
48
69
|
if (h < 0) {
|
|
@@ -52,13 +73,41 @@ int wasm_pipeline_create(const char *json, int len) {
|
|
|
52
73
|
return h;
|
|
53
74
|
}
|
|
54
75
|
|
|
76
|
+
EXPORT
|
|
77
|
+
int wasm_pipeline_create(const char *json, int len) {
|
|
78
|
+
return wasm_pipeline_create_policy(json, len, 0, 0, 0, NULL);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
EXPORT
|
|
82
|
+
int wasm_pipeline_create_with_policy(const char *json, int len, int allow_fs,
|
|
83
|
+
int allow_spill, int allow_rules_file,
|
|
84
|
+
const char *workspace_root) {
|
|
85
|
+
return wasm_pipeline_create_policy(json, len, allow_fs, allow_spill,
|
|
86
|
+
allow_rules_file, workspace_root);
|
|
87
|
+
}
|
|
88
|
+
|
|
55
89
|
EXPORT
|
|
56
90
|
int wasm_pipeline_push(int handle, const uint8_t *data, int len) {
|
|
57
91
|
tf_pipeline *p = get_handle(handle);
|
|
58
92
|
if (!p) return -1;
|
|
93
|
+
if (!wasm_validate_buffer(data, len, "invalid WASM input buffer")) return -1;
|
|
59
94
|
return tf_pipeline_push(p, data, (size_t)len);
|
|
60
95
|
}
|
|
61
96
|
|
|
97
|
+
EXPORT
|
|
98
|
+
int wasm_pipeline_flush_input(int handle) {
|
|
99
|
+
tf_pipeline *p = get_handle(handle);
|
|
100
|
+
if (!p) return -1;
|
|
101
|
+
return tf_pipeline_flush_input(p);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
EXPORT
|
|
105
|
+
int wasm_pipeline_set_source_name(int handle, const char *name) {
|
|
106
|
+
tf_pipeline *p = get_handle(handle);
|
|
107
|
+
if (!p) return -1;
|
|
108
|
+
return tf_pipeline_set_source_name(p, name);
|
|
109
|
+
}
|
|
110
|
+
|
|
62
111
|
EXPORT
|
|
63
112
|
int wasm_pipeline_finish(int handle) {
|
|
64
113
|
tf_pipeline *p = get_handle(handle);
|
|
@@ -66,10 +115,18 @@ int wasm_pipeline_finish(int handle) {
|
|
|
66
115
|
return tf_pipeline_finish(p);
|
|
67
116
|
}
|
|
68
117
|
|
|
118
|
+
EXPORT
|
|
119
|
+
int wasm_pipeline_finish_step(int handle) {
|
|
120
|
+
tf_pipeline *p = get_handle(handle);
|
|
121
|
+
if (!p) return -1;
|
|
122
|
+
return tf_pipeline_finish_step(p);
|
|
123
|
+
}
|
|
124
|
+
|
|
69
125
|
EXPORT
|
|
70
126
|
int wasm_pipeline_pull(int handle, int channel, uint8_t *buf, int buf_len) {
|
|
71
127
|
tf_pipeline *p = get_handle(handle);
|
|
72
128
|
if (!p) return 0;
|
|
129
|
+
if (!wasm_validate_buffer(buf, buf_len, "invalid WASM output buffer")) return -1;
|
|
73
130
|
return (int)tf_pipeline_pull(p, channel, buf, (size_t)buf_len);
|
|
74
131
|
}
|
|
75
132
|
|
|
@@ -98,16 +155,14 @@ void wasm_pipeline_free(int handle) {
|
|
|
98
155
|
*/
|
|
99
156
|
EXPORT
|
|
100
157
|
char *wasm_compile_dsl(const char *dsl, int len) {
|
|
158
|
+
if (!wasm_validate_buffer(dsl, len, "invalid WASM DSL buffer")) return NULL;
|
|
101
159
|
char *error = NULL;
|
|
102
|
-
|
|
103
|
-
if (!
|
|
104
|
-
|
|
105
|
-
(void)error; /* error accessible via tf_last_error() */
|
|
160
|
+
char *json = tf_compile_dsl(dsl, (size_t)len, &error);
|
|
161
|
+
if (!json) {
|
|
162
|
+
tf_set_last_error(error ? error : "DSL compile failed");
|
|
106
163
|
free(error);
|
|
107
164
|
return NULL;
|
|
108
165
|
}
|
|
109
|
-
char *json = tf_ir_plan_to_json(plan);
|
|
110
|
-
tf_ir_plan_destroy(plan);
|
|
111
166
|
return json;
|
|
112
167
|
}
|
|
113
168
|
|
|
@@ -118,8 +173,14 @@ char *wasm_compile_dsl(const char *dsl, int len) {
|
|
|
118
173
|
*/
|
|
119
174
|
EXPORT
|
|
120
175
|
char *wasm_compile_to_sql(const char *dsl, int len) {
|
|
176
|
+
if (!wasm_validate_buffer(dsl, len, "invalid WASM DSL buffer")) return NULL;
|
|
121
177
|
char *error = NULL;
|
|
122
178
|
char *sql = tf_compile_to_sql(dsl, (size_t)len, &error);
|
|
179
|
+
if (!sql) {
|
|
180
|
+
tf_set_last_error(error ? error : "SQL compile failed");
|
|
181
|
+
free(error);
|
|
182
|
+
return NULL;
|
|
183
|
+
}
|
|
123
184
|
free(error);
|
|
124
185
|
return sql;
|
|
125
186
|
}
|
package/napi_api.c
CHANGED
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
#include "tranfi.h"
|
|
9
9
|
#include "dsl.h"
|
|
10
10
|
#include "recipes.h"
|
|
11
|
+
#include "napi_transform.h"
|
|
11
12
|
#include <stdlib.h>
|
|
12
13
|
#include <string.h>
|
|
13
14
|
|
|
@@ -20,10 +21,87 @@
|
|
|
20
21
|
} \
|
|
21
22
|
} while (0)
|
|
22
23
|
|
|
23
|
-
|
|
24
|
+
|
|
25
|
+
static int get_named_bool(napi_env env, napi_value obj, const char *name, bool default_value, bool *out) {
|
|
26
|
+
bool has = false;
|
|
27
|
+
napi_status st = napi_has_named_property(env, obj, name, &has);
|
|
28
|
+
if (st != napi_ok || !has) { *out = default_value; return 0; }
|
|
29
|
+
napi_value value;
|
|
30
|
+
st = napi_get_named_property(env, obj, name, &value);
|
|
31
|
+
if (st != napi_ok) { *out = default_value; return 0; }
|
|
32
|
+
napi_valuetype type;
|
|
33
|
+
st = napi_typeof(env, value, &type);
|
|
34
|
+
if (st != napi_ok || type == napi_undefined || type == napi_null) { *out = default_value; return 0; }
|
|
35
|
+
if (type != napi_boolean) {
|
|
36
|
+
napi_throw_type_error(env, NULL, "host policy option must be boolean");
|
|
37
|
+
return -1;
|
|
38
|
+
}
|
|
39
|
+
bool b = false;
|
|
40
|
+
st = napi_get_value_bool(env, value, &b);
|
|
41
|
+
if (st != napi_ok) return -1;
|
|
42
|
+
*out = b;
|
|
43
|
+
return 0;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
static int get_named_bool_alias(napi_env env, napi_value obj, const char *camel,
|
|
47
|
+
const char *snake, bool default_value, bool *out) {
|
|
48
|
+
bool has = false;
|
|
49
|
+
if (napi_has_named_property(env, obj, camel, &has) == napi_ok && has)
|
|
50
|
+
return get_named_bool(env, obj, camel, default_value, out);
|
|
51
|
+
return get_named_bool(env, obj, snake, default_value, out);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
static char *get_named_string(napi_env env, napi_value obj, const char *name) {
|
|
55
|
+
bool has = false;
|
|
56
|
+
if (napi_has_named_property(env, obj, name, &has) != napi_ok || !has) return NULL;
|
|
57
|
+
napi_value value;
|
|
58
|
+
if (napi_get_named_property(env, obj, name, &value) != napi_ok) return NULL;
|
|
59
|
+
napi_valuetype type;
|
|
60
|
+
if (napi_typeof(env, value, &type) != napi_ok || type == napi_undefined || type == napi_null) return NULL;
|
|
61
|
+
if (type != napi_string) {
|
|
62
|
+
napi_throw_type_error(env, NULL, "workspaceRoot must be a string");
|
|
63
|
+
return (char *)-1;
|
|
64
|
+
}
|
|
65
|
+
size_t len = 0;
|
|
66
|
+
if (napi_get_value_string_utf8(env, value, NULL, 0, &len) != napi_ok) return (char *)-1;
|
|
67
|
+
char *s = malloc(len + 1);
|
|
68
|
+
if (!s) return (char *)-1;
|
|
69
|
+
if (napi_get_value_string_utf8(env, value, s, len + 1, &len) != napi_ok) {
|
|
70
|
+
free(s);
|
|
71
|
+
return (char *)-1;
|
|
72
|
+
}
|
|
73
|
+
return s;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
static int parse_host_policy_options(napi_env env, napi_value value, tf_host_policy *policy,
|
|
77
|
+
char **workspace_root) {
|
|
78
|
+
memset(policy, 0, sizeof(*policy));
|
|
79
|
+
policy->allow_blocking = true;
|
|
80
|
+
*workspace_root = NULL;
|
|
81
|
+
if (!value) return 0;
|
|
82
|
+
napi_valuetype type;
|
|
83
|
+
if (napi_typeof(env, value, &type) != napi_ok || type == napi_undefined || type == napi_null) return 0;
|
|
84
|
+
if (type != napi_object) {
|
|
85
|
+
napi_throw_type_error(env, NULL, "createPipeline options must be an object");
|
|
86
|
+
return -1;
|
|
87
|
+
}
|
|
88
|
+
if (get_named_bool_alias(env, value, "allowFs", "allow_fs", false, &policy->allow_fs) != 0) return -1;
|
|
89
|
+
if (get_named_bool_alias(env, value, "allowNet", "allow_net", false, &policy->allow_net) != 0) return -1;
|
|
90
|
+
if (get_named_bool_alias(env, value, "allowSpill", "allow_spill", false, &policy->allow_spill) != 0) return -1;
|
|
91
|
+
if (get_named_bool_alias(env, value, "allowRulesFile", "allow_rules_file", false, &policy->allow_rules_file) != 0) return -1;
|
|
92
|
+
if (get_named_bool_alias(env, value, "allowBlocking", "allow_blocking", true, &policy->allow_blocking) != 0) return -1;
|
|
93
|
+
*workspace_root = get_named_string(env, value, "workspaceRoot");
|
|
94
|
+
if (*workspace_root == (char *)-1) { *workspace_root = NULL; return -1; }
|
|
95
|
+
if (!*workspace_root) *workspace_root = get_named_string(env, value, "workspace_root");
|
|
96
|
+
if (*workspace_root == (char *)-1) { *workspace_root = NULL; return -1; }
|
|
97
|
+
policy->workspace_root = *workspace_root && (*workspace_root)[0] ? *workspace_root : NULL;
|
|
98
|
+
return 0;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/* createPipeline(planJson: string, options?: HostPolicy) → External */
|
|
24
102
|
static napi_value napi_create_pipeline(napi_env env, napi_callback_info info) {
|
|
25
|
-
size_t argc =
|
|
26
|
-
napi_value argv[
|
|
103
|
+
size_t argc = 2;
|
|
104
|
+
napi_value argv[2] = {0};
|
|
27
105
|
NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, NULL, NULL));
|
|
28
106
|
|
|
29
107
|
if (argc < 1) {
|
|
@@ -31,13 +109,21 @@ static napi_value napi_create_pipeline(napi_env env, napi_callback_info info) {
|
|
|
31
109
|
return NULL;
|
|
32
110
|
}
|
|
33
111
|
|
|
112
|
+
tf_host_policy policy;
|
|
113
|
+
char *workspace_root = NULL;
|
|
114
|
+
if (parse_host_policy_options(env, argc >= 2 ? argv[1] : NULL, &policy, &workspace_root) != 0) {
|
|
115
|
+
free(workspace_root);
|
|
116
|
+
return NULL;
|
|
117
|
+
}
|
|
118
|
+
|
|
34
119
|
size_t str_len;
|
|
35
120
|
NAPI_CALL(env, napi_get_value_string_utf8(env, argv[0], NULL, 0, &str_len));
|
|
36
121
|
char *json = malloc(str_len + 1);
|
|
37
122
|
NAPI_CALL(env, napi_get_value_string_utf8(env, argv[0], json, str_len + 1, &str_len));
|
|
38
123
|
|
|
39
|
-
tf_pipeline *p =
|
|
124
|
+
tf_pipeline *p = tf_pipeline_create_with_host_policy(json, str_len, &policy);
|
|
40
125
|
free(json);
|
|
126
|
+
free(workspace_root);
|
|
41
127
|
|
|
42
128
|
if (!p) {
|
|
43
129
|
const char *err = tf_last_error();
|
|
@@ -71,6 +157,66 @@ static napi_value napi_push(napi_env env, napi_callback_info info) {
|
|
|
71
157
|
return NULL;
|
|
72
158
|
}
|
|
73
159
|
|
|
160
|
+
/* flushInput(pipeline: External) → void */
|
|
161
|
+
static napi_value napi_flush_input(napi_env env, napi_callback_info info) {
|
|
162
|
+
size_t argc = 1;
|
|
163
|
+
napi_value argv[1];
|
|
164
|
+
NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, NULL, NULL));
|
|
165
|
+
|
|
166
|
+
tf_pipeline *p;
|
|
167
|
+
NAPI_CALL(env, napi_get_value_external(env, argv[0], (void **)&p));
|
|
168
|
+
|
|
169
|
+
int rc = tf_pipeline_flush_input(p);
|
|
170
|
+
if (rc != 0) {
|
|
171
|
+
const char *err = tf_pipeline_error(p);
|
|
172
|
+
napi_throw_error(env, NULL, err ? err : "input flush failed");
|
|
173
|
+
}
|
|
174
|
+
return NULL;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/* setSourceName(pipeline: External, name?: string | null) → void */
|
|
178
|
+
static napi_value napi_set_source_name(napi_env env, napi_callback_info info) {
|
|
179
|
+
size_t argc = 2;
|
|
180
|
+
napi_value argv[2];
|
|
181
|
+
NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, NULL, NULL));
|
|
182
|
+
|
|
183
|
+
if (argc < 1) {
|
|
184
|
+
napi_throw_error(env, NULL, "setSourceName requires pipeline");
|
|
185
|
+
return NULL;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
tf_pipeline *p;
|
|
189
|
+
NAPI_CALL(env, napi_get_value_external(env, argv[0], (void **)&p));
|
|
190
|
+
|
|
191
|
+
char *name = NULL;
|
|
192
|
+
if (argc >= 2) {
|
|
193
|
+
napi_valuetype type;
|
|
194
|
+
NAPI_CALL(env, napi_typeof(env, argv[1], &type));
|
|
195
|
+
if (type != napi_null && type != napi_undefined) {
|
|
196
|
+
if (type != napi_string) {
|
|
197
|
+
napi_throw_error(env, NULL, "source name must be a string, null, or undefined");
|
|
198
|
+
return NULL;
|
|
199
|
+
}
|
|
200
|
+
size_t str_len = 0;
|
|
201
|
+
NAPI_CALL(env, napi_get_value_string_utf8(env, argv[1], NULL, 0, &str_len));
|
|
202
|
+
name = malloc(str_len + 1);
|
|
203
|
+
if (!name) {
|
|
204
|
+
napi_throw_error(env, NULL, "out of memory");
|
|
205
|
+
return NULL;
|
|
206
|
+
}
|
|
207
|
+
NAPI_CALL(env, napi_get_value_string_utf8(env, argv[1], name, str_len + 1, &str_len));
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
int rc = tf_pipeline_set_source_name(p, name);
|
|
212
|
+
free(name);
|
|
213
|
+
if (rc != 0) {
|
|
214
|
+
const char *err = tf_pipeline_error(p);
|
|
215
|
+
napi_throw_error(env, NULL, err ? err : "set source name failed");
|
|
216
|
+
}
|
|
217
|
+
return NULL;
|
|
218
|
+
}
|
|
219
|
+
|
|
74
220
|
/* finish(pipeline: External) → void */
|
|
75
221
|
static napi_value napi_finish(napi_env env, napi_callback_info info) {
|
|
76
222
|
size_t argc = 1;
|
|
@@ -88,6 +234,26 @@ static napi_value napi_finish(napi_env env, napi_callback_info info) {
|
|
|
88
234
|
return NULL;
|
|
89
235
|
}
|
|
90
236
|
|
|
237
|
+
/* finishStep(pipeline: External) → boolean done */
|
|
238
|
+
static napi_value napi_finish_step(napi_env env, napi_callback_info info) {
|
|
239
|
+
size_t argc = 1;
|
|
240
|
+
napi_value argv[1];
|
|
241
|
+
NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, NULL, NULL));
|
|
242
|
+
|
|
243
|
+
tf_pipeline *p;
|
|
244
|
+
NAPI_CALL(env, napi_get_value_external(env, argv[0], (void **)&p));
|
|
245
|
+
|
|
246
|
+
int rc = tf_pipeline_finish_step(p);
|
|
247
|
+
if (rc == TF_ERROR) {
|
|
248
|
+
const char *err = tf_pipeline_error(p);
|
|
249
|
+
napi_throw_error(env, NULL, err ? err : "finish failed");
|
|
250
|
+
return NULL;
|
|
251
|
+
}
|
|
252
|
+
napi_value result;
|
|
253
|
+
NAPI_CALL(env, napi_get_boolean(env, rc == TF_DONE, &result));
|
|
254
|
+
return result;
|
|
255
|
+
}
|
|
256
|
+
|
|
91
257
|
/* pull(pipeline: External, channel: number) → Buffer */
|
|
92
258
|
static napi_value napi_pull(napi_env env, napi_callback_info info) {
|
|
93
259
|
size_t argc = 2;
|
|
@@ -124,6 +290,46 @@ static napi_value napi_pull(napi_env env, napi_callback_info info) {
|
|
|
124
290
|
return buffer;
|
|
125
291
|
}
|
|
126
292
|
|
|
293
|
+
/* pullChunk(pipeline: External, channel: number, maxBytes?: number) → Buffer */
|
|
294
|
+
static napi_value napi_pull_chunk(napi_env env, napi_callback_info info) {
|
|
295
|
+
size_t argc = 3;
|
|
296
|
+
napi_value argv[3];
|
|
297
|
+
NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, NULL, NULL));
|
|
298
|
+
|
|
299
|
+
if (argc < 2) {
|
|
300
|
+
napi_throw_error(env, NULL, "pullChunk requires pipeline and channel");
|
|
301
|
+
return NULL;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
tf_pipeline *p;
|
|
305
|
+
NAPI_CALL(env, napi_get_value_external(env, argv[0], (void **)&p));
|
|
306
|
+
|
|
307
|
+
int32_t channel;
|
|
308
|
+
NAPI_CALL(env, napi_get_value_int32(env, argv[1], &channel));
|
|
309
|
+
|
|
310
|
+
uint32_t max_bytes = 65536;
|
|
311
|
+
if (argc >= 3) {
|
|
312
|
+
NAPI_CALL(env, napi_get_value_uint32(env, argv[2], &max_bytes));
|
|
313
|
+
if (max_bytes == 0) {
|
|
314
|
+
napi_throw_error(env, NULL, "pullChunk maxBytes must be positive");
|
|
315
|
+
return NULL;
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
uint8_t *tmp = malloc((size_t)max_bytes);
|
|
320
|
+
if (!tmp) {
|
|
321
|
+
napi_throw_error(env, NULL, "out of memory");
|
|
322
|
+
return NULL;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
size_t n = tf_pipeline_pull(p, channel, tmp, (size_t)max_bytes);
|
|
326
|
+
napi_value buffer;
|
|
327
|
+
void *buf_data;
|
|
328
|
+
NAPI_CALL(env, napi_create_buffer_copy(env, n, tmp, &buf_data, &buffer));
|
|
329
|
+
free(tmp);
|
|
330
|
+
return buffer;
|
|
331
|
+
}
|
|
332
|
+
|
|
127
333
|
/* free(pipeline: External) → void */
|
|
128
334
|
static napi_value napi_free_pipeline(napi_env env, napi_callback_info info) {
|
|
129
335
|
size_t argc = 1;
|
|
@@ -184,18 +390,15 @@ static napi_value napi_compile_dsl(napi_env env, napi_callback_info info) {
|
|
|
184
390
|
NAPI_CALL(env, napi_get_value_string_utf8(env, argv[0], dsl, str_len + 1, &str_len));
|
|
185
391
|
|
|
186
392
|
char *error = NULL;
|
|
187
|
-
|
|
393
|
+
char *json = tf_compile_dsl(dsl, str_len, &error);
|
|
188
394
|
free(dsl);
|
|
189
395
|
|
|
190
|
-
if (!
|
|
191
|
-
napi_throw_error(env, NULL, error ? error : "DSL
|
|
396
|
+
if (!json) {
|
|
397
|
+
napi_throw_error(env, NULL, error ? error : "DSL compile failed");
|
|
192
398
|
free(error);
|
|
193
399
|
return NULL;
|
|
194
400
|
}
|
|
195
401
|
|
|
196
|
-
char *json = tf_ir_plan_to_json(plan);
|
|
197
|
-
tf_ir_plan_destroy(plan);
|
|
198
|
-
|
|
199
402
|
napi_value result;
|
|
200
403
|
NAPI_CALL(env, napi_create_string_utf8(env, json, strlen(json), &result));
|
|
201
404
|
free(json);
|
|
@@ -306,8 +509,12 @@ static napi_value init(napi_env env, napi_value exports) {
|
|
|
306
509
|
napi_property_descriptor props[] = {
|
|
307
510
|
{"createPipeline", NULL, napi_create_pipeline, NULL, NULL, NULL, napi_default, NULL},
|
|
308
511
|
{"push", NULL, napi_push, NULL, NULL, NULL, napi_default, NULL},
|
|
512
|
+
{"flushInput", NULL, napi_flush_input, NULL, NULL, NULL, napi_default, NULL},
|
|
513
|
+
{"setSourceName", NULL, napi_set_source_name, NULL, NULL, NULL, napi_default, NULL},
|
|
309
514
|
{"finish", NULL, napi_finish, NULL, NULL, NULL, napi_default, NULL},
|
|
515
|
+
{"finishStep", NULL, napi_finish_step, NULL, NULL, NULL, napi_default, NULL},
|
|
310
516
|
{"pull", NULL, napi_pull, NULL, NULL, NULL, napi_default, NULL},
|
|
517
|
+
{"pullChunk", NULL, napi_pull_chunk, NULL, NULL, NULL, napi_default, NULL},
|
|
311
518
|
{"free", NULL, napi_free_pipeline, NULL, NULL, NULL, napi_default, NULL},
|
|
312
519
|
{"version", NULL, napi_tranfi_version, NULL, NULL, NULL, napi_default, NULL},
|
|
313
520
|
{"error", NULL, napi_tranfi_error, NULL, NULL, NULL, napi_default, NULL},
|
|
@@ -319,7 +526,8 @@ static napi_value init(napi_env env, napi_value exports) {
|
|
|
319
526
|
{"recipeDescription", NULL, napi_recipe_description, NULL, NULL, NULL, napi_default, NULL},
|
|
320
527
|
{"recipeFindDsl", NULL, napi_recipe_find_dsl, NULL, NULL, NULL, napi_default, NULL},
|
|
321
528
|
};
|
|
322
|
-
NAPI_CALL(env, napi_define_properties(env, exports,
|
|
529
|
+
NAPI_CALL(env, napi_define_properties(env, exports, 18, props));
|
|
530
|
+
NAPI_CALL(env, tranfi_napi_define_transform(env, exports));
|
|
323
531
|
return exports;
|
|
324
532
|
}
|
|
325
533
|
|