@temporalio/core-bridge 1.4.4 → 1.5.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.
Files changed (123) hide show
  1. package/Cargo.lock +327 -419
  2. package/Cargo.toml +1 -1
  3. package/index.js +25 -2
  4. package/lib/errors.d.ts +22 -0
  5. package/lib/errors.js +65 -0
  6. package/lib/errors.js.map +1 -0
  7. package/lib/index.d.ts +440 -0
  8. package/lib/index.js +8 -0
  9. package/lib/index.js.map +1 -0
  10. package/package.json +11 -5
  11. package/releases/aarch64-apple-darwin/index.node +0 -0
  12. package/releases/aarch64-unknown-linux-gnu/index.node +0 -0
  13. package/releases/x86_64-apple-darwin/index.node +0 -0
  14. package/releases/x86_64-pc-windows-msvc/index.node +0 -0
  15. package/releases/x86_64-unknown-linux-gnu/index.node +0 -0
  16. package/sdk-core/.buildkite/docker/Dockerfile +1 -1
  17. package/sdk-core/.buildkite/docker/docker-compose.yaml +2 -2
  18. package/sdk-core/bridge-ffi/Cargo.toml +1 -1
  19. package/sdk-core/bridge-ffi/include/sdk-core-bridge.h +0 -25
  20. package/sdk-core/bridge-ffi/src/lib.rs +29 -108
  21. package/sdk-core/bridge-ffi/src/wrappers.rs +35 -25
  22. package/sdk-core/client/Cargo.toml +1 -1
  23. package/sdk-core/client/src/lib.rs +12 -20
  24. package/sdk-core/client/src/raw.rs +9 -8
  25. package/sdk-core/client/src/retry.rs +100 -23
  26. package/sdk-core/core/Cargo.toml +5 -5
  27. package/sdk-core/core/benches/workflow_replay.rs +13 -10
  28. package/sdk-core/core/src/abstractions.rs +22 -22
  29. package/sdk-core/core/src/core_tests/activity_tasks.rs +1 -1
  30. package/sdk-core/core/src/core_tests/local_activities.rs +228 -6
  31. package/sdk-core/core/src/core_tests/queries.rs +247 -89
  32. package/sdk-core/core/src/core_tests/workers.rs +2 -2
  33. package/sdk-core/core/src/core_tests/workflow_cancels.rs +1 -1
  34. package/sdk-core/core/src/core_tests/workflow_tasks.rs +46 -27
  35. package/sdk-core/core/src/lib.rs +139 -32
  36. package/sdk-core/core/src/replay/mod.rs +185 -41
  37. package/sdk-core/core/src/telemetry/log_export.rs +190 -0
  38. package/sdk-core/core/src/telemetry/metrics.rs +184 -139
  39. package/sdk-core/core/src/telemetry/mod.rs +296 -318
  40. package/sdk-core/core/src/telemetry/prometheus_server.rs +4 -3
  41. package/sdk-core/core/src/test_help/mod.rs +9 -7
  42. package/sdk-core/core/src/worker/activities/local_activities.rs +2 -1
  43. package/sdk-core/core/src/worker/activities.rs +40 -23
  44. package/sdk-core/core/src/worker/client/mocks.rs +1 -1
  45. package/sdk-core/core/src/worker/client.rs +30 -4
  46. package/sdk-core/core/src/worker/mod.rs +22 -18
  47. package/sdk-core/core/src/worker/workflow/driven_workflow.rs +10 -19
  48. package/sdk-core/core/src/worker/workflow/history_update.rs +99 -25
  49. package/sdk-core/core/src/worker/workflow/machines/activity_state_machine.rs +1 -5
  50. package/sdk-core/core/src/worker/workflow/machines/cancel_external_state_machine.rs +1 -5
  51. package/sdk-core/core/src/worker/workflow/machines/cancel_workflow_state_machine.rs +1 -5
  52. package/sdk-core/core/src/worker/workflow/machines/child_workflow_state_machine.rs +1 -5
  53. package/sdk-core/core/src/worker/workflow/machines/complete_workflow_state_machine.rs +1 -5
  54. package/sdk-core/core/src/worker/workflow/machines/continue_as_new_workflow_state_machine.rs +2 -6
  55. package/sdk-core/core/src/worker/workflow/machines/fail_workflow_state_machine.rs +1 -5
  56. package/sdk-core/core/src/worker/workflow/machines/local_activity_state_machine.rs +18 -21
  57. package/sdk-core/core/src/worker/workflow/machines/mod.rs +12 -38
  58. package/sdk-core/core/src/worker/workflow/machines/modify_workflow_properties_state_machine.rs +178 -0
  59. package/sdk-core/core/src/worker/workflow/machines/patch_state_machine.rs +1 -5
  60. package/sdk-core/core/src/worker/workflow/machines/signal_external_state_machine.rs +1 -5
  61. package/sdk-core/core/src/worker/workflow/machines/timer_state_machine.rs +1 -5
  62. package/sdk-core/core/src/worker/workflow/machines/transition_coverage.rs +8 -2
  63. package/sdk-core/core/src/worker/workflow/machines/upsert_search_attributes_state_machine.rs +1 -5
  64. package/sdk-core/core/src/worker/workflow/machines/workflow_machines.rs +232 -216
  65. package/sdk-core/core/src/worker/workflow/machines/workflow_task_state_machine.rs +1 -6
  66. package/sdk-core/core/src/worker/workflow/managed_run/managed_wf_test.rs +4 -4
  67. package/sdk-core/core/src/worker/workflow/managed_run.rs +13 -5
  68. package/sdk-core/core/src/worker/workflow/mod.rs +61 -9
  69. package/sdk-core/core/src/worker/workflow/wft_poller.rs +2 -2
  70. package/sdk-core/core/src/worker/workflow/workflow_stream.rs +56 -11
  71. package/sdk-core/core-api/Cargo.toml +4 -3
  72. package/sdk-core/core-api/src/lib.rs +1 -43
  73. package/sdk-core/core-api/src/telemetry.rs +147 -0
  74. package/sdk-core/core-api/src/worker.rs +13 -0
  75. package/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/no_handle_conversions_require_into_fail.stderr +1 -1
  76. package/sdk-core/histories/evict_while_la_running_no_interference-23_history.bin +0 -0
  77. package/sdk-core/histories/evict_while_la_running_no_interference-85_history.bin +0 -0
  78. package/sdk-core/protos/api_upstream/.github/CODEOWNERS +1 -1
  79. package/sdk-core/protos/api_upstream/buf.yaml +0 -3
  80. package/sdk-core/protos/api_upstream/temporal/api/batch/v1/message.proto +3 -7
  81. package/sdk-core/protos/api_upstream/temporal/api/command/v1/message.proto +8 -0
  82. package/sdk-core/protos/api_upstream/temporal/api/enums/v1/command_type.proto +1 -2
  83. package/sdk-core/protos/api_upstream/temporal/api/enums/v1/event_type.proto +2 -0
  84. package/sdk-core/protos/api_upstream/temporal/api/enums/v1/failed_cause.proto +3 -0
  85. package/sdk-core/protos/api_upstream/temporal/api/history/v1/message.proto +13 -0
  86. package/sdk-core/protos/api_upstream/temporal/api/operatorservice/v1/request_response.proto +19 -59
  87. package/sdk-core/protos/api_upstream/temporal/api/operatorservice/v1/service.proto +0 -19
  88. package/sdk-core/protos/api_upstream/temporal/api/schedule/v1/message.proto +108 -29
  89. package/sdk-core/protos/api_upstream/temporal/api/taskqueue/v1/message.proto +2 -2
  90. package/sdk-core/protos/api_upstream/temporal/api/workflow/v1/message.proto +1 -0
  91. package/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/request_response.proto +47 -8
  92. package/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/service.proto +15 -1
  93. package/sdk-core/protos/local/temporal/sdk/core/workflow_activation/workflow_activation.proto +2 -0
  94. package/sdk-core/protos/local/temporal/sdk/core/workflow_commands/workflow_commands.proto +8 -1
  95. package/sdk-core/sdk/src/interceptors.rs +36 -3
  96. package/sdk-core/sdk/src/lib.rs +7 -4
  97. package/sdk-core/sdk/src/workflow_context.rs +13 -2
  98. package/sdk-core/sdk-core-protos/src/history_builder.rs +47 -1
  99. package/sdk-core/sdk-core-protos/src/history_info.rs +22 -22
  100. package/sdk-core/sdk-core-protos/src/lib.rs +49 -27
  101. package/sdk-core/test-utils/Cargo.toml +1 -0
  102. package/sdk-core/test-utils/src/lib.rs +81 -29
  103. package/sdk-core/tests/integ_tests/metrics_tests.rs +37 -0
  104. package/sdk-core/tests/integ_tests/polling_tests.rs +0 -13
  105. package/sdk-core/tests/integ_tests/workflow_tests/local_activities.rs +145 -4
  106. package/sdk-core/tests/integ_tests/workflow_tests/modify_wf_properties.rs +53 -0
  107. package/sdk-core/tests/integ_tests/workflow_tests/replay.rs +106 -20
  108. package/sdk-core/tests/integ_tests/workflow_tests.rs +18 -8
  109. package/sdk-core/tests/main.rs +6 -4
  110. package/src/conversions.rs +52 -47
  111. package/src/errors.rs +28 -86
  112. package/src/helpers.rs +3 -4
  113. package/src/lib.rs +2 -2
  114. package/src/runtime.rs +132 -61
  115. package/src/testing.rs +7 -4
  116. package/src/worker.rs +67 -50
  117. package/ts/errors.ts +55 -0
  118. package/{index.d.ts → ts/index.ts} +121 -15
  119. package/sdk-core/core/src/log_export.rs +0 -62
  120. package/sdk-core/core/src/worker/workflow/machines/mutable_side_effect_state_machine.rs +0 -127
  121. package/sdk-core/core/src/worker/workflow/machines/side_effect_state_machine.rs +0 -71
  122. package/sdk-core/protos/api_upstream/temporal/api/cluster/v1/message.proto +0 -83
  123. package/sdk-core/protos/api_upstream/temporal/api/enums/v1/cluster.proto +0 -40
@@ -6,6 +6,7 @@ mod child_workflows;
6
6
  mod continue_as_new;
7
7
  mod determinism;
8
8
  mod local_activities;
9
+ mod modify_wf_properties;
9
10
  mod patches;
10
11
  mod replay;
11
12
  mod resets;
@@ -28,6 +29,7 @@ use temporal_client::{WorkflowClientTrait, WorkflowOptions};
28
29
  use temporal_sdk::{
29
30
  interceptors::WorkerInterceptor, ActContext, ActivityOptions, WfContext, WorkflowResult,
30
31
  };
32
+ use temporal_sdk_core::replay::HistoryForReplay;
31
33
  use temporal_sdk_core_api::{errors::PollWfError, Worker};
32
34
  use temporal_sdk_core_protos::{
33
35
  coresdk::{
@@ -37,7 +39,7 @@ use temporal_sdk_core_protos::{
37
39
  workflow_completion::WorkflowActivationCompletion,
38
40
  ActivityTaskCompletion, AsJsonPayloadExt, IntoCompletion,
39
41
  },
40
- temporal::api::failure::v1::Failure,
42
+ temporal::api::{failure::v1::Failure, history::v1::history_event},
41
43
  };
42
44
  use temporal_sdk_core_test_utils::{
43
45
  history_from_proto_binary, init_core_and_create_wf, init_core_replay_preloaded,
@@ -102,6 +104,7 @@ async fn parallel_workflows_same_queue() {
102
104
  for handle in handles {
103
105
  handle.await.unwrap()
104
106
  }
107
+ core.shutdown().await;
105
108
  }
106
109
 
107
110
  static RUN_CT: AtomicUsize = AtomicUsize::new(0);
@@ -179,13 +182,20 @@ async fn shutdown_aborts_actively_blocked_poll() {
179
182
  #[tokio::test]
180
183
  async fn fail_wf_task(#[values(true, false)] replay: bool) {
181
184
  let core = if replay {
182
- let (core, _) = init_core_replay_preloaded(
183
- "fail_wf_task",
184
- &history_from_proto_binary("histories/fail_wf_task.bin")
185
- .await
186
- .unwrap(),
187
- );
188
- core
185
+ // We need to send the history twice, since we fail it the first time.
186
+ let mut hist_proto = history_from_proto_binary("histories/fail_wf_task.bin")
187
+ .await
188
+ .unwrap();
189
+ let hist = HistoryForReplay::new(hist_proto.clone(), "fake".to_string());
190
+ if let Some(history_event::Attributes::WorkflowExecutionStartedEventAttributes(
191
+ ref mut attrs,
192
+ )) = hist_proto.events[0].attributes
193
+ {
194
+ attrs.original_execution_run_id = "run2".to_string();
195
+ attrs.first_execution_run_id = "run2".to_string();
196
+ }
197
+ let hist2 = HistoryForReplay::new(hist_proto, "fake".to_string());
198
+ init_core_replay_preloaded("fail_wf_task", [hist, hist2])
189
199
  } else {
190
200
  let mut starter = init_core_and_create_wf("fail_wf_task").await;
191
201
  starter.get_worker().await
@@ -20,6 +20,7 @@ mod integ_tests {
20
20
  mod client_tests;
21
21
  mod ephemeral_server_tests;
22
22
  mod heartbeat_tests;
23
+ mod metrics_tests;
23
24
  mod polling_tests;
24
25
  mod queries_tests;
25
26
  mod visibility_tests;
@@ -28,10 +29,10 @@ mod integ_tests {
28
29
  use std::str::FromStr;
29
30
  use temporal_client::WorkflowService;
30
31
  use temporal_sdk_core::{
31
- init_worker, telemetry_init, ClientOptionsBuilder, ClientTlsConfig, TlsConfig,
32
+ init_worker, ClientOptionsBuilder, ClientTlsConfig, CoreRuntime, TlsConfig,
32
33
  WorkflowClientTrait,
33
34
  };
34
- use temporal_sdk_core_api::{worker::WorkerConfigBuilder, CoreTelemetry};
35
+ use temporal_sdk_core_api::worker::WorkerConfigBuilder;
35
36
  use temporal_sdk_core_protos::temporal::api::workflowservice::v1::ListNamespacesRequest;
36
37
  use temporal_sdk_core_test_utils::{
37
38
  get_integ_server_options, get_integ_telem_options, NAMESPACE,
@@ -43,13 +44,14 @@ mod integ_tests {
43
44
  #[ignore] // Really a compile time check more than anything
44
45
  async fn lang_bridge_example() {
45
46
  let opts = get_integ_server_options();
46
- let telem_d = telemetry_init(&get_integ_telem_options()).unwrap();
47
+ let runtime = CoreRuntime::new_assume_tokio(get_integ_telem_options()).unwrap();
47
48
  let mut retrying_client = opts
48
- .connect_no_namespace(telem_d.get_metric_meter(), None)
49
+ .connect_no_namespace(runtime.metric_meter(), None)
49
50
  .await
50
51
  .unwrap();
51
52
 
52
53
  let _worker = init_worker(
54
+ &runtime,
53
55
  WorkerConfigBuilder::default()
54
56
  .namespace("default")
55
57
  .task_queue("Wheee!")
@@ -1,5 +1,4 @@
1
1
  use crate::helpers::*;
2
- use log::LevelFilter;
3
2
  use neon::{
4
3
  context::Context,
5
4
  handle::Handle,
@@ -9,13 +8,15 @@ use neon::{
9
8
  use opentelemetry::trace::{SpanContext, SpanId, TraceFlags, TraceId, TraceState};
10
9
  use std::{collections::HashMap, net::SocketAddr, str::FromStr, time::Duration};
11
10
  use temporal_sdk_core::{
11
+ api::telemetry::{
12
+ Logger, MetricTemporality, MetricsExporter, OtelCollectorOptions, TelemetryOptions,
13
+ TelemetryOptionsBuilder, TraceExportConfig, TraceExporter,
14
+ },
12
15
  api::worker::{WorkerConfig, WorkerConfigBuilder},
13
16
  ephemeral_server::{
14
17
  TemporaliteConfig, TemporaliteConfigBuilder, TestServerConfig, TestServerConfigBuilder,
15
18
  },
16
- ClientOptions, ClientOptionsBuilder, ClientTlsConfig, Logger, MetricTemporality,
17
- MetricsExporter, OtelCollectorOptions, RetryConfig, TelemetryOptions, TelemetryOptionsBuilder,
18
- TlsConfig, TraceExporter, Url,
19
+ ClientOptions, ClientOptionsBuilder, ClientTlsConfig, RetryConfig, TlsConfig, Url,
19
20
  };
20
21
 
21
22
  pub enum EphemeralServerConfig {
@@ -63,8 +64,8 @@ impl ObjectHandleConversionsExt for Handle<'_, JsObject> {
63
64
  let span_id = js_value_getter!(ctx, self, "spanId", JsString);
64
65
  let trace_flags = js_value_getter!(ctx, self, "traceFlags", JsNumber);
65
66
  Ok(SpanContext::new(
66
- TraceId::from_hex(&trace_id),
67
- SpanId::from_hex(&span_id),
67
+ TraceId::from_hex(&trace_id).expect("TraceId is valid"),
68
+ SpanId::from_hex(&span_id).expect("SpanId is valid"),
68
69
  TraceFlags::new(trace_flags as u8),
69
70
  false,
70
71
  TraceState::from_str("").expect("Trace state must be valid"),
@@ -151,7 +152,7 @@ impl ObjectHandleConversionsExt for Handle<'_, JsObject> {
151
152
  ) as u64),
152
153
  max_elapsed_time: js_optional_value_getter!(
153
154
  cx,
154
- &retry_config,
155
+ retry_config,
155
156
  "maxElapsedTime",
156
157
  JsNumber
157
158
  )
@@ -176,38 +177,27 @@ impl ObjectHandleConversionsExt for Handle<'_, JsObject> {
176
177
 
177
178
  fn as_telemetry_options(&self, cx: &mut FunctionContext) -> NeonResult<TelemetryOptions> {
178
179
  let mut telemetry_opts = TelemetryOptionsBuilder::default();
179
-
180
- if let Some(tf) = js_optional_value_getter!(cx, self, "tracingFilter", JsString) {
181
- telemetry_opts.tracing_filter(tf);
182
- }
183
180
  telemetry_opts.no_temporal_prefix_for_metrics(
184
181
  js_optional_value_getter!(cx, self, "noTemporalPrefixForMetrics", JsBoolean)
185
182
  .unwrap_or_default(),
186
183
  );
184
+
187
185
  if let Some(ref logging) = js_optional_getter!(cx, self, "logging", JsObject) {
188
- if let Some(_) = get_optional(cx, logging, "console") {
189
- telemetry_opts.logging(Logger::Console);
190
- } else if let Some(ref forward) = js_optional_getter!(cx, logging, "forward", JsObject)
191
- {
192
- let level = js_value_getter!(cx, forward, "level", JsString);
193
- match LevelFilter::from_str(&level) {
194
- Ok(level) => {
195
- telemetry_opts.logging(Logger::Forward(level));
196
- }
197
- Err(err) => cx.throw_type_error(format!(
198
- "Invalid telemetryOptions.logging.forward.level: {}",
199
- err
200
- ))?,
201
- }
186
+ let filter = js_value_getter!(cx, logging, "filter", JsString);
187
+ if get_optional(cx, logging, "console").is_some() {
188
+ telemetry_opts.logging(Logger::Console { filter });
189
+ } else if get_optional(cx, logging, "forward").is_some() {
190
+ telemetry_opts.logging(Logger::Forward { filter });
202
191
  } else {
203
- cx.throw_type_error(format!(
204
- "Invalid telemetryOptions.logging, missing `console` or `forward` option"
205
- ))?
192
+ cx.throw_type_error(
193
+ "Invalid telemetryOptions.logging, expected either 'console' or 'forward' property",
194
+ )?;
206
195
  }
207
196
  }
208
- if let Some(metrics) = js_optional_getter!(cx, self, "metrics", JsObject) {
197
+
198
+ if let Some(ref metrics) = js_optional_getter!(cx, self, "metrics", JsObject) {
209
199
  if let Some(temporality) =
210
- js_optional_value_getter!(cx, &metrics, "temporality", JsString)
200
+ js_optional_value_getter!(cx, metrics, "temporality", JsString)
211
201
  {
212
202
  match temporality.as_str() {
213
203
  "cumulative" => {
@@ -221,8 +211,7 @@ impl ObjectHandleConversionsExt for Handle<'_, JsObject> {
221
211
  }
222
212
  };
223
213
  }
224
-
225
- if let Some(ref prom) = js_optional_getter!(cx, &metrics, "prometheus", JsObject) {
214
+ if let Some(ref prom) = js_optional_getter!(cx, metrics, "prometheus", JsObject) {
226
215
  let addr = js_value_getter!(cx, prom, "bindAddress", JsString);
227
216
  match addr.parse::<SocketAddr>() {
228
217
  Ok(address) => telemetry_opts.metrics(MetricsExporter::Prometheus(address)),
@@ -230,47 +219,63 @@ impl ObjectHandleConversionsExt for Handle<'_, JsObject> {
230
219
  "Invalid telemetryOptions.metrics.prometheus.bindAddress",
231
220
  )?,
232
221
  };
233
- } else if let Some(ref otel) = js_optional_getter!(cx, &metrics, "otel", JsObject) {
222
+ } else if let Some(ref otel) = js_optional_getter!(cx, metrics, "otel", JsObject) {
234
223
  let url = js_value_getter!(cx, otel, "url", JsString);
235
224
  let url = match Url::parse(&url) {
236
225
  Ok(url) => url,
237
226
  Err(_) => cx.throw_type_error("Invalid telemetryOptions.metrics.otel.url")?,
238
227
  };
239
228
  let headers =
240
- if let Some(headers) = js_optional_getter!(cx, otel, "headers", JsObject) {
229
+ if let Some(ref headers) = js_optional_getter!(cx, otel, "headers", JsObject) {
241
230
  headers.as_hash_map_of_string_to_string(cx)?
242
231
  } else {
243
232
  Default::default()
244
233
  };
245
- telemetry_opts
246
- .metrics(MetricsExporter::Otel(OtelCollectorOptions { url, headers }));
234
+ let metric_periodicity = Some(Duration::from_millis(js_value_getter!(
235
+ cx,
236
+ otel,
237
+ "metricPeriodicity",
238
+ JsNumber
239
+ ) as u64));
240
+ telemetry_opts.metrics(MetricsExporter::Otel(OtelCollectorOptions {
241
+ url,
242
+ headers,
243
+ metric_periodicity,
244
+ }));
247
245
  } else {
248
- cx.throw_type_error(format!(
249
- "Invalid telemetryOptions.metrics, missing `prometheus` or `otel` option"
250
- ))?
246
+ cx.throw_type_error(
247
+ "Invalid telemetryOptions.metrics, missing `prometheus` or `otel` option",
248
+ )?
251
249
  }
252
250
  }
253
251
 
254
- if let Some(tracing) = js_optional_getter!(cx, self, "tracing", JsObject) {
255
- if let Some(ref otel) = js_optional_getter!(cx, &tracing, "otel", JsObject) {
252
+ if let Some(ref tracing) = js_optional_getter!(cx, self, "tracing", JsObject) {
253
+ let filter = js_value_getter!(cx, tracing, "filter", JsString);
254
+ if let Some(ref otel) = js_optional_getter!(cx, tracing, "otel", JsObject) {
256
255
  let url = js_value_getter!(cx, otel, "url", JsString);
257
256
  let url = match Url::parse(&url) {
258
257
  Ok(url) => url,
259
258
  Err(_) => cx.throw_type_error("Invalid telemetryOptions.tracing.otel.url")?,
260
259
  };
261
260
  let headers =
262
- if let Some(headers) = js_optional_getter!(cx, otel, "headers", JsObject) {
261
+ if let Some(ref headers) = js_optional_getter!(cx, otel, "headers", JsObject) {
263
262
  headers.as_hash_map_of_string_to_string(cx)?
264
263
  } else {
265
264
  Default::default()
266
265
  };
267
- telemetry_opts.tracing(TraceExporter::Otel(OtelCollectorOptions { url, headers }));
266
+ telemetry_opts.tracing(TraceExportConfig {
267
+ filter,
268
+ exporter: TraceExporter::Otel(OtelCollectorOptions {
269
+ url,
270
+ headers,
271
+ metric_periodicity: None,
272
+ }),
273
+ });
268
274
  } else {
269
- cx.throw_type_error(format!(
270
- "Invalid telemetryOptions.tracing, missing `otel` option"
271
- ))?
275
+ cx.throw_type_error("Invalid telemetryOptions.tracing, missing `otel` option")?
272
276
  }
273
277
  }
278
+
274
279
  telemetry_opts.build().map_err(|reason| {
275
280
  cx.throw_type_error::<_, TelemetryOptions>(format!("{}", reason))
276
281
  .unwrap_err()
@@ -363,7 +368,7 @@ impl ObjectHandleConversionsExt for Handle<'_, JsObject> {
363
368
  let executable = match exec_type.as_str() {
364
369
  "cached-download" => {
365
370
  let version = js_optional_value_getter!(cx, &js_executable, "version", JsString)
366
- .unwrap_or("default".to_owned());
371
+ .unwrap_or_else(|| "default".to_owned());
367
372
  let dest_dir =
368
373
  js_optional_value_getter!(cx, &js_executable, "downloadDir", JsString);
369
374
 
package/src/errors.rs CHANGED
@@ -1,96 +1,38 @@
1
1
  use neon::prelude::*;
2
- use once_cell::sync::OnceCell;
3
2
 
4
3
  /// An unhandled error while communicating with the server, considered fatal
5
- pub static TRANSPORT_ERROR: OnceCell<Root<JsFunction>> = OnceCell::new();
4
+ pub static TRANSPORT_ERROR: &str = "TransportError";
6
5
  /// Thrown after shutdown was requested as a response to a poll function, JS should stop polling
7
6
  /// once this error is encountered
8
- pub static SHUTDOWN_ERROR: OnceCell<Root<JsFunction>> = OnceCell::new();
7
+ pub static SHUTDOWN_ERROR: &str = "ShutdownError";
9
8
  /// Something unexpected happened, considered fatal
10
- pub static UNEXPECTED_ERROR: OnceCell<Root<JsFunction>> = OnceCell::new();
9
+ pub static UNEXPECTED_ERROR: &str = "UnexpectedError";
11
10
  /// Used in different parts of the project to signal that something unexpected has happened
12
- pub static ILLEGAL_STATE_ERROR: OnceCell<Root<JsFunction>> = OnceCell::new();
13
-
14
- static ALREADY_REGISTERED_ERRORS: OnceCell<bool> = OnceCell::new();
15
-
16
- /// This is one of the ways to implement custom errors in neon.
17
- /// Taken from the answer in GitHub issues: https://github.com/neon-bindings/neon/issues/714
18
- pub trait CustomError {
19
- fn construct<'a, C>(&self, cx: &mut C, args: Vec<Handle<JsValue>>) -> JsResult<'a, JsObject>
20
- where
21
- C: Context<'a>;
22
-
23
- fn from_string<'a, C>(&self, cx: &mut C, message: impl Into<String>) -> JsResult<'a, JsObject>
24
- where
25
- C: Context<'a>;
26
-
27
- fn from_error<'a, C, E>(&self, cx: &mut C, err: E) -> JsResult<'a, JsObject>
28
- where
29
- C: Context<'a>,
30
- E: std::error::Error;
31
- }
32
-
33
- // Implement `CustomError` for ALL errors in a `OnceCell`. This only needs to be
34
- // done _once_ even if other errors are added.
35
- impl CustomError for OnceCell<Root<JsFunction>> {
36
- fn construct<'a, C>(&self, cx: &mut C, args: Vec<Handle<JsValue>>) -> JsResult<'a, JsObject>
37
- where
38
- C: Context<'a>,
39
- {
40
- let error = self
41
- .get()
42
- .expect("Expected module to be initialized")
43
- .to_inner(cx);
44
-
45
- // Use `.construct` to call this as a constructor instead of a normal function
46
- error.construct(cx, args)
47
- }
48
-
49
- fn from_string<'a, C>(&self, cx: &mut C, message: impl Into<String>) -> JsResult<'a, JsObject>
50
- where
51
- C: Context<'a>,
52
- {
53
- let args = vec![cx.string(message.into()).upcast()];
54
- self.construct(cx, args)
55
- }
56
-
57
- fn from_error<'a, C, E>(&self, cx: &mut C, err: E) -> JsResult<'a, JsObject>
58
- where
59
- C: Context<'a>,
60
- E: std::error::Error,
61
- {
62
- self.from_string(cx, format!("{:?}", err))
63
- }
11
+ pub static ILLEGAL_STATE_ERROR: &str = "IllegalStateError";
12
+
13
+ pub fn make_named_error_from_string<'a, C>(
14
+ cx: &mut C,
15
+ name: &str,
16
+ message: impl Into<String>,
17
+ ) -> JsResult<'a, JsError>
18
+ where
19
+ C: Context<'a>,
20
+ {
21
+ let error = cx.error(message.into()).unwrap();
22
+ let name = cx.string(name);
23
+ error.set(cx, "name", name)?;
24
+
25
+ Ok(error)
64
26
  }
65
27
 
66
- /// This method should be manually called _once_ from JavaScript to initialize the module
67
- /// It expects a single argument, an object with the various Error constructors.
68
- /// This is a very common pattern in Neon modules.
69
- pub fn register_errors(mut cx: FunctionContext) -> JsResult<JsUndefined> {
70
- let res = ALREADY_REGISTERED_ERRORS.set(true);
71
- if res.is_err() {
72
- // Don't do anything if errors are already registered
73
- return Ok(cx.undefined());
74
- }
75
-
76
- let mapping = cx.argument::<JsObject>(0)?;
77
- let shutdown_error = mapping
78
- .get::<JsFunction, _, _>(&mut cx, "ShutdownError")?
79
- .root(&mut cx);
80
- let transport_error = mapping
81
- .get::<JsFunction, _, _>(&mut cx, "TransportError")?
82
- .root(&mut cx);
83
- let unexpected_error = mapping
84
- .get::<JsFunction, _, _>(&mut cx, "UnexpectedError")?
85
- .root(&mut cx);
86
- let illegal_state_error = mapping
87
- .get::<JsFunction, _, _>(&mut cx, "IllegalStateError")?
88
- .root(&mut cx);
89
-
90
- TRANSPORT_ERROR.get_or_try_init(|| Ok(transport_error))?;
91
- SHUTDOWN_ERROR.get_or_try_init(|| Ok(shutdown_error))?;
92
- UNEXPECTED_ERROR.get_or_try_init(|| Ok(unexpected_error))?;
93
- ILLEGAL_STATE_ERROR.get_or_try_init(|| Ok(illegal_state_error))?;
94
-
95
- Ok(cx.undefined())
28
+ pub fn make_named_error_from_error<'a, C, E>(
29
+ cx: &mut C,
30
+ name: &str,
31
+ err: E,
32
+ ) -> JsResult<'a, JsError>
33
+ where
34
+ C: Context<'a>,
35
+ E: std::error::Error,
36
+ {
37
+ make_named_error_from_string(cx, name, format!("{:?}", err))
96
38
  }
package/src/helpers.rs CHANGED
@@ -1,6 +1,5 @@
1
1
  use crate::errors::*;
2
- use neon::prelude::*;
3
- use neon::types::buffer::TypedArray;
2
+ use neon::{prelude::*, types::buffer::TypedArray};
4
3
  use std::{fmt::Display, future::Future, sync::Arc};
5
4
 
6
5
  /// Send a result to JS via callback using a [Channel]
@@ -59,11 +58,11 @@ pub fn callback_with_unexpected_error<'a, C, E>(
59
58
  ) -> NeonResult<()>
60
59
  where
61
60
  C: Context<'a>,
62
- E: std::fmt::Display,
61
+ E: Display,
63
62
  {
64
63
  let err_str = format!("{}", err);
65
64
  callback_with_error(cx, callback, move |cx| {
66
- UNEXPECTED_ERROR.from_string(cx, err_str)
65
+ make_named_error_from_string(cx, UNEXPECTED_ERROR, err_str)
67
66
  })
68
67
  }
69
68
 
package/src/lib.rs CHANGED
@@ -13,13 +13,13 @@ use testing::*;
13
13
  #[neon::main]
14
14
  fn main(mut cx: ModuleContext) -> NeonResult<()> {
15
15
  cx.export_function("getTimeOfDay", get_time_of_day)?;
16
- cx.export_function("registerErrors", errors::register_errors)?;
17
- cx.export_function("initTelemetry", init_telemetry)?;
18
16
  cx.export_function("newRuntime", runtime_new)?;
19
17
  cx.export_function("newClient", client_new)?;
20
18
  cx.export_function("clientUpdateHeaders", client_update_headers)?;
21
19
  cx.export_function("newWorker", worker_new)?;
22
20
  cx.export_function("newReplayWorker", replay_worker_new)?;
21
+ cx.export_function("pushHistory", push_history)?;
22
+ cx.export_function("closeHistoryStream", close_history_stream)?;
23
23
  cx.export_function("workerInitiateShutdown", worker_initiate_shutdown)?;
24
24
  cx.export_function("workerFinalizeShutdown", worker_finalize_shutdown)?;
25
25
  cx.export_function("clientClose", client_close)?;