From f9a6cc3f03ceecba7b00236a91e5eacbe0a6b9d2 Mon Sep 17 00:00:00 2001 From: Mathias Lykkegaard Lorenzen Date: Mon, 2 Dec 2024 16:05:59 +0100 Subject: [PATCH 1/7] chore: export variables from node compat tools script (#27189) --- tests/node_compat/runner/setup.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/node_compat/runner/setup.ts b/tests/node_compat/runner/setup.ts index 32c0e2a63a..eeae3ae92d 100755 --- a/tests/node_compat/runner/setup.ts +++ b/tests/node_compat/runner/setup.ts @@ -19,7 +19,7 @@ const encoder = new TextEncoder(); const NODE_VERSION = version; -const NODE_IGNORED_TEST_DIRS = [ +export const NODE_IGNORED_TEST_DIRS = [ "addons", "async-hooks", "cctest", @@ -40,13 +40,13 @@ const NODE_IGNORED_TEST_DIRS = [ "wpt", ]; -const VENDORED_NODE_TEST = new URL("./suite/test/", import.meta.url); -const NODE_COMPAT_TEST_DEST_URL = new URL( +export const VENDORED_NODE_TEST = new URL("./suite/test/", import.meta.url); +export const NODE_COMPAT_TEST_DEST_URL = new URL( "../test/", import.meta.url, ); -async function getNodeTests(): Promise { +export async function getNodeTests(): Promise { const paths: string[] = []; const rootPath = VENDORED_NODE_TEST.href.slice(7); for await ( @@ -61,7 +61,7 @@ async function getNodeTests(): Promise { return paths.sort(); } -function getDenoTests() { +export function getDenoTests() { return Object.entries(config.tests) .filter(([testDir]) => !NODE_IGNORED_TEST_DIRS.includes(testDir)) .flatMap(([testDir, tests]) => tests.map((test) => testDir + "/" + test)); From 6dd2d5e49e00b5d1b7c30fd44c1975b3b2101148 Mon Sep 17 00:00:00 2001 From: David Sherret Date: Mon, 2 Dec 2024 11:00:31 -0500 Subject: [PATCH 2/7] refactor: upgrade to deno_npm 0.26 (#27194) --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- cli/npm/managed/resolution.rs | 34 ++++++++++++++++------------------ 3 files changed, 19 insertions(+), 21 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 77dc2cb4c4..9e000ddafc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1981,9 +1981,9 @@ dependencies = [ [[package]] name = "deno_npm" -version = "0.25.5" +version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89ded7af9db5d9f2986a739d1b5fbe1c57f498e4f996ae4114728e7c6dad213f" +checksum = "f2f125a5dba7839c46394a0a9c835da9fe60f5f412587ab4956a76492a1cc6a8" dependencies = [ "anyhow", "async-trait", diff --git a/Cargo.toml b/Cargo.toml index f6606b54c3..068046607f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -53,7 +53,7 @@ deno_bench_util = { version = "0.174.0", path = "./bench_util" } deno_config = { version = "=0.39.3", features = ["workspace", "sync"] } deno_lockfile = "=0.23.2" deno_media_type = { version = "0.2.0", features = ["module_specifier"] } -deno_npm = "=0.25.5" +deno_npm = "=0.26.0" deno_path_util = "=0.2.1" deno_permissions = { version = "0.40.0", path = "./runtime/permissions" } deno_runtime = { version = "0.189.0", path = "./runtime" } diff --git a/cli/npm/managed/resolution.rs b/cli/npm/managed/resolution.rs index ecfe5cb25c..033c853233 100644 --- a/cli/npm/managed/resolution.rs +++ b/cli/npm/managed/resolution.rs @@ -8,11 +8,10 @@ use deno_core::error::AnyError; use deno_lockfile::NpmPackageDependencyLockfileInfo; use deno_lockfile::NpmPackageLockfileInfo; use deno_npm::registry::NpmRegistryApi; +use deno_npm::resolution::AddPkgReqsOptions; use deno_npm::resolution::NpmPackagesPartitioned; use deno_npm::resolution::NpmResolutionError; use deno_npm::resolution::NpmResolutionSnapshot; -use deno_npm::resolution::NpmResolutionSnapshotPendingResolver; -use deno_npm::resolution::NpmResolutionSnapshotPendingResolverOptions; use deno_npm::resolution::PackageCacheFolderIdNotFoundError; use deno_npm::resolution::PackageNotFoundFromReferrerError; use deno_npm::resolution::PackageNvNotFoundError; @@ -283,8 +282,9 @@ async fn add_package_reqs_to_snapshot( /* this string is used in tests */ "Running npm resolution." ); - let pending_resolver = get_npm_pending_resolver(api); - let result = pending_resolver.add_pkg_reqs(snapshot, package_reqs).await; + let result = snapshot + .add_pkg_reqs(api, get_add_pkg_reqs_options(package_reqs)) + .await; api.clear_memory_cache(); let result = match &result.dep_graph_result { Err(NpmResolutionError::Resolution(err)) if api.mark_force_reload() => { @@ -293,7 +293,9 @@ async fn add_package_reqs_to_snapshot( // try again let snapshot = get_new_snapshot(); - let result = pending_resolver.add_pkg_reqs(snapshot, package_reqs).await; + let result = snapshot + .add_pkg_reqs(api, get_add_pkg_reqs_options(package_reqs)) + .await; api.clear_memory_cache(); result } @@ -309,19 +311,15 @@ async fn add_package_reqs_to_snapshot( result } -fn get_npm_pending_resolver( - api: &CliNpmRegistryApi, -) -> NpmResolutionSnapshotPendingResolver { - NpmResolutionSnapshotPendingResolver::new( - NpmResolutionSnapshotPendingResolverOptions { - api, - // WARNING: When bumping this version, check if anything needs to be - // updated in the `setNodeOnlyGlobalNames` call in 99_main_compiler.js - types_node_version_req: Some( - VersionReq::parse_from_npm("22.0.0 - 22.5.4").unwrap(), - ), - }, - ) +fn get_add_pkg_reqs_options(package_reqs: &[PackageReq]) -> AddPkgReqsOptions { + AddPkgReqsOptions { + package_reqs, + // WARNING: When bumping this version, check if anything needs to be + // updated in the `setNodeOnlyGlobalNames` call in 99_main_compiler.js + types_node_version_req: Some( + VersionReq::parse_from_npm("22.0.0 - 22.5.4").unwrap(), + ), + } } fn populate_lockfile_from_snapshot( From 7c036772df1554561b908655006f92f71e47fcec Mon Sep 17 00:00:00 2001 From: snek Date: Mon, 2 Dec 2024 20:45:41 +0100 Subject: [PATCH 3/7] feat(unstable): add metrics to otel (#27143) Refs: https://github.com/denoland/deno/issues/26852 Initial support for exporting metrics. Co-authored-by: Luca Casonato --- ext/telemetry/lib.rs | 748 +++++++++++++++++- ext/telemetry/telemetry.ts | 280 ++++++- .../@opentelemetry/sdk-metrics/registry.json | 1 + tests/specs/cli/otel_basic/__test__.jsonc | 4 + tests/specs/cli/otel_basic/basic.out | 3 +- tests/specs/cli/otel_basic/deno_dot_exit.out | 3 +- tests/specs/cli/otel_basic/main.ts | 6 + tests/specs/cli/otel_basic/metric.out | 124 +++ tests/specs/cli/otel_basic/metric.ts | 34 + tests/specs/cli/otel_basic/natural_exit.out | 3 +- tests/specs/cli/otel_basic/uncaught.out | 3 +- 11 files changed, 1174 insertions(+), 35 deletions(-) create mode 100644 tests/registry/npm/@opentelemetry/sdk-metrics/registry.json create mode 100644 tests/specs/cli/otel_basic/metric.out create mode 100644 tests/specs/cli/otel_basic/metric.ts diff --git a/ext/telemetry/lib.rs b/ext/telemetry/lib.rs index 1ce8ac1dcc..9612401014 100644 --- a/ext/telemetry/lib.rs +++ b/ext/telemetry/lib.rs @@ -16,6 +16,7 @@ use once_cell::sync::OnceCell; use opentelemetry::logs::AnyValue; use opentelemetry::logs::LogRecord as LogRecordTrait; use opentelemetry::logs::Severity; +use opentelemetry::otel_error; use opentelemetry::trace::SpanContext; use opentelemetry::trace::SpanId; use opentelemetry::trace::SpanKind; @@ -27,15 +28,21 @@ use opentelemetry::KeyValue; use opentelemetry::StringValue; use opentelemetry::Value; use opentelemetry_otlp::HttpExporterBuilder; +use opentelemetry_otlp::MetricExporter; use opentelemetry_otlp::Protocol; use opentelemetry_otlp::WithExportConfig; use opentelemetry_otlp::WithHttpConfig; use opentelemetry_sdk::export::trace::SpanData; use opentelemetry_sdk::logs::BatchLogProcessor; -use opentelemetry_sdk::logs::LogProcessor as LogProcessorTrait; +use opentelemetry_sdk::logs::LogProcessor; use opentelemetry_sdk::logs::LogRecord; +use opentelemetry_sdk::metrics::data::Metric; +use opentelemetry_sdk::metrics::data::ResourceMetrics; +use opentelemetry_sdk::metrics::data::ScopeMetrics; +use opentelemetry_sdk::metrics::exporter::PushMetricExporter; +use opentelemetry_sdk::metrics::Temporality; use opentelemetry_sdk::trace::BatchSpanProcessor; -use opentelemetry_sdk::trace::SpanProcessor as SpanProcessorTrait; +use opentelemetry_sdk::trace::SpanProcessor; use opentelemetry_sdk::Resource; use opentelemetry_semantic_conventions::resource::PROCESS_RUNTIME_NAME; use opentelemetry_semantic_conventions::resource::PROCESS_RUNTIME_VERSION; @@ -54,9 +61,6 @@ use std::thread; use std::time::Duration; use std::time::SystemTime; -type SpanProcessor = BatchSpanProcessor; -type LogProcessor = BatchLogProcessor; - deno_core::extension!( deno_telemetry, ops = [ @@ -71,6 +75,23 @@ deno_core::extension!( op_otel_span_attribute3, op_otel_span_set_dropped, op_otel_span_flush, + op_otel_metrics_resource_attribute, + op_otel_metrics_resource_attribute2, + op_otel_metrics_resource_attribute3, + op_otel_metrics_scope, + op_otel_metrics_sum, + op_otel_metrics_gauge, + op_otel_metrics_sum_or_gauge_data_point, + op_otel_metrics_histogram, + op_otel_metrics_histogram_data_point, + op_otel_metrics_histogram_data_point_entry_final, + op_otel_metrics_histogram_data_point_entry1, + op_otel_metrics_histogram_data_point_entry2, + op_otel_metrics_histogram_data_point_entry3, + op_otel_metrics_data_point_attribute, + op_otel_metrics_data_point_attribute2, + op_otel_metrics_data_point_attribute3, + op_otel_metrics_submit, ], esm = ["telemetry.ts", "util.ts"], ); @@ -322,8 +343,69 @@ mod hyper_client { } } -static OTEL_PROCESSORS: OnceCell<(SpanProcessor, LogProcessor)> = - OnceCell::new(); +enum MetricProcessorMessage { + ResourceMetrics(ResourceMetrics), + Flush(tokio::sync::oneshot::Sender<()>), +} + +struct MetricProcessor { + tx: tokio::sync::mpsc::Sender, +} + +impl MetricProcessor { + fn new(exporter: MetricExporter) -> Self { + let (tx, mut rx) = tokio::sync::mpsc::channel(2048); + let future = async move { + while let Some(message) = rx.recv().await { + match message { + MetricProcessorMessage::ResourceMetrics(mut rm) => { + if let Err(err) = exporter.export(&mut rm).await { + otel_error!( + name: "MetricProcessor.Export.Error", + error = format!("{}", err) + ); + } + } + MetricProcessorMessage::Flush(tx) => { + if let Err(()) = tx.send(()) { + otel_error!( + name: "MetricProcessor.Flush.SendResultError", + error = "()", + ); + } + } + } + } + }; + + (*OTEL_SHARED_RUNTIME_SPAWN_TASK_TX) + .unbounded_send(Box::pin(future)) + .expect("failed to send task to shared OpenTelemetry runtime"); + + Self { tx } + } + + fn submit(&self, rm: ResourceMetrics) { + let _ = self + .tx + .try_send(MetricProcessorMessage::ResourceMetrics(rm)); + } + + fn force_flush(&self) -> Result<(), anyhow::Error> { + let (tx, rx) = tokio::sync::oneshot::channel(); + self.tx.try_send(MetricProcessorMessage::Flush(tx))?; + deno_core::futures::executor::block_on(rx)?; + Ok(()) + } +} + +struct Processors { + spans: BatchSpanProcessor, + logs: BatchLogProcessor, + metrics: MetricProcessor, +} + +static OTEL_PROCESSORS: OnceCell = OnceCell::new(); static BUILT_IN_INSTRUMENTATION_SCOPE: OnceCell< opentelemetry::InstrumentationScope, @@ -404,6 +486,12 @@ pub fn init(config: OtelConfig) -> anyhow::Result<()> { BatchSpanProcessor::builder(span_exporter, OtelSharedRuntime).build(); span_processor.set_resource(&resource); + let metric_exporter = HttpExporterBuilder::default() + .with_http_client(client.clone()) + .with_protocol(protocol) + .build_metrics_exporter(Temporality::Cumulative)?; + let metric_processor = MetricProcessor::new(metric_exporter); + let log_exporter = HttpExporterBuilder::default() .with_http_client(client) .with_protocol(protocol) @@ -413,7 +501,11 @@ pub fn init(config: OtelConfig) -> anyhow::Result<()> { log_processor.set_resource(&resource); OTEL_PROCESSORS - .set((span_processor, log_processor)) + .set(Processors { + spans: span_processor, + logs: log_processor, + metrics: metric_processor, + }) .map_err(|_| anyhow!("failed to init otel"))?; let builtin_instrumentation_scope = @@ -431,16 +523,22 @@ pub fn init(config: OtelConfig) -> anyhow::Result<()> { /// `process::exit()`, to ensure that all OpenTelemetry logs are properly /// flushed before the process terminates. pub fn flush() { - if let Some((span_processor, log_processor)) = OTEL_PROCESSORS.get() { - let _ = span_processor.force_flush(); - let _ = log_processor.force_flush(); + if let Some(Processors { + spans, + logs, + metrics, + }) = OTEL_PROCESSORS.get() + { + let _ = spans.force_flush(); + let _ = logs.force_flush(); + let _ = metrics.force_flush(); } } pub fn handle_log(record: &log::Record) { use log::Level; - let Some((_, log_processor)) = OTEL_PROCESSORS.get() else { + let Some(Processors { logs, .. }) = OTEL_PROCESSORS.get() else { return; }; @@ -490,7 +588,7 @@ pub fn handle_log(record: &log::Record) { let _ = record.key_values().visit(&mut Visitor(&mut log_record)); - log_processor.emit( + logs.emit( &mut log_record, BUILT_IN_INSTRUMENTATION_SCOPE.get().unwrap(), ); @@ -648,7 +746,7 @@ fn op_otel_log( span_id: v8::Local<'_, v8::Value>, #[smi] trace_flags: u8, ) { - let Some((_, log_processor)) = OTEL_PROCESSORS.get() else { + let Some(Processors { logs, .. }) = OTEL_PROCESSORS.get() else { return; }; @@ -678,12 +776,25 @@ fn op_otel_log( ); } - log_processor.emit( + logs.emit( &mut log_record, BUILT_IN_INSTRUMENTATION_SCOPE.get().unwrap(), ); } +fn owned_string<'s>( + scope: &mut v8::HandleScope<'s>, + string: v8::Local<'s, v8::String>, +) -> String { + let x = v8::ValueView::new(scope, string); + match x.data() { + v8::ValueViewData::OneByte(bytes) => { + String::from_utf8_lossy(bytes).into_owned() + } + v8::ValueViewData::TwoByte(bytes) => String::from_utf16_lossy(bytes), + } +} + struct TemporarySpan(SpanData); #[allow(clippy::too_many_arguments)] @@ -700,10 +811,10 @@ fn op_otel_span_start<'s>( end_time: f64, ) -> Result<(), anyhow::Error> { if let Some(temporary_span) = state.try_take::() { - let Some((span_processor, _)) = OTEL_PROCESSORS.get() else { + let Some(Processors { spans, .. }) = OTEL_PROCESSORS.get() else { return Ok(()); }; - span_processor.on_end(temporary_span.0); + spans.on_end(temporary_span.0); }; let Some(InstrumentationScope(instrumentation_scope)) = @@ -724,15 +835,7 @@ fn op_otel_span_start<'s>( let parent_span_id = parse_span_id(scope, parent_span_id); - let name = { - let x = v8::ValueView::new(scope, name.try_cast()?); - match x.data() { - v8::ValueViewData::OneByte(bytes) => { - String::from_utf8_lossy(bytes).into_owned() - } - v8::ValueViewData::TwoByte(bytes) => String::from_utf16_lossy(bytes), - } - }; + let name = owned_string(scope, name.try_cast()?); let temporary_span = TemporarySpan(SpanData { span_context: SpanContext::new( @@ -866,9 +969,598 @@ fn op_otel_span_flush(state: &mut OpState) { return; }; - let Some((span_processor, _)) = OTEL_PROCESSORS.get() else { + let Some(Processors { spans, .. }) = OTEL_PROCESSORS.get() else { return; }; - span_processor.on_end(temporary_span.0); + spans.on_end(temporary_span.0); +} + +// Holds data being built from JS before +// it is submitted to the rust processor. +struct TemporaryMetricsExport { + resource_attributes: Vec, + scope_metrics: Vec, + metric: Option, +} + +struct TemporaryMetric { + name: String, + description: String, + unit: String, + data: TemporaryMetricData, +} + +enum TemporaryMetricData { + Sum(opentelemetry_sdk::metrics::data::Sum), + Gauge(opentelemetry_sdk::metrics::data::Gauge), + Histogram(opentelemetry_sdk::metrics::data::Histogram), +} + +impl From for Metric { + fn from(value: TemporaryMetric) -> Self { + Metric { + name: Cow::Owned(value.name), + description: Cow::Owned(value.description), + unit: Cow::Owned(value.unit), + data: match value.data { + TemporaryMetricData::Sum(sum) => Box::new(sum), + TemporaryMetricData::Gauge(gauge) => Box::new(gauge), + TemporaryMetricData::Histogram(histogram) => Box::new(histogram), + }, + } + } +} + +#[op2(fast)] +fn op_otel_metrics_resource_attribute<'s>( + scope: &mut v8::HandleScope<'s>, + state: &mut OpState, + #[smi] capacity: u32, + key: v8::Local<'s, v8::Value>, + value: v8::Local<'s, v8::Value>, +) { + let metrics_export = if let Some(metrics_export) = + state.try_borrow_mut::() + { + metrics_export.resource_attributes.reserve_exact( + (capacity as usize) - metrics_export.resource_attributes.capacity(), + ); + metrics_export + } else { + state.put(TemporaryMetricsExport { + resource_attributes: Vec::with_capacity(capacity as usize), + scope_metrics: vec![], + metric: None, + }); + state.borrow_mut() + }; + attr!(scope, metrics_export.resource_attributes, key, value); +} + +#[op2(fast)] +fn op_otel_metrics_resource_attribute2<'s>( + scope: &mut v8::HandleScope<'s>, + state: &mut OpState, + #[smi] capacity: u32, + key1: v8::Local<'s, v8::Value>, + value1: v8::Local<'s, v8::Value>, + key2: v8::Local<'s, v8::Value>, + value2: v8::Local<'s, v8::Value>, +) { + let metrics_export = if let Some(metrics_export) = + state.try_borrow_mut::() + { + metrics_export.resource_attributes.reserve_exact( + (capacity as usize) - metrics_export.resource_attributes.capacity(), + ); + metrics_export + } else { + state.put(TemporaryMetricsExport { + resource_attributes: Vec::with_capacity(capacity as usize), + scope_metrics: vec![], + metric: None, + }); + state.borrow_mut() + }; + attr!(scope, metrics_export.resource_attributes, key1, value1); + attr!(scope, metrics_export.resource_attributes, key2, value2); +} + +#[allow(clippy::too_many_arguments)] +#[op2(fast)] +fn op_otel_metrics_resource_attribute3<'s>( + scope: &mut v8::HandleScope<'s>, + state: &mut OpState, + #[smi] capacity: u32, + key1: v8::Local<'s, v8::Value>, + value1: v8::Local<'s, v8::Value>, + key2: v8::Local<'s, v8::Value>, + value2: v8::Local<'s, v8::Value>, + key3: v8::Local<'s, v8::Value>, + value3: v8::Local<'s, v8::Value>, +) { + let metrics_export = if let Some(metrics_export) = + state.try_borrow_mut::() + { + metrics_export.resource_attributes.reserve_exact( + (capacity as usize) - metrics_export.resource_attributes.capacity(), + ); + metrics_export + } else { + state.put(TemporaryMetricsExport { + resource_attributes: Vec::with_capacity(capacity as usize), + scope_metrics: vec![], + metric: None, + }); + state.borrow_mut() + }; + attr!(scope, metrics_export.resource_attributes, key1, value1); + attr!(scope, metrics_export.resource_attributes, key2, value2); + attr!(scope, metrics_export.resource_attributes, key3, value3); +} + +#[op2(fast)] +fn op_otel_metrics_scope<'s>( + scope: &mut v8::HandleScope<'s>, + state: &mut OpState, + name: v8::Local<'s, v8::Value>, + schema_url: v8::Local<'s, v8::Value>, + version: v8::Local<'s, v8::Value>, +) { + let name = owned_string(scope, name.cast()); + + let scope_builder = opentelemetry::InstrumentationScope::builder(name); + let scope_builder = if schema_url.is_null_or_undefined() { + scope_builder + } else { + scope_builder.with_schema_url(owned_string(scope, schema_url.cast())) + }; + let scope_builder = if version.is_null_or_undefined() { + scope_builder + } else { + scope_builder.with_version(owned_string(scope, version.cast())) + }; + let scope = scope_builder.build(); + let scope_metric = ScopeMetrics { + scope, + metrics: vec![], + }; + + match state.try_borrow_mut::() { + Some(temp) => { + if let Some(current_metric) = temp.metric.take() { + let metric = Metric::from(current_metric); + temp.scope_metrics.last_mut().unwrap().metrics.push(metric); + } + temp.scope_metrics.push(scope_metric); + } + None => { + state.put(TemporaryMetricsExport { + resource_attributes: vec![], + scope_metrics: vec![scope_metric], + metric: None, + }); + } + } +} + +#[op2(fast)] +fn op_otel_metrics_sum<'s>( + scope: &mut v8::HandleScope<'s>, + state: &mut OpState, + name: v8::Local<'s, v8::Value>, + description: v8::Local<'s, v8::Value>, + unit: v8::Local<'s, v8::Value>, + #[smi] temporality: u8, + is_monotonic: bool, +) { + let Some(temp) = state.try_borrow_mut::() else { + return; + }; + + if let Some(current_metric) = temp.metric.take() { + let metric = Metric::from(current_metric); + temp.scope_metrics.last_mut().unwrap().metrics.push(metric); + } + + let name = owned_string(scope, name.cast()); + let description = owned_string(scope, description.cast()); + let unit = owned_string(scope, unit.cast()); + let temporality = match temporality { + 0 => Temporality::Delta, + 1 => Temporality::Cumulative, + _ => return, + }; + let sum = opentelemetry_sdk::metrics::data::Sum { + data_points: vec![], + temporality, + is_monotonic, + }; + + temp.metric = Some(TemporaryMetric { + name, + description, + unit, + data: TemporaryMetricData::Sum(sum), + }); +} + +#[op2(fast)] +fn op_otel_metrics_gauge<'s>( + scope: &mut v8::HandleScope<'s>, + state: &mut OpState, + name: v8::Local<'s, v8::Value>, + description: v8::Local<'s, v8::Value>, + unit: v8::Local<'s, v8::Value>, +) { + let Some(temp) = state.try_borrow_mut::() else { + return; + }; + + if let Some(current_metric) = temp.metric.take() { + let metric = Metric::from(current_metric); + temp.scope_metrics.last_mut().unwrap().metrics.push(metric); + } + + let name = owned_string(scope, name.cast()); + let description = owned_string(scope, description.cast()); + let unit = owned_string(scope, unit.cast()); + + let gauge = opentelemetry_sdk::metrics::data::Gauge { + data_points: vec![], + }; + + temp.metric = Some(TemporaryMetric { + name, + description, + unit, + data: TemporaryMetricData::Gauge(gauge), + }); +} + +#[op2(fast)] +fn op_otel_metrics_sum_or_gauge_data_point( + state: &mut OpState, + value: f64, + start_time: f64, + time: f64, +) { + let Some(temp) = state.try_borrow_mut::() else { + return; + }; + + let start_time = SystemTime::UNIX_EPOCH + .checked_add(std::time::Duration::from_secs_f64(start_time)) + .unwrap(); + let time = SystemTime::UNIX_EPOCH + .checked_add(std::time::Duration::from_secs_f64(time)) + .unwrap(); + + let data_point = opentelemetry_sdk::metrics::data::DataPoint { + value, + start_time: Some(start_time), + time: Some(time), + attributes: vec![], + exemplars: vec![], + }; + + match &mut temp.metric { + Some(TemporaryMetric { + data: TemporaryMetricData::Sum(sum), + .. + }) => sum.data_points.push(data_point), + Some(TemporaryMetric { + data: TemporaryMetricData::Gauge(gauge), + .. + }) => gauge.data_points.push(data_point), + _ => {} + } +} + +#[op2(fast)] +fn op_otel_metrics_histogram<'s>( + scope: &mut v8::HandleScope<'s>, + state: &mut OpState, + name: v8::Local<'s, v8::Value>, + description: v8::Local<'s, v8::Value>, + unit: v8::Local<'s, v8::Value>, + #[smi] temporality: u8, +) { + let Some(temp) = state.try_borrow_mut::() else { + return; + }; + + if let Some(current_metric) = temp.metric.take() { + let metric = Metric::from(current_metric); + temp.scope_metrics.last_mut().unwrap().metrics.push(metric); + } + + let name = owned_string(scope, name.cast()); + let description = owned_string(scope, description.cast()); + let unit = owned_string(scope, unit.cast()); + + let temporality = match temporality { + 0 => Temporality::Delta, + 1 => Temporality::Cumulative, + _ => return, + }; + let histogram = opentelemetry_sdk::metrics::data::Histogram { + data_points: vec![], + temporality, + }; + + temp.metric = Some(TemporaryMetric { + name, + description, + unit, + data: TemporaryMetricData::Histogram(histogram), + }); +} + +#[allow(clippy::too_many_arguments)] +#[op2(fast)] +fn op_otel_metrics_histogram_data_point( + state: &mut OpState, + #[number] count: u64, + min: f64, + max: f64, + sum: f64, + start_time: f64, + time: f64, + #[smi] buckets: u32, +) { + let Some(temp) = state.try_borrow_mut::() else { + return; + }; + + let min = if min.is_nan() { None } else { Some(min) }; + let max = if max.is_nan() { None } else { Some(max) }; + + let start_time = SystemTime::UNIX_EPOCH + .checked_add(std::time::Duration::from_secs_f64(start_time)) + .unwrap(); + let time = SystemTime::UNIX_EPOCH + .checked_add(std::time::Duration::from_secs_f64(time)) + .unwrap(); + + let data_point = opentelemetry_sdk::metrics::data::HistogramDataPoint { + bounds: Vec::with_capacity(buckets as usize), + bucket_counts: Vec::with_capacity((buckets as usize) + 1), + count, + sum, + min, + max, + start_time, + time, + attributes: vec![], + exemplars: vec![], + }; + + if let Some(TemporaryMetric { + data: TemporaryMetricData::Histogram(histogram), + .. + }) = &mut temp.metric + { + histogram.data_points.push(data_point); + } +} + +#[op2(fast)] +fn op_otel_metrics_histogram_data_point_entry_final( + state: &mut OpState, + #[number] count1: u64, +) { + let Some(temp) = state.try_borrow_mut::() else { + return; + }; + + if let Some(TemporaryMetric { + data: TemporaryMetricData::Histogram(histogram), + .. + }) = &mut temp.metric + { + histogram + .data_points + .last_mut() + .unwrap() + .bucket_counts + .push(count1) + } +} + +#[op2(fast)] +fn op_otel_metrics_histogram_data_point_entry1( + state: &mut OpState, + #[number] count1: u64, + bound1: f64, +) { + let Some(temp) = state.try_borrow_mut::() else { + return; + }; + + if let Some(TemporaryMetric { + data: TemporaryMetricData::Histogram(histogram), + .. + }) = &mut temp.metric + { + let data_point = histogram.data_points.last_mut().unwrap(); + data_point.bucket_counts.push(count1); + data_point.bounds.push(bound1); + } +} + +#[op2(fast)] +fn op_otel_metrics_histogram_data_point_entry2( + state: &mut OpState, + #[number] count1: u64, + bound1: f64, + #[number] count2: u64, + bound2: f64, +) { + let Some(temp) = state.try_borrow_mut::() else { + return; + }; + + if let Some(TemporaryMetric { + data: TemporaryMetricData::Histogram(histogram), + .. + }) = &mut temp.metric + { + let data_point = histogram.data_points.last_mut().unwrap(); + data_point.bucket_counts.push(count1); + data_point.bounds.push(bound1); + data_point.bucket_counts.push(count2); + data_point.bounds.push(bound2); + } +} + +#[op2(fast)] +fn op_otel_metrics_histogram_data_point_entry3( + state: &mut OpState, + #[number] count1: u64, + bound1: f64, + #[number] count2: u64, + bound2: f64, + #[number] count3: u64, + bound3: f64, +) { + let Some(temp) = state.try_borrow_mut::() else { + return; + }; + + if let Some(TemporaryMetric { + data: TemporaryMetricData::Histogram(histogram), + .. + }) = &mut temp.metric + { + let data_point = histogram.data_points.last_mut().unwrap(); + data_point.bucket_counts.push(count1); + data_point.bounds.push(bound1); + data_point.bucket_counts.push(count2); + data_point.bounds.push(bound2); + data_point.bucket_counts.push(count3); + data_point.bounds.push(bound3); + } +} + +#[op2(fast)] +fn op_otel_metrics_data_point_attribute<'s>( + scope: &mut v8::HandleScope<'s>, + state: &mut OpState, + #[smi] capacity: u32, + key: v8::Local<'s, v8::Value>, + value: v8::Local<'s, v8::Value>, +) { + if let Some(TemporaryMetricsExport { + metric: Some(metric), + .. + }) = state.try_borrow_mut::() + { + let attributes = match &mut metric.data { + TemporaryMetricData::Sum(sum) => { + &mut sum.data_points.last_mut().unwrap().attributes + } + TemporaryMetricData::Gauge(gauge) => { + &mut gauge.data_points.last_mut().unwrap().attributes + } + TemporaryMetricData::Histogram(histogram) => { + &mut histogram.data_points.last_mut().unwrap().attributes + } + }; + attributes.reserve_exact((capacity as usize) - attributes.capacity()); + attr!(scope, attributes, key, value); + } +} + +#[op2(fast)] +fn op_otel_metrics_data_point_attribute2<'s>( + scope: &mut v8::HandleScope<'s>, + state: &mut OpState, + #[smi] capacity: u32, + key1: v8::Local<'s, v8::Value>, + value1: v8::Local<'s, v8::Value>, + key2: v8::Local<'s, v8::Value>, + value2: v8::Local<'s, v8::Value>, +) { + if let Some(TemporaryMetricsExport { + metric: Some(metric), + .. + }) = state.try_borrow_mut::() + { + let attributes = match &mut metric.data { + TemporaryMetricData::Sum(sum) => { + &mut sum.data_points.last_mut().unwrap().attributes + } + TemporaryMetricData::Gauge(gauge) => { + &mut gauge.data_points.last_mut().unwrap().attributes + } + TemporaryMetricData::Histogram(histogram) => { + &mut histogram.data_points.last_mut().unwrap().attributes + } + }; + attributes.reserve_exact((capacity as usize) - attributes.capacity()); + attr!(scope, attributes, key1, value1); + attr!(scope, attributes, key2, value2); + } +} + +#[allow(clippy::too_many_arguments)] +#[op2(fast)] +fn op_otel_metrics_data_point_attribute3<'s>( + scope: &mut v8::HandleScope<'s>, + state: &mut OpState, + #[smi] capacity: u32, + key1: v8::Local<'s, v8::Value>, + value1: v8::Local<'s, v8::Value>, + key2: v8::Local<'s, v8::Value>, + value2: v8::Local<'s, v8::Value>, + key3: v8::Local<'s, v8::Value>, + value3: v8::Local<'s, v8::Value>, +) { + if let Some(TemporaryMetricsExport { + metric: Some(metric), + .. + }) = state.try_borrow_mut::() + { + let attributes = match &mut metric.data { + TemporaryMetricData::Sum(sum) => { + &mut sum.data_points.last_mut().unwrap().attributes + } + TemporaryMetricData::Gauge(gauge) => { + &mut gauge.data_points.last_mut().unwrap().attributes + } + TemporaryMetricData::Histogram(histogram) => { + &mut histogram.data_points.last_mut().unwrap().attributes + } + }; + attributes.reserve_exact((capacity as usize) - attributes.capacity()); + attr!(scope, attributes, key1, value1); + attr!(scope, attributes, key2, value2); + attr!(scope, attributes, key3, value3); + } +} + +#[op2(fast)] +fn op_otel_metrics_submit(state: &mut OpState) { + let Some(mut temp) = state.try_take::() else { + return; + }; + + let Some(Processors { metrics, .. }) = OTEL_PROCESSORS.get() else { + return; + }; + + if let Some(current_metric) = temp.metric { + let metric = Metric::from(current_metric); + temp.scope_metrics.last_mut().unwrap().metrics.push(metric); + } + + let resource = Resource::new(temp.resource_attributes); + let scope_metrics = temp.scope_metrics; + + metrics.submit(ResourceMetrics { + resource, + scope_metrics, + }); } diff --git a/ext/telemetry/telemetry.ts b/ext/telemetry/telemetry.ts index 03fbd83e2f..e8065e8a3b 100644 --- a/ext/telemetry/telemetry.ts +++ b/ext/telemetry/telemetry.ts @@ -7,6 +7,23 @@ import { op_otel_instrumentation_scope_enter, op_otel_instrumentation_scope_enter_builtin, op_otel_log, + op_otel_metrics_data_point_attribute, + op_otel_metrics_data_point_attribute2, + op_otel_metrics_data_point_attribute3, + op_otel_metrics_gauge, + op_otel_metrics_histogram, + op_otel_metrics_histogram_data_point, + op_otel_metrics_histogram_data_point_entry1, + op_otel_metrics_histogram_data_point_entry2, + op_otel_metrics_histogram_data_point_entry3, + op_otel_metrics_histogram_data_point_entry_final, + op_otel_metrics_resource_attribute, + op_otel_metrics_resource_attribute2, + op_otel_metrics_resource_attribute3, + op_otel_metrics_scope, + op_otel_metrics_submit, + op_otel_metrics_sum, + op_otel_metrics_sum_or_gauge_data_point, op_otel_span_attribute, op_otel_span_attribute2, op_otel_span_attribute3, @@ -186,7 +203,7 @@ const instrumentationScopes = new SafeWeakMap< >(); let activeInstrumentationLibrary: WeakRef | null = null; -function submit( +function submitSpan( spanId: string | Uint8Array, traceId: string | Uint8Array, traceFlags: number, @@ -411,7 +428,7 @@ export class Span { endSpan = (span: Span) => { const endTime = now(); - submit( + submitSpan( span.#spanId, span.#traceId, span.#traceFlags, @@ -571,7 +588,7 @@ class SpanExporter { for (let i = 0; i < spans.length; i += 1) { const span = spans[i]; const context = span.spanContext(); - submit( + submitSpan( context.spanId, context.traceId, context.traceFlags, @@ -671,6 +688,262 @@ class ContextManager { } } +function attributeValue(value: IAnyValue) { + return value.boolValue ?? value.stringValue ?? value.doubleValue ?? + value.intValue; +} + +function submitMetrics(resource, scopeMetrics) { + let i = 0; + while (i < resource.attributes.length) { + if (i + 2 < resource.attributes.length) { + op_otel_metrics_resource_attribute3( + resource.attributes.length, + resource.attributes[i].key, + attributeValue(resource.attributes[i].value), + resource.attributes[i + 1].key, + attributeValue(resource.attributes[i + 1].value), + resource.attributes[i + 2].key, + attributeValue(resource.attributes[i + 2].value), + ); + i += 3; + } else if (i + 1 < resource.attributes.length) { + op_otel_metrics_resource_attribute2( + resource.attributes.length, + resource.attributes[i].key, + attributeValue(resource.attributes[i].value), + resource.attributes[i + 1].key, + attributeValue(resource.attributes[i + 1].value), + ); + i += 2; + } else { + op_otel_metrics_resource_attribute( + resource.attributes.length, + resource.attributes[i].key, + attributeValue(resource.attributes[i].value), + ); + i += 1; + } + } + + for (let smi = 0; smi < scopeMetrics.length; smi += 1) { + const { scope, metrics } = scopeMetrics[smi]; + + op_otel_metrics_scope(scope.name, scope.schemaUrl, scope.version); + + for (let mi = 0; mi < metrics.length; mi += 1) { + const metric = metrics[mi]; + switch (metric.dataPointType) { + case 3: + op_otel_metrics_sum( + metric.descriptor.name, + // deno-lint-ignore prefer-primordials + metric.descriptor.description, + metric.descriptor.unit, + metric.aggregationTemporality, + metric.isMonotonic, + ); + for (let di = 0; di < metric.dataPoints.length; di += 1) { + const dataPoint = metric.dataPoints[di]; + op_otel_metrics_sum_or_gauge_data_point( + dataPoint.value, + hrToSecs(dataPoint.startTime), + hrToSecs(dataPoint.endTime), + ); + const attributes = ObjectEntries(dataPoint.attributes); + let i = 0; + while (i < attributes.length) { + if (i + 2 < attributes.length) { + op_otel_metrics_data_point_attribute3( + attributes.length, + attributes[i][0], + attributes[i][1], + attributes[i + 1][0], + attributes[i + 1][1], + attributes[i + 2][0], + attributes[i + 2][1], + ); + i += 3; + } else if (i + 1 < attributes.length) { + op_otel_metrics_data_point_attribute2( + attributes.length, + attributes[i][0], + attributes[i][1], + attributes[i + 1][0], + attributes[i + 1][1], + ); + i += 2; + } else { + op_otel_metrics_data_point_attribute( + attributes.length, + attributes[i][0], + attributes[i][1], + ); + i += 1; + } + } + } + break; + case 2: + op_otel_metrics_gauge( + metric.descriptor.name, + // deno-lint-ignore prefer-primordials + metric.descriptor.description, + metric.descriptor.unit, + ); + for (let di = 0; di < metric.dataPoints.length; di += 1) { + const dataPoint = metric.dataPoints[di]; + op_otel_metrics_sum_or_gauge_data_point( + dataPoint.value, + hrToSecs(dataPoint.startTime), + hrToSecs(dataPoint.endTime), + ); + const attributes = ObjectEntries(dataPoint.attributes); + let i = 0; + while (i < attributes.length) { + if (i + 2 < attributes.length) { + op_otel_metrics_data_point_attribute3( + attributes.length, + attributes[i][0], + attributes[i][1], + attributes[i + 1][0], + attributes[i + 1][1], + attributes[i + 2][0], + attributes[i + 2][1], + ); + i += 3; + } else if (i + 1 < attributes.length) { + op_otel_metrics_data_point_attribute2( + attributes.length, + attributes[i][0], + attributes[i][1], + attributes[i + 1][0], + attributes[i + 1][1], + ); + i += 2; + } else { + op_otel_metrics_data_point_attribute( + attributes.length, + attributes[i][0], + attributes[i][1], + ); + i += 1; + } + } + } + break; + case 0: + op_otel_metrics_histogram( + metric.descriptor.name, + // deno-lint-ignore prefer-primordials + metric.descriptor.description, + metric.descriptor.unit, + metric.aggregationTemporality, + ); + for (let di = 0; di < metric.dataPoints.length; di += 1) { + const dataPoint = metric.dataPoints[di]; + const { boundaries, counts } = dataPoint.value.buckets; + op_otel_metrics_histogram_data_point( + dataPoint.value.count, + dataPoint.value.min ?? NaN, + dataPoint.value.max ?? NaN, + dataPoint.value.sum, + hrToSecs(dataPoint.startTime), + hrToSecs(dataPoint.endTime), + boundaries.length, + ); + let j = 0; + while (j < boundaries.length) { + if (j + 3 < boundaries.length) { + op_otel_metrics_histogram_data_point_entry3( + counts[j], + boundaries[j], + counts[j + 1], + boundaries[j + 1], + counts[j + 2], + boundaries[j + 2], + ); + j += 3; + } else if (j + 2 < boundaries.length) { + op_otel_metrics_histogram_data_point_entry2( + counts[j], + boundaries[j], + counts[j + 1], + boundaries[j + 1], + ); + j += 2; + } else { + op_otel_metrics_histogram_data_point_entry1( + counts[j], + boundaries[j], + ); + j += 1; + } + } + op_otel_metrics_histogram_data_point_entry_final(counts[j]); + const attributes = ObjectEntries(dataPoint.attributes); + let i = 0; + while (i < attributes.length) { + if (i + 2 < attributes.length) { + op_otel_metrics_data_point_attribute3( + attributes.length, + attributes[i][0], + attributes[i][1], + attributes[i + 1][0], + attributes[i + 1][1], + attributes[i + 2][0], + attributes[i + 2][1], + ); + i += 3; + } else if (i + 1 < attributes.length) { + op_otel_metrics_data_point_attribute2( + attributes.length, + attributes[i][0], + attributes[i][1], + attributes[i + 1][0], + attributes[i + 1][1], + ); + i += 2; + } else { + op_otel_metrics_data_point_attribute( + attributes.length, + attributes[i][0], + attributes[i][1], + ); + i += 1; + } + } + } + break; + default: + continue; + } + } + } + + op_otel_metrics_submit(); +} + +class MetricExporter { + export(metrics, resultCallback: (result: ExportResult) => void) { + try { + submitMetrics(metrics.resource, metrics.scopeMetrics); + resultCallback({ code: 0 }); + } catch (error) { + resultCallback({ + code: 1, + error: ObjectPrototypeIsPrototypeOf(error, Error) + ? error as Error + : new Error(String(error)), + }); + } + } + + async forceFlush() {} + + async shutdown() {} +} + const otelConsoleConfig = { ignore: 0, capture: 1, @@ -708,4 +981,5 @@ export function bootstrap( export const telemetry = { SpanExporter, ContextManager, + MetricExporter, }; diff --git a/tests/registry/npm/@opentelemetry/sdk-metrics/registry.json b/tests/registry/npm/@opentelemetry/sdk-metrics/registry.json new file mode 100644 index 0000000000..1e55892f95 --- /dev/null +++ b/tests/registry/npm/@opentelemetry/sdk-metrics/registry.json @@ -0,0 +1 @@ +{"_id":"@opentelemetry/sdk-metrics","_rev":"32-fd2f541de5aecbe413589147b6cc22fc","name":"@opentelemetry/sdk-metrics","dist-tags":{"next":"1.8.0","latest":"1.28.0"},"versions":{"0.32.0":{"name":"@opentelemetry/sdk-metrics","version":"0.32.0","keywords":["opentelemetry","nodejs","metrics","stats","profiling"],"author":{"name":"OpenTelemetry Authors"},"license":"Apache-2.0","_id":"@opentelemetry/sdk-metrics@0.32.0","maintainers":[{"name":"bogdandrutu","email":"bogdandrutu@gmail.com"},{"name":"dyladan","email":"dyladan@gmail.com"}],"homepage":"https://github.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/opentelemetry-sdk-metrics","bugs":{"url":"https://github.com/open-telemetry/opentelemetry-js/issues"},"dist":{"shasum":"463cd3a2b267f044db9aaab85887a171710345a0","tarball":"https://registry.npmjs.org/@opentelemetry/sdk-metrics/-/sdk-metrics-0.32.0.tgz","fileCount":480,"integrity":"sha512-zC9RCOIsXRqOHWmWfcxArtDHbip2/jaIH1yu/OKau/shDZYFluAxY6zAEYIb4YEAzKKEF+fpaoRgpodDWNGVGA==","signatures":[{"sig":"MEUCIHBrzbDjk66vVi3mOQOqt4aIRr90QWqLXe7z6pqSOS6GAiEAxRW5Nt/5Uo5aJhfbXMPZUZSd1f5UYsLkrC5WVFl9u0o=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":1364783,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjBmODACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqU5Q//X8u5PAiNpAJrFIXflu/338sR9oMsluNoiuoPba0zw6ikiPUv\r\nXCYlQMw1XBSE63X2CVpSDakAhG4WtkWXbsi2zRCfOLUze5CuQPf+TqikvwM/\r\nFOGeHl67KjYw20u1K0H0kxB1qAsBQNBV0lWIM8aF6Yty2J05kP7dACmT6o4v\r\nUn6n2+fjQFMlhRA0WeCrEk+6usmFQDBaZSieZofKGm9C3KCeasPZRfnAJZq3\r\nQvbINhGXDOfFdXrwQPNRqZEIDI5/9frr9dJuRsL+h59AEBizdkezofZGvJPr\r\n860MZqidZhyrzC8NBpodJK0sGxQutbssmSKDT2dptVEd9jjj7mj7iKhNPEFy\r\ntUQDgD/4ltCoLyqraDQi+twaE9gFDhol6EwwdRTIMV8pvazMXFuQ1ik6lsC8\r\nPMt4UDYjtOwDkOGqOjtK/AebAOkJWhoEOuz3znl4VAowL5+qPblVRUEOm7HY\r\nKM/I5DEJltVpWJymDlvRNyvN/ysah+p3b6QtAz5ZcXlipFBh/qFozY7GpemB\r\nIHNryYjSZiAvRCsbnWgHsNg2dIDHJQvN440q6cWfX49Hs03r1rYuKlJjkBpy\r\nFFxrzMAoUejzJ/4j9lVc0rfacQrIoUtQ+j4uLJVPCqy4BPk1LMTnyWY16zb4\r\nIvRTJJH4pe1bz0ucrcj7GawkrVRaoxvNO2U=\r\n=wJDK\r\n-----END PGP SIGNATURE-----\r\n"},"main":"build/src/index.js","types":"build/src/index.d.ts","esnext":"build/esnext/index.js","module":"build/esm/index.js","engines":{"node":">=14"},"gitHead":"a5abee69119cc41d9d34f6beb5c1826eef1ac0dd","scripts":{"tdd":"npm run test -- --watch-extensions ts --watch","lint":"eslint . --ext .ts","test":"nyc ts-mocha -p tsconfig.json 'test/**/*.test.ts'","clean":"tsc --build --clean tsconfig.all.json","watch":"tsc --build --watch tsconfig.all.json","codecov":"nyc report --reporter=json && codecov -f coverage/*.json -p ../../../","compile":"tsc --build tsconfig.all.json","version":"node ../../../scripts/version-update.js","lint:fix":"eslint . --ext .ts --fix","prewatch":"node ../../../scripts/version-update.js","precompile":"lerna run version --scope $(npm pkg get name) --include-dependencies","tdd:browser":"karma start","test:browser":"nyc karma start --single-run","peer-api-check":"node ../../../scripts/peer-api-check.js","prepublishOnly":"npm run compile"},"_npmUser":{"name":"dyladan","email":"dyladan@gmail.com"},"repository":{"url":"git+https://github.com/open-telemetry/opentelemetry-js.git","type":"git"},"_npmVersion":"lerna/5.4.3/node@v14.18.1+x64 (darwin)","description":"Work in progress OpenTelemetry metrics SDK","directories":{},"_nodeVersion":"14.18.1","dependencies":{"lodash.merge":"4.6.2","@opentelemetry/core":"1.6.0","@opentelemetry/resources":"1.6.0","@opentelemetry/api-metrics":"0.32.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"nyc":"15.1.0","karma":"6.3.16","mocha":"10.0.0","sinon":"14.0.0","rimraf":"3.0.2","codecov":"3.8.3","ts-mocha":"10.0.0","typescript":"4.4.4","@types/node":"18.6.5","karma-mocha":"2.0.1","@types/mocha":"9.1.1","@types/sinon":"10.0.13","karma-webpack":"4.0.2","@opentelemetry/api":"^1.0.0","@types/lodash.merge":"4.6.6","karma-spec-reporter":"0.0.32","karma-chrome-launcher":"3.1.0","karma-coverage-istanbul-reporter":"3.0.3"},"peerDependencies":{"@opentelemetry/api":"^1.0.0"},"_npmOperationalInternal":{"tmp":"tmp/sdk-metrics_0.32.0_1661363075429_0.18961817621798693","host":"s3://npm-registry-packages"}},"0.33.0":{"name":"@opentelemetry/sdk-metrics","version":"0.33.0","keywords":["opentelemetry","nodejs","metrics","stats","profiling"],"author":{"name":"OpenTelemetry Authors"},"license":"Apache-2.0","_id":"@opentelemetry/sdk-metrics@0.33.0","maintainers":[{"name":"bogdandrutu","email":"bogdandrutu@gmail.com"},{"name":"dyladan","email":"dyladan@gmail.com"}],"homepage":"https://github.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/opentelemetry-sdk-metrics","bugs":{"url":"https://github.com/open-telemetry/opentelemetry-js/issues"},"dist":{"shasum":"c4e51decc6e3bb0e1e97c7b081955d357e46c2fe","tarball":"https://registry.npmjs.org/@opentelemetry/sdk-metrics/-/sdk-metrics-0.33.0.tgz","fileCount":489,"integrity":"sha512-ZXPixOlTd/FHLwpkmm5nTpJE7bZOPfmbSz8hBVFCEHkXE1aKEKaM38UFnZ+2xzOY1tDsDwyxEiiBiDX8y3039A==","signatures":[{"sig":"MEUCIBeHiozEczRdIpEbB1UwgCro3jj+tB2iGk+FQ+CZuc3LAiEA97t2teODixmkZuRZk4z+IPqaULq8SBNRrV8c3JVlTys=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":1425603,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjJGjCACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrNERAAjSfh3/c433lR4GMa9u1DjMIVy7MYOZe0YftxnQ9VPGs2jgfa\r\nWC4r/3Qbantsq49xoVj8GjmiZnIrhzm833P8L7lNLes8LDtI8TEbv+6SPfsq\r\nRLBvUdPHww4UlbfShEo5hnGXVIC3qudVRlvGv2DKxFD9AF2QZszGKsrNQ+P8\r\nB5A/lWp4dqY+IhB0xMk3y7asdEggiF/isxMsCGhNFpDiyL8iHQWuW3ylt5pq\r\nZmPLY23ax1kWkTSvj7Us9X7tgIjGuGgzU+cBSf29WI0L2gyVu5TBBRk5NY5x\r\nryXCnzi1MoNdY669ToCEVcCxJoWb4DY9Mg2ihhJq2argdUPzwEBThC1EecAP\r\nJ/786fw+PKmQAzKGVGEXRmDZljF4+3Zk/KIujlHZK7RP6h1kaMCRAKYwnBLT\r\nR9v3W4ljHnbPgV0OmX+W0suV8oEoYtIJxe/7yyznWsLxcndndZq6WFqzcJQN\r\nVdPk6kxtXdSx7hzcnn1CXxckq+fiG0EdZX32ZRGEi1X4EXmTeNL8s2CMiVUl\r\ndGQm+vbP517Nj2oQvOcnO+YSf55XGNtv49cbusZ8JHVGQhHE26HXCK6A2ci1\r\nhEgPOMtjRH43f3kncjdQXW/vTsS/vMiacwyM94686CkEOaJJNnTv8R2DlV2s\r\nkvO54QGc0KDggcsxEqzpfo9OuQEFKWUe0lU=\r\n=fhUv\r\n-----END PGP SIGNATURE-----\r\n"},"main":"build/src/index.js","types":"build/src/index.d.ts","esnext":"build/esnext/index.js","module":"build/esm/index.js","engines":{"node":">=14"},"gitHead":"ad88c3d9aa0100fe259b93f4b660e84417b757ac","scripts":{"tdd":"npm run test -- --watch-extensions ts --watch","lint":"eslint . --ext .ts","test":"nyc ts-mocha -p tsconfig.json 'test/**/*.test.ts'","clean":"tsc --build --clean tsconfig.all.json","watch":"tsc --build --watch tsconfig.all.json","codecov":"nyc report --reporter=json && codecov -f coverage/*.json -p ../../../","compile":"tsc --build tsconfig.all.json","version":"node ../../../scripts/version-update.js","lint:fix":"eslint . --ext .ts --fix","prewatch":"node ../../../scripts/version-update.js","precompile":"lerna run version --scope $(npm pkg get name) --include-dependencies","tdd:browser":"karma start","test:browser":"nyc karma start --single-run","peer-api-check":"node ../../../scripts/peer-api-check.js","prepublishOnly":"npm run compile"},"_npmUser":{"name":"dyladan","email":"dyladan@gmail.com"},"repository":{"url":"git+https://github.com/open-telemetry/opentelemetry-js.git","type":"git"},"_npmVersion":"lerna/5.4.3/node@v14.18.1+x64 (darwin)","description":"Work in progress OpenTelemetry metrics SDK","directories":{},"_nodeVersion":"14.18.1","dependencies":{"lodash.merge":"4.6.2","@opentelemetry/core":"1.7.0","@opentelemetry/resources":"1.7.0","@opentelemetry/api-metrics":"0.33.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"nyc":"15.1.0","karma":"6.3.16","mocha":"10.0.0","sinon":"14.0.0","rimraf":"3.0.2","codecov":"3.8.3","ts-mocha":"10.0.0","typescript":"4.4.4","@types/node":"18.6.5","karma-mocha":"2.0.1","@types/mocha":"9.1.1","@types/sinon":"10.0.13","karma-webpack":"4.0.2","@opentelemetry/api":"^1.0.0","@types/lodash.merge":"4.6.6","karma-spec-reporter":"0.0.32","karma-chrome-launcher":"3.1.0","karma-coverage-istanbul-reporter":"3.0.3"},"peerDependencies":{"@opentelemetry/api":"^1.0.0"},"_npmOperationalInternal":{"tmp":"tmp/sdk-metrics_0.33.0_1663330498049_0.15542963522751552","host":"s3://npm-registry-packages"}},"1.8.0":{"name":"@opentelemetry/sdk-metrics","version":"1.8.0","keywords":["opentelemetry","nodejs","metrics","stats","profiling"],"author":{"name":"OpenTelemetry Authors"},"license":"Apache-2.0","_id":"@opentelemetry/sdk-metrics@1.8.0","maintainers":[{"name":"bogdandrutu","email":"bogdandrutu@gmail.com"},{"name":"dyladan","email":"dyladan@gmail.com"}],"homepage":"https://github.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/opentelemetry-sdk-metrics","bugs":{"url":"https://github.com/open-telemetry/opentelemetry-js/issues"},"dist":{"shasum":"d061060f03861ab3f345d0f924922bc1a6396157","tarball":"https://registry.npmjs.org/@opentelemetry/sdk-metrics/-/sdk-metrics-1.8.0.tgz","fileCount":489,"integrity":"sha512-+KYb+uj0vHhl8xzJO+oChS4oP1e+/2Wl3SXoHoIdcEjd1TQfDV+lxOm4oqxWq6wykXvI35/JHyejxSoT+qxGmg==","signatures":[{"sig":"MEYCIQDsOqqaWHTqJVYLyeRb+ZNiGkJbd34UCyCqyHX6UgwbCAIhAMvGlF7I5klQng1omsJ/Nk8Nzz0TlqjJqpvJj76kcBV2","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":1416962,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjbANeACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqikQ/9EWJ03wBF//CwkzW46y4mBkSgukPe+k9sfS4+cd4/+nErVF2O\r\nMTKRhSpoDQcVLBdmTfeaObKRmgYg2p3PeOrGPphcfkEmZjrRv6342ubUWjRW\r\nm39DSPq8NmZp7J5hRf2hLYSg6tXKZnflCmj+T8upYC/KmW7kOKtx/B3tTy7c\r\nq6q1Kc6vBToqid7yNdFLsIYTjVHM8xSvtg0QVx84S6mtzR2iO8uAzL3ucu34\r\nfLXyN2MzbqJIO516Jt1vE0ix9q/xmt7TrbqCi5k5yZ8cIOianx1Yl7MFGOAX\r\nKwaGILDNoBnb7c8mQITWnP286rsO4NMNnBoXt7ZJCmIavKe8XlbxFZAwuM/q\r\nl0bC9nG8l4r+182xF5XKV2/wnRPQ3j8+uQyBx/8+7YGoIVbowgd4GvJEZGRm\r\n83hxM4/xGxmHiWbkngJlyspY7s86o1MTuwPgwns73cgAhNZsuti2SVgtdoFc\r\n4prfRtGRXUtHJkBQMItiPDEG+Mnfq9hBxHh2F1zuvDLzyN93nCs22gBY79jT\r\n33kticfFECGRLhuCIhZIuV+yzBu4ciYXk0fg9hMY6wagCqQ+tPRs4HPqO92f\r\nuVGhapMpKJPclhvOvlbY4d4Ixm4mo5rrnJx0BPkn445hV6JwJbUC3PAU9yPp\r\nJhIpEHNdZQc8ntThHRpYRCSBmecy8YkzSdo=\r\n=haC6\r\n-----END PGP SIGNATURE-----\r\n"},"main":"build/src/index.js","types":"build/src/index.d.ts","esnext":"build/esnext/index.js","module":"build/esm/index.js","engines":{"node":">=14"},"gitHead":"7972edf6659fb6e0d5928a5cf7a35f26683e168f","scripts":{"tdd":"npm run test -- --watch-extensions ts --watch","lint":"eslint . --ext .ts","test":"nyc ts-mocha -p tsconfig.json 'test/**/*.test.ts'","clean":"tsc --build --clean tsconfig.all.json","watch":"tsc --build --watch tsconfig.all.json","codecov":"nyc report --reporter=json && codecov -f coverage/*.json -p ../../","compile":"tsc --build tsconfig.all.json","version":"node ../../scripts/version-update.js","lint:fix":"eslint . --ext .ts --fix","prewatch":"node ../../scripts/version-update.js","precompile":"lerna run version --scope $(npm pkg get name) --include-dependencies","tdd:browser":"karma start","test:browser":"nyc karma start --single-run","peer-api-check":"node ../../scripts/peer-api-check.js","prepublishOnly":"npm run compile"},"_npmUser":{"name":"dyladan","email":"dyladan@gmail.com"},"repository":{"url":"git+https://github.com/open-telemetry/opentelemetry-js.git","type":"git"},"_npmVersion":"lerna/5.4.3/node@v14.18.1+x64 (darwin)","description":"Work in progress OpenTelemetry metrics SDK","directories":{},"sideEffects":false,"_nodeVersion":"14.18.1","dependencies":{"lodash.merge":"4.6.2","@opentelemetry/core":"1.8.0","@opentelemetry/resources":"1.8.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"nyc":"15.1.0","karma":"6.3.16","mocha":"10.0.0","sinon":"14.0.0","rimraf":"3.0.2","codecov":"3.8.3","ts-mocha":"10.0.0","typescript":"4.4.4","@types/node":"18.6.5","karma-mocha":"2.0.1","@types/mocha":"10.0.0","@types/sinon":"10.0.13","karma-webpack":"4.0.2","@opentelemetry/api":">=1.3.0 <1.4.0","@types/lodash.merge":"4.6.6","karma-spec-reporter":"0.0.32","karma-chrome-launcher":"3.1.0","karma-coverage-istanbul-reporter":"3.0.3"},"peerDependencies":{"@opentelemetry/api":">=1.3.0 <1.4.0"},"_npmOperationalInternal":{"tmp":"tmp/sdk-metrics_1.8.0_1668023134085_0.198580524230221","host":"s3://npm-registry-packages"}},"1.9.0":{"name":"@opentelemetry/sdk-metrics","version":"1.9.0","keywords":["opentelemetry","nodejs","metrics","stats","profiling"],"author":{"name":"OpenTelemetry Authors"},"license":"Apache-2.0","_id":"@opentelemetry/sdk-metrics@1.9.0","maintainers":[{"name":"bogdandrutu","email":"bogdandrutu@gmail.com"},{"name":"dyladan","email":"dyladan@gmail.com"}],"homepage":"https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/sdk-metrics","bugs":{"url":"https://github.com/open-telemetry/opentelemetry-js/issues"},"dist":{"shasum":"1c3a51abeb7f45ea25b91daf7e05e43d25ddd20a","tarball":"https://registry.npmjs.org/@opentelemetry/sdk-metrics/-/sdk-metrics-1.9.0.tgz","fileCount":489,"integrity":"sha512-fSlJWhp86kCan1zuxdH6LTyUBYlohQwDKnxep5qHMnRTNErkYmdjgsmjZvSMdAfUFtQqfZmTXe2Lap7a5AIf9Q==","signatures":[{"sig":"MEUCIGoaNR3oyipKjYbn2fxyiZ4BKdIFiSOmx699LRzKo0vWAiEAyTvGUxH0WbB1bXUpv9AlkibTlQ51uAHPzOa9yFD7L7A=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":1432686,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjvy41ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrSjg//czBDsjkHKhMQ+UP70UHKKTG+xRRSxL0WB8vcvSu2U1VFJldP\r\nBiEOUKKfXMNMTlwB6fuo8mdBnwT/Pn6rmbYyW30mkRtc0n9rpakFtdvASSUg\r\nSsLAROHI+NpaNG3lygIpwXu6wLNGzh1ejL8/1/sfRFKBZIGlb/4l9eHtLj8z\r\nNEZ2r0IAOVOQ2JWnMon0gSM1yjplES4pF30tt5j+UeJbNqgbu9CxD8mUOt/E\r\nV4KT3XawHrjMB5VmPlUhZ66OwbF4P7dZF3ukETA/ezK2XBQeUBBNCiJbW6C0\r\np6WdlJZ/1chyseR9hKiBm8bOrx9XQlNcKyM8brOL9G0joCa/YDX12z0lK5xg\r\nlv/As+8IcQUBkcMsBnzl/BVZUnVQ/qacyWXsYpuMmSCfCOCcCAfLXP/kkVDG\r\nNtNpb3RWySMTuqhYBNxQ2wSBmu0TnXxc3y7ubWfqVNh8SJu9kLZQo8fRFyrM\r\nrVATAIjhFPpZAGBeDca3YHuElfFhXdxtklvHX4ATh3yN0DlVqaaWxQXp6W/I\r\n671fbqRQWCy29YlLoS7k4WR8CGkvNFPYedOgIPinE/g3Qv4oTF0z8vcFYI9G\r\nP2PyfHSre1bHm/5rTIiB9xWEK+XUb+9uV/33gGfTkZqz+6oGd4E0pg9q16cy\r\nEZrSABE83nfpxgpbmLMjACClgyQWshGNr4I=\r\n=qh/2\r\n-----END PGP SIGNATURE-----\r\n"},"main":"build/src/index.js","types":"build/src/index.d.ts","esnext":"build/esnext/index.js","module":"build/esm/index.js","engines":{"node":">=14"},"gitHead":"08f597f3a3d71a4852b0afbba120af15ca038121","scripts":{"tdd":"npm run test -- --watch-extensions ts --watch","lint":"eslint . --ext .ts","test":"nyc ts-mocha -p tsconfig.json 'test/**/*.test.ts'","clean":"tsc --build --clean tsconfig.json tsconfig.esm.json tsconfig.esnext.json","watch":"tsc --build --watch tsconfig.json tsconfig.esm.json tsconfig.esnext.json","codecov":"nyc report --reporter=json && codecov -f coverage/*.json -p ../../","compile":"tsc --build tsconfig.json tsconfig.esm.json tsconfig.esnext.json","version":"node ../../scripts/version-update.js","lint:fix":"eslint . --ext .ts --fix","prewatch":"node ../../scripts/version-update.js","precompile":"lerna run version --scope $(npm pkg get name) --include-dependencies","tdd:browser":"karma start","test:browser":"nyc karma start --single-run","peer-api-check":"node ../../scripts/peer-api-check.js","prepublishOnly":"npm run compile"},"_npmUser":{"name":"dyladan","email":"dyladan@gmail.com"},"repository":{"url":"git+https://github.com/open-telemetry/opentelemetry-js.git","type":"git"},"_npmVersion":"lerna/6.0.3/node@v14.18.1+x64 (darwin)","description":"OpenTelemetry metrics SDK","directories":{},"sideEffects":false,"_nodeVersion":"14.18.1","dependencies":{"lodash.merge":"4.6.2","@opentelemetry/core":"1.9.0","@opentelemetry/resources":"1.9.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"nyc":"15.1.0","karma":"6.3.16","mocha":"10.0.0","sinon":"15.0.0","rimraf":"3.0.2","codecov":"3.8.3","ts-mocha":"10.0.0","typescript":"4.4.4","@types/node":"18.6.5","karma-mocha":"2.0.1","@types/mocha":"10.0.0","@types/sinon":"10.0.13","karma-webpack":"4.0.2","@opentelemetry/api":">=1.3.0 <1.5.0","@types/lodash.merge":"4.6.6","karma-spec-reporter":"0.0.32","karma-chrome-launcher":"3.1.0","karma-coverage-istanbul-reporter":"3.0.3"},"peerDependencies":{"@opentelemetry/api":">=1.3.0 <1.5.0"},"_npmOperationalInternal":{"tmp":"tmp/sdk-metrics_1.9.0_1673473589677_0.62979083795101","host":"s3://npm-registry-packages"}},"1.9.1":{"name":"@opentelemetry/sdk-metrics","version":"1.9.1","keywords":["opentelemetry","nodejs","metrics","stats","profiling"],"author":{"name":"OpenTelemetry Authors"},"license":"Apache-2.0","_id":"@opentelemetry/sdk-metrics@1.9.1","maintainers":[{"name":"bogdandrutu","email":"bogdandrutu@gmail.com"},{"name":"dyladan","email":"dyladan@gmail.com"}],"homepage":"https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/sdk-metrics","bugs":{"url":"https://github.com/open-telemetry/opentelemetry-js/issues"},"dist":{"shasum":"babc162a81df9884c16b1e67c2dd26ab478f3080","tarball":"https://registry.npmjs.org/@opentelemetry/sdk-metrics/-/sdk-metrics-1.9.1.tgz","fileCount":543,"integrity":"sha512-AyhKDcA8NuV7o1+9KvzRMxNbATJ8AcrutKilJ6hWSo9R5utnzxgffV4y+Hp4mJn84iXxkv+CBb99GOJ2A5OMzA==","signatures":[{"sig":"MEYCIQCYUyFLpMVK/wDHg6lU87nZ3MQB9nQh8JvM/VryTCdksgIhAKZDK2iXOPbTaQ6GOK3qt6u560bXhXh+VmFjYH9uiaHo","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":1556782,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJj1+KFACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmpp3w//cVciehkq5CKoOUjcEovwgleHJd+eCwOEc40/05fiVn6NmDuW\r\nHAs1UekoxG9cc+MHhvp/38o5o1WFK2sFGXO7ymvMluXheGXx7nI6U+qnqkb9\r\nWWvI53gNcfN5GUgJGarHX6kt+DoyV5+0ig0R/2U37hk6DWm89kZArd+X8xEI\r\nD+2GADx/m1uTUO/PJnaJ8LB1LLK2SJ2vQmViYTP8icykDzIJT5flZyBeb+hk\r\nRqgaFcx7Qa+XecZIjTUXfY5ZQCOc5IYf3JAVea/0kAosP63vSaK9TU+p4GG6\r\n4mYBEANc4Inn4ocav0UoYb5kDNntNo/wAusSI4gH/sByMaQhW/EGy9qmKTA+\r\nKpsIPqZO/FPXZEUJZsEUBOD7GxGp8rUB38JEvW3d3ACDFPfVl/AAuIJ4wipt\r\nM4cKsHtewTdDbDGrkO7o9EDG+OACTTBbvAQ/vxWoC8lDZ+vVWbc0pT+taLcs\r\nlimhIk0XDHJGZ+vxL/T7ib0nOCE1qgt6TL5F0Mmx/Juen4Go2NhOa9dbZG1Y\r\nSI6b/SXe5izJQR6vGhyx2mo3OOXrBQmQc/jjcJbwaRRzLshUY/GmZeqrsPLO\r\n91kJNQIUfFRZLhY0tLPlUaYoFjUY+HL4d0RHWKxLoenZ1POPTBwbrfTpwTRD\r\nOTqOB4P/zL3AutUyuX+FOPevSBguIKxq7wA=\r\n=AXfq\r\n-----END PGP SIGNATURE-----\r\n"},"main":"build/src/index.js","types":"build/src/index.d.ts","esnext":"build/esnext/index.js","module":"build/esm/index.js","engines":{"node":">=14"},"gitHead":"279458e7ddf16f7ddca5fe60c78672e05fafce66","scripts":{"tdd":"npm run test -- --watch-extensions ts --watch","lint":"eslint . --ext .ts","test":"nyc ts-mocha -p tsconfig.json 'test/**/*.test.ts'","clean":"tsc --build --clean tsconfig.json tsconfig.esm.json tsconfig.esnext.json","watch":"tsc --build --watch tsconfig.json tsconfig.esm.json tsconfig.esnext.json","codecov":"nyc report --reporter=json && codecov -f coverage/*.json -p ../../","compile":"tsc --build tsconfig.json tsconfig.esm.json tsconfig.esnext.json","version":"node ../../scripts/version-update.js","lint:fix":"eslint . --ext .ts --fix","prewatch":"node ../../scripts/version-update.js","precompile":"lerna run version --scope $(npm pkg get name) --include-dependencies","tdd:browser":"karma start","test:browser":"nyc karma start --single-run","peer-api-check":"node ../../scripts/peer-api-check.js","prepublishOnly":"npm run compile"},"_npmUser":{"name":"dyladan","email":"dyladan@gmail.com"},"repository":{"url":"git+https://github.com/open-telemetry/opentelemetry-js.git","type":"git"},"_npmVersion":"lerna/6.0.3/node@v14.18.1+x64 (darwin)","description":"OpenTelemetry metrics SDK","directories":{},"sideEffects":false,"_nodeVersion":"14.18.1","dependencies":{"lodash.merge":"4.6.2","@opentelemetry/core":"1.9.1","@opentelemetry/resources":"1.9.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"nyc":"15.1.0","karma":"6.3.16","mocha":"10.0.0","sinon":"15.0.0","rimraf":"4.1.2","codecov":"3.8.3","ts-mocha":"10.0.0","typescript":"4.4.4","@types/node":"18.6.5","karma-mocha":"2.0.1","@types/mocha":"10.0.0","@types/sinon":"10.0.13","karma-webpack":"4.0.2","@opentelemetry/api":">=1.3.0 <1.5.0","@types/lodash.merge":"4.6.6","karma-spec-reporter":"0.0.32","karma-chrome-launcher":"3.1.0","karma-coverage-istanbul-reporter":"3.0.3"},"peerDependencies":{"@opentelemetry/api":">=1.3.0 <1.5.0"},"_npmOperationalInternal":{"tmp":"tmp/sdk-metrics_1.9.1_1675092613192_0.7361446399809115","host":"s3://npm-registry-packages"}},"1.10.0":{"name":"@opentelemetry/sdk-metrics","version":"1.10.0","keywords":["opentelemetry","nodejs","metrics","stats","profiling"],"author":{"name":"OpenTelemetry Authors"},"license":"Apache-2.0","_id":"@opentelemetry/sdk-metrics@1.10.0","maintainers":[{"name":"bogdandrutu","email":"bogdandrutu@gmail.com"},{"name":"dyladan","email":"dyladan@gmail.com"}],"homepage":"https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/sdk-metrics","bugs":{"url":"https://github.com/open-telemetry/opentelemetry-js/issues"},"dist":{"shasum":"627f164036ad053551b3e75447adf9a902b066aa","tarball":"https://registry.npmjs.org/@opentelemetry/sdk-metrics/-/sdk-metrics-1.10.0.tgz","fileCount":543,"integrity":"sha512-vOB3khvj894ppOwafNqKNavpChZYR2S2IZyy8PmL0DwNgFPGYwkWxZkv7YJduBNzcCd+Ao+ug93jdSFFhnpIhQ==","signatures":[{"sig":"MEUCIQDL/qHYi9VPBH3poMg/gvlnmTAxuK7zGkYo7FXRK1XAMgIgPAiYWDmawt1pshH1UtUsHcw9izgXdV8pWQMROlpkKEQ=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":1571910,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkD0cTACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpZ/w/9G8OISP56mEsFRcrjWT+zXdW4zgKR3RBzQcZ+RjfqhV2Gq51K\r\nkwhYJ/bIk/xXtSJkpZ+gHjQIy1lwNXU9ux62RcZXzO/EcDLEg1aDDBD+d7G4\r\naYN81H49JVfrstGQzxduGK1vamLm2EBg0PbQGK7r8oNiNkK/Rt+qRY0ZYi6f\r\neYFhc8Nvbh9MKquBU21z/En/IhrxlbUQyetJ0TKfoonVsoj9VK1F7BBf/7cD\r\nYirI9GZzNKfk+y3IPmQ3aalntJmoN+aWWGYFn3hbE2IIo48N1EOkv3ZPXLwm\r\nHIaEN4MbK1vIjbjaS0LHC6lWYDooa5GCvVEXSl1ZJimyIpdx3FV5z0mVgusJ\r\nyb2PuPPm2okM7FM4xg0sDOqajIBbTy253Q8F+dqEBiZah1ELX/HTXV+3TG8l\r\nUJjlP6oE1CQwW43F+o46Pmf9eF0qi3pPEPwFpuX6JQfnWgWrAgR4LAhAh1UA\r\nhbVTVTBixGvNCZFvMh8Irbj3DNz/6pj2h5akehMBbaENpKj8g8Ij/tFIH7ho\r\nVXKGbDTUrnJPAcm4q1lghjiuBOgvJ3mZxacCayI+5daZBpL1rzXp9TrMSZqq\r\nsk5NuYgpfwBunGAjyeH3J4BirEKMUQElOKUr0oPvGYz11Rz6cs2Xa3U679q6\r\nZ7ZlwIHa3hghQeF62mlagpDWNJ1MweZb3zU=\r\n=fjdK\r\n-----END PGP SIGNATURE-----\r\n"},"main":"build/src/index.js","types":"build/src/index.d.ts","esnext":"build/esnext/index.js","module":"build/esm/index.js","engines":{"node":">=14"},"gitHead":"56e6b1bb890f844b8963a146780d0b9cfa8abd0d","scripts":{"tdd":"npm run test -- --watch-extensions ts --watch","lint":"eslint . --ext .ts","test":"nyc ts-mocha -p tsconfig.json 'test/**/*.test.ts'","clean":"tsc --build --clean tsconfig.json tsconfig.esm.json tsconfig.esnext.json","watch":"tsc --build --watch tsconfig.json tsconfig.esm.json tsconfig.esnext.json","codecov":"nyc report --reporter=json && codecov -f coverage/*.json -p ../../","compile":"tsc --build tsconfig.json tsconfig.esm.json tsconfig.esnext.json","version":"node ../../scripts/version-update.js","lint:fix":"eslint . --ext .ts --fix","prewatch":"node ../../scripts/version-update.js","precompile":"lerna run version --scope $(npm pkg get name) --include-dependencies","tdd:browser":"karma start","test:browser":"nyc karma start --single-run","peer-api-check":"node ../../scripts/peer-api-check.js","prepublishOnly":"npm run compile"},"_npmUser":{"name":"dyladan","email":"dyladan@gmail.com"},"repository":{"url":"git+https://github.com/open-telemetry/opentelemetry-js.git","type":"git"},"_npmVersion":"lerna/6.0.3/node@v14.18.1+x64 (darwin)","description":"OpenTelemetry metrics SDK","directories":{},"sideEffects":false,"_nodeVersion":"14.18.1","dependencies":{"lodash.merge":"4.6.2","@opentelemetry/core":"1.10.0","@opentelemetry/resources":"1.10.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"nyc":"15.1.0","karma":"6.3.16","mocha":"10.0.0","sinon":"15.0.0","rimraf":"4.1.2","codecov":"3.8.3","ts-mocha":"10.0.0","typescript":"4.4.4","@types/node":"18.6.5","karma-mocha":"2.0.1","@types/mocha":"10.0.0","@types/sinon":"10.0.13","karma-webpack":"4.0.2","@opentelemetry/api":">=1.3.0 <1.5.0","@types/lodash.merge":"4.6.6","karma-spec-reporter":"0.0.32","karma-chrome-launcher":"3.1.0","karma-coverage-istanbul-reporter":"3.0.3"},"peerDependencies":{"@opentelemetry/api":">=1.3.0 <1.5.0"},"_npmOperationalInternal":{"tmp":"tmp/sdk-metrics_1.10.0_1678722835367_0.34217119288271447","host":"s3://npm-registry-packages"}},"1.10.1":{"name":"@opentelemetry/sdk-metrics","version":"1.10.1","keywords":["opentelemetry","nodejs","metrics","stats","profiling"],"author":{"name":"OpenTelemetry Authors"},"license":"Apache-2.0","_id":"@opentelemetry/sdk-metrics@1.10.1","maintainers":[{"name":"bogdandrutu","email":"bogdandrutu@gmail.com"},{"name":"dyladan","email":"dyladan@gmail.com"}],"homepage":"https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/sdk-metrics","bugs":{"url":"https://github.com/open-telemetry/opentelemetry-js/issues"},"dist":{"shasum":"1389a8524ba59dc2e1d9cf627d504119c111fca1","tarball":"https://registry.npmjs.org/@opentelemetry/sdk-metrics/-/sdk-metrics-1.10.1.tgz","fileCount":543,"integrity":"sha512-ARAD4e6lZhLwstwW+1HG2Q3XuYFA/t8vn10KK/mA4em1pZYKFn64c45RJZJcntxWp4wOZRbp9iL1RXsg7zIjow==","signatures":[{"sig":"MEQCIF7l8lYSyGXYbwwaiNKB4rSrfukNeC9FI7PrmRetWSCaAiAEvWmV3Mebg7p+TvQxAN44ZzolcH3+uz+10I6dLs+2BA==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":1571910,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkGIV6ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrjQg//V5N9A3eIarDzrRPXxYMuJ3TO2qYzZxGLjCSbFBab/UFBKK2g\r\n4KS7ImLvfoP7k9S5xKMEQlCgG+0dGWt3SFELbhpLmwjVPM7OUcfF+es8dfAE\r\nQC6aLfq5juKIz/hcNBUGPZfauUQqReb+KptJUlCfvIW1RUi12dCoXSLm89/r\r\nXOUbhsIo3v+Lj5HBvn4lIl/3iJ07SaB3ehaVtypnSmpcgl2sWyMv77USvagd\r\nENNV4IbUFYM9YRnMFCWgSxtZtFDKmkLypkvUyu9jepecvgbXT+J4Z8hl6zgo\r\nv2Sqbi5PjkY035ZgSHqQ09yHGg5azUwn8AN0Yecqq88Mrqt35As1kdJLvrXg\r\nDK5lDQaxPqtaMSzLAg34Ck/Cng8HANjiKGaRA5ITCuJhoVMRt9va+mHscMwv\r\ngdfkJHKyq3wlGPZAvroDkljKROic2cYZv35zSwHXAoQ1PxYgEvbtxYDxsxPk\r\nSv5azrVgUBpKBM33EE+MMQ3AeizxdjCHnl8mPgv5u4C26MfdEd5f8cOKt9BS\r\nlhvukjFyU9DjoyMypt+LZWjWz1WVxircRPkXwSQa7t2FIGSV5XHL5nHSrBt4\r\nam5WwdCTJntt5jdeiL5RHN0myvOBDPB10G9ZoaogPjGUIXJK/XERuVD4/e9w\r\nJMVSLW8zW0CgZaAGWoaA4KhhW2OYXC/OdUk=\r\n=O4i4\r\n-----END PGP SIGNATURE-----\r\n"},"main":"build/src/index.js","types":"build/src/index.d.ts","esnext":"build/esnext/index.js","module":"build/esm/index.js","engines":{"node":">=14"},"gitHead":"486df99906958de9b8b666839785b00160a6a229","scripts":{"tdd":"npm run test -- --watch-extensions ts --watch","lint":"eslint . --ext .ts","test":"nyc ts-mocha -p tsconfig.json 'test/**/*.test.ts'","clean":"tsc --build --clean tsconfig.json tsconfig.esm.json tsconfig.esnext.json","watch":"tsc --build --watch tsconfig.json tsconfig.esm.json tsconfig.esnext.json","codecov":"nyc report --reporter=json && codecov -f coverage/*.json -p ../../","compile":"tsc --build tsconfig.json tsconfig.esm.json tsconfig.esnext.json","version":"node ../../scripts/version-update.js","lint:fix":"eslint . --ext .ts --fix","prewatch":"node ../../scripts/version-update.js","precompile":"lerna run version --scope $(npm pkg get name) --include-dependencies","tdd:browser":"karma start","test:browser":"nyc karma start --single-run","peer-api-check":"node ../../scripts/peer-api-check.js","prepublishOnly":"npm run compile"},"_npmUser":{"name":"dyladan","email":"dyladan@gmail.com"},"repository":{"url":"git+https://github.com/open-telemetry/opentelemetry-js.git","type":"git"},"_npmVersion":"lerna/6.0.3/node@v14.18.1+x64 (darwin)","description":"OpenTelemetry metrics SDK","directories":{},"sideEffects":false,"_nodeVersion":"14.18.1","dependencies":{"lodash.merge":"4.6.2","@opentelemetry/core":"1.10.1","@opentelemetry/resources":"1.10.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"nyc":"15.1.0","karma":"6.3.16","mocha":"10.0.0","sinon":"15.0.0","rimraf":"4.1.2","codecov":"3.8.3","ts-mocha":"10.0.0","typescript":"4.4.4","@types/node":"18.6.5","karma-mocha":"2.0.1","@types/mocha":"10.0.0","@types/sinon":"10.0.13","karma-webpack":"4.0.2","@opentelemetry/api":">=1.3.0 <1.5.0","@types/lodash.merge":"4.6.6","karma-spec-reporter":"0.0.32","karma-chrome-launcher":"3.1.0","karma-coverage-istanbul-reporter":"3.0.3"},"peerDependencies":{"@opentelemetry/api":">=1.3.0 <1.5.0"},"_npmOperationalInternal":{"tmp":"tmp/sdk-metrics_1.10.1_1679328634706_0.9289571491726534","host":"s3://npm-registry-packages"}},"1.11.0":{"name":"@opentelemetry/sdk-metrics","version":"1.11.0","keywords":["opentelemetry","nodejs","metrics","stats","profiling"],"author":{"name":"OpenTelemetry Authors"},"license":"Apache-2.0","_id":"@opentelemetry/sdk-metrics@1.11.0","maintainers":[{"name":"bogdandrutu","email":"bogdandrutu@gmail.com"},{"name":"dyladan","email":"dyladan@gmail.com"}],"homepage":"https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/sdk-metrics","bugs":{"url":"https://github.com/open-telemetry/opentelemetry-js/issues"},"dist":{"shasum":"0fe347fb39a802ec270315cba0eba2e3ce64c4a2","tarball":"https://registry.npmjs.org/@opentelemetry/sdk-metrics/-/sdk-metrics-1.11.0.tgz","fileCount":561,"integrity":"sha512-knuq3pwU0+46FEMdw9Ses+alXL9cbcLUUTdYBBBsaKkqKwoVMHfhBufW7u6YCu4i+47Wg6ZZTN/eGc4LbTbK5Q==","signatures":[{"sig":"MEUCICcPE7ow3GH80M4VwObQJPDkCO3SK4VTYmZkd1STJ+uZAiEA35ZtKgFt5GMZa3WnCxdCI7yWWkwAk9QYu88ktlLJYVk=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":1839857,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkJaswACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmrzcg/9FdLBYGIFXRPNUEc+CsQRabaC90KOwOp+7HV39/LXozs0FSB1\r\niKe3uUkfFBCLhcRSCQns1EVifv+Xda02Wa/Y0r28uhKc1y/N7uGQWLFpR7Iu\r\ngVVKTxpLt2QPsTYyQuuj4a6XGpGk7frKzv+uss7ByMKXUsC7YmzMS1DUJt+4\r\nekB8LXK7MEMrsN1ze0pp9+r9KTPGMDQXT9I64a/AuWR7IhM4RuPqjpriq/7R\r\nV38kOjgp4I6uj1H4hAB3FQ1NwdVOSajrDQ2HHLUvT4lv22LKIABQr0TDtQsN\r\naJq9rK7IfWSAE5zj5q9t8VfpNkhph3pFPPgg/l1Mnryr+VYhvErInyIuuPcM\r\n6X3csId2wFKauJR4oSXTLDxE6IMfvPk1ln2aXe3u/bSDrjEkd8bJvAS45yhW\r\n8JxegGRcA3SMuTtJcy85S6mVc/rksLjDSGDGpBaL4eYnR1qQ1hGYLljdpbuy\r\nbDRNcL2ZERMu3CmmXsFEmDqfTdFaMIzGTXXN20+ti6HtcBL9WFsKgVudxD5O\r\nTU40gKMtkAc+kfQ7cheqj+WjbH6ED0dPA7BHCE8Mo7kQTuGCVR1pMZZHh50h\r\nb/CaOKc7PCzVltN0PRnNPouwHzSM00LFqU4O2dvfnDkM6yyNJ86Je01ls6Fu\r\nQooqG9QlA64TxWqtWwXfGRY/w5p7wZSrXrE=\r\n=KFj4\r\n-----END PGP SIGNATURE-----\r\n"},"main":"build/src/index.js","types":"build/src/index.d.ts","esnext":"build/esnext/index.js","module":"build/esm/index.js","engines":{"node":">=14"},"gitHead":"1328ee04ae78f9f6cf143af7050c00aaa6d2eb3b","scripts":{"tdd":"npm run test -- --watch-extensions ts --watch","lint":"eslint . --ext .ts","test":"nyc ts-mocha -p tsconfig.json 'test/**/*.test.ts'","clean":"tsc --build --clean tsconfig.json tsconfig.esm.json tsconfig.esnext.json","watch":"tsc --build --watch tsconfig.json tsconfig.esm.json tsconfig.esnext.json","codecov":"nyc report --reporter=json && codecov -f coverage/*.json -p ../../","compile":"tsc --build tsconfig.json tsconfig.esm.json tsconfig.esnext.json","version":"node ../../scripts/version-update.js","lint:fix":"eslint . --ext .ts --fix","prewatch":"node ../../scripts/version-update.js","precompile":"lerna run version --scope $(npm pkg get name) --include-dependencies","tdd:browser":"karma start","test:browser":"nyc karma start --single-run","peer-api-check":"node ../../scripts/peer-api-check.js","prepublishOnly":"npm run compile"},"_npmUser":{"name":"dyladan","email":"dyladan@gmail.com"},"repository":{"url":"git+https://github.com/open-telemetry/opentelemetry-js.git","type":"git"},"_npmVersion":"lerna/6.0.3/node@v14.18.1+x64 (darwin)","description":"OpenTelemetry metrics SDK","directories":{},"sideEffects":false,"_nodeVersion":"14.18.1","dependencies":{"lodash.merge":"4.6.2","@opentelemetry/core":"1.11.0","@opentelemetry/resources":"1.11.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"nyc":"15.1.0","karma":"6.3.16","mocha":"10.0.0","sinon":"15.0.0","rimraf":"4.1.2","codecov":"3.8.3","ts-mocha":"10.0.0","typescript":"4.4.4","@types/node":"18.6.5","karma-mocha":"2.0.1","@types/mocha":"10.0.0","@types/sinon":"10.0.13","karma-webpack":"4.0.2","@opentelemetry/api":">=1.3.0 <1.5.0","@types/lodash.merge":"4.6.6","karma-spec-reporter":"0.0.32","karma-chrome-launcher":"3.1.0","karma-coverage-istanbul-reporter":"3.0.3"},"peerDependencies":{"@opentelemetry/api":">=1.3.0 <1.5.0"},"_npmOperationalInternal":{"tmp":"tmp/sdk-metrics_1.11.0_1680190255856_0.4488883258029981","host":"s3://npm-registry-packages"}},"1.12.0":{"name":"@opentelemetry/sdk-metrics","version":"1.12.0","keywords":["opentelemetry","nodejs","metrics","stats","profiling"],"author":{"name":"OpenTelemetry Authors"},"license":"Apache-2.0","_id":"@opentelemetry/sdk-metrics@1.12.0","maintainers":[{"name":"bogdandrutu","email":"bogdandrutu@gmail.com"},{"name":"dyladan","email":"dyladan@gmail.com"}],"homepage":"https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/sdk-metrics","bugs":{"url":"https://github.com/open-telemetry/opentelemetry-js/issues"},"dist":{"shasum":"52c135b8ca6af677a3e93b6721bc866a74c98b4b","tarball":"https://registry.npmjs.org/@opentelemetry/sdk-metrics/-/sdk-metrics-1.12.0.tgz","fileCount":561,"integrity":"sha512-zOy88Jfk88eTxqu+9ypHLs184dGydJocSWtvWMY10QKVVaxhC3SLKa0uxI/zBtD9S+x0LP65wxrTSfSoUNtCOA==","signatures":[{"sig":"MEQCIEAfZBHAMQVNInXN1E0ihfClv5NylKPFc0jrD34SRJMvAiBzpMnq2Iu5C00sNF1GPtmv10V2RrlKn7msJG8pBtnd5g==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":1839857,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkOEYtACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmobXQ/6AsboU2mCpdhs/tPwnXUqcjmoBV3/aVWoXwM22/jxCszCX8vk\r\nRFoTQHvvMZOMjqOLOPW2S3U2sPumqm7tj7V2aT/tVoZ7En09afYCbKO1fClj\r\ndtm9zB4H/GeL9uT4j8E7mFzPGMkgl/Wo8xZzrifKGknDwoO5sITFwXYCb1XI\r\nVprJn7eNMQEeMuGNd8WG2SFiI+VwVDfRz9eCmaI6ozABBw+Xd/Ae2SzPRfqo\r\nlbV46b6MN47oJHPNNjvPDPpQ8PUu+usZ2CZZR0/DYvHryjJnsTEaBOEqefXl\r\nvL7ommVdZW6DNSzMEQ5k4DQIMIHrvYYL/j8Cwkl7UcpmzrXgWoHNfQLlP3zk\r\nOqHvW+AEAYeiAs1ZrLRwNId+SpdNdERohMR70BxyU1ZXXx6NcpzJv6V+a+4q\r\nrtfX4oazI7rldM1BHO3sJM3g0cCyUtllFGTb5Mg8EI1qXBZppQF33jLvj20n\r\n4Ulb6wpsteaDDlBOK1TmN0s8VftM4ekrz2b5+UvE5yYq7RX+FVRFWb8U5xiZ\r\nHRc/5H4txVGZXLFvmSCJm6WmzUy83njG0qSF3wS6dOetNRXlrJrhS0tnHBqM\r\nnC4RbTqtdrp4EDi4F521hcdm6uo2cAmCxHbVhwgL+3lM2me9VmAtxB/BJacp\r\nvupg+95/zDYgsEWSTaFE/0t7TGuFe0UJ9j4=\r\n=5rhT\r\n-----END PGP SIGNATURE-----\r\n"},"main":"build/src/index.js","types":"build/src/index.d.ts","esnext":"build/esnext/index.js","module":"build/esm/index.js","engines":{"node":">=14"},"gitHead":"a04090010ee18e17487b449984807cc2b7b6e3e6","scripts":{"tdd":"npm run test -- --watch-extensions ts --watch","lint":"eslint . --ext .ts","test":"nyc ts-mocha -p tsconfig.json 'test/**/*.test.ts'","clean":"tsc --build --clean tsconfig.json tsconfig.esm.json tsconfig.esnext.json","watch":"tsc --build --watch tsconfig.json tsconfig.esm.json tsconfig.esnext.json","codecov":"nyc report --reporter=json && codecov -f coverage/*.json -p ../../","compile":"tsc --build tsconfig.json tsconfig.esm.json tsconfig.esnext.json","version":"node ../../scripts/version-update.js","lint:fix":"eslint . --ext .ts --fix","prewatch":"node ../../scripts/version-update.js","precompile":"lerna run version --scope $(npm pkg get name) --include-dependencies","tdd:browser":"karma start","test:browser":"nyc karma start --single-run","peer-api-check":"node ../../scripts/peer-api-check.js","prepublishOnly":"npm run compile"},"_npmUser":{"name":"dyladan","email":"dyladan@gmail.com"},"repository":{"url":"git+https://github.com/open-telemetry/opentelemetry-js.git","type":"git"},"_npmVersion":"lerna/6.0.3/node@v14.18.1+x64 (darwin)","description":"OpenTelemetry metrics SDK","directories":{},"sideEffects":false,"_nodeVersion":"14.18.1","dependencies":{"lodash.merge":"4.6.2","@opentelemetry/core":"1.12.0","@opentelemetry/resources":"1.12.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"nyc":"15.1.0","karma":"6.3.16","mocha":"10.0.0","sinon":"15.0.0","rimraf":"4.1.2","codecov":"3.8.3","ts-mocha":"10.0.0","typescript":"4.4.4","@types/node":"18.6.5","karma-mocha":"2.0.1","@types/mocha":"10.0.0","@types/sinon":"10.0.13","karma-webpack":"4.0.2","@opentelemetry/api":">=1.3.0 <1.5.0","@types/lodash.merge":"4.6.6","karma-spec-reporter":"0.0.32","karma-chrome-launcher":"3.1.0","karma-coverage-istanbul-reporter":"3.0.3"},"peerDependencies":{"@opentelemetry/api":">=1.3.0 <1.5.0"},"_npmOperationalInternal":{"tmp":"tmp/sdk-metrics_1.12.0_1681409581531_0.31698151736882196","host":"s3://npm-registry-packages"}},"1.13.0":{"name":"@opentelemetry/sdk-metrics","version":"1.13.0","keywords":["opentelemetry","nodejs","metrics","stats","profiling"],"author":{"name":"OpenTelemetry Authors"},"license":"Apache-2.0","_id":"@opentelemetry/sdk-metrics@1.13.0","maintainers":[{"name":"bogdandrutu","email":"bogdandrutu@gmail.com"},{"name":"dyladan","email":"dyladan@gmail.com"}],"homepage":"https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/sdk-metrics","bugs":{"url":"https://github.com/open-telemetry/opentelemetry-js/issues"},"dist":{"shasum":"4e859107a7a4389bcda7b37d3952bc7dd34211d7","tarball":"https://registry.npmjs.org/@opentelemetry/sdk-metrics/-/sdk-metrics-1.13.0.tgz","fileCount":561,"integrity":"sha512-MOjZX6AnSOqLliCcZUrb+DQKjAWXBiGeICGbHAGe5w0BB18PJIeIo995lO5JSaFfHpmUMgJButTPfJJD27W3Vg==","signatures":[{"sig":"MEYCIQCUeO+qPBpw+CVNlqlTfDO++08VfOb0W3UdO9pIYolUCAIhAJH6JOYZuj9SxAwhyK86XMhqrxGloVuk7E7pzmTPdjJr","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":1839834},"main":"build/src/index.js","types":"build/src/index.d.ts","esnext":"build/esnext/index.js","module":"build/esm/index.js","engines":{"node":">=14"},"gitHead":"8fc76896595aac912bf9e15d4f19c167317844c8","scripts":{"tdd":"npm run test -- --watch-extensions ts --watch","lint":"eslint . --ext .ts","test":"nyc ts-mocha -p tsconfig.json 'test/**/*.test.ts'","clean":"tsc --build --clean tsconfig.json tsconfig.esm.json tsconfig.esnext.json","watch":"tsc --build --watch tsconfig.json tsconfig.esm.json tsconfig.esnext.json","codecov":"nyc report --reporter=json && codecov -f coverage/*.json -p ../../","compile":"tsc --build tsconfig.json tsconfig.esm.json tsconfig.esnext.json","version":"node ../../scripts/version-update.js","lint:fix":"eslint . --ext .ts --fix","prewatch":"node ../../scripts/version-update.js","precompile":"lerna run version --scope $(npm pkg get name) --include-dependencies","tdd:browser":"karma start","test:browser":"nyc karma start --single-run","peer-api-check":"node ../../scripts/peer-api-check.js","prepublishOnly":"npm run compile"},"_npmUser":{"name":"dyladan","email":"dyladan@gmail.com"},"repository":{"url":"git+https://github.com/open-telemetry/opentelemetry-js.git","type":"git"},"_npmVersion":"lerna/6.0.3/node@v18.12.1+x64 (linux)","description":"OpenTelemetry metrics SDK","directories":{},"sideEffects":false,"_nodeVersion":"18.12.1","dependencies":{"lodash.merge":"4.6.2","@opentelemetry/core":"1.13.0","@opentelemetry/resources":"1.13.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"nyc":"15.1.0","karma":"6.3.16","mocha":"10.0.0","sinon":"15.0.0","codecov":"3.8.3","ts-mocha":"10.0.0","typescript":"4.4.4","@types/node":"18.6.5","karma-mocha":"2.0.1","@types/mocha":"10.0.0","@types/sinon":"10.0.13","karma-webpack":"4.0.2","@opentelemetry/api":">=1.3.0 <1.5.0","@types/lodash.merge":"4.6.6","karma-spec-reporter":"0.0.32","karma-chrome-launcher":"3.1.0","karma-coverage-istanbul-reporter":"3.0.3"},"peerDependencies":{"@opentelemetry/api":">=1.3.0 <1.5.0"},"_npmOperationalInternal":{"tmp":"tmp/sdk-metrics_1.13.0_1683811806809_0.022001801192962578","host":"s3://npm-registry-packages"}},"1.14.0":{"name":"@opentelemetry/sdk-metrics","version":"1.14.0","keywords":["opentelemetry","nodejs","metrics","stats","profiling"],"author":{"name":"OpenTelemetry Authors"},"license":"Apache-2.0","_id":"@opentelemetry/sdk-metrics@1.14.0","maintainers":[{"name":"pichlermarc","email":"marc.pichler@dynatrace.com"},{"name":"bogdandrutu","email":"bogdandrutu@gmail.com"},{"name":"dyladan","email":"dyladan@gmail.com"}],"homepage":"https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/sdk-metrics","bugs":{"url":"https://github.com/open-telemetry/opentelemetry-js/issues"},"dist":{"shasum":"ee51d72eb32a74108e6632681ce2df46cddc0714","tarball":"https://registry.npmjs.org/@opentelemetry/sdk-metrics/-/sdk-metrics-1.14.0.tgz","fileCount":561,"integrity":"sha512-F0JXmLqT4LmsaiaE28fl0qMtc5w0YuMWTHt1hnANTNX8hxW4IKSv9+wrYG7BZd61HEbPm032Re7fXyzzNA6nIw==","signatures":[{"sig":"MEUCIQDZy6AZC4gsrIqvrLyc0L21UL/+PakTzlDTNsuwjRpDhwIgMSf9ZJoCKDB8uD708TqJtggoPZ9cpVP/LIthheTWDWM=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":1839834},"main":"build/src/index.js","types":"build/src/index.d.ts","esnext":"build/esnext/index.js","module":"build/esm/index.js","engines":{"node":">=14"},"gitHead":"edebbcc757535bc88f01340409dbbecc0bb6ccf8","scripts":{"tdd":"npm run test -- --watch-extensions ts --watch","lint":"eslint . --ext .ts","test":"nyc ts-mocha -p tsconfig.json 'test/**/*.test.ts'","clean":"tsc --build --clean tsconfig.json tsconfig.esm.json tsconfig.esnext.json","watch":"tsc --build --watch tsconfig.json tsconfig.esm.json tsconfig.esnext.json","codecov":"nyc report --reporter=json && codecov -f coverage/*.json -p ../../","compile":"tsc --build tsconfig.json tsconfig.esm.json tsconfig.esnext.json","version":"node ../../scripts/version-update.js","lint:fix":"eslint . --ext .ts --fix","prewatch":"node ../../scripts/version-update.js","precompile":"lerna run version --scope $(npm pkg get name) --include-dependencies","tdd:browser":"karma start","test:browser":"nyc karma start --single-run","peer-api-check":"node ../../scripts/peer-api-check.js","prepublishOnly":"npm run compile"},"_npmUser":{"name":"pichlermarc","email":"marc.pichler@dynatrace.com"},"repository":{"url":"git+https://github.com/open-telemetry/opentelemetry-js.git","type":"git"},"_npmVersion":"lerna/6.0.3/node@v18.12.1+x64 (linux)","description":"OpenTelemetry metrics SDK","directories":{},"sideEffects":false,"_nodeVersion":"18.12.1","dependencies":{"lodash.merge":"4.6.2","@opentelemetry/core":"1.14.0","@opentelemetry/resources":"1.14.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"nyc":"15.1.0","karma":"6.3.16","mocha":"10.0.0","sinon":"15.0.0","codecov":"3.8.3","ts-mocha":"10.0.0","typescript":"4.4.4","@types/node":"18.6.5","karma-mocha":"2.0.1","@types/mocha":"10.0.0","@types/sinon":"10.0.13","karma-webpack":"4.0.2","@opentelemetry/api":">=1.3.0 <1.5.0","@types/lodash.merge":"4.6.6","karma-spec-reporter":"0.0.32","karma-chrome-launcher":"3.1.0","karma-coverage-istanbul-reporter":"3.0.3"},"peerDependencies":{"@opentelemetry/api":">=1.3.0 <1.5.0"},"_npmOperationalInternal":{"tmp":"tmp/sdk-metrics_1.14.0_1686031255514_0.6205545095237606","host":"s3://npm-registry-packages"}},"1.15.0":{"name":"@opentelemetry/sdk-metrics","version":"1.15.0","keywords":["opentelemetry","nodejs","metrics","stats","profiling"],"author":{"name":"OpenTelemetry Authors"},"license":"Apache-2.0","_id":"@opentelemetry/sdk-metrics@1.15.0","maintainers":[{"name":"pichlermarc","email":"marc.pichler@dynatrace.com"},{"name":"bogdandrutu","email":"bogdandrutu@gmail.com"},{"name":"dyladan","email":"dyladan@gmail.com"}],"homepage":"https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/sdk-metrics","bugs":{"url":"https://github.com/open-telemetry/opentelemetry-js/issues"},"dist":{"shasum":"e47ad688882fc2daedcbbe3db16a5c110feb23e8","tarball":"https://registry.npmjs.org/@opentelemetry/sdk-metrics/-/sdk-metrics-1.15.0.tgz","fileCount":561,"integrity":"sha512-fFUnAcPvlXO39nlIduGuaeCuiZyFtSLCn9gW/0djFRO5DFst4m4gcT6+llXvNWuUvtGB49s56NP10B9IZRN0Rw==","signatures":[{"sig":"MEQCIA6mPFnkdT47rCrHsCh4ePv+jy+q7abH27EHpIw2DKE0AiB9rZUo59MjzXY9Uih4EbPVSQZ5I/uFRmYTdzVsP7a68g==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":1803014},"main":"build/src/index.js","types":"build/src/index.d.ts","esnext":"build/esnext/index.js","module":"build/esm/index.js","engines":{"node":">=14"},"gitHead":"06e919d6c909e8cc8e28b6624d9843f401d9b059","scripts":{"tdd":"npm run test -- --watch-extensions ts --watch","lint":"eslint . --ext .ts","test":"nyc ts-mocha -p tsconfig.json 'test/**/*.test.ts'","clean":"tsc --build --clean tsconfig.json tsconfig.esm.json tsconfig.esnext.json","watch":"tsc --build --watch tsconfig.json tsconfig.esm.json tsconfig.esnext.json","codecov":"nyc report --reporter=json && codecov -f coverage/*.json -p ../../","compile":"tsc --build tsconfig.json tsconfig.esm.json tsconfig.esnext.json","version":"node ../../scripts/version-update.js","lint:fix":"eslint . --ext .ts --fix","prewatch":"node ../../scripts/version-update.js","precompile":"cross-var lerna run version --scope $npm_package_name --include-dependencies","tdd:browser":"karma start","test:browser":"nyc karma start --single-run","peer-api-check":"node ../../scripts/peer-api-check.js","prepublishOnly":"npm run compile"},"_npmUser":{"name":"pichlermarc","email":"marc.pichler@dynatrace.com"},"repository":{"url":"git+https://github.com/open-telemetry/opentelemetry-js.git","type":"git"},"_npmVersion":"lerna/7.1.1/node@v18.12.1+x64 (linux)","description":"OpenTelemetry metrics SDK","directories":{},"sideEffects":false,"_nodeVersion":"18.12.1","dependencies":{"tslib":"^2.3.1","lodash.merge":"^4.6.2","@opentelemetry/core":"1.15.0","@opentelemetry/resources":"1.15.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"nyc":"15.1.0","karma":"6.4.2","lerna":"7.1.1","mocha":"10.2.0","sinon":"15.1.2","codecov":"3.8.3","ts-mocha":"10.0.0","cross-var":"1.1.0","typescript":"4.4.4","@types/node":"18.6.5","karma-mocha":"2.0.1","@types/mocha":"10.0.1","@types/sinon":"10.0.15","karma-webpack":"4.0.2","@opentelemetry/api":">=1.3.0 <1.5.0","@types/lodash.merge":"4.6.7","karma-spec-reporter":"0.0.36","karma-chrome-launcher":"3.1.0","karma-coverage-istanbul-reporter":"3.0.3"},"peerDependencies":{"@opentelemetry/api":">=1.3.0 <1.5.0"},"_npmOperationalInternal":{"tmp":"tmp/sdk-metrics_1.15.0_1688642828881_0.612950022765163","host":"s3://npm-registry-packages"}},"1.15.1":{"name":"@opentelemetry/sdk-metrics","version":"1.15.1","keywords":["opentelemetry","nodejs","metrics","stats","profiling"],"author":{"name":"OpenTelemetry Authors"},"license":"Apache-2.0","_id":"@opentelemetry/sdk-metrics@1.15.1","maintainers":[{"name":"pichlermarc","email":"marc.pichler@dynatrace.com"},{"name":"bogdandrutu","email":"bogdandrutu@gmail.com"},{"name":"dyladan","email":"dyladan@gmail.com"}],"homepage":"https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/sdk-metrics","bugs":{"url":"https://github.com/open-telemetry/opentelemetry-js/issues"},"dist":{"shasum":"e0d2844191ecd7fce3fccf18ae50ed35389f0885","tarball":"https://registry.npmjs.org/@opentelemetry/sdk-metrics/-/sdk-metrics-1.15.1.tgz","fileCount":561,"integrity":"sha512-ojcrzexOQfto83NvKfIvsJap4SHH3ZvLjsDGhQ04AfvWWGR7mPcqLSlLedoSkEdIe0k1H6uBEsHBtIprkMpTHA==","signatures":[{"sig":"MEYCIQCBwveTbaE79v4tJk8CdBffRh5H6Loc8hSu+ysnZzK1YAIhAMHsh5T/As5lzxnmYm6j7V704gjjvyvEm2CaH1bpx5cO","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":1841179},"main":"build/src/index.js","types":"build/src/index.d.ts","esnext":"build/esnext/index.js","module":"build/esm/index.js","engines":{"node":">=14"},"gitHead":"9f71800fdc2a5ee5055684037a12498af71955f2","scripts":{"tdd":"npm run test -- --watch-extensions ts --watch","lint":"eslint . --ext .ts","test":"nyc ts-mocha -p tsconfig.json 'test/**/*.test.ts'","clean":"tsc --build --clean tsconfig.json tsconfig.esm.json tsconfig.esnext.json","watch":"tsc --build --watch tsconfig.json tsconfig.esm.json tsconfig.esnext.json","codecov":"nyc report --reporter=json && codecov -f coverage/*.json -p ../../","compile":"tsc --build tsconfig.json tsconfig.esm.json tsconfig.esnext.json","version":"node ../../scripts/version-update.js","lint:fix":"eslint . --ext .ts --fix","prewatch":"node ../../scripts/version-update.js","precompile":"cross-var lerna run version --scope $npm_package_name --include-dependencies","tdd:browser":"karma start","test:browser":"karma start --single-run","peer-api-check":"node ../../scripts/peer-api-check.js","prepublishOnly":"npm run compile"},"_npmUser":{"name":"dyladan","email":"dyladan@gmail.com"},"repository":{"url":"git+https://github.com/open-telemetry/opentelemetry-js.git","type":"git"},"_npmVersion":"lerna/7.1.3/node@v18.4.0+x64 (darwin)","description":"OpenTelemetry metrics SDK","directories":{},"sideEffects":false,"_nodeVersion":"18.4.0","dependencies":{"lodash.merge":"^4.6.2","@opentelemetry/core":"1.15.1","@opentelemetry/resources":"1.15.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"nyc":"15.1.0","karma":"6.4.2","lerna":"7.1.3","mocha":"10.2.0","sinon":"15.1.2","codecov":"3.8.3","webpack":"4.46.0","ts-mocha":"10.0.0","cross-var":"1.1.0","ts-loader":"8.4.0","typescript":"4.4.4","@babel/core":"7.22.9","@types/node":"18.6.5","karma-mocha":"2.0.1","webpack-cli":"4.10.0","@types/mocha":"10.0.1","@types/sinon":"10.0.15","karma-webpack":"4.0.2","webpack-merge":"5.9.0","karma-coverage":"2.2.1","@opentelemetry/api":">=1.3.0 <1.5.0","@types/lodash.merge":"4.6.7","karma-spec-reporter":"0.0.36","babel-plugin-istanbul":"6.1.1","karma-chrome-launcher":"3.1.0"},"peerDependencies":{"@opentelemetry/api":">=1.3.0 <1.5.0"},"_npmOperationalInternal":{"tmp":"tmp/sdk-metrics_1.15.1_1690209168814_0.4696021233708716","host":"s3://npm-registry-packages"}},"1.15.2":{"name":"@opentelemetry/sdk-metrics","version":"1.15.2","keywords":["opentelemetry","nodejs","metrics","stats","profiling"],"author":{"name":"OpenTelemetry Authors"},"license":"Apache-2.0","_id":"@opentelemetry/sdk-metrics@1.15.2","maintainers":[{"name":"pichlermarc","email":"marc.pichler@dynatrace.com"},{"name":"bogdandrutu","email":"bogdandrutu@gmail.com"},{"name":"dyladan","email":"dyladan@gmail.com"}],"homepage":"https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/sdk-metrics","bugs":{"url":"https://github.com/open-telemetry/opentelemetry-js/issues"},"dist":{"shasum":"eadd0a049de9cd860e1e0d49eea01156469c4b60","tarball":"https://registry.npmjs.org/@opentelemetry/sdk-metrics/-/sdk-metrics-1.15.2.tgz","fileCount":561,"integrity":"sha512-9aIlcX8GnhcsAHW/Wl8bzk4ZnWTpNlLtud+fxUfBtFATu6OZ6TrGrF4JkT9EVrnoxwtPIDtjHdEsSjOqisY/iA==","signatures":[{"sig":"MEUCIQCFKX9DaFzjXDXPu/N+lf5A+VZoJEIuX5BlwqR2YxqIPQIgTriFUfsIieNy4ajXosd23GlEnVapJ9nRDMUvRFJYIGk=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":1848194},"main":"build/src/index.js","types":"build/src/index.d.ts","esnext":"build/esnext/index.js","module":"build/esm/index.js","engines":{"node":">=14"},"gitHead":"48fb15862e801b742059a3e39dbcc8ef4c10b2e2","scripts":{"tdd":"npm run test -- --watch-extensions ts --watch","lint":"eslint . --ext .ts","test":"nyc ts-mocha -p tsconfig.json 'test/**/*.test.ts'","clean":"tsc --build --clean tsconfig.json tsconfig.esm.json tsconfig.esnext.json","watch":"tsc --build --watch tsconfig.json tsconfig.esm.json tsconfig.esnext.json","codecov":"nyc report --reporter=json && codecov -f coverage/*.json -p ../../","compile":"tsc --build tsconfig.json tsconfig.esm.json tsconfig.esnext.json","version":"node ../../scripts/version-update.js","lint:fix":"eslint . --ext .ts --fix","prewatch":"node ../../scripts/version-update.js","precompile":"cross-var lerna run version --scope $npm_package_name --include-dependencies","tdd:browser":"karma start","test:browser":"karma start --single-run","peer-api-check":"node ../../scripts/peer-api-check.js","prepublishOnly":"npm run compile"},"_npmUser":{"name":"pichlermarc","email":"marc.pichler@dynatrace.com"},"repository":{"url":"git+https://github.com/open-telemetry/opentelemetry-js.git","type":"git"},"_npmVersion":"lerna/7.1.4/node@v18.12.1+x64 (linux)","description":"OpenTelemetry metrics SDK","directories":{},"sideEffects":false,"_nodeVersion":"18.12.1","dependencies":{"lodash.merge":"^4.6.2","@opentelemetry/core":"1.15.2","@opentelemetry/resources":"1.15.2"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"nyc":"15.1.0","karma":"6.4.2","lerna":"7.1.4","mocha":"10.2.0","sinon":"15.1.2","codecov":"3.8.3","webpack":"4.46.0","ts-mocha":"10.0.0","cross-var":"1.1.0","ts-loader":"8.4.0","typescript":"4.4.4","@babel/core":"7.22.10","@types/node":"18.6.5","karma-mocha":"2.0.1","webpack-cli":"4.10.0","@types/mocha":"10.0.1","@types/sinon":"10.0.16","karma-webpack":"4.0.2","webpack-merge":"5.9.0","karma-coverage":"2.2.1","@opentelemetry/api":">=1.3.0 <1.5.0","@types/lodash.merge":"4.6.7","karma-spec-reporter":"0.0.36","babel-plugin-istanbul":"6.1.1","karma-chrome-launcher":"3.1.0"},"peerDependencies":{"@opentelemetry/api":">=1.3.0 <1.5.0"},"_npmOperationalInternal":{"tmp":"tmp/sdk-metrics_1.15.2_1691500878806_0.21964542929012487","host":"s3://npm-registry-packages"}},"1.16.0":{"name":"@opentelemetry/sdk-metrics","version":"1.16.0","keywords":["opentelemetry","nodejs","metrics","stats","profiling"],"author":{"name":"OpenTelemetry Authors"},"license":"Apache-2.0","_id":"@opentelemetry/sdk-metrics@1.16.0","maintainers":[{"name":"pichlermarc","email":"marc.pichler@dynatrace.com"},{"name":"bogdandrutu","email":"bogdandrutu@gmail.com"},{"name":"dyladan","email":"dyladan@gmail.com"}],"homepage":"https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/sdk-metrics","bugs":{"url":"https://github.com/open-telemetry/opentelemetry-js/issues"},"dist":{"shasum":"6c413c6abb1d68dbfe59984384d4031feeccbe1e","tarball":"https://registry.npmjs.org/@opentelemetry/sdk-metrics/-/sdk-metrics-1.16.0.tgz","fileCount":561,"integrity":"sha512-58obaKzBY0CB6ZQS/sxcGvihqZk2zL2KDCQe734NofVfE7JpKMn/TtyzA8O4nw9sXIO2N9Wx2zzKRyGFXVGrcw==","signatures":[{"sig":"MEUCIGu4l4M/yMtx2D8TpJeVo1nvcoCzRr6o5+wZtJj2W23YAiEAzPdInj1ng6V1HXJhfyT/sRzxXuC3taYmiuKCASO4G2g=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":1872545},"main":"build/src/index.js","types":"build/src/index.d.ts","esnext":"build/esnext/index.js","module":"build/esm/index.js","engines":{"node":">=14"},"gitHead":"5fcd8cf136e2235903dde3df9ba03ced594f0e95","scripts":{"tdd":"npm run test -- --watch-extensions ts --watch","lint":"eslint . --ext .ts","test":"nyc ts-mocha -p tsconfig.json 'test/**/*.test.ts'","clean":"tsc --build --clean tsconfig.json tsconfig.esm.json tsconfig.esnext.json","watch":"tsc --build --watch tsconfig.json tsconfig.esm.json tsconfig.esnext.json","codecov":"nyc report --reporter=json && codecov -f coverage/*.json -p ../../","compile":"tsc --build tsconfig.json tsconfig.esm.json tsconfig.esnext.json","version":"node ../../scripts/version-update.js","lint:fix":"eslint . --ext .ts --fix","prewatch":"node ../../scripts/version-update.js","precompile":"cross-var lerna run version --scope $npm_package_name --include-dependencies","tdd:browser":"karma start","test:browser":"karma start --single-run","peer-api-check":"node ../../scripts/peer-api-check.js","prepublishOnly":"npm run compile"},"_npmUser":{"name":"pichlermarc","email":"marc.pichler@dynatrace.com"},"repository":{"url":"git+https://github.com/open-telemetry/opentelemetry-js.git","type":"git"},"_npmVersion":"lerna/7.1.5/node@v18.12.1+x64 (linux)","description":"OpenTelemetry metrics SDK","directories":{},"sideEffects":false,"_nodeVersion":"18.12.1","dependencies":{"lodash.merge":"^4.6.2","@opentelemetry/core":"1.16.0","@opentelemetry/resources":"1.16.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"nyc":"15.1.0","karma":"6.4.2","lerna":"7.1.5","mocha":"10.2.0","sinon":"15.1.2","codecov":"3.8.3","webpack":"4.46.0","ts-mocha":"10.0.0","cross-var":"1.1.0","ts-loader":"8.4.0","typescript":"4.4.4","@babel/core":"7.22.17","@types/node":"18.6.5","karma-mocha":"2.0.1","webpack-cli":"4.10.0","@types/mocha":"10.0.1","@types/sinon":"10.0.16","karma-webpack":"4.0.2","webpack-merge":"5.9.0","karma-coverage":"2.2.1","@opentelemetry/api":">=1.3.0 <1.6.0","@types/lodash.merge":"4.6.7","karma-spec-reporter":"0.0.36","babel-plugin-istanbul":"6.1.1","karma-chrome-launcher":"3.1.0"},"peerDependencies":{"@opentelemetry/api":">=1.3.0 <1.6.0"},"_npmOperationalInternal":{"tmp":"tmp/sdk-metrics_1.16.0_1694434471320_0.42251452448444704","host":"s3://npm-registry-packages"}},"1.17.0":{"name":"@opentelemetry/sdk-metrics","version":"1.17.0","keywords":["opentelemetry","nodejs","metrics","stats","profiling"],"author":{"name":"OpenTelemetry Authors"},"license":"Apache-2.0","_id":"@opentelemetry/sdk-metrics@1.17.0","maintainers":[{"name":"pichlermarc","email":"marc.pichler@dynatrace.com"},{"name":"bogdandrutu","email":"bogdandrutu@gmail.com"},{"name":"dyladan","email":"dyladan@gmail.com"}],"homepage":"https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/sdk-metrics","bugs":{"url":"https://github.com/open-telemetry/opentelemetry-js/issues"},"dist":{"shasum":"e51d39e0bb749780d17f9b1df12f0490438dec1a","tarball":"https://registry.npmjs.org/@opentelemetry/sdk-metrics/-/sdk-metrics-1.17.0.tgz","fileCount":561,"integrity":"sha512-HlWM27yGmYuwCoVRe3yg2PqKnIsq0kEF0HQgvkeDWz2NYkq9fFaSspR6kvjxUTbghAlZrabiqbgyKoYpYaXS3w==","signatures":[{"sig":"MEQCIEGFsgaNt88vPUiItoys14mI96KUmsfCU3V9/M9zEFrHAiAgibedup1xc0Uh7HFSGEe8a8IEZbYsRxYQhUM7mMJJmQ==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":1872545},"main":"build/src/index.js","types":"build/src/index.d.ts","esnext":"build/esnext/index.js","module":"build/esm/index.js","engines":{"node":">=14"},"gitHead":"faf939c77591f709afbc23fadbe629c9d3607ef6","scripts":{"tdd":"npm run test -- --watch-extensions ts --watch","lint":"eslint . --ext .ts","test":"nyc ts-mocha -p tsconfig.json 'test/**/*.test.ts'","clean":"tsc --build --clean tsconfig.json tsconfig.esm.json tsconfig.esnext.json","watch":"tsc --build --watch tsconfig.json tsconfig.esm.json tsconfig.esnext.json","codecov":"nyc report --reporter=json && codecov -f coverage/*.json -p ../../","compile":"tsc --build tsconfig.json tsconfig.esm.json tsconfig.esnext.json","version":"node ../../scripts/version-update.js","lint:fix":"eslint . --ext .ts --fix","prewatch":"node ../../scripts/version-update.js","precompile":"cross-var lerna run version --scope $npm_package_name --include-dependencies","tdd:browser":"karma start","test:browser":"karma start --single-run","peer-api-check":"node ../../scripts/peer-api-check.js","prepublishOnly":"npm run compile"},"_npmUser":{"name":"pichlermarc","email":"marc.pichler@dynatrace.com"},"repository":{"url":"git+https://github.com/open-telemetry/opentelemetry-js.git","type":"git"},"_npmVersion":"lerna/7.1.5/node@v18.12.1+x64 (linux)","description":"OpenTelemetry metrics SDK","directories":{},"sideEffects":false,"_nodeVersion":"18.12.1","dependencies":{"lodash.merge":"^4.6.2","@opentelemetry/core":"1.17.0","@opentelemetry/resources":"1.17.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"nyc":"15.1.0","karma":"6.4.2","lerna":"7.1.5","mocha":"10.2.0","sinon":"15.1.2","codecov":"3.8.3","webpack":"4.46.0","ts-mocha":"10.0.0","cross-var":"1.1.0","ts-loader":"8.4.0","typescript":"4.4.4","@babel/core":"7.22.17","@types/node":"18.6.5","karma-mocha":"2.0.1","webpack-cli":"4.10.0","@types/mocha":"10.0.1","@types/sinon":"10.0.16","karma-webpack":"4.0.2","webpack-merge":"5.9.0","karma-coverage":"2.2.1","@opentelemetry/api":">=1.3.0 <1.7.0","@types/lodash.merge":"4.6.7","karma-spec-reporter":"0.0.36","babel-plugin-istanbul":"6.1.1","karma-chrome-launcher":"3.1.0"},"peerDependencies":{"@opentelemetry/api":">=1.3.0 <1.7.0"},"_npmOperationalInternal":{"tmp":"tmp/sdk-metrics_1.17.0_1694524354547_0.27289065421627656","host":"s3://npm-registry-packages"}},"1.17.1":{"name":"@opentelemetry/sdk-metrics","version":"1.17.1","keywords":["opentelemetry","nodejs","metrics","stats","profiling"],"author":{"name":"OpenTelemetry Authors"},"license":"Apache-2.0","_id":"@opentelemetry/sdk-metrics@1.17.1","maintainers":[{"name":"pichlermarc","email":"marc.pichler@dynatrace.com"},{"name":"bogdandrutu","email":"bogdandrutu@gmail.com"},{"name":"dyladan","email":"dyladan@gmail.com"}],"homepage":"https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/sdk-metrics","bugs":{"url":"https://github.com/open-telemetry/opentelemetry-js/issues"},"dist":{"shasum":"9c4d13d845bcc82be8684050d9db7cce10f61580","tarball":"https://registry.npmjs.org/@opentelemetry/sdk-metrics/-/sdk-metrics-1.17.1.tgz","fileCount":561,"integrity":"sha512-eHdpsMCKhKhwznxvEfls8Wv3y4ZBWkkXlD3m7vtHIiWBqsMHspWSfie1s07mM45i/bBCf6YBMgz17FUxIXwmZA==","signatures":[{"sig":"MEUCIQC6T+my/2xzI2vaedMangtbqdpdAHiTTnwC85I9zGxvdwIgJwgxV8Jz14/su/N16gkO8rU//itJPXSzxcx7YCPtM6U=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":1883659},"main":"build/src/index.js","types":"build/src/index.d.ts","esnext":"build/esnext/index.js","module":"build/esm/index.js","engines":{"node":">=14"},"gitHead":"f8e187b473274cc2011e7385992f07d319d667dc","scripts":{"tdd":"npm run test -- --watch-extensions ts --watch","lint":"eslint . --ext .ts","test":"nyc ts-mocha -p tsconfig.json 'test/**/*.test.ts'","clean":"tsc --build --clean tsconfig.json tsconfig.esm.json tsconfig.esnext.json","watch":"tsc --build --watch tsconfig.json tsconfig.esm.json tsconfig.esnext.json","codecov":"nyc report --reporter=json && codecov -f coverage/*.json -p ../../","compile":"tsc --build tsconfig.json tsconfig.esm.json tsconfig.esnext.json","version":"node ../../scripts/version-update.js","lint:fix":"eslint . --ext .ts --fix","prewatch":"node ../../scripts/version-update.js","precompile":"cross-var lerna run version --scope $npm_package_name --include-dependencies","tdd:browser":"karma start","test:browser":"karma start --single-run","peer-api-check":"node ../../scripts/peer-api-check.js","prepublishOnly":"npm run compile"},"_npmUser":{"name":"pichlermarc","email":"marc.pichler@dynatrace.com"},"repository":{"url":"git+https://github.com/open-telemetry/opentelemetry-js.git","type":"git"},"_npmVersion":"lerna/7.1.5/node@v18.12.1+x64 (linux)","description":"OpenTelemetry metrics SDK","directories":{},"sideEffects":false,"_nodeVersion":"18.12.1","dependencies":{"lodash.merge":"^4.6.2","@opentelemetry/core":"1.17.1","@opentelemetry/resources":"1.17.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"nyc":"15.1.0","karma":"6.4.2","lerna":"7.1.5","mocha":"10.2.0","sinon":"15.1.2","codecov":"3.8.3","webpack":"4.46.0","ts-mocha":"10.0.0","cross-var":"1.1.0","ts-loader":"8.4.0","typescript":"4.4.4","@babel/core":"7.22.20","@types/node":"18.6.5","karma-mocha":"2.0.1","webpack-cli":"4.10.0","@types/mocha":"10.0.2","@types/sinon":"10.0.18","karma-webpack":"4.0.2","webpack-merge":"5.9.0","karma-coverage":"2.2.1","@opentelemetry/api":">=1.3.0 <1.7.0","@types/lodash.merge":"4.6.7","karma-spec-reporter":"0.0.36","babel-plugin-istanbul":"6.1.1","karma-chrome-launcher":"3.1.0"},"peerDependencies":{"@opentelemetry/api":">=1.3.0 <1.7.0"},"_npmOperationalInternal":{"tmp":"tmp/sdk-metrics_1.17.1_1696947498625_0.4798664177082872","host":"s3://npm-registry-packages"}},"1.18.0":{"name":"@opentelemetry/sdk-metrics","version":"1.18.0","keywords":["opentelemetry","nodejs","metrics","stats","profiling"],"author":{"name":"OpenTelemetry Authors"},"license":"Apache-2.0","_id":"@opentelemetry/sdk-metrics@1.18.0","maintainers":[{"name":"pichlermarc","email":"marc.pichler@dynatrace.com"},{"name":"bogdandrutu","email":"bogdandrutu@gmail.com"},{"name":"dyladan","email":"dyladan@gmail.com"}],"homepage":"https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/sdk-metrics","bugs":{"url":"https://github.com/open-telemetry/opentelemetry-js/issues"},"dist":{"shasum":"f84fffcabdb0e9504e3b219635c1099aabc9e207","tarball":"https://registry.npmjs.org/@opentelemetry/sdk-metrics/-/sdk-metrics-1.18.0.tgz","fileCount":561,"integrity":"sha512-wK5zdNCo5cJvZog/lsqXCg9/Dt9UeNXQsskgqX8Yz+40t13Kb5CKFFkAMU8tNUxkvidHnD6G6sT6xeVCHQYe4A==","signatures":[{"sig":"MEUCIQCMiT/6j2k3CLJNS9PVe/gMQM/shgZfXDwNLg9l7E3QdgIgFnmCSIgxrXYgrtIppJgyKJkGNUzsbBET1HwAZBRXfG8=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":1890396},"main":"build/src/index.js","types":"build/src/index.d.ts","esnext":"build/esnext/index.js","module":"build/esm/index.js","engines":{"node":">=14"},"gitHead":"73b446688f10fd8dc4cf403a085f0a39070df7b4","scripts":{"tdd":"npm run test -- --watch-extensions ts --watch","lint":"eslint . --ext .ts","test":"nyc ts-mocha -p tsconfig.json 'test/**/*.test.ts'","clean":"tsc --build --clean tsconfig.json tsconfig.esm.json tsconfig.esnext.json","watch":"tsc --build --watch tsconfig.json tsconfig.esm.json tsconfig.esnext.json","codecov":"nyc report --reporter=json && codecov -f coverage/*.json -p ../../","compile":"tsc --build tsconfig.json tsconfig.esm.json tsconfig.esnext.json","version":"node ../../scripts/version-update.js","lint:fix":"eslint . --ext .ts --fix","prewatch":"node ../../scripts/version-update.js","precompile":"cross-var lerna run version --scope $npm_package_name --include-dependencies","tdd:browser":"karma start","test:browser":"karma start --single-run","peer-api-check":"node ../../scripts/peer-api-check.js","prepublishOnly":"npm run compile"},"_npmUser":{"name":"pichlermarc","email":"marc.pichler@dynatrace.com"},"repository":{"url":"git+https://github.com/open-telemetry/opentelemetry-js.git","type":"git"},"_npmVersion":"lerna/6.6.2/node@v18.18.2+x64 (linux)","description":"OpenTelemetry metrics SDK","directories":{},"sideEffects":false,"_nodeVersion":"18.18.2","dependencies":{"lodash.merge":"^4.6.2","@opentelemetry/core":"1.18.0","@opentelemetry/resources":"1.18.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"nyc":"15.1.0","karma":"6.4.2","lerna":"6.6.2","mocha":"10.2.0","sinon":"15.1.2","codecov":"3.8.3","webpack":"4.46.0","ts-mocha":"10.0.0","cross-var":"1.1.0","ts-loader":"8.4.0","typescript":"4.4.4","@babel/core":"7.22.20","@types/node":"18.6.5","karma-mocha":"2.0.1","webpack-cli":"4.10.0","@types/mocha":"10.0.3","@types/sinon":"10.0.20","karma-webpack":"4.0.2","webpack-merge":"5.9.0","karma-coverage":"2.2.1","@opentelemetry/api":">=1.3.0 <1.8.0","@types/lodash.merge":"4.6.8","karma-spec-reporter":"0.0.36","babel-plugin-istanbul":"6.1.1","karma-chrome-launcher":"3.1.0"},"peerDependencies":{"@opentelemetry/api":">=1.3.0 <1.8.0"},"_npmOperationalInternal":{"tmp":"tmp/sdk-metrics_1.18.0_1699353886784_0.2402177673494048","host":"s3://npm-registry-packages"}},"1.18.1":{"name":"@opentelemetry/sdk-metrics","version":"1.18.1","keywords":["opentelemetry","nodejs","metrics","stats","profiling"],"author":{"name":"OpenTelemetry Authors"},"license":"Apache-2.0","_id":"@opentelemetry/sdk-metrics@1.18.1","maintainers":[{"name":"pichlermarc","email":"marc.pichler@dynatrace.com"},{"name":"bogdandrutu","email":"bogdandrutu@gmail.com"},{"name":"dyladan","email":"dyladan@gmail.com"}],"homepage":"https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/sdk-metrics","bugs":{"url":"https://github.com/open-telemetry/opentelemetry-js/issues"},"dist":{"shasum":"1dd334744a1e5d2eec27e9e9765c73cd2f43aef3","tarball":"https://registry.npmjs.org/@opentelemetry/sdk-metrics/-/sdk-metrics-1.18.1.tgz","fileCount":561,"integrity":"sha512-TEFgeNFhdULBYiCoHbz31Y4PDsfjjxRp8Wmdp6ybLQZPqMNEb+dRq+XN8Xw3ivIgTaf9gYsomgV5ensX99RuEQ==","signatures":[{"sig":"MEUCIQDZiuGHcrjzMGF/TJ452D+P3TvNuhbyNQDLJOkdYsDPFQIgKtcP2GNoTjs9raH1wfRgj93Kw4tqRy7FLSmt98YetyQ=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":1892649},"main":"build/src/index.js","types":"build/src/index.d.ts","esnext":"build/esnext/index.js","module":"build/esm/index.js","engines":{"node":">=14"},"gitHead":"f665499096189390e691cf1a772e677fa67812d7","scripts":{"tdd":"npm run test -- --watch-extensions ts --watch","lint":"eslint . --ext .ts","test":"nyc ts-mocha -p tsconfig.json 'test/**/*.test.ts'","clean":"tsc --build --clean tsconfig.json tsconfig.esm.json tsconfig.esnext.json","watch":"tsc --build --watch tsconfig.json tsconfig.esm.json tsconfig.esnext.json","codecov":"nyc report --reporter=json && codecov -f coverage/*.json -p ../../","compile":"tsc --build tsconfig.json tsconfig.esm.json tsconfig.esnext.json","version":"node ../../scripts/version-update.js","lint:fix":"eslint . --ext .ts --fix","prewatch":"node ../../scripts/version-update.js","precompile":"cross-var lerna run version --scope $npm_package_name --include-dependencies","tdd:browser":"karma start","test:browser":"karma start --single-run","peer-api-check":"node ../../scripts/peer-api-check.js","prepublishOnly":"npm run compile"},"_npmUser":{"name":"pichlermarc","email":"marc.pichler@dynatrace.com"},"repository":{"url":"git+https://github.com/open-telemetry/opentelemetry-js.git","type":"git"},"_npmVersion":"lerna/6.6.2/node@v18.18.2+x64 (linux)","description":"OpenTelemetry metrics SDK","directories":{},"sideEffects":false,"_nodeVersion":"18.18.2","dependencies":{"lodash.merge":"^4.6.2","@opentelemetry/core":"1.18.1","@opentelemetry/resources":"1.18.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"nyc":"15.1.0","karma":"6.4.2","lerna":"6.6.2","mocha":"10.2.0","sinon":"15.1.2","codecov":"3.8.3","webpack":"4.46.0","ts-mocha":"10.0.0","cross-var":"1.1.0","ts-loader":"8.4.0","typescript":"4.4.4","@babel/core":"7.22.20","@types/node":"18.6.5","karma-mocha":"2.0.1","webpack-cli":"4.10.0","@types/mocha":"10.0.3","@types/sinon":"10.0.20","karma-webpack":"4.0.2","webpack-merge":"5.9.0","karma-coverage":"2.2.1","@opentelemetry/api":">=1.3.0 <1.8.0","@types/lodash.merge":"4.6.8","karma-spec-reporter":"0.0.36","babel-plugin-istanbul":"6.1.1","karma-chrome-launcher":"3.1.0"},"peerDependencies":{"@opentelemetry/api":">=1.3.0 <1.8.0"},"_npmOperationalInternal":{"tmp":"tmp/sdk-metrics_1.18.1_1699466949698_0.2731195093463463","host":"s3://npm-registry-packages"}},"1.19.0":{"name":"@opentelemetry/sdk-metrics","version":"1.19.0","keywords":["opentelemetry","nodejs","metrics","stats","profiling"],"author":{"name":"OpenTelemetry Authors"},"license":"Apache-2.0","_id":"@opentelemetry/sdk-metrics@1.19.0","maintainers":[{"name":"pichlermarc","email":"marc.pichler@dynatrace.com"},{"name":"bogdandrutu","email":"bogdandrutu@gmail.com"},{"name":"dyladan","email":"dyladan@gmail.com"}],"homepage":"https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/sdk-metrics","bugs":{"url":"https://github.com/open-telemetry/opentelemetry-js/issues"},"dist":{"shasum":"fe8029af29402563eb8dba75a85fc02006ea92c4","tarball":"https://registry.npmjs.org/@opentelemetry/sdk-metrics/-/sdk-metrics-1.19.0.tgz","fileCount":561,"integrity":"sha512-FiMii40zr0Fmys4F1i8gmuCvbinBnBsDeGBr4FQemOf0iPCLytYQm5AZJ/nn4xSc71IgKBQwTFQRAGJI7JvZ4Q==","signatures":[{"sig":"MEUCIQCQbl3KfCIEDQc8lHtdKlCRprXMXq1iqFxWHzS7fhRAMQIgOOpi/ti3SCJMstM0WHGr81bNA0QPpltVs/+OuHKDlyw=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":1892648},"main":"build/src/index.js","types":"build/src/index.d.ts","esnext":"build/esnext/index.js","module":"build/esm/index.js","engines":{"node":">=14"},"gitHead":"d3c311aec24137084dc820805a2597e120335672","scripts":{"tdd":"npm run test -- --watch-extensions ts --watch","lint":"eslint . --ext .ts","test":"nyc ts-mocha -p tsconfig.json 'test/**/*.test.ts'","clean":"tsc --build --clean tsconfig.json tsconfig.esm.json tsconfig.esnext.json","watch":"tsc --build --watch tsconfig.json tsconfig.esm.json tsconfig.esnext.json","codecov":"nyc report --reporter=json && codecov -f coverage/*.json -p ../../","compile":"tsc --build tsconfig.json tsconfig.esm.json tsconfig.esnext.json","version":"node ../../scripts/version-update.js","lint:fix":"eslint . --ext .ts --fix","prewatch":"node ../../scripts/version-update.js","precompile":"cross-var lerna run version --scope $npm_package_name --include-dependencies","tdd:browser":"karma start","test:browser":"karma start --single-run","peer-api-check":"node ../../scripts/peer-api-check.js","prepublishOnly":"npm run compile"},"_npmUser":{"name":"pichlermarc","email":"marc.pichler@dynatrace.com"},"repository":{"url":"git+https://github.com/open-telemetry/opentelemetry-js.git","type":"git"},"_npmVersion":"lerna/6.6.2/node@v18.18.2+x64 (linux)","description":"OpenTelemetry metrics SDK","directories":{},"sideEffects":false,"_nodeVersion":"18.18.2","dependencies":{"lodash.merge":"^4.6.2","@opentelemetry/core":"1.19.0","@opentelemetry/resources":"1.19.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"nyc":"15.1.0","karma":"6.4.2","lerna":"6.6.2","mocha":"10.2.0","sinon":"15.1.2","codecov":"3.8.3","webpack":"5.89.0","ts-mocha":"10.0.0","cross-var":"1.1.0","ts-loader":"8.4.0","typescript":"4.4.4","@babel/core":"7.23.6","@types/node":"18.6.5","karma-mocha":"2.0.1","webpack-cli":"5.1.4","@types/mocha":"10.0.6","@types/sinon":"10.0.20","karma-webpack":"4.0.2","webpack-merge":"5.10.0","karma-coverage":"2.2.1","@opentelemetry/api":">=1.3.0 <1.8.0","@types/lodash.merge":"4.6.9","karma-spec-reporter":"0.0.36","babel-plugin-istanbul":"6.1.1","karma-chrome-launcher":"3.1.0"},"peerDependencies":{"@opentelemetry/api":">=1.3.0 <1.8.0"},"_npmOperationalInternal":{"tmp":"tmp/sdk-metrics_1.19.0_1702557329935_0.360745159718469","host":"s3://npm-registry-packages"}},"1.20.0":{"name":"@opentelemetry/sdk-metrics","version":"1.20.0","keywords":["opentelemetry","nodejs","metrics","stats","profiling"],"author":{"name":"OpenTelemetry Authors"},"license":"Apache-2.0","_id":"@opentelemetry/sdk-metrics@1.20.0","maintainers":[{"name":"pichlermarc","email":"marc.pichler@dynatrace.com"},{"name":"bogdandrutu","email":"bogdandrutu@gmail.com"},{"name":"dyladan","email":"dyladan@gmail.com"}],"homepage":"https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/sdk-metrics","bugs":{"url":"https://github.com/open-telemetry/opentelemetry-js/issues"},"dist":{"shasum":"472d723d986a0a0cc1ee1170ed086dc18269d7e0","tarball":"https://registry.npmjs.org/@opentelemetry/sdk-metrics/-/sdk-metrics-1.20.0.tgz","fileCount":561,"integrity":"sha512-07bFOQUrpN/Q5biJ/cuBePztKwkc1VGkFblZxAcVkuvCLDAPJfsyr0NNWegWeYe0bpGt1jmXScpUWnVD+t8Q0w==","signatures":[{"sig":"MEUCIC3XY/+kezXMIGl3icXMEXdu0pKWhpKhJ7kpzNi6cW5lAiEAtKlujqgWTX99ep+IDoNQKi5a4BEjbPjw6yGUGzBa6hU=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":1892648},"main":"build/src/index.js","types":"build/src/index.d.ts","esnext":"build/esnext/index.js","module":"build/esm/index.js","engines":{"node":">=14"},"gitHead":"57008533aba7ccd51ea80f38ff4f29404d47eb9c","scripts":{"tdd":"npm run test -- --watch-extensions ts --watch","lint":"eslint . --ext .ts","test":"nyc ts-mocha -p tsconfig.json 'test/**/*.test.ts'","clean":"tsc --build --clean tsconfig.json tsconfig.esm.json tsconfig.esnext.json","watch":"tsc --build --watch tsconfig.json tsconfig.esm.json tsconfig.esnext.json","codecov":"nyc report --reporter=json && codecov -f coverage/*.json -p ../../","compile":"tsc --build tsconfig.json tsconfig.esm.json tsconfig.esnext.json","version":"node ../../scripts/version-update.js","lint:fix":"eslint . --ext .ts --fix","prewatch":"node ../../scripts/version-update.js","precompile":"cross-var lerna run version --scope $npm_package_name --include-dependencies","tdd:browser":"karma start","test:browser":"karma start --single-run","peer-api-check":"node ../../scripts/peer-api-check.js","prepublishOnly":"npm run compile"},"_npmUser":{"name":"pichlermarc","email":"marc.pichler@dynatrace.com"},"repository":{"url":"git+https://github.com/open-telemetry/opentelemetry-js.git","type":"git"},"_npmVersion":"lerna/6.6.2/node@v18.19.0+x64 (linux)","description":"OpenTelemetry metrics SDK","directories":{},"sideEffects":false,"_nodeVersion":"18.19.0","dependencies":{"lodash.merge":"^4.6.2","@opentelemetry/core":"1.20.0","@opentelemetry/resources":"1.20.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"nyc":"15.1.0","karma":"6.4.2","lerna":"6.6.2","mocha":"10.2.0","sinon":"15.1.2","codecov":"3.8.3","webpack":"5.89.0","ts-mocha":"10.0.0","cross-var":"1.1.0","ts-loader":"8.4.0","typescript":"4.4.4","@babel/core":"7.23.6","@types/node":"18.6.5","karma-mocha":"2.0.1","webpack-cli":"5.1.4","@types/mocha":"10.0.6","@types/sinon":"10.0.20","karma-webpack":"4.0.2","webpack-merge":"5.10.0","karma-coverage":"2.2.1","@opentelemetry/api":">=1.3.0 <1.8.0","@types/lodash.merge":"4.6.9","karma-spec-reporter":"0.0.36","babel-plugin-istanbul":"6.1.1","karma-chrome-launcher":"3.1.0"},"peerDependencies":{"@opentelemetry/api":">=1.3.0 <1.8.0"},"_npmOperationalInternal":{"tmp":"tmp/sdk-metrics_1.20.0_1705313747415_0.3264673460411951","host":"s3://npm-registry-packages"}},"1.21.0":{"name":"@opentelemetry/sdk-metrics","version":"1.21.0","keywords":["opentelemetry","nodejs","metrics","stats","profiling"],"author":{"name":"OpenTelemetry Authors"},"license":"Apache-2.0","_id":"@opentelemetry/sdk-metrics@1.21.0","maintainers":[{"name":"pichlermarc","email":"marc.pichler@dynatrace.com"},{"name":"bogdandrutu","email":"bogdandrutu@gmail.com"},{"name":"dyladan","email":"dyladan@gmail.com"}],"homepage":"https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/sdk-metrics","bugs":{"url":"https://github.com/open-telemetry/opentelemetry-js/issues"},"dist":{"shasum":"40d71aaec5b696e58743889ce6d5bf2593f9a23d","tarball":"https://registry.npmjs.org/@opentelemetry/sdk-metrics/-/sdk-metrics-1.21.0.tgz","fileCount":561,"integrity":"sha512-on1jTzIHc5DyWhRP+xpf+zrgrREXcHBH4EDAfaB5mIG7TWpKxNXooQ1JCylaPsswZUv4wGnVTinr4HrBdGARAQ==","signatures":[{"sig":"MEQCIGpBDMhU8lTH5TE6aUTa3/f+ZAAJNZyvJR4W+y34uKgyAiA9nbAm4W2G9iFlp1OSXMtF3+Qs3M8RTAz9dMzR/gPTXA==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":1898573},"main":"build/src/index.js","types":"build/src/index.d.ts","esnext":"build/esnext/index.js","module":"build/esm/index.js","engines":{"node":">=14"},"gitHead":"828f2ed730e4d26d71f92e220f96b60a552a673a","scripts":{"tdd":"npm run test -- --watch-extensions ts --watch","lint":"eslint . --ext .ts","test":"nyc ts-mocha -p tsconfig.json 'test/**/*.test.ts'","clean":"tsc --build --clean tsconfig.json tsconfig.esm.json tsconfig.esnext.json","watch":"tsc --build --watch tsconfig.json tsconfig.esm.json tsconfig.esnext.json","codecov":"nyc report --reporter=json && codecov -f coverage/*.json -p ../../","compile":"tsc --build tsconfig.json tsconfig.esm.json tsconfig.esnext.json","version":"node ../../scripts/version-update.js","lint:fix":"eslint . --ext .ts --fix","prewatch":"node ../../scripts/version-update.js","precompile":"cross-var lerna run version --scope $npm_package_name --include-dependencies","tdd:browser":"karma start","test:browser":"karma start --single-run","peer-api-check":"node ../../scripts/peer-api-check.js","prepublishOnly":"npm run compile"},"_npmUser":{"name":"pichlermarc","email":"marc.pichler@dynatrace.com"},"repository":{"url":"git+https://github.com/open-telemetry/opentelemetry-js.git","type":"git"},"_npmVersion":"lerna/6.6.2/node@v18.19.0+x64 (linux)","description":"OpenTelemetry metrics SDK","directories":{},"sideEffects":false,"_nodeVersion":"18.19.0","dependencies":{"lodash.merge":"^4.6.2","@opentelemetry/core":"1.21.0","@opentelemetry/resources":"1.21.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"nyc":"15.1.0","karma":"6.4.2","lerna":"6.6.2","mocha":"10.2.0","sinon":"15.1.2","codecov":"3.8.3","webpack":"5.89.0","ts-mocha":"10.0.0","cross-var":"1.1.0","ts-loader":"8.4.0","typescript":"4.4.4","@babel/core":"7.23.6","@types/node":"18.6.5","karma-mocha":"2.0.1","webpack-cli":"5.1.4","@types/mocha":"10.0.6","@types/sinon":"10.0.20","karma-webpack":"4.0.2","webpack-merge":"5.10.0","karma-coverage":"2.2.1","@babel/preset-env":"7.22.20","@opentelemetry/api":">=1.3.0 <1.8.0","@types/lodash.merge":"4.6.9","karma-spec-reporter":"0.0.36","babel-plugin-istanbul":"6.1.1","karma-chrome-launcher":"3.1.0"},"peerDependencies":{"@opentelemetry/api":">=1.3.0 <1.8.0"},"_npmOperationalInternal":{"tmp":"tmp/sdk-metrics_1.21.0_1706249469816_0.2681154592027921","host":"s3://npm-registry-packages"}},"1.22.0":{"name":"@opentelemetry/sdk-metrics","version":"1.22.0","keywords":["opentelemetry","nodejs","metrics","stats","profiling"],"author":{"name":"OpenTelemetry Authors"},"license":"Apache-2.0","_id":"@opentelemetry/sdk-metrics@1.22.0","maintainers":[{"name":"pichlermarc","email":"marc.pichler@dynatrace.com"},{"name":"bogdandrutu","email":"bogdandrutu@gmail.com"},{"name":"dyladan","email":"dyladan@gmail.com"}],"homepage":"https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/sdk-metrics","bugs":{"url":"https://github.com/open-telemetry/opentelemetry-js/issues"},"dist":{"shasum":"b94c62403013e4c72b96dc747d71d786073efafc","tarball":"https://registry.npmjs.org/@opentelemetry/sdk-metrics/-/sdk-metrics-1.22.0.tgz","fileCount":561,"integrity":"sha512-k6iIx6H3TZ+BVMr2z8M16ri2OxWaljg5h8ihGJxi/KQWcjign6FEaEzuigXt5bK9wVEhqAcWLCfarSftaNWkkg==","signatures":[{"sig":"MEUCIQDNXgVv9Uxbxg3/33/6F66wijwbwDd7GOiqKURWpli14gIgE4NQsN1CjuPkQcHMyQ25CAKybwbYPJODQxdspPHt3+E=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":1903538},"main":"build/src/index.js","types":"build/src/index.d.ts","esnext":"build/esnext/index.js","module":"build/esm/index.js","engines":{"node":">=14"},"gitHead":"7be35c7845e206b27b682e8ce1cee850b09cec04","scripts":{"tdd":"npm run test -- --watch-extensions ts --watch","lint":"eslint . --ext .ts","test":"nyc ts-mocha -p tsconfig.json 'test/**/*.test.ts'","clean":"tsc --build --clean tsconfig.json tsconfig.esm.json tsconfig.esnext.json","watch":"tsc --build --watch tsconfig.json tsconfig.esm.json tsconfig.esnext.json","codecov":"nyc report --reporter=json && codecov -f coverage/*.json -p ../../","compile":"tsc --build tsconfig.json tsconfig.esm.json tsconfig.esnext.json","version":"node ../../scripts/version-update.js","lint:fix":"eslint . --ext .ts --fix","prewatch":"node ../../scripts/version-update.js","precompile":"cross-var lerna run version --scope $npm_package_name --include-dependencies","tdd:browser":"karma start","test:browser":"karma start --single-run","peer-api-check":"node ../../scripts/peer-api-check.js","prepublishOnly":"npm run compile"},"_npmUser":{"name":"pichlermarc","email":"marc.pichler@dynatrace.com"},"repository":{"url":"git+https://github.com/open-telemetry/opentelemetry-js.git","type":"git"},"_npmVersion":"lerna/6.6.2/node@v18.19.0+x64 (linux)","description":"OpenTelemetry metrics SDK","directories":{},"sideEffects":false,"_nodeVersion":"18.19.0","dependencies":{"lodash.merge":"^4.6.2","@opentelemetry/core":"1.22.0","@opentelemetry/resources":"1.22.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"nyc":"15.1.0","karma":"6.4.2","lerna":"6.6.2","mocha":"10.2.0","sinon":"15.1.2","codecov":"3.8.3","webpack":"5.89.0","ts-mocha":"10.0.0","cross-var":"1.1.0","ts-loader":"8.4.0","typescript":"4.4.4","@babel/core":"7.23.6","@types/node":"18.6.5","karma-mocha":"2.0.1","webpack-cli":"5.1.4","@types/mocha":"10.0.6","@types/sinon":"10.0.20","karma-webpack":"4.0.2","webpack-merge":"5.10.0","karma-coverage":"2.2.1","@babel/preset-env":"7.22.20","@opentelemetry/api":">=1.3.0 <1.9.0","@types/lodash.merge":"4.6.9","karma-spec-reporter":"0.0.36","babel-plugin-istanbul":"6.1.1","karma-chrome-launcher":"3.1.0"},"peerDependencies":{"@opentelemetry/api":">=1.3.0 <1.9.0"},"_npmOperationalInternal":{"tmp":"tmp/sdk-metrics_1.22.0_1709198294535_0.21078722486314505","host":"s3://npm-registry-packages"}},"1.23.0":{"name":"@opentelemetry/sdk-metrics","version":"1.23.0","keywords":["opentelemetry","nodejs","metrics","stats","profiling"],"author":{"name":"OpenTelemetry Authors"},"license":"Apache-2.0","_id":"@opentelemetry/sdk-metrics@1.23.0","maintainers":[{"name":"pichlermarc","email":"marc.pichler@dynatrace.com"},{"name":"bogdandrutu","email":"bogdandrutu@gmail.com"},{"name":"dyladan","email":"dyladan@gmail.com"}],"homepage":"https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/sdk-metrics","bugs":{"url":"https://github.com/open-telemetry/opentelemetry-js/issues"},"dist":{"shasum":"b4cf3cc86b6dedf5c438c67c829df7399bf64be1","tarball":"https://registry.npmjs.org/@opentelemetry/sdk-metrics/-/sdk-metrics-1.23.0.tgz","fileCount":561,"integrity":"sha512-4OkvW6+wST4h6LFG23rXSTf6nmTf201h9dzq7bE0z5R9ESEVLERZz6WXwE7PSgg1gdjlaznm1jLJf8GttypFDg==","signatures":[{"sig":"MEUCIQCRviOtBHY4cxAbFmlSe5/d1UlZwJANaHyzFmHvAstAfgIgcfcrCMSSgbzKnYncXB5RxmguAOFxcmRGxTgWETblVvM=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":1914895},"main":"build/src/index.js","types":"build/src/index.d.ts","esnext":"build/esnext/index.js","module":"build/esm/index.js","engines":{"node":">=14"},"gitHead":"5231aa255047fbc6ee3d6a299f4423ab2f8a5fbc","scripts":{"tdd":"npm run test -- --watch-extensions ts --watch","lint":"eslint . --ext .ts","test":"nyc ts-mocha -p tsconfig.json 'test/**/*.test.ts'","clean":"tsc --build --clean tsconfig.json tsconfig.esm.json tsconfig.esnext.json","watch":"tsc --build --watch tsconfig.json tsconfig.esm.json tsconfig.esnext.json","codecov":"nyc report --reporter=json && codecov -f coverage/*.json -p ../../","compile":"tsc --build tsconfig.json tsconfig.esm.json tsconfig.esnext.json","version":"node ../../scripts/version-update.js","lint:fix":"eslint . --ext .ts --fix","prewatch":"node ../../scripts/version-update.js","precompile":"cross-var lerna run version --scope $npm_package_name --include-dependencies","tdd:browser":"karma start","test:browser":"karma start --single-run","peer-api-check":"node ../../scripts/peer-api-check.js","prepublishOnly":"npm run compile"},"_npmUser":{"name":"pichlermarc","email":"marc.pichler@dynatrace.com"},"repository":{"url":"git+https://github.com/open-telemetry/opentelemetry-js.git","type":"git"},"_npmVersion":"lerna/6.6.2/node@v18.19.0+x64 (linux)","description":"OpenTelemetry metrics SDK","directories":{},"sideEffects":false,"_nodeVersion":"18.19.0","dependencies":{"lodash.merge":"^4.6.2","@opentelemetry/core":"1.23.0","@opentelemetry/resources":"1.23.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"nyc":"15.1.0","karma":"6.4.2","lerna":"6.6.2","mocha":"10.2.0","sinon":"15.1.2","codecov":"3.8.3","webpack":"5.89.0","ts-mocha":"10.0.0","cross-var":"1.1.0","ts-loader":"8.4.0","typescript":"4.4.4","@babel/core":"7.23.6","@types/node":"18.6.5","karma-mocha":"2.0.1","webpack-cli":"5.1.4","@types/mocha":"10.0.6","@types/sinon":"10.0.20","karma-webpack":"4.0.2","webpack-merge":"5.10.0","karma-coverage":"2.2.1","@babel/preset-env":"7.22.20","@opentelemetry/api":">=1.3.0 <1.9.0","@types/lodash.merge":"4.6.9","karma-spec-reporter":"0.0.36","babel-plugin-istanbul":"6.1.1","karma-chrome-launcher":"3.1.0"},"peerDependencies":{"@opentelemetry/api":">=1.3.0 <1.9.0"},"_npmOperationalInternal":{"tmp":"tmp/sdk-metrics_1.23.0_1712131805787_0.6556898049242013","host":"s3://npm-registry-packages"}},"1.24.0":{"name":"@opentelemetry/sdk-metrics","version":"1.24.0","keywords":["opentelemetry","nodejs","metrics","stats","profiling"],"author":{"name":"OpenTelemetry Authors"},"license":"Apache-2.0","_id":"@opentelemetry/sdk-metrics@1.24.0","maintainers":[{"name":"pichlermarc","email":"marc.pichler@dynatrace.com"},{"name":"bogdandrutu","email":"bogdandrutu@gmail.com"},{"name":"dyladan","email":"dyladan@gmail.com"}],"homepage":"https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/sdk-metrics","bugs":{"url":"https://github.com/open-telemetry/opentelemetry-js/issues"},"dist":{"shasum":"205c19b6d18e385039d0a261c784a203c644fc28","tarball":"https://registry.npmjs.org/@opentelemetry/sdk-metrics/-/sdk-metrics-1.24.0.tgz","fileCount":561,"integrity":"sha512-4tJ+E6N019OZVB/nUW/LoK9xHxfeh88TCoaTqHeLBE9wLYfi6irWW6J9cphMav7J8Qk0D5b7/RM4VEY4dArWOA==","signatures":[{"sig":"MEUCIFw7C6N1PHTi2sUnPwYd6pb4MEYB0sdDPAfLyVHSEEL0AiEAhRBkWnU/RMsb1e2pd8JuT67Zi9eH87TbDc40JN74Plg=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":1914895},"main":"build/src/index.js","types":"build/src/index.d.ts","esnext":"build/esnext/index.js","module":"build/esm/index.js","engines":{"node":">=14"},"gitHead":"3ab4f765d8d696327b7d139ae6a45e7bd7edd924","scripts":{"tdd":"npm run test -- --watch-extensions ts --watch","lint":"eslint . --ext .ts","test":"nyc ts-mocha -p tsconfig.json 'test/**/*.test.ts'","clean":"tsc --build --clean tsconfig.json tsconfig.esm.json tsconfig.esnext.json","watch":"tsc --build --watch tsconfig.json tsconfig.esm.json tsconfig.esnext.json","codecov":"nyc report --reporter=json && codecov -f coverage/*.json -p ../../","compile":"tsc --build tsconfig.json tsconfig.esm.json tsconfig.esnext.json","version":"node ../../scripts/version-update.js","lint:fix":"eslint . --ext .ts --fix","prewatch":"node ../../scripts/version-update.js","precompile":"cross-var lerna run version --scope $npm_package_name --include-dependencies","tdd:browser":"karma start","test:browser":"karma start --single-run","peer-api-check":"node ../../scripts/peer-api-check.js","prepublishOnly":"npm run compile"},"_npmUser":{"name":"pichlermarc","email":"marc.pichler@dynatrace.com"},"repository":{"url":"git+https://github.com/open-telemetry/opentelemetry-js.git","type":"git"},"_npmVersion":"lerna/6.6.2/node@v18.19.0+x64 (linux)","description":"OpenTelemetry metrics SDK","directories":{},"sideEffects":false,"_nodeVersion":"18.19.0","dependencies":{"lodash.merge":"^4.6.2","@opentelemetry/core":"1.24.0","@opentelemetry/resources":"1.24.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"nyc":"15.1.0","karma":"6.4.2","lerna":"6.6.2","mocha":"10.2.0","sinon":"15.1.2","codecov":"3.8.3","webpack":"5.89.0","ts-mocha":"10.0.0","cross-var":"1.1.0","ts-loader":"8.4.0","typescript":"4.4.4","@babel/core":"7.23.6","@types/node":"18.6.5","karma-mocha":"2.0.1","webpack-cli":"5.1.4","@types/mocha":"10.0.6","@types/sinon":"10.0.20","karma-webpack":"4.0.2","webpack-merge":"5.10.0","karma-coverage":"2.2.1","@babel/preset-env":"7.22.20","@opentelemetry/api":">=1.3.0 <1.9.0","@types/lodash.merge":"4.6.9","karma-spec-reporter":"0.0.36","babel-plugin-istanbul":"6.1.1","karma-chrome-launcher":"3.1.0"},"peerDependencies":{"@opentelemetry/api":">=1.3.0 <1.9.0"},"_npmOperationalInternal":{"tmp":"tmp/sdk-metrics_1.24.0_1713969585182_0.37633556794494494","host":"s3://npm-registry-packages"}},"1.24.1":{"name":"@opentelemetry/sdk-metrics","version":"1.24.1","keywords":["opentelemetry","nodejs","metrics","stats","profiling"],"author":{"name":"OpenTelemetry Authors"},"license":"Apache-2.0","_id":"@opentelemetry/sdk-metrics@1.24.1","maintainers":[{"name":"pichlermarc","email":"marc.pichler@dynatrace.com"},{"name":"bogdandrutu","email":"bogdandrutu@gmail.com"},{"name":"dyladan","email":"dyladan@gmail.com"}],"homepage":"https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/sdk-metrics","bugs":{"url":"https://github.com/open-telemetry/opentelemetry-js/issues"},"dist":{"shasum":"82ee3069b2ca9bb7c1e91272ff81536dc2e9bc8d","tarball":"https://registry.npmjs.org/@opentelemetry/sdk-metrics/-/sdk-metrics-1.24.1.tgz","fileCount":561,"integrity":"sha512-FrAqCbbGao9iKI+Mgh+OsC9+U2YMoXnlDHe06yH7dvavCKzE3S892dGtX54+WhSFVxHR/TMRVJiK/CV93GR0TQ==","signatures":[{"sig":"MEUCIQCTMSUw6bs+C6f+azmvQBAAOS2F2zkdYmTaUA0WsSSESgIgVgEsIIBcrrCeUZGl8a4ziCe01KmMiEcyeTk5/btVJww=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":1914895},"main":"build/src/index.js","types":"build/src/index.d.ts","esnext":"build/esnext/index.js","module":"build/esm/index.js","engines":{"node":">=14"},"gitHead":"41c2626fe0ed03e2e83bd79ee43c9bdf0ffd80d8","scripts":{"tdd":"npm run test -- --watch-extensions ts --watch","lint":"eslint . --ext .ts","test":"nyc ts-mocha -p tsconfig.json 'test/**/*.test.ts'","clean":"tsc --build --clean tsconfig.json tsconfig.esm.json tsconfig.esnext.json","watch":"tsc --build --watch tsconfig.json tsconfig.esm.json tsconfig.esnext.json","codecov":"nyc report --reporter=json && codecov -f coverage/*.json -p ../../","compile":"tsc --build tsconfig.json tsconfig.esm.json tsconfig.esnext.json","version":"node ../../scripts/version-update.js","lint:fix":"eslint . --ext .ts --fix","prewatch":"node ../../scripts/version-update.js","precompile":"cross-var lerna run version --scope $npm_package_name --include-dependencies","tdd:browser":"karma start","test:browser":"karma start --single-run","peer-api-check":"node ../../scripts/peer-api-check.js","prepublishOnly":"npm run compile"},"_npmUser":{"name":"pichlermarc","email":"marc.pichler@dynatrace.com"},"repository":{"url":"git+https://github.com/open-telemetry/opentelemetry-js.git","type":"git"},"_npmVersion":"lerna/6.6.2/node@v18.19.0+x64 (linux)","description":"OpenTelemetry metrics SDK","directories":{},"sideEffects":false,"_nodeVersion":"18.19.0","dependencies":{"lodash.merge":"^4.6.2","@opentelemetry/core":"1.24.1","@opentelemetry/resources":"1.24.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"nyc":"15.1.0","karma":"6.4.2","lerna":"6.6.2","mocha":"10.2.0","sinon":"15.1.2","codecov":"3.8.3","webpack":"5.89.0","ts-mocha":"10.0.0","cross-var":"1.1.0","ts-loader":"8.4.0","typescript":"4.4.4","@babel/core":"7.23.6","@types/node":"18.6.5","karma-mocha":"2.0.1","webpack-cli":"5.1.4","@types/mocha":"10.0.6","@types/sinon":"10.0.20","karma-webpack":"4.0.2","webpack-merge":"5.10.0","karma-coverage":"2.2.1","@babel/preset-env":"7.22.20","@opentelemetry/api":">=1.3.0 <1.9.0","@types/lodash.merge":"4.6.9","karma-spec-reporter":"0.0.36","babel-plugin-istanbul":"6.1.1","karma-chrome-launcher":"3.1.0"},"peerDependencies":{"@opentelemetry/api":">=1.3.0 <1.9.0"},"_npmOperationalInternal":{"tmp":"tmp/sdk-metrics_1.24.1_1715093558847_0.03178144750682588","host":"s3://npm-registry-packages"}},"1.25.0":{"name":"@opentelemetry/sdk-metrics","version":"1.25.0","keywords":["opentelemetry","nodejs","metrics","stats","profiling"],"author":{"name":"OpenTelemetry Authors"},"license":"Apache-2.0","_id":"@opentelemetry/sdk-metrics@1.25.0","maintainers":[{"name":"pichlermarc","email":"marc.pichler@dynatrace.com"},{"name":"bogdandrutu","email":"bogdandrutu@gmail.com"},{"name":"dyladan","email":"dyladan@gmail.com"}],"homepage":"https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/sdk-metrics","bugs":{"url":"https://github.com/open-telemetry/opentelemetry-js/issues"},"dist":{"shasum":"0c954d580c17821ae4385d29447718df09e80b79","tarball":"https://registry.npmjs.org/@opentelemetry/sdk-metrics/-/sdk-metrics-1.25.0.tgz","fileCount":561,"integrity":"sha512-IF+Sv4VHgBr/BPMKabl+GouJIhEqAOexCHgXVTISdz3q9P9H/uA8ScCF+22gitQ69aFtESbdYOV+Fen5+avQng==","signatures":[{"sig":"MEUCIQCTGV0/dFktbxE5zP6XFH0Eu0/cZ7CGkU7c5BAAq4CVjAIgG3QIuMsMnEWURsoo1SS0GKQqtBcHiCbSGaaBzrbsXaE=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":1914152},"main":"build/src/index.js","types":"build/src/index.d.ts","esnext":"build/esnext/index.js","module":"build/esm/index.js","engines":{"node":">=14"},"gitHead":"c4d3351b6b3f5593c8d7cbfec97b45cea9fe1511","scripts":{"tdd":"npm run test -- --watch-extensions ts --watch","lint":"eslint . --ext .ts","test":"nyc ts-mocha -p tsconfig.json 'test/**/*.test.ts'","clean":"tsc --build --clean tsconfig.json tsconfig.esm.json tsconfig.esnext.json","watch":"tsc --build --watch tsconfig.json tsconfig.esm.json tsconfig.esnext.json","codecov":"nyc report --reporter=json && codecov -f coverage/*.json -p ../../","compile":"tsc --build tsconfig.json tsconfig.esm.json tsconfig.esnext.json","version":"node ../../scripts/version-update.js","lint:fix":"eslint . --ext .ts --fix","prewatch":"node ../../scripts/version-update.js","precompile":"cross-var lerna run version --scope $npm_package_name --include-dependencies","tdd:browser":"karma start","test:browser":"karma start --single-run","align-api-deps":"node ../../scripts/align-api-deps.js","peer-api-check":"node ../../scripts/peer-api-check.js","prepublishOnly":"npm run compile"},"_npmUser":{"name":"pichlermarc","email":"marc.pichler@dynatrace.com"},"repository":{"url":"git+https://github.com/open-telemetry/opentelemetry-js.git","type":"git"},"_npmVersion":"lerna/6.6.2/node@v18.19.0+x64 (linux)","description":"OpenTelemetry metrics SDK","directories":{},"sideEffects":false,"_nodeVersion":"18.19.0","dependencies":{"lodash.merge":"^4.6.2","@opentelemetry/core":"1.25.0","@opentelemetry/resources":"1.25.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"nyc":"15.1.0","karma":"6.4.3","lerna":"6.6.2","mocha":"10.2.0","sinon":"15.1.2","codecov":"3.8.3","webpack":"5.89.0","ts-mocha":"10.0.0","cross-var":"1.1.0","ts-loader":"9.5.1","typescript":"4.4.4","@babel/core":"7.24.6","@types/node":"18.6.5","karma-mocha":"2.0.1","webpack-cli":"5.1.4","@types/mocha":"10.0.6","@types/sinon":"17.0.3","karma-webpack":"5.0.1","webpack-merge":"5.10.0","karma-coverage":"2.2.1","@babel/preset-env":"7.24.6","@opentelemetry/api":">=1.3.0 <1.10.0","@types/lodash.merge":"4.6.9","karma-spec-reporter":"0.0.36","babel-plugin-istanbul":"6.1.1","karma-chrome-launcher":"3.1.0"},"peerDependencies":{"@opentelemetry/api":">=1.3.0 <1.10.0"},"_npmOperationalInternal":{"tmp":"tmp/sdk-metrics_1.25.0_1717607758345_0.42159719696026543","host":"s3://npm-registry-packages"}},"1.25.1":{"name":"@opentelemetry/sdk-metrics","version":"1.25.1","keywords":["opentelemetry","nodejs","metrics","stats","profiling"],"author":{"name":"OpenTelemetry Authors"},"license":"Apache-2.0","_id":"@opentelemetry/sdk-metrics@1.25.1","maintainers":[{"name":"pichlermarc","email":"marc.pichler@dynatrace.com"},{"name":"bogdandrutu","email":"bogdandrutu@gmail.com"},{"name":"dyladan","email":"dyladan@gmail.com"}],"homepage":"https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/sdk-metrics","bugs":{"url":"https://github.com/open-telemetry/opentelemetry-js/issues"},"dist":{"shasum":"50c985ec15557a9654334e7fa1018dc47a8a56b7","tarball":"https://registry.npmjs.org/@opentelemetry/sdk-metrics/-/sdk-metrics-1.25.1.tgz","fileCount":561,"integrity":"sha512-9Mb7q5ioFL4E4dDrc4wC/A3NTHDat44v4I3p2pLPSxRvqUbDIQyMVr9uK+EU69+HWhlET1VaSrRzwdckWqY15Q==","signatures":[{"sig":"MEUCIQCNZXU0MM/EDXNSq8ZV/6psCW97vGmYrurc/e/iYg7LOAIgS3/fl7W9LtXeIauAqM5ZL24hsmc39zaKuX+90I3Edn8=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":1914152},"main":"build/src/index.js","types":"build/src/index.d.ts","esnext":"build/esnext/index.js","module":"build/esm/index.js","engines":{"node":">=14"},"gitHead":"0608f405573901e54db01e44c533009cf28be262","scripts":{"tdd":"npm run test -- --watch-extensions ts --watch","lint":"eslint . --ext .ts","test":"nyc ts-mocha -p tsconfig.json 'test/**/*.test.ts'","clean":"tsc --build --clean tsconfig.json tsconfig.esm.json tsconfig.esnext.json","watch":"tsc --build --watch tsconfig.json tsconfig.esm.json tsconfig.esnext.json","codecov":"nyc report --reporter=json && codecov -f coverage/*.json -p ../../","compile":"tsc --build tsconfig.json tsconfig.esm.json tsconfig.esnext.json","version":"node ../../scripts/version-update.js","lint:fix":"eslint . --ext .ts --fix","prewatch":"node ../../scripts/version-update.js","precompile":"cross-var lerna run version --scope $npm_package_name --include-dependencies","tdd:browser":"karma start","test:browser":"karma start --single-run","align-api-deps":"node ../../scripts/align-api-deps.js","peer-api-check":"node ../../scripts/peer-api-check.js","prepublishOnly":"npm run compile"},"_npmUser":{"name":"pichlermarc","email":"marc.pichler@dynatrace.com"},"repository":{"url":"git+https://github.com/open-telemetry/opentelemetry-js.git","type":"git"},"_npmVersion":"lerna/6.6.2/node@v18.19.0+x64 (linux)","description":"OpenTelemetry metrics SDK","directories":{},"sideEffects":false,"_nodeVersion":"18.19.0","dependencies":{"lodash.merge":"^4.6.2","@opentelemetry/core":"1.25.1","@opentelemetry/resources":"1.25.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"nyc":"15.1.0","karma":"6.4.3","lerna":"6.6.2","mocha":"10.2.0","sinon":"15.1.2","codecov":"3.8.3","webpack":"5.89.0","ts-mocha":"10.0.0","cross-var":"1.1.0","ts-loader":"9.5.1","typescript":"4.4.4","@babel/core":"7.24.7","@types/node":"18.6.5","karma-mocha":"2.0.1","webpack-cli":"5.1.4","@types/mocha":"10.0.6","@types/sinon":"17.0.3","karma-webpack":"5.0.1","webpack-merge":"5.10.0","karma-coverage":"2.2.1","@babel/preset-env":"7.24.7","@opentelemetry/api":">=1.3.0 <1.10.0","@types/lodash.merge":"4.6.9","karma-spec-reporter":"0.0.36","babel-plugin-istanbul":"6.1.1","karma-chrome-launcher":"3.1.0"},"peerDependencies":{"@opentelemetry/api":">=1.3.0 <1.10.0"},"_npmOperationalInternal":{"tmp":"tmp/sdk-metrics_1.25.1_1718875163722_0.02638450999168529","host":"s3://npm-registry-packages"}},"1.26.0":{"name":"@opentelemetry/sdk-metrics","version":"1.26.0","keywords":["opentelemetry","nodejs","metrics","stats","profiling"],"author":{"name":"OpenTelemetry Authors"},"license":"Apache-2.0","_id":"@opentelemetry/sdk-metrics@1.26.0","maintainers":[{"name":"pichlermarc","email":"marc.pichler@dynatrace.com"},{"name":"bogdandrutu","email":"bogdandrutu@gmail.com"},{"name":"dyladan","email":"dyladan@gmail.com"}],"homepage":"https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/sdk-metrics","bugs":{"url":"https://github.com/open-telemetry/opentelemetry-js/issues"},"dist":{"shasum":"37bb0afb1d4447f50aab9cdd05db6f2d8b86103e","tarball":"https://registry.npmjs.org/@opentelemetry/sdk-metrics/-/sdk-metrics-1.26.0.tgz","fileCount":561,"integrity":"sha512-0SvDXmou/JjzSDOjUmetAAvcKQW6ZrvosU0rkbDGpXvvZN+pQF6JbK/Kd4hNdK4q/22yeruqvukXEJyySTzyTQ==","signatures":[{"sig":"MEQCICUUc6/yySv2TiNLcq7AT6pbNR/Hi6zEZwTkoKabjKDXAiBJffQVgekh2F9ABx6OLgxEpstV/+ZyN55vBGwjKtK3bg==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":1922196},"main":"build/src/index.js","types":"build/src/index.d.ts","esnext":"build/esnext/index.js","module":"build/esm/index.js","engines":{"node":">=14"},"gitHead":"720bc8c70d47029cb6b41a34ffdc3d25cbaa2f80","scripts":{"tdd":"npm run test -- --watch-extensions ts --watch","lint":"eslint . --ext .ts","test":"nyc mocha 'test/**/*.test.ts'","clean":"tsc --build --clean tsconfig.json tsconfig.esm.json tsconfig.esnext.json","watch":"tsc --build --watch tsconfig.json tsconfig.esm.json tsconfig.esnext.json","codecov":"nyc report --reporter=json && codecov -f coverage/*.json -p ../../","compile":"tsc --build tsconfig.json tsconfig.esm.json tsconfig.esnext.json","version":"node ../../scripts/version-update.js","lint:fix":"eslint . --ext .ts --fix","prewatch":"node ../../scripts/version-update.js","precompile":"cross-var lerna run version --scope $npm_package_name --include-dependencies","tdd:browser":"karma start","test:browser":"karma start --single-run","align-api-deps":"node ../../scripts/align-api-deps.js","peer-api-check":"node ../../scripts/peer-api-check.js","prepublishOnly":"npm run compile"},"_npmUser":{"name":"pichlermarc","email":"marc.pichler@dynatrace.com"},"repository":{"url":"git+https://github.com/open-telemetry/opentelemetry-js.git","type":"git"},"_npmVersion":"lerna/6.6.2/node@v18.20.4+x64 (linux)","description":"OpenTelemetry metrics SDK","directories":{},"sideEffects":false,"_nodeVersion":"18.20.4","dependencies":{"@opentelemetry/core":"1.26.0","@opentelemetry/resources":"1.26.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"nyc":"15.1.0","karma":"6.4.4","lerna":"6.6.2","mocha":"10.7.3","sinon":"15.1.2","codecov":"3.8.3","webpack":"5.89.0","cross-var":"1.1.0","ts-loader":"9.5.1","typescript":"4.4.4","@babel/core":"7.25.2","@types/node":"18.6.5","karma-mocha":"2.0.1","webpack-cli":"5.1.4","@types/mocha":"10.0.7","@types/sinon":"17.0.3","karma-webpack":"5.0.1","webpack-merge":"5.10.0","karma-coverage":"2.2.1","@babel/preset-env":"7.25.3","@opentelemetry/api":">=1.3.0 <1.10.0","karma-spec-reporter":"0.0.36","babel-plugin-istanbul":"7.0.0","karma-chrome-launcher":"3.1.0"},"peerDependencies":{"@opentelemetry/api":">=1.3.0 <1.10.0"},"_npmOperationalInternal":{"tmp":"tmp/sdk-metrics_1.26.0_1724836642462_0.8363214110577704","host":"s3://npm-registry-packages"}},"1.27.0":{"name":"@opentelemetry/sdk-metrics","version":"1.27.0","keywords":["opentelemetry","nodejs","metrics","stats","profiling"],"author":{"name":"OpenTelemetry Authors"},"license":"Apache-2.0","_id":"@opentelemetry/sdk-metrics@1.27.0","maintainers":[{"name":"pichlermarc","email":"marc.pichler@dynatrace.com"},{"name":"bogdandrutu","email":"bogdandrutu@gmail.com"},{"name":"dyladan","email":"dyladan@gmail.com"}],"homepage":"https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/sdk-metrics","bugs":{"url":"https://github.com/open-telemetry/opentelemetry-js/issues"},"dist":{"shasum":"fb4f55017dc95a95ee00260262952b18e3e7c25c","tarball":"https://registry.npmjs.org/@opentelemetry/sdk-metrics/-/sdk-metrics-1.27.0.tgz","fileCount":561,"integrity":"sha512-JzWgzlutoXCydhHWIbLg+r76m+m3ncqvkCcsswXAQ4gqKS+LOHKhq+t6fx1zNytvLuaOUBur7EvWxECc4jPQKg==","signatures":[{"sig":"MEQCICee8j7NTKwwuMDYrj9aQl8y/q4kq6aAAzlgQtPxV3QOAiBvOudBQcJ+lEOSc3vaMLEPFzNp4YjETGVxdyID8KO5GQ==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@opentelemetry%2fsdk-metrics@1.27.0","provenance":{"predicateType":"https://slsa.dev/provenance/v0.2"}},"unpackedSize":1920417},"main":"build/src/index.js","types":"build/src/index.d.ts","esnext":"build/esnext/index.js","module":"build/esm/index.js","engines":{"node":">=14"},"gitHead":"eb3ca4fb07ee31c62093f5fcec56575573c902ce","scripts":{"tdd":"npm run test -- --watch-extensions ts --watch","lint":"eslint . --ext .ts","test":"nyc mocha 'test/**/*.test.ts'","clean":"tsc --build --clean tsconfig.json tsconfig.esm.json tsconfig.esnext.json","watch":"tsc --build --watch tsconfig.json tsconfig.esm.json tsconfig.esnext.json","compile":"tsc --build tsconfig.json tsconfig.esm.json tsconfig.esnext.json","version":"node ../../scripts/version-update.js","lint:fix":"eslint . --ext .ts --fix","prewatch":"node ../../scripts/version-update.js","precompile":"cross-var lerna run version --scope $npm_package_name --include-dependencies","tdd:browser":"karma start","test:browser":"karma start --single-run","align-api-deps":"node ../../scripts/align-api-deps.js","peer-api-check":"node ../../scripts/peer-api-check.js","prepublishOnly":"npm run compile"},"_npmUser":{"name":"dyladan","email":"dyladan@gmail.com"},"repository":{"url":"git+https://github.com/open-telemetry/opentelemetry-js.git","type":"git"},"_npmVersion":"lerna/6.6.2/node@v18.20.4+x64 (linux)","description":"OpenTelemetry metrics SDK","directories":{},"sideEffects":false,"_nodeVersion":"18.20.4","dependencies":{"@opentelemetry/core":"1.27.0","@opentelemetry/resources":"1.27.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"nyc":"15.1.0","karma":"6.4.4","lerna":"6.6.2","mocha":"10.7.3","sinon":"15.1.2","webpack":"5.94.0","cross-var":"1.1.0","ts-loader":"9.5.1","typescript":"4.4.4","@babel/core":"7.25.2","@types/node":"18.6.5","karma-mocha":"2.0.1","webpack-cli":"5.1.4","@types/mocha":"10.0.8","@types/sinon":"17.0.3","karma-webpack":"5.0.1","webpack-merge":"5.10.0","karma-coverage":"2.2.1","@babel/preset-env":"7.25.4","@opentelemetry/api":">=1.3.0 <1.10.0","karma-spec-reporter":"0.0.36","babel-plugin-istanbul":"7.0.0","karma-chrome-launcher":"3.1.0"},"peerDependencies":{"@opentelemetry/api":">=1.3.0 <1.10.0"},"_npmOperationalInternal":{"tmp":"tmp/sdk-metrics_1.27.0_1729695104075_0.2954021766849051","host":"s3://npm-registry-packages"}},"1.28.0":{"name":"@opentelemetry/sdk-metrics","version":"1.28.0","description":"OpenTelemetry metrics SDK","main":"build/src/index.js","module":"build/esm/index.js","esnext":"build/esnext/index.js","types":"build/src/index.d.ts","repository":{"type":"git","url":"git+https://github.com/open-telemetry/opentelemetry-js.git"},"scripts":{"prepublishOnly":"npm run compile","compile":"tsc --build tsconfig.json tsconfig.esm.json tsconfig.esnext.json","clean":"tsc --build --clean tsconfig.json tsconfig.esm.json tsconfig.esnext.json","test":"nyc mocha 'test/**/*.test.ts'","test:browser":"karma start --single-run","tdd":"npm run test -- --watch-extensions ts --watch","tdd:browser":"karma start","lint":"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix","version":"node ../../scripts/version-update.js","watch":"tsc --build --watch tsconfig.json tsconfig.esm.json tsconfig.esnext.json","precompile":"cross-var lerna run version --scope $npm_package_name --include-dependencies","prewatch":"node ../../scripts/version-update.js","peer-api-check":"node ../../scripts/peer-api-check.js","align-api-deps":"node ../../scripts/align-api-deps.js"},"keywords":["opentelemetry","nodejs","metrics","stats","profiling"],"author":{"name":"OpenTelemetry Authors"},"license":"Apache-2.0","engines":{"node":">=14"},"publishConfig":{"access":"public"},"devDependencies":{"@babel/core":"7.26.0","@babel/preset-env":"7.26.0","@opentelemetry/api":">=1.3.0 <1.10.0","@types/mocha":"10.0.9","@types/node":"18.6.5","@types/sinon":"17.0.3","babel-plugin-istanbul":"7.0.0","cross-var":"1.1.0","karma":"6.4.4","karma-chrome-launcher":"3.1.0","karma-coverage":"2.2.1","karma-mocha":"2.0.1","karma-spec-reporter":"0.0.36","karma-webpack":"5.0.1","lerna":"6.6.2","mocha":"10.8.2","nyc":"15.1.0","sinon":"15.1.2","ts-loader":"9.5.1","typescript":"4.4.4","webpack":"5.96.1","webpack-cli":"5.1.4","webpack-merge":"5.10.0"},"peerDependencies":{"@opentelemetry/api":">=1.3.0 <1.10.0"},"dependencies":{"@opentelemetry/core":"1.28.0","@opentelemetry/resources":"1.28.0"},"homepage":"https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/sdk-metrics","sideEffects":false,"gitHead":"4b1ad3fda0cde58907e30fab25c3c767546708e5","bugs":{"url":"https://github.com/open-telemetry/opentelemetry-js/issues"},"_id":"@opentelemetry/sdk-metrics@1.28.0","_nodeVersion":"18.20.4","_npmVersion":"lerna/6.6.2/node@v18.20.4+x64 (linux)","dist":{"integrity":"sha512-43tqMK/0BcKTyOvm15/WQ3HLr0Vu/ucAl/D84NO7iSlv6O4eOprxSHa3sUtmYkaZWHqdDJV0AHVz/R6u4JALVQ==","shasum":"257b5295bbe9de1ad31c5e8cb43a660c25911d20","tarball":"https://registry.npmjs.org/@opentelemetry/sdk-metrics/-/sdk-metrics-1.28.0.tgz","fileCount":561,"unpackedSize":1922324,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@opentelemetry%2fsdk-metrics@1.28.0","provenance":{"predicateType":"https://slsa.dev/provenance/v0.2"}},"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIH/Z6d+HyDNtyNUtpuzVdAyqhlTCfvqGItbZ06UPzbGwAiEA1ZqqIIyQTA5ZM/DN/dHtZc0GZcZv5TtaAtdiIAF0eZI="}]},"_npmUser":{"name":"dyladan","email":"dyladan@gmail.com"},"directories":{},"maintainers":[{"name":"pichlermarc","email":"marc.pichler@dynatrace.com"},{"name":"bogdandrutu","email":"bogdandrutu@gmail.com"},{"name":"dyladan","email":"dyladan@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/sdk-metrics_1.28.0_1731926513320_0.5425586601271688"},"_hasShrinkwrap":false}},"time":{"created":"2022-08-24T17:44:35.369Z","modified":"2024-11-18T10:41:53.964Z","0.32.0":"2022-08-24T17:44:35.717Z","0.33.0":"2022-09-16T12:14:58.301Z","1.8.0":"2022-11-09T19:45:34.297Z","1.9.0":"2023-01-11T21:46:29.914Z","1.9.1":"2023-01-30T15:30:13.362Z","1.10.0":"2023-03-13T15:53:55.612Z","1.10.1":"2023-03-20T16:10:34.822Z","1.11.0":"2023-03-30T15:30:56.074Z","1.12.0":"2023-04-13T18:13:01.808Z","1.13.0":"2023-05-11T13:30:07.116Z","1.14.0":"2023-06-06T06:00:55.809Z","1.15.0":"2023-07-06T11:27:09.167Z","1.15.1":"2023-07-24T14:32:49.159Z","1.15.2":"2023-08-08T13:21:18.974Z","1.16.0":"2023-09-11T12:14:31.689Z","1.17.0":"2023-09-12T13:12:34.838Z","1.17.1":"2023-10-10T14:18:19.024Z","1.18.0":"2023-11-07T10:44:47.115Z","1.18.1":"2023-11-08T18:09:09.980Z","1.19.0":"2023-12-14T12:35:30.166Z","1.20.0":"2024-01-15T10:15:47.729Z","1.21.0":"2024-01-26T06:11:10.039Z","1.22.0":"2024-02-29T09:18:14.841Z","1.23.0":"2024-04-03T08:10:06.050Z","1.24.0":"2024-04-24T14:39:45.460Z","1.24.1":"2024-05-07T14:52:39.090Z","1.25.0":"2024-06-05T17:15:58.569Z","1.25.1":"2024-06-20T09:19:23.925Z","1.26.0":"2024-08-28T09:17:22.703Z","1.27.0":"2024-10-23T14:51:44.571Z","1.28.0":"2024-11-18T10:41:53.564Z"},"bugs":{"url":"https://github.com/open-telemetry/opentelemetry-js/issues"},"author":{"name":"OpenTelemetry Authors"},"license":"Apache-2.0","homepage":"https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/sdk-metrics","keywords":["opentelemetry","nodejs","metrics","stats","profiling"],"repository":{"type":"git","url":"git+https://github.com/open-telemetry/opentelemetry-js.git"},"description":"OpenTelemetry metrics SDK","maintainers":[{"name":"pichlermarc","email":"marc.pichler@dynatrace.com"},{"name":"bogdandrutu","email":"bogdandrutu@gmail.com"},{"name":"dyladan","email":"dyladan@gmail.com"}],"readme":"# OpenTelemetry Metrics SDK\n\n[![NPM Published Version][npm-img]][npm-url]\n[![Apache License][license-image]][license-image]\n\nThis module contains the Metrics SDK of [opentelemetry-js](https://github.com/open-telemetry/opentelemetry-js).\n\nUsed standalone, this module provides methods for manual instrumentation of code, offering full control over recording metrics for client-side JavaScript (browser) and Node.js.\n\nIt does **not** provide automated instrumentation of known libraries or host environment metrics out-of-the-box.\n\n## Installation\n\n```bash\nnpm install --save @opentelemetry/api\nnpm install --save @opentelemetry/sdk-metrics\n```\n\n## Usage\n\nThe basic setup of the SDK can be seen as followings:\n\n```js\nconst opentelemetry = require('@opentelemetry/api');\nconst { MeterProvider } = require('@opentelemetry/sdk-metrics');\n\n// To create an instrument, you first need to initialize the Meter provider.\n// NOTE: The default OpenTelemetry meter provider does not record any metric instruments.\n// Registering a working meter provider allows the API methods to record instruments.\nopentelemetry.metrics.setGlobalMeterProvider(new MeterProvider());\n\n// To record a metric event, we used the global singleton meter to create an instrument.\nconst counter = opentelemetry.metrics.getMeter('default').createCounter('foo');\n\n// record a metric event.\ncounter.add(1, { attributeKey: 'attribute-value' });\n```\n\nIn conditions, we may need to setup an async instrument to observe costly events:\n\n```js\n// Creating an async instrument, similar to synchronous instruments\nconst observableCounter = opentelemetry.metrics.getMeter('default')\n .createObservableCounter('observable-counter');\n\n// Register a single-instrument callback to the async instrument.\nobservableCounter.addCallback(async (observableResult) => {\n // ... do async stuff\n observableResult.observe(1, { attributeKey: 'attribute-value' });\n});\n\n// Register a multi-instrument callback and associate it with a set of async instruments.\nopentelemetry.metrics.getMeter('default')\n .addBatchObservableCallback(batchObservableCallback, [ observableCounter ]);\nasync function batchObservableCallback(batchObservableResult) {\n // ... do async stuff\n batchObservableResult.observe(observableCounter, 1, { attributeKey: 'attribute-value' });\n}\n```\n\nViews can be registered when instantiating a `MeterProvider`:\n\n```js\nconst meterProvider = new MeterProvider({\n views: [\n // override the bucket boundaries on `my.histogram` to [0, 50, 100]\n new View({ aggregation: new ExplicitBucketHistogramAggregation([0, 50, 100]), instrumentName: 'my.histogram'}),\n // rename 'my.counter' to 'my.renamed.counter'\n new View({ name: 'my.renamed.counter', instrumentName: 'my.counter'})\n ]\n})\n```\n\n## Example\n\nSee [examples/prometheus](https://github.com/open-telemetry/opentelemetry-js/tree/main/experimental/examples/prometheus) for an end-to-end example, including exporting metrics.\n\n## Useful links\n\n- For more information on OpenTelemetry, visit: \n- For more about OpenTelemetry JavaScript: \n- For help or feedback on this project, join us in [GitHub Discussions][discussions-url]\n\n## License\n\nApache 2.0 - See [LICENSE][license-url] for more information.\n\n[discussions-url]: https://github.com/open-telemetry/opentelemetry-js/discussions\n[license-url]: https://github.com/open-telemetry/opentelemetry-js/blob/main/LICENSE\n[license-image]: https://img.shields.io/badge/license-Apache_2.0-green.svg?style=flat\n[npm-url]: https://www.npmjs.com/package/@opentelemetry/sdk-metrics\n[npm-img]: https://badge.fury.io/js/%40opentelemetry%2Fsdk%2Dmetrics.svg\n","readmeFilename":"README.md"} \ No newline at end of file diff --git a/tests/specs/cli/otel_basic/__test__.jsonc b/tests/specs/cli/otel_basic/__test__.jsonc index 991413c3d5..05e23d32e9 100644 --- a/tests/specs/cli/otel_basic/__test__.jsonc +++ b/tests/specs/cli/otel_basic/__test__.jsonc @@ -15,6 +15,10 @@ { "args": "run -A main.ts uncaught.ts", "output": "uncaught.out" + }, + { + "args": "run -A main.ts metric.ts", + "output": "metric.out" } ] } diff --git a/tests/specs/cli/otel_basic/basic.out b/tests/specs/cli/otel_basic/basic.out index 88296a7c04..1e82ba59b3 100644 --- a/tests/specs/cli/otel_basic/basic.out +++ b/tests/specs/cli/otel_basic/basic.out @@ -188,5 +188,6 @@ "traceId": "00000000000000000000000000000003", "spanId": "1000000000000002" } - ] + ], + "metrics": [] } diff --git a/tests/specs/cli/otel_basic/deno_dot_exit.out b/tests/specs/cli/otel_basic/deno_dot_exit.out index 98a41cf606..025fdfc874 100644 --- a/tests/specs/cli/otel_basic/deno_dot_exit.out +++ b/tests/specs/cli/otel_basic/deno_dot_exit.out @@ -15,5 +15,6 @@ "traceId": "", "spanId": "" } - ] + ], + "metrics": [] } diff --git a/tests/specs/cli/otel_basic/main.ts b/tests/specs/cli/otel_basic/main.ts index bdbae0cc0e..ccba126cc1 100644 --- a/tests/specs/cli/otel_basic/main.ts +++ b/tests/specs/cli/otel_basic/main.ts @@ -3,6 +3,7 @@ const data = { spans: [], logs: [], + metrics: [], }; const server = Deno.serve( @@ -45,6 +46,11 @@ const server = Deno.serve( data.spans.push(...sSpans.spans); }); }); + body.resourceMetrics?.forEach((rMetrics) => { + rMetrics.scopeMetrics.forEach((sMetrics) => { + data.metrics.push(...sMetrics.metrics); + }); + }); return Response.json({ partialSuccess: {} }, { status: 200 }); }, }, diff --git a/tests/specs/cli/otel_basic/metric.out b/tests/specs/cli/otel_basic/metric.out new file mode 100644 index 0000000000..26ed4a23c6 --- /dev/null +++ b/tests/specs/cli/otel_basic/metric.out @@ -0,0 +1,124 @@ +{ + "spans": [], + "logs": [], + "metrics": [ + { + "name": "counter", + "description": "Example of a Counter", + "unit": "", + "metadata": [], + "sum": { + "dataPoints": [ + { + "attributes": [ + { + "key": "attribute", + "value": { + "doubleValue": 1 + } + } + ], + "startTimeUnixNano": "[WILDCARD]", + "timeUnixNano": "[WILDCARD]", + "exemplars": [], + "flags": 0, + "asDouble": 1 + } + ], + "aggregationTemporality": 2, + "isMonotonic": true + } + }, + { + "name": "up_down_counter", + "description": "Example of a UpDownCounter", + "unit": "", + "metadata": [], + "sum": { + "dataPoints": [ + { + "attributes": [ + { + "key": "attribute", + "value": { + "doubleValue": 1 + } + } + ], + "startTimeUnixNano": "[WILDCARD]", + "timeUnixNano": "[WILDCARD]", + "exemplars": [], + "flags": 0, + "asDouble": -1 + } + ], + "aggregationTemporality": 2, + "isMonotonic": false + } + }, + { + "name": "histogram", + "description": "Example of a Histogram", + "unit": "", + "metadata": [], + "histogram": { + "dataPoints": [ + { + "attributes": [ + { + "key": "attribute", + "value": { + "doubleValue": 1 + } + } + ], + "startTimeUnixNano": "[WILDCARD]", + "timeUnixNano": "[WILDCARD]", + "count": 1, + "sum": 1, + "bucketCounts": [ + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "explicitBounds": [ + 0, + 5, + 10, + 25, + 50, + 75, + 100, + 250, + 500, + 750, + 1000, + 2500, + 5000, + 7500, + 10000 + ], + "exemplars": [], + "flags": 0, + "min": 1, + "max": 1 + } + ], + "aggregationTemporality": 2 + } + } + ] +} diff --git a/tests/specs/cli/otel_basic/metric.ts b/tests/specs/cli/otel_basic/metric.ts new file mode 100644 index 0000000000..7d332f0432 --- /dev/null +++ b/tests/specs/cli/otel_basic/metric.ts @@ -0,0 +1,34 @@ +import { + MeterProvider, + PeriodicExportingMetricReader, +} from "npm:@opentelemetry/sdk-metrics@1.28.0"; + +const meterProvider = new MeterProvider(); + +meterProvider.addMetricReader( + new PeriodicExportingMetricReader({ + exporter: new Deno.telemetry.MetricExporter(), + exportIntervalMillis: 100, + }), +); + +const meter = meterProvider.getMeter("m"); + +const counter = meter.createCounter("counter", { + description: "Example of a Counter", +}); + +const upDownCounter = meter.createUpDownCounter("up_down_counter", { + description: "Example of a UpDownCounter", +}); + +const histogram = meter.createHistogram("histogram", { + description: "Example of a Histogram", +}); + +const attributes = { attribute: 1 }; +counter.add(1, attributes); +upDownCounter.add(-1, attributes); +histogram.record(1, attributes); + +await meterProvider.forceFlush(); diff --git a/tests/specs/cli/otel_basic/natural_exit.out b/tests/specs/cli/otel_basic/natural_exit.out index 98a41cf606..025fdfc874 100644 --- a/tests/specs/cli/otel_basic/natural_exit.out +++ b/tests/specs/cli/otel_basic/natural_exit.out @@ -15,5 +15,6 @@ "traceId": "", "spanId": "" } - ] + ], + "metrics": [] } diff --git a/tests/specs/cli/otel_basic/uncaught.out b/tests/specs/cli/otel_basic/uncaught.out index a5a886bfeb..4ff08e6dba 100644 --- a/tests/specs/cli/otel_basic/uncaught.out +++ b/tests/specs/cli/otel_basic/uncaught.out @@ -33,5 +33,6 @@ throw new Error("uncaught"); "traceId": "", "spanId": "" } - ] + ], + "metrics": [] } From 76571fd5a5ae0ebd31e10ed5bcea5e44c51621d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartek=20Iwa=C5=84czuk?= Date: Mon, 2 Dec 2024 21:53:00 +0000 Subject: [PATCH 4/7] chore: upgrade deno_lint to 0.68.2 (#27197) --- Cargo.lock | 4 ++-- cli/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9e000ddafc..09e63cbb3d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1803,9 +1803,9 @@ dependencies = [ [[package]] name = "deno_lint" -version = "0.68.1" +version = "0.68.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce2a040657166e39c7d59ad34230f0cc829f8ea8b7b2377038cc012ec1a1ef16" +checksum = "ce713d564f76efd90535061113210bdc6b942ed6327b33eb1d5f76a5daf8e7a5" dependencies = [ "anyhow", "deno_ast", diff --git a/cli/Cargo.toml b/cli/Cargo.toml index ac093a7238..728f6726b5 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -74,7 +74,7 @@ deno_config.workspace = true deno_core = { workspace = true, features = ["include_js_files_for_snapshotting"] } deno_doc = { version = "=0.161.2", features = ["rust", "comrak"] } deno_graph = { version = "=0.86.3" } -deno_lint = { version = "=0.68.1", features = ["docs"] } +deno_lint = { version = "=0.68.2", features = ["docs"] } deno_lockfile.workspace = true deno_npm.workspace = true deno_package_json.workspace = true From 53936eda11ba0b2e9845d940772be774750e1184 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartek=20Iwa=C5=84czuk?= Date: Tue, 3 Dec 2024 01:04:55 +0000 Subject: [PATCH 5/7] fix(fmt): stable formatting of HTML files with JS (#27164) Closes https://github.com/denoland/deno/issues/26407 Closes https://github.com/denoland/deno/issues/26763 Closes https://github.com/denoland/deno/issues/26560 Closes https://github.com/denoland/deno/issues/26744 Closes https://github.com/denoland/deno/issues/27030 --- Cargo.lock | 4 ++-- cli/Cargo.toml | 2 +- cli/tools/fmt.rs | 19 ++++++++++++++----- tests/specs/fmt/html/__test__.jsonc | 4 ++++ tests/specs/fmt/html/with_js.html | 9 +++++++++ 5 files changed, 30 insertions(+), 8 deletions(-) create mode 100644 tests/specs/fmt/html/with_js.html diff --git a/Cargo.lock b/Cargo.lock index 09e63cbb3d..f9288c9eb5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4682,9 +4682,9 @@ dependencies = [ [[package]] name = "markup_fmt" -version = "0.16.0" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f303c36143671ac6c54112eb5aa95649b169dae783fdb6ead2c0e88b408c425c" +checksum = "fa7605bb4ad755a9ab5c96f2ce3bfd4eb8acd559b842c041fc8a5f84d63aed3a" dependencies = [ "aho-corasick", "css_dataset", diff --git a/cli/Cargo.toml b/cli/Cargo.toml index 728f6726b5..2012c90dfb 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -130,7 +130,7 @@ libz-sys.workspace = true log = { workspace = true, features = ["serde"] } lsp-types.workspace = true malva = "=0.11.0" -markup_fmt = "=0.16.0" +markup_fmt = "=0.18.0" memmem.workspace = true monch.workspace = true notify.workspace = true diff --git a/cli/tools/fmt.rs b/cli/tools/fmt.rs index c2c2a6bb6b..e29627345c 100644 --- a/cli/tools/fmt.rs +++ b/cli/tools/fmt.rs @@ -440,8 +440,10 @@ pub fn format_html( ) } _ => { - let mut typescript_config = - get_resolved_typescript_config(fmt_options); + let mut typescript_config_builder = + get_typescript_config_builder(fmt_options); + typescript_config_builder.file_indent_level(hints.indent_level); + let mut typescript_config = typescript_config_builder.build(); typescript_config.line_width = hints.print_width as u32; dprint_plugin_typescript::format_text( &path, @@ -919,9 +921,9 @@ fn files_str(len: usize) -> &'static str { } } -fn get_resolved_typescript_config( +fn get_typescript_config_builder( options: &FmtOptionsConfig, -) -> dprint_plugin_typescript::configuration::Configuration { +) -> dprint_plugin_typescript::configuration::ConfigurationBuilder { let mut builder = dprint_plugin_typescript::configuration::ConfigurationBuilder::new(); builder.deno(); @@ -953,7 +955,13 @@ fn get_resolved_typescript_config( }); } - builder.build() + builder +} + +fn get_resolved_typescript_config( + options: &FmtOptionsConfig, +) -> dprint_plugin_typescript::configuration::Configuration { + get_typescript_config_builder(options).build() } fn get_resolved_markdown_config( @@ -1075,6 +1083,7 @@ fn get_resolved_markup_fmt_config( }; let language_options = LanguageOptions { + script_formatter: Some(markup_fmt::config::ScriptFormatter::Dprint), quotes: Quotes::Double, format_comments: false, script_indent: true, diff --git a/tests/specs/fmt/html/__test__.jsonc b/tests/specs/fmt/html/__test__.jsonc index 2e6d08d4cc..96b7f4ed92 100644 --- a/tests/specs/fmt/html/__test__.jsonc +++ b/tests/specs/fmt/html/__test__.jsonc @@ -12,6 +12,10 @@ "broken": { "args": "fmt broken.html", "output": "broken.out" + }, + "with_js": { + "args": "fmt --check with_js.html", + "output": "Checked 1 file\n" } } } diff --git a/tests/specs/fmt/html/with_js.html b/tests/specs/fmt/html/with_js.html new file mode 100644 index 0000000000..d956c6728b --- /dev/null +++ b/tests/specs/fmt/html/with_js.html @@ -0,0 +1,9 @@ + + + + + From 70d69a88288a0ec05947a0fa385eb661011e9947 Mon Sep 17 00:00:00 2001 From: David Sherret Date: Mon, 2 Dec 2024 20:37:40 -0500 Subject: [PATCH 6/7] chore: fix cjs_with_deps test to use a temp dir (#27199) It was creating a node_modules directory. --- tests/specs/npm/cjs_with_deps/__test__.jsonc | 1 + tests/specs/npm/cjs_with_deps/main_info.out | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/specs/npm/cjs_with_deps/__test__.jsonc b/tests/specs/npm/cjs_with_deps/__test__.jsonc index a09f172053..7441b5509f 100644 --- a/tests/specs/npm/cjs_with_deps/__test__.jsonc +++ b/tests/specs/npm/cjs_with_deps/__test__.jsonc @@ -1,4 +1,5 @@ { + "tempDir": true, "tests": { "cjs_with_deps": { "args": "run --allow-read --allow-env main.js", diff --git a/tests/specs/npm/cjs_with_deps/main_info.out b/tests/specs/npm/cjs_with_deps/main_info.out index 8e37c88eb0..f1271ec1f1 100644 --- a/tests/specs/npm/cjs_with_deps/main_info.out +++ b/tests/specs/npm/cjs_with_deps/main_info.out @@ -3,7 +3,7 @@ type: JavaScript dependencies: 14 unique size: [WILDCARD] -file:///[WILDCARD]/cjs_with_deps/main.js ([WILDCARD]) +file:///[WILDCARD]/main.js ([WILDCARD]) ├─┬ npm:/chalk@4.1.2 ([WILDCARD]) │ ├─┬ npm:/ansi-styles@4.3.0 ([WILDCARD]) │ │ └─┬ npm:/color-convert@2.0.1 ([WILDCARD]) From c1dcf1b618e87f1a50869fffe38b473a77377fe8 Mon Sep 17 00:00:00 2001 From: David Sherret Date: Mon, 2 Dec 2024 21:10:16 -0500 Subject: [PATCH 7/7] refactor: add deno_npm_cache crate (#27200) Extracting out more code from the CLI for reuse elsewhere (still more work to do, but this is a start). This is the code for extracting npm tarballs and saving information in the npm cache in the global deno_dir. --- Cargo.lock | 35 ++- Cargo.toml | 3 + cli/Cargo.toml | 1 + cli/args/mod.rs | 28 ++- cli/npm/managed/mod.rs | 73 +++--- cli/npm/managed/registry.rs | 23 +- cli/npm/managed/resolvers/common.rs | 4 +- cli/npm/managed/resolvers/global.rs | 12 +- cli/npm/managed/resolvers/local.rs | 16 +- cli/npm/managed/resolvers/mod.rs | 8 +- cli/npm/mod.rs | 111 ++++++++- cli/util/path.rs | 13 -- cli/util/sync/mod.rs | 2 - cli/util/sync/value_creator.rs | 213 ------------------ resolvers/npm_cache/Cargo.toml | 42 ++++ resolvers/npm_cache/README.md | 6 + .../mod.rs => resolvers/npm_cache/lib.rs | 130 ++++++++--- .../npm_cache}/registry_info.rs | 71 +++--- .../npm_cache/remote.rs | 6 +- .../cache => resolvers/npm_cache}/tarball.rs | 76 +++---- .../npm_cache}/tarball_extract.rs | 45 ++-- resolvers/npm_cache/todo.md | 9 + 22 files changed, 492 insertions(+), 435 deletions(-) delete mode 100644 cli/util/sync/value_creator.rs create mode 100644 resolvers/npm_cache/Cargo.toml create mode 100644 resolvers/npm_cache/README.md rename cli/npm/managed/cache/mod.rs => resolvers/npm_cache/lib.rs (71%) rename {cli/npm/managed/cache => resolvers/npm_cache}/registry_info.rs (84%) rename cli/npm/common.rs => resolvers/npm_cache/remote.rs (95%) rename {cli/npm/managed/cache => resolvers/npm_cache}/tarball.rs (77%) rename {cli/npm/managed/cache => resolvers/npm_cache}/tarball_extract.rs (90%) create mode 100644 resolvers/npm_cache/todo.md diff --git a/Cargo.lock b/Cargo.lock index f9288c9eb5..28548ab84c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1220,6 +1220,7 @@ dependencies = [ "deno_lint", "deno_lockfile", "deno_npm", + "deno_npm_cache", "deno_package_json", "deno_path_util", "deno_resolver", @@ -1998,6 +1999,35 @@ dependencies = [ "url", ] +[[package]] +name = "deno_npm_cache" +version = "0.0.1" +dependencies = [ + "anyhow", + "async-trait", + "base64 0.21.7", + "boxed_error", + "deno_cache_dir", + "deno_core", + "deno_npm", + "deno_semver", + "deno_unsync", + "faster-hex", + "flate2", + "futures", + "http 1.1.0", + "log", + "parking_lot", + "percent-encoding", + "rand", + "ring", + "serde_json", + "tar", + "tempfile", + "thiserror 1.0.64", + "url", +] + [[package]] name = "deno_ops" version = "0.199.0" @@ -2260,10 +2290,11 @@ dependencies = [ [[package]] name = "deno_unsync" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f36b4ef61a04ce201b925a5dffa90f88437d37fee4836c758470dd15ba7f05e" +checksum = "d774fd83f26b24f0805a6ab8b26834a0d06ceac0db517b769b1e4633c96a2057" dependencies = [ + "futures", "parking_lot", "tokio", ] diff --git a/Cargo.toml b/Cargo.toml index 068046607f..23670beec3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -30,6 +30,7 @@ members = [ "ext/webstorage", "resolvers/deno", "resolvers/node", + "resolvers/npm_cache", "runtime", "runtime/permissions", "tests", @@ -93,6 +94,7 @@ deno_websocket = { version = "0.185.0", path = "./ext/websocket" } deno_webstorage = { version = "0.175.0", path = "./ext/webstorage" } # resolvers +deno_npm_cache = { version = "0.0.1", path = "./resolvers/npm_cache" } deno_resolver = { version = "0.12.0", path = "./resolvers/deno" } node_resolver = { version = "0.19.0", path = "./resolvers/node" } @@ -117,6 +119,7 @@ data-encoding = "2.3.3" data-url = "=0.3.0" deno_cache_dir = "=0.14.0" deno_package_json = { version = "0.2.1", default-features = false } +deno_unsync = "0.4.2" dlopen2 = "0.6.1" ecb = "=0.1.2" elliptic-curve = { version = "0.13.4", features = ["alloc", "arithmetic", "ecdh", "std", "pem", "jwk"] } diff --git a/cli/Cargo.toml b/cli/Cargo.toml index 2012c90dfb..4a343ce747 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -77,6 +77,7 @@ deno_graph = { version = "=0.86.3" } deno_lint = { version = "=0.68.2", features = ["docs"] } deno_lockfile.workspace = true deno_npm.workspace = true +deno_npm_cache.workspace = true deno_package_json.workspace = true deno_path_util.workspace = true deno_resolver.workspace = true diff --git a/cli/args/mod.rs b/cli/args/mod.rs index fb576a8c3e..0b049cf409 100644 --- a/cli/args/mod.rs +++ b/cli/args/mod.rs @@ -27,6 +27,7 @@ use deno_npm::npm_rc::NpmRc; use deno_npm::npm_rc::ResolvedNpmRc; use deno_npm::resolution::ValidSerializedNpmResolutionSnapshot; use deno_npm::NpmSystemInfo; +use deno_npm_cache::NpmCacheSetting; use deno_path_util::normalize_path; use deno_semver::npm::NpmPackageReqReference; use deno_telemetry::OtelConfig; @@ -238,20 +239,25 @@ pub enum CacheSetting { } impl CacheSetting { - pub fn should_use_for_npm_package(&self, package_name: &str) -> bool { + pub fn as_npm_cache_setting(&self) -> NpmCacheSetting { match self { - CacheSetting::ReloadAll => false, - CacheSetting::ReloadSome(list) => { - if list.iter().any(|i| i == "npm:") { - return false; + CacheSetting::Only => NpmCacheSetting::Only, + CacheSetting::ReloadAll => NpmCacheSetting::ReloadAll, + CacheSetting::ReloadSome(values) => { + if values.iter().any(|v| v == "npm:") { + NpmCacheSetting::ReloadAll + } else { + NpmCacheSetting::ReloadSome { + npm_package_names: values + .iter() + .filter_map(|v| v.strip_prefix("npm:")) + .map(|n| n.to_string()) + .collect(), + } } - let specifier = format!("npm:{package_name}"); - if list.contains(&specifier) { - return false; - } - true } - _ => true, + CacheSetting::RespectHeaders => unreachable!(), // not supported + CacheSetting::Use => NpmCacheSetting::Use, } } } diff --git a/cli/npm/managed/mod.rs b/cli/npm/managed/mod.rs index 88094d5141..da39f55e85 100644 --- a/cli/npm/managed/mod.rs +++ b/cli/npm/managed/mod.rs @@ -5,8 +5,6 @@ use std::path::Path; use std::path::PathBuf; use std::sync::Arc; -use cache::RegistryInfoDownloader; -use cache::TarballCache; use deno_ast::ModuleSpecifier; use deno_cache_dir::npm::NpmCacheDir; use deno_core::anyhow::Context; @@ -42,22 +40,23 @@ use crate::args::NpmProcessState; use crate::args::NpmProcessStateKind; use crate::args::PackageJsonDepValueParseWithLocationError; use crate::cache::FastInsecureHasher; -use crate::http_util::HttpClientProvider; use crate::util::fs::canonicalize_path_maybe_not_exists_with_fs; use crate::util::progress_bar::ProgressBar; use crate::util::sync::AtomicFlag; -use self::cache::NpmCache; use self::registry::CliNpmRegistryApi; use self::resolution::NpmResolution; use self::resolvers::create_npm_fs_resolver; use self::resolvers::NpmPackageFsResolver; +use super::CliNpmCache; +use super::CliNpmCacheEnv; +use super::CliNpmRegistryInfoProvider; use super::CliNpmResolver; +use super::CliNpmTarballCache; use super::InnerCliNpmResolverRef; use super::ResolvePkgFolderFromDenoReqError; -pub mod cache; mod registry; mod resolution; mod resolvers; @@ -85,8 +84,9 @@ pub struct CliManagedNpmResolverCreateOptions { pub async fn create_managed_npm_resolver_for_lsp( options: CliManagedNpmResolverCreateOptions, ) -> Arc { - let npm_cache = create_cache(&options); - let npm_api = create_api(&options, npm_cache.clone()); + let cache_env = create_cache_env(&options); + let npm_cache = create_cache(cache_env.clone(), &options); + let npm_api = create_api(npm_cache.clone(), cache_env.clone(), &options); // spawn due to the lsp's `Send` requirement deno_core::unsync::spawn(async move { let snapshot = match resolve_snapshot(&npm_api, options.snapshot).await { @@ -97,8 +97,8 @@ pub async fn create_managed_npm_resolver_for_lsp( } }; create_inner( + cache_env, options.fs, - options.http_client_provider, options.maybe_lockfile, npm_api, npm_cache, @@ -118,12 +118,13 @@ pub async fn create_managed_npm_resolver_for_lsp( pub async fn create_managed_npm_resolver( options: CliManagedNpmResolverCreateOptions, ) -> Result, AnyError> { - let npm_cache = create_cache(&options); - let npm_api = create_api(&options, npm_cache.clone()); + let npm_cache_env = create_cache_env(&options); + let npm_cache = create_cache(npm_cache_env.clone(), &options); + let npm_api = create_api(npm_cache.clone(), npm_cache_env.clone(), &options); let snapshot = resolve_snapshot(&npm_api, options.snapshot).await?; Ok(create_inner( + npm_cache_env, options.fs, - options.http_client_provider, options.maybe_lockfile, npm_api, npm_cache, @@ -139,11 +140,11 @@ pub async fn create_managed_npm_resolver( #[allow(clippy::too_many_arguments)] fn create_inner( + env: Arc, fs: Arc, - http_client_provider: Arc, maybe_lockfile: Option>, npm_api: Arc, - npm_cache: Arc, + npm_cache: Arc, npm_rc: Arc, npm_install_deps_provider: Arc, text_only_progress_bar: crate::util::progress_bar::ProgressBar, @@ -157,12 +158,10 @@ fn create_inner( snapshot, maybe_lockfile.clone(), )); - let tarball_cache = Arc::new(TarballCache::new( + let tarball_cache = Arc::new(CliNpmTarballCache::new( npm_cache.clone(), - fs.clone(), - http_client_provider.clone(), + env, npm_rc.clone(), - text_only_progress_bar.clone(), )); let fs_resolver = create_npm_fs_resolver( fs.clone(), @@ -190,25 +189,39 @@ fn create_inner( )) } -fn create_cache(options: &CliManagedNpmResolverCreateOptions) -> Arc { - Arc::new(NpmCache::new( +fn create_cache_env( + options: &CliManagedNpmResolverCreateOptions, +) -> Arc { + Arc::new(CliNpmCacheEnv::new( + options.fs.clone(), + options.http_client_provider.clone(), + options.text_only_progress_bar.clone(), + )) +} + +fn create_cache( + env: Arc, + options: &CliManagedNpmResolverCreateOptions, +) -> Arc { + Arc::new(CliNpmCache::new( options.npm_cache_dir.clone(), - options.cache_setting.clone(), + options.cache_setting.as_npm_cache_setting(), + env, options.npmrc.clone(), )) } fn create_api( + cache: Arc, + env: Arc, options: &CliManagedNpmResolverCreateOptions, - npm_cache: Arc, ) -> Arc { Arc::new(CliNpmRegistryApi::new( - npm_cache.clone(), - Arc::new(RegistryInfoDownloader::new( - npm_cache, - options.http_client_provider.clone(), + cache.clone(), + Arc::new(CliNpmRegistryInfoProvider::new( + cache, + env, options.npmrc.clone(), - options.text_only_progress_bar.clone(), )), )) } @@ -292,10 +305,10 @@ pub struct ManagedCliNpmResolver { fs_resolver: Arc, maybe_lockfile: Option>, npm_api: Arc, - npm_cache: Arc, + npm_cache: Arc, npm_install_deps_provider: Arc, resolution: Arc, - tarball_cache: Arc, + tarball_cache: Arc, text_only_progress_bar: ProgressBar, npm_system_info: NpmSystemInfo, top_level_install_flag: AtomicFlag, @@ -317,10 +330,10 @@ impl ManagedCliNpmResolver { fs_resolver: Arc, maybe_lockfile: Option>, npm_api: Arc, - npm_cache: Arc, + npm_cache: Arc, npm_install_deps_provider: Arc, resolution: Arc, - tarball_cache: Arc, + tarball_cache: Arc, text_only_progress_bar: ProgressBar, npm_system_info: NpmSystemInfo, lifecycle_scripts: LifecycleScriptsConfig, diff --git a/cli/npm/managed/registry.rs b/cli/npm/managed/registry.rs index 8f15d619b9..b431c77c5d 100644 --- a/cli/npm/managed/registry.rs +++ b/cli/npm/managed/registry.rs @@ -14,27 +14,28 @@ use deno_core::parking_lot::Mutex; use deno_npm::registry::NpmPackageInfo; use deno_npm::registry::NpmRegistryApi; use deno_npm::registry::NpmRegistryPackageInfoLoadError; +use deno_npm_cache::NpmCacheSetting; -use crate::args::CacheSetting; +use crate::npm::CliNpmCache; +use crate::npm::CliNpmRegistryInfoProvider; use crate::util::sync::AtomicFlag; -use super::cache::NpmCache; -use super::cache::RegistryInfoDownloader; - +// todo(#27198): Remove this and move functionality down into +// RegistryInfoProvider, which already does most of this. #[derive(Debug)] pub struct CliNpmRegistryApi(Option>); impl CliNpmRegistryApi { pub fn new( - cache: Arc, - registry_info_downloader: Arc, + cache: Arc, + registry_info_provider: Arc, ) -> Self { Self(Some(Arc::new(CliNpmRegistryApiInner { cache, force_reload_flag: Default::default(), mem_cache: Default::default(), previously_reloaded_packages: Default::default(), - registry_info_downloader, + registry_info_provider, }))) } @@ -83,11 +84,11 @@ enum CacheItem { #[derive(Debug)] struct CliNpmRegistryApiInner { - cache: Arc, + cache: Arc, force_reload_flag: AtomicFlag, mem_cache: Mutex>, previously_reloaded_packages: Mutex>, - registry_info_downloader: Arc, + registry_info_provider: Arc, } impl CliNpmRegistryApiInner { @@ -118,7 +119,7 @@ impl CliNpmRegistryApiInner { return Ok(result); } } - api.registry_info_downloader + api.registry_info_provider .load_package_info(&name) .await .map_err(Arc::new) @@ -159,7 +160,7 @@ impl CliNpmRegistryApiInner { // is disabled or if we're already reloading if matches!( self.cache.cache_setting(), - CacheSetting::Only | CacheSetting::ReloadAll + NpmCacheSetting::Only | NpmCacheSetting::ReloadAll ) { return false; } diff --git a/cli/npm/managed/resolvers/common.rs b/cli/npm/managed/resolvers/common.rs index eee11c7604..332756daa4 100644 --- a/cli/npm/managed/resolvers/common.rs +++ b/cli/npm/managed/resolvers/common.rs @@ -24,7 +24,7 @@ use deno_runtime::deno_fs::FileSystem; use deno_runtime::deno_node::NodePermissions; use node_resolver::errors::PackageFolderResolveError; -use crate::npm::managed::cache::TarballCache; +use crate::npm::CliNpmTarballCache; /// Part of the resolution that interacts with the file system. #[async_trait(?Send)] @@ -140,7 +140,7 @@ impl RegistryReadPermissionChecker { /// Caches all the packages in parallel. pub async fn cache_packages( packages: &[NpmResolutionPackage], - tarball_cache: &Arc, + tarball_cache: &Arc, ) -> Result<(), AnyError> { let mut futures_unordered = futures::stream::FuturesUnordered::new(); for package in packages { diff --git a/cli/npm/managed/resolvers/global.rs b/cli/npm/managed/resolvers/global.rs index f0193e78e9..2b48c3d2fc 100644 --- a/cli/npm/managed/resolvers/global.rs +++ b/cli/npm/managed/resolvers/global.rs @@ -8,6 +8,8 @@ use std::path::PathBuf; use std::sync::Arc; use crate::colors; +use crate::npm::CliNpmCache; +use crate::npm::CliNpmTarballCache; use async_trait::async_trait; use deno_ast::ModuleSpecifier; use deno_core::error::AnyError; @@ -24,8 +26,6 @@ use node_resolver::errors::ReferrerNotFoundError; use crate::args::LifecycleScriptsConfig; use crate::cache::FastInsecureHasher; -use super::super::cache::NpmCache; -use super::super::cache::TarballCache; use super::super::resolution::NpmResolution; use super::common::cache_packages; use super::common::lifecycle_scripts::LifecycleScriptsStrategy; @@ -35,8 +35,8 @@ use super::common::RegistryReadPermissionChecker; /// Resolves packages from the global npm cache. #[derive(Debug)] pub struct GlobalNpmPackageResolver { - cache: Arc, - tarball_cache: Arc, + cache: Arc, + tarball_cache: Arc, resolution: Arc, system_info: NpmSystemInfo, registry_read_permission_checker: RegistryReadPermissionChecker, @@ -45,9 +45,9 @@ pub struct GlobalNpmPackageResolver { impl GlobalNpmPackageResolver { pub fn new( - cache: Arc, + cache: Arc, fs: Arc, - tarball_cache: Arc, + tarball_cache: Arc, resolution: Arc, system_info: NpmSystemInfo, lifecycle_scripts: LifecycleScriptsConfig, diff --git a/cli/npm/managed/resolvers/local.rs b/cli/npm/managed/resolvers/local.rs index ca7867425d..0c279d9e12 100644 --- a/cli/npm/managed/resolvers/local.rs +++ b/cli/npm/managed/resolvers/local.rs @@ -17,6 +17,8 @@ use std::sync::Arc; use crate::args::LifecycleScriptsConfig; use crate::colors; +use crate::npm::CliNpmCache; +use crate::npm::CliNpmTarballCache; use async_trait::async_trait; use deno_ast::ModuleSpecifier; use deno_cache_dir::npm::mixed_case_package_name_decode; @@ -52,8 +54,6 @@ use crate::util::fs::LaxSingleProcessFsFlag; use crate::util::progress_bar::ProgressBar; use crate::util::progress_bar::ProgressMessagePrompt; -use super::super::cache::NpmCache; -use super::super::cache::TarballCache; use super::super::resolution::NpmResolution; use super::common::bin_entries; use super::common::NpmPackageFsResolver; @@ -63,12 +63,12 @@ use super::common::RegistryReadPermissionChecker; /// and resolves packages from it. #[derive(Debug)] pub struct LocalNpmPackageResolver { - cache: Arc, + cache: Arc, fs: Arc, npm_install_deps_provider: Arc, progress_bar: ProgressBar, resolution: Arc, - tarball_cache: Arc, + tarball_cache: Arc, root_node_modules_path: PathBuf, root_node_modules_url: Url, system_info: NpmSystemInfo, @@ -79,12 +79,12 @@ pub struct LocalNpmPackageResolver { impl LocalNpmPackageResolver { #[allow(clippy::too_many_arguments)] pub fn new( - cache: Arc, + cache: Arc, fs: Arc, npm_install_deps_provider: Arc, progress_bar: ProgressBar, resolution: Arc, - tarball_cache: Arc, + tarball_cache: Arc, node_modules_folder: PathBuf, system_info: NpmSystemInfo, lifecycle_scripts: LifecycleScriptsConfig, @@ -284,10 +284,10 @@ fn local_node_modules_package_contents_path( #[allow(clippy::too_many_arguments)] async fn sync_resolution_with_fs( snapshot: &NpmResolutionSnapshot, - cache: &Arc, + cache: &Arc, npm_install_deps_provider: &NpmInstallDepsProvider, progress_bar: &ProgressBar, - tarball_cache: &Arc, + tarball_cache: &Arc, root_node_modules_dir_path: &Path, system_info: &NpmSystemInfo, lifecycle_scripts: &LifecycleScriptsConfig, diff --git a/cli/npm/managed/resolvers/mod.rs b/cli/npm/managed/resolvers/mod.rs index 36d795ee7e..736270749f 100644 --- a/cli/npm/managed/resolvers/mod.rs +++ b/cli/npm/managed/resolvers/mod.rs @@ -12,6 +12,8 @@ use deno_runtime::deno_fs::FileSystem; use crate::args::LifecycleScriptsConfig; use crate::args::NpmInstallDepsProvider; +use crate::npm::CliNpmCache; +use crate::npm::CliNpmTarballCache; use crate::util::progress_bar::ProgressBar; pub use self::common::NpmPackageFsResolver; @@ -19,18 +21,16 @@ pub use self::common::NpmPackageFsResolver; use self::global::GlobalNpmPackageResolver; use self::local::LocalNpmPackageResolver; -use super::cache::NpmCache; -use super::cache::TarballCache; use super::resolution::NpmResolution; #[allow(clippy::too_many_arguments)] pub fn create_npm_fs_resolver( fs: Arc, - npm_cache: Arc, + npm_cache: Arc, npm_install_deps_provider: &Arc, progress_bar: &ProgressBar, resolution: Arc, - tarball_cache: Arc, + tarball_cache: Arc, maybe_node_modules_path: Option, system_info: NpmSystemInfo, lifecycle_scripts: LifecycleScriptsConfig, diff --git a/cli/npm/mod.rs b/cli/npm/mod.rs index 0e955ac5b4..48d90d7dd0 100644 --- a/cli/npm/mod.rs +++ b/cli/npm/mod.rs @@ -1,33 +1,39 @@ // Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. mod byonm; -mod common; mod managed; use std::borrow::Cow; use std::path::Path; use std::sync::Arc; -use common::maybe_auth_header_for_npm_registry; use dashmap::DashMap; use deno_core::error::AnyError; use deno_core::serde_json; +use deno_core::url::Url; use deno_npm::npm_rc::ResolvedNpmRc; use deno_npm::registry::NpmPackageInfo; use deno_resolver::npm::ByonmInNpmPackageChecker; use deno_resolver::npm::ByonmNpmResolver; use deno_resolver::npm::CliNpmReqResolver; use deno_resolver::npm::ResolvePkgFolderFromDenoReqError; +use deno_runtime::deno_fs::FileSystem; use deno_runtime::deno_node::NodePermissions; use deno_runtime::ops::process::NpmProcessStateProvider; use deno_semver::package::PackageNv; use deno_semver::package::PackageReq; -use managed::cache::registry_info::get_package_url; +use http::HeaderName; +use http::HeaderValue; use managed::create_managed_in_npm_pkg_checker; use node_resolver::InNpmPackageChecker; use node_resolver::NpmPackageFolderResolver; use crate::file_fetcher::FileFetcher; +use crate::http_util::HttpClientProvider; +use crate::util::fs::atomic_write_file_with_retries_and_fs; +use crate::util::fs::hard_link_dir_recursive; +use crate::util::fs::AtomicWriteFileFsAdapter; +use crate::util::progress_bar::ProgressBar; pub use self::byonm::CliByonmNpmResolver; pub use self::byonm::CliByonmNpmResolverCreateOptions; @@ -36,6 +42,99 @@ pub use self::managed::CliManagedNpmResolverCreateOptions; pub use self::managed::CliNpmResolverManagedSnapshotOption; pub use self::managed::ManagedCliNpmResolver; +pub type CliNpmTarballCache = deno_npm_cache::TarballCache; +pub type CliNpmCache = deno_npm_cache::NpmCache; +pub type CliNpmRegistryInfoProvider = + deno_npm_cache::RegistryInfoProvider; + +#[derive(Debug)] +pub struct CliNpmCacheEnv { + fs: Arc, + http_client_provider: Arc, + progress_bar: ProgressBar, +} + +impl CliNpmCacheEnv { + pub fn new( + fs: Arc, + http_client_provider: Arc, + progress_bar: ProgressBar, + ) -> Self { + Self { + fs, + http_client_provider, + progress_bar, + } + } +} + +#[async_trait::async_trait(?Send)] +impl deno_npm_cache::NpmCacheEnv for CliNpmCacheEnv { + fn exists(&self, path: &Path) -> bool { + self.fs.exists_sync(path) + } + + fn hard_link_dir_recursive( + &self, + from: &Path, + to: &Path, + ) -> Result<(), AnyError> { + // todo(dsherret): use self.fs here instead + hard_link_dir_recursive(from, to) + } + + fn atomic_write_file_with_retries( + &self, + file_path: &Path, + data: &[u8], + ) -> std::io::Result<()> { + atomic_write_file_with_retries_and_fs( + &AtomicWriteFileFsAdapter { + fs: self.fs.as_ref(), + write_mode: crate::cache::CACHE_PERM, + }, + file_path, + data, + ) + } + + async fn download_with_retries_on_any_tokio_runtime( + &self, + url: Url, + maybe_auth_header: Option<(HeaderName, HeaderValue)>, + ) -> Result>, deno_npm_cache::DownloadError> { + let guard = self.progress_bar.update(url.as_str()); + let client = self.http_client_provider.get_or_create().map_err(|err| { + deno_npm_cache::DownloadError { + status_code: None, + error: err, + } + })?; + client + .download_with_progress_and_retries(url, maybe_auth_header, &guard) + .await + .map_err(|err| { + use crate::http_util::DownloadError::*; + let status_code = match &err { + Fetch { .. } + | UrlParse { .. } + | HttpParse { .. } + | Json { .. } + | ToStr { .. } + | NoRedirectHeader { .. } + | TooManyRedirects => None, + BadResponse(bad_response_error) => { + Some(bad_response_error.status_code) + } + }; + deno_npm_cache::DownloadError { + status_code, + error: err.into(), + } + }) + } +} + pub enum CliNpmResolverCreateOptions { Managed(CliManagedNpmResolverCreateOptions), Byonm(CliByonmNpmResolverCreateOptions), @@ -179,13 +278,15 @@ impl NpmFetchResolver { if let Some(info) = self.info_by_name.get(name) { return info.value().clone(); } + // todo(#27198): use RegistryInfoProvider instead let fetch_package_info = || async { - let info_url = get_package_url(&self.npmrc, name); + let info_url = deno_npm_cache::get_package_url(&self.npmrc, name); let file_fetcher = self.file_fetcher.clone(); let registry_config = self.npmrc.get_registry_config(name); // TODO(bartlomieju): this should error out, not use `.ok()`. let maybe_auth_header = - maybe_auth_header_for_npm_registry(registry_config).ok()?; + deno_npm_cache::maybe_auth_header_for_npm_registry(registry_config) + .ok()?; // spawn due to the lsp's `Send` requirement let file = deno_core::unsync::spawn(async move { file_fetcher diff --git a/cli/util/path.rs b/cli/util/path.rs index 173f357c08..df66b83766 100644 --- a/cli/util/path.rs +++ b/cli/util/path.rs @@ -51,19 +51,6 @@ pub fn get_extension(file_path: &Path) -> Option { .map(|e| e.to_lowercase()); } -pub fn get_atomic_dir_path(file_path: &Path) -> PathBuf { - let rand = gen_rand_path_component(); - let new_file_name = format!( - ".{}_{}", - file_path - .file_name() - .map(|f| f.to_string_lossy()) - .unwrap_or(Cow::Borrowed("")), - rand - ); - file_path.with_file_name(new_file_name) -} - pub fn get_atomic_file_path(file_path: &Path) -> PathBuf { let rand = gen_rand_path_component(); let extension = format!("{rand}.tmp"); diff --git a/cli/util/sync/mod.rs b/cli/util/sync/mod.rs index 3c2ffbd7dd..c3b2a315b0 100644 --- a/cli/util/sync/mod.rs +++ b/cli/util/sync/mod.rs @@ -3,11 +3,9 @@ mod async_flag; mod sync_read_async_write_lock; mod task_queue; -mod value_creator; pub use async_flag::AsyncFlag; pub use deno_core::unsync::sync::AtomicFlag; pub use sync_read_async_write_lock::SyncReadAsyncWriteLock; pub use task_queue::TaskQueue; pub use task_queue::TaskQueuePermit; -pub use value_creator::MultiRuntimeAsyncValueCreator; diff --git a/cli/util/sync/value_creator.rs b/cli/util/sync/value_creator.rs deleted file mode 100644 index 57aabe801a..0000000000 --- a/cli/util/sync/value_creator.rs +++ /dev/null @@ -1,213 +0,0 @@ -// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. - -use std::sync::Arc; - -use deno_core::futures::future::BoxFuture; -use deno_core::futures::future::LocalBoxFuture; -use deno_core::futures::future::Shared; -use deno_core::futures::FutureExt; -use deno_core::parking_lot::Mutex; -use tokio::task::JoinError; - -type JoinResult = Result>; -type CreateFutureFn = - Box LocalBoxFuture<'static, TResult> + Send + Sync>; - -#[derive(Debug)] -struct State { - retry_index: usize, - future: Option>>>, -} - -/// Attempts to create a shared value asynchronously on one tokio runtime while -/// many runtimes are requesting the value. -/// -/// This is only useful when the value needs to get created once across -/// many runtimes. -/// -/// This handles the case where the tokio runtime creating the value goes down -/// while another one is waiting on the value. -pub struct MultiRuntimeAsyncValueCreator { - create_future: CreateFutureFn, - state: Mutex>, -} - -impl std::fmt::Debug - for MultiRuntimeAsyncValueCreator -{ - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_struct("MultiRuntimeAsyncValueCreator").finish() - } -} - -impl MultiRuntimeAsyncValueCreator { - pub fn new(create_future: CreateFutureFn) -> Self { - Self { - state: Mutex::new(State { - retry_index: 0, - future: None, - }), - create_future, - } - } - - pub async fn get(&self) -> TResult { - let (mut future, mut retry_index) = { - let mut state = self.state.lock(); - let future = match &state.future { - Some(future) => future.clone(), - None => { - let future = self.create_shared_future(); - state.future = Some(future.clone()); - future - } - }; - (future, state.retry_index) - }; - - loop { - let result = future.await; - - match result { - Ok(result) => return result, - Err(join_error) => { - if join_error.is_cancelled() { - let mut state = self.state.lock(); - - if state.retry_index == retry_index { - // we were the first one to retry, so create a new future - // that we'll run from the current runtime - state.retry_index += 1; - state.future = Some(self.create_shared_future()); - } - - retry_index = state.retry_index; - future = state.future.as_ref().unwrap().clone(); - - // just in case we're stuck in a loop - if retry_index > 1000 { - panic!("Something went wrong.") // should never happen - } - } else { - panic!("{}", join_error); - } - } - } - } - } - - fn create_shared_future( - &self, - ) -> Shared>> { - let future = (self.create_future)(); - deno_core::unsync::spawn(future) - .map(|result| result.map_err(Arc::new)) - .boxed() - .shared() - } -} - -#[cfg(test)] -mod test { - use deno_core::unsync::spawn; - - use super::*; - - #[tokio::test] - async fn single_runtime() { - let value_creator = MultiRuntimeAsyncValueCreator::new(Box::new(|| { - async { 1 }.boxed_local() - })); - let value = value_creator.get().await; - assert_eq!(value, 1); - } - - #[test] - fn multi_runtimes() { - let value_creator = - Arc::new(MultiRuntimeAsyncValueCreator::new(Box::new(|| { - async { - tokio::task::yield_now().await; - 1 - } - .boxed_local() - }))); - let handles = (0..3) - .map(|_| { - let value_creator = value_creator.clone(); - std::thread::spawn(|| { - create_runtime().block_on(async move { value_creator.get().await }) - }) - }) - .collect::>(); - for handle in handles { - assert_eq!(handle.join().unwrap(), 1); - } - } - - #[test] - fn multi_runtimes_first_never_finishes() { - let is_first_run = Arc::new(Mutex::new(true)); - let (tx, rx) = std::sync::mpsc::channel::<()>(); - let value_creator = Arc::new(MultiRuntimeAsyncValueCreator::new({ - let is_first_run = is_first_run.clone(); - Box::new(move || { - let is_first_run = is_first_run.clone(); - let tx = tx.clone(); - async move { - let is_first_run = { - let mut is_first_run = is_first_run.lock(); - let initial_value = *is_first_run; - *is_first_run = false; - tx.send(()).unwrap(); - initial_value - }; - if is_first_run { - tokio::time::sleep(std::time::Duration::from_millis(30_000)).await; - panic!("TIMED OUT"); // should not happen - } else { - tokio::task::yield_now().await; - } - 1 - } - .boxed_local() - }) - })); - std::thread::spawn({ - let value_creator = value_creator.clone(); - let is_first_run = is_first_run.clone(); - move || { - create_runtime().block_on(async { - let value_creator = value_creator.clone(); - // spawn a task that will never complete - spawn(async move { value_creator.get().await }); - // wait for the task to set is_first_run to false - while *is_first_run.lock() { - tokio::time::sleep(std::time::Duration::from_millis(20)).await; - } - // now exit the runtime while the value_creator is still pending - }) - } - }); - let handle = { - let value_creator = value_creator.clone(); - std::thread::spawn(|| { - create_runtime().block_on(async move { - let value_creator = value_creator.clone(); - rx.recv().unwrap(); - // even though the other runtime shutdown, this get() should - // recover and still get the value - value_creator.get().await - }) - }) - }; - assert_eq!(handle.join().unwrap(), 1); - } - - fn create_runtime() -> tokio::runtime::Runtime { - tokio::runtime::Builder::new_current_thread() - .enable_all() - .build() - .unwrap() - } -} diff --git a/resolvers/npm_cache/Cargo.toml b/resolvers/npm_cache/Cargo.toml new file mode 100644 index 0000000000..df01f62131 --- /dev/null +++ b/resolvers/npm_cache/Cargo.toml @@ -0,0 +1,42 @@ +# Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. + +[package] +name = "deno_npm_cache" +version = "0.0.1" +authors.workspace = true +edition.workspace = true +license.workspace = true +readme = "README.md" +repository.workspace = true +description = "Helpers for downloading and caching npm dependencies for Deno" + +[lib] +path = "lib.rs" + +[dependencies] +# todo(dsherret): remove this dependency +anyhow.workspace = true +# todo(dsherret): remove this dependency +deno_core.workspace = true + +async-trait.workspace = true +base64.workspace = true +boxed_error.workspace = true +deno_cache_dir.workspace = true +deno_npm.workspace = true +deno_semver.workspace = true +deno_unsync = { workspace = true, features = ["tokio"] } +faster-hex.workspace = true +flate2 = { workspace = true, features = ["zlib-ng-compat"] } +futures.workspace = true +http.workspace = true +log.workspace = true +parking_lot.workspace = true +percent-encoding.workspace = true +rand.workspace = true +ring.workspace = true +serde_json.workspace = true +tar.workspace = true +tempfile = "3.4.0" +thiserror.workspace = true +url.workspace = true diff --git a/resolvers/npm_cache/README.md b/resolvers/npm_cache/README.md new file mode 100644 index 0000000000..a7edbb4159 --- /dev/null +++ b/resolvers/npm_cache/README.md @@ -0,0 +1,6 @@ +# deno_npm_cache + +[![crates](https://img.shields.io/crates/v/deno_npm_cache.svg)](https://crates.io/crates/deno_npm_cache) +[![docs](https://docs.rs/deno_npm_cache/badge.svg)](https://docs.rs/deno_npm_cache) + +Helpers for downloading and caching npm dependencies for Deno. diff --git a/cli/npm/managed/cache/mod.rs b/resolvers/npm_cache/lib.rs similarity index 71% rename from cli/npm/managed/cache/mod.rs rename to resolvers/npm_cache/lib.rs index 8ae99f41e0..4e8966a4e1 100644 --- a/cli/npm/managed/cache/mod.rs +++ b/resolvers/npm_cache/lib.rs @@ -1,63 +1,133 @@ // Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. use std::collections::HashSet; -use std::fs; use std::io::ErrorKind; use std::path::Path; use std::path::PathBuf; use std::sync::Arc; -use deno_ast::ModuleSpecifier; +use anyhow::bail; +use anyhow::Context; +use anyhow::Error as AnyError; use deno_cache_dir::npm::NpmCacheDir; -use deno_core::anyhow::bail; -use deno_core::anyhow::Context; -use deno_core::error::AnyError; -use deno_core::parking_lot::Mutex; -use deno_core::serde_json; -use deno_core::url::Url; use deno_npm::npm_rc::ResolvedNpmRc; use deno_npm::registry::NpmPackageInfo; use deno_npm::NpmPackageCacheFolderId; use deno_semver::package::PackageNv; use deno_semver::Version; +use http::HeaderName; +use http::HeaderValue; +use http::StatusCode; +use parking_lot::Mutex; +use url::Url; -use crate::args::CacheSetting; -use crate::cache::CACHE_PERM; -use crate::util::fs::atomic_write_file_with_retries; -use crate::util::fs::hard_link_dir_recursive; - -pub mod registry_info; +mod registry_info; +mod remote; mod tarball; mod tarball_extract; -pub use registry_info::RegistryInfoDownloader; +pub use registry_info::RegistryInfoProvider; pub use tarball::TarballCache; +// todo(#27198): make both of these private and get the rest of the code +// using RegistryInfoProvider. +pub use registry_info::get_package_url; +pub use remote::maybe_auth_header_for_npm_registry; + +#[derive(Debug)] +pub struct DownloadError { + pub status_code: Option, + pub error: AnyError, +} + +impl std::error::Error for DownloadError { + fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { + Some(self.error.as_ref()) + } +} + +impl std::fmt::Display for DownloadError { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + self.error.fmt(f) + } +} + +#[async_trait::async_trait(?Send)] +pub trait NpmCacheEnv: Send + Sync + 'static { + fn exists(&self, path: &Path) -> bool; + fn hard_link_dir_recursive( + &self, + from: &Path, + to: &Path, + ) -> Result<(), AnyError>; + fn atomic_write_file_with_retries( + &self, + file_path: &Path, + data: &[u8], + ) -> std::io::Result<()>; + async fn download_with_retries_on_any_tokio_runtime( + &self, + url: Url, + maybe_auth_header: Option<(HeaderName, HeaderValue)>, + ) -> Result>, DownloadError>; +} + +/// Indicates how cached source files should be handled. +#[derive(Debug, Clone, Eq, PartialEq)] +pub enum NpmCacheSetting { + /// Only the cached files should be used. Any files not in the cache will + /// error. This is the equivalent of `--cached-only` in the CLI. + Only, + /// No cached source files should be used, and all files should be reloaded. + /// This is the equivalent of `--reload` in the CLI. + ReloadAll, + /// Only some cached resources should be used. This is the equivalent of + /// `--reload=npm:chalk` + ReloadSome { npm_package_names: Vec }, + /// The cached source files should be used for local modules. This is the + /// default behavior of the CLI. + Use, +} + +impl NpmCacheSetting { + pub fn should_use_for_npm_package(&self, package_name: &str) -> bool { + match self { + NpmCacheSetting::ReloadAll => false, + NpmCacheSetting::ReloadSome { npm_package_names } => { + !npm_package_names.iter().any(|n| n == package_name) + } + _ => true, + } + } +} + /// Stores a single copy of npm packages in a cache. #[derive(Debug)] -pub struct NpmCache { +pub struct NpmCache { + env: Arc, cache_dir: Arc, - cache_setting: CacheSetting, + cache_setting: NpmCacheSetting, npmrc: Arc, - /// ensures a package is only downloaded once per run previously_reloaded_packages: Mutex>, } -impl NpmCache { +impl NpmCache { pub fn new( cache_dir: Arc, - cache_setting: CacheSetting, + cache_setting: NpmCacheSetting, + env: Arc, npmrc: Arc, ) -> Self { Self { cache_dir, cache_setting, + env, previously_reloaded_packages: Default::default(), npmrc, } } - pub fn cache_setting(&self) -> &CacheSetting { + pub fn cache_setting(&self) -> &NpmCacheSetting { &self.cache_setting } @@ -118,7 +188,9 @@ impl NpmCache { // it seems Windows does an "AccessDenied" error when moving a // directory with hard links, so that's why this solution is done with_folder_sync_lock(&folder_id.nv, &package_folder, || { - hard_link_dir_recursive(&original_package_folder, &package_folder) + self + .env + .hard_link_dir_recursive(&original_package_folder, &package_folder) })?; Ok(()) } @@ -158,7 +230,7 @@ impl NpmCache { pub fn resolve_package_folder_id_from_specifier( &self, - specifier: &ModuleSpecifier, + specifier: &Url, ) -> Option { self .cache_dir @@ -180,7 +252,7 @@ impl NpmCache { ) -> Result, AnyError> { let file_cache_path = self.get_registry_package_info_file_cache_path(name); - let file_text = match fs::read_to_string(file_cache_path) { + let file_text = match std::fs::read_to_string(file_cache_path) { Ok(file_text) => file_text, Err(err) if err.kind() == ErrorKind::NotFound => return Ok(None), Err(err) => return Err(err.into()), @@ -195,7 +267,9 @@ impl NpmCache { ) -> Result<(), AnyError> { let file_cache_path = self.get_registry_package_info_file_cache_path(name); let file_text = serde_json::to_string(&package_info)?; - atomic_write_file_with_retries(&file_cache_path, file_text, CACHE_PERM)?; + self + .env + .atomic_write_file_with_retries(&file_cache_path, file_text.as_bytes())?; Ok(()) } @@ -216,7 +290,7 @@ fn with_folder_sync_lock( output_folder: &Path, action: impl FnOnce() -> Result<(), AnyError>, ) -> Result<(), AnyError> { - fs::create_dir_all(output_folder).with_context(|| { + std::fs::create_dir_all(output_folder).with_context(|| { format!("Error creating '{}'.", output_folder.display()) })?; @@ -229,7 +303,7 @@ fn with_folder_sync_lock( // then wait until the other process finishes with a timeout), but // for now this is good enough. let sync_lock_path = output_folder.join(NPM_PACKAGE_SYNC_LOCK_FILENAME); - match fs::OpenOptions::new() + match std::fs::OpenOptions::new() .write(true) .create(true) .truncate(false) @@ -257,7 +331,7 @@ fn with_folder_sync_lock( match inner(output_folder, action) { Ok(()) => Ok(()), Err(err) => { - if let Err(remove_err) = fs::remove_dir_all(output_folder) { + if let Err(remove_err) = std::fs::remove_dir_all(output_folder) { if remove_err.kind() != std::io::ErrorKind::NotFound { bail!( concat!( diff --git a/cli/npm/managed/cache/registry_info.rs b/resolvers/npm_cache/registry_info.rs similarity index 84% rename from cli/npm/managed/cache/registry_info.rs rename to resolvers/npm_cache/registry_info.rs index 6d39d3c13f..7ab50f0495 100644 --- a/cli/npm/managed/cache/registry_info.rs +++ b/resolvers/npm_cache/registry_info.rs @@ -3,28 +3,22 @@ use std::collections::HashMap; use std::sync::Arc; -use deno_core::anyhow::anyhow; -use deno_core::anyhow::bail; -use deno_core::anyhow::Context; -use deno_core::error::custom_error; -use deno_core::error::AnyError; -use deno_core::futures::future::LocalBoxFuture; -use deno_core::futures::FutureExt; -use deno_core::parking_lot::Mutex; -use deno_core::serde_json; -use deno_core::url::Url; +use anyhow::anyhow; +use anyhow::bail; +use anyhow::Context; +use anyhow::Error as AnyError; use deno_npm::npm_rc::ResolvedNpmRc; use deno_npm::registry::NpmPackageInfo; +use deno_unsync::sync::MultiRuntimeAsyncValueCreator; +use futures::future::LocalBoxFuture; +use futures::FutureExt; +use parking_lot::Mutex; +use url::Url; -use crate::args::CacheSetting; -use crate::http_util::HttpClientProvider; -use crate::npm::common::maybe_auth_header_for_npm_registry; -use crate::util::progress_bar::ProgressBar; -use crate::util::sync::MultiRuntimeAsyncValueCreator; - -use super::NpmCache; - -// todo(dsherret): create seams and unit test this +use crate::remote::maybe_auth_header_for_npm_registry; +use crate::NpmCache; +use crate::NpmCacheEnv; +use crate::NpmCacheSetting; type LoadResult = Result>; type LoadFuture = LocalBoxFuture<'static, LoadResult>; @@ -49,30 +43,31 @@ enum MemoryCacheItem { MemoryCached(Result>, Arc>), } +// todo(#27198): refactor to store this only in the http cache and also +// consolidate with CliNpmRegistryApi. + /// Downloads packuments from the npm registry. /// /// This is shared amongst all the workers. #[derive(Debug)] -pub struct RegistryInfoDownloader { - cache: Arc, - http_client_provider: Arc, +pub struct RegistryInfoProvider { + // todo(#27198): remove this + cache: Arc>, + env: Arc, npmrc: Arc, - progress_bar: ProgressBar, memory_cache: Mutex>, } -impl RegistryInfoDownloader { +impl RegistryInfoProvider { pub fn new( - cache: Arc, - http_client_provider: Arc, + cache: Arc>, + env: Arc, npmrc: Arc, - progress_bar: ProgressBar, ) -> Self { Self { cache, - http_client_provider, + env, npmrc, - progress_bar, memory_cache: Default::default(), } } @@ -94,8 +89,8 @@ impl RegistryInfoDownloader { self: &Arc, name: &str, ) -> Result>, AnyError> { - if *self.cache.cache_setting() == CacheSetting::Only { - return Err(custom_error( + if *self.cache.cache_setting() == NpmCacheSetting::Only { + return Err(deno_core::error::custom_error( "NotCached", format!( "An npm specifier not found in cache: \"{name}\", --cached-only is specified." @@ -167,7 +162,7 @@ impl RegistryInfoDownloader { ) -> Result { // this scenario failing should be exceptionally rare so let's // deal with improving it only when anyone runs into an issue - let maybe_package_info = deno_core::unsync::spawn_blocking({ + let maybe_package_info = deno_unsync::spawn_blocking({ let cache = self.cache.clone(); let name = name.to_string(); move || cache.load_package_info(&name) @@ -199,20 +194,18 @@ impl RegistryInfoDownloader { return std::future::ready(Err(Arc::new(err))).boxed_local() } }; - let guard = self.progress_bar.update(package_url.as_str()); let name = name.to_string(); async move { - let client = downloader.http_client_provider.get_or_create()?; - let maybe_bytes = client - .download_with_progress_and_retries( + let maybe_bytes = downloader + .env + .download_with_retries_on_any_tokio_runtime( package_url, maybe_auth_header, - &guard, ) .await?; match maybe_bytes { Some(bytes) => { - let future_result = deno_core::unsync::spawn_blocking( + let future_result = deno_unsync::spawn_blocking( move || -> Result { let package_info = serde_json::from_slice(&bytes)?; match downloader.cache.save_package_info(&name, &package_info) { @@ -241,6 +234,8 @@ impl RegistryInfoDownloader { } } +// todo(#27198): make this private and only use RegistryInfoProvider in the rest of +// the code pub fn get_package_url(npmrc: &ResolvedNpmRc, name: &str) -> Url { let registry_url = npmrc.get_registry_url(name); // The '/' character in scoped package names "@scope/name" must be diff --git a/cli/npm/common.rs b/resolvers/npm_cache/remote.rs similarity index 95% rename from cli/npm/common.rs rename to resolvers/npm_cache/remote.rs index 55f1bc086d..538554612f 100644 --- a/cli/npm/common.rs +++ b/resolvers/npm_cache/remote.rs @@ -1,10 +1,10 @@ // Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. +use anyhow::bail; +use anyhow::Context; +use anyhow::Error as AnyError; use base64::prelude::BASE64_STANDARD; use base64::Engine; -use deno_core::anyhow::bail; -use deno_core::anyhow::Context; -use deno_core::error::AnyError; use deno_npm::npm_rc::RegistryConfig; use http::header; diff --git a/cli/npm/managed/cache/tarball.rs b/resolvers/npm_cache/tarball.rs similarity index 77% rename from cli/npm/managed/cache/tarball.rs rename to resolvers/npm_cache/tarball.rs index 7cf88d6d64..3102d811d1 100644 --- a/cli/npm/managed/cache/tarball.rs +++ b/resolvers/npm_cache/tarball.rs @@ -3,33 +3,26 @@ use std::collections::HashMap; use std::sync::Arc; -use deno_core::anyhow::anyhow; -use deno_core::anyhow::bail; -use deno_core::anyhow::Context; -use deno_core::error::custom_error; -use deno_core::error::AnyError; -use deno_core::futures::future::LocalBoxFuture; -use deno_core::futures::FutureExt; -use deno_core::parking_lot::Mutex; -use deno_core::url::Url; +use anyhow::anyhow; +use anyhow::bail; +use anyhow::Context; +use anyhow::Error as AnyError; use deno_npm::npm_rc::ResolvedNpmRc; use deno_npm::registry::NpmPackageVersionDistInfo; -use deno_runtime::deno_fs::FileSystem; use deno_semver::package::PackageNv; +use deno_unsync::sync::MultiRuntimeAsyncValueCreator; +use futures::future::LocalBoxFuture; +use futures::FutureExt; use http::StatusCode; +use parking_lot::Mutex; +use url::Url; -use crate::args::CacheSetting; -use crate::http_util::DownloadError; -use crate::http_util::HttpClientProvider; -use crate::npm::common::maybe_auth_header_for_npm_registry; -use crate::util::progress_bar::ProgressBar; -use crate::util::sync::MultiRuntimeAsyncValueCreator; - -use super::tarball_extract::verify_and_extract_tarball; -use super::tarball_extract::TarballExtractionMode; -use super::NpmCache; - -// todo(dsherret): create seams and unit test this +use crate::remote::maybe_auth_header_for_npm_registry; +use crate::tarball_extract::verify_and_extract_tarball; +use crate::tarball_extract::TarballExtractionMode; +use crate::NpmCache; +use crate::NpmCacheEnv; +use crate::NpmCacheSetting; type LoadResult = Result<(), Arc>; type LoadFuture = LocalBoxFuture<'static, LoadResult>; @@ -49,29 +42,23 @@ enum MemoryCacheItem { /// /// This is shared amongst all the workers. #[derive(Debug)] -pub struct TarballCache { - cache: Arc, - fs: Arc, - http_client_provider: Arc, +pub struct TarballCache { + cache: Arc>, + env: Arc, npmrc: Arc, - progress_bar: ProgressBar, memory_cache: Mutex>, } -impl TarballCache { +impl TarballCache { pub fn new( - cache: Arc, - fs: Arc, - http_client_provider: Arc, + cache: Arc>, + env: Arc, npmrc: Arc, - progress_bar: ProgressBar, ) -> Self { Self { cache, - fs, - http_client_provider, + env, npmrc, - progress_bar, memory_cache: Default::default(), } } @@ -144,11 +131,11 @@ impl TarballCache { let package_folder = tarball_cache.cache.package_folder_for_nv_and_url(&package_nv, registry_url); let should_use_cache = tarball_cache.cache.should_use_cache_for_package(&package_nv); - let package_folder_exists = tarball_cache.fs.exists_sync(&package_folder); + let package_folder_exists = tarball_cache.env.exists(&package_folder); if should_use_cache && package_folder_exists { return Ok(()); - } else if tarball_cache.cache.cache_setting() == &CacheSetting::Only { - return Err(custom_error( + } else if tarball_cache.cache.cache_setting() == &NpmCacheSetting::Only { + return Err(deno_core::error::custom_error( "NotCached", format!( "An npm specifier not found in cache: \"{}\", --cached-only is specified.", @@ -169,15 +156,13 @@ impl TarballCache { tarball_cache.npmrc.tarball_config(&tarball_uri); let maybe_auth_header = maybe_registry_config.and_then(|c| maybe_auth_header_for_npm_registry(c).ok()?); - let guard = tarball_cache.progress_bar.update(&dist.tarball); - let result = tarball_cache.http_client_provider - .get_or_create()? - .download_with_progress_and_retries(tarball_uri, maybe_auth_header, &guard) + let result = tarball_cache.env + .download_with_retries_on_any_tokio_runtime(tarball_uri, maybe_auth_header) .await; let maybe_bytes = match result { Ok(maybe_bytes) => maybe_bytes, - Err(DownloadError::BadResponse(err)) => { - if err.status_code == StatusCode::UNAUTHORIZED + Err(err) => { + if err.status_code == Some(StatusCode::UNAUTHORIZED) && maybe_registry_config.is_none() && tarball_cache.npmrc.get_registry_config(&package_nv.name).auth_token.is_some() { @@ -194,7 +179,6 @@ impl TarballCache { } return Err(err.into()) }, - Err(err) => return Err(err.into()), }; match maybe_bytes { Some(bytes) => { @@ -213,7 +197,7 @@ impl TarballCache { }; let dist = dist.clone(); let package_nv = package_nv.clone(); - deno_core::unsync::spawn_blocking(move || { + deno_unsync::spawn_blocking(move || { verify_and_extract_tarball( &package_nv, &bytes, diff --git a/cli/npm/managed/cache/tarball_extract.rs b/resolvers/npm_cache/tarball_extract.rs similarity index 90% rename from cli/npm/managed/cache/tarball_extract.rs rename to resolvers/npm_cache/tarball_extract.rs index e2d242e662..262618d905 100644 --- a/cli/npm/managed/cache/tarball_extract.rs +++ b/resolvers/npm_cache/tarball_extract.rs @@ -1,16 +1,17 @@ // Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. +use std::borrow::Cow; use std::collections::HashSet; use std::fs; use std::io::ErrorKind; use std::path::Path; use std::path::PathBuf; +use anyhow::bail; +use anyhow::Context; +use anyhow::Error as AnyError; use base64::prelude::BASE64_STANDARD; use base64::Engine; -use deno_core::anyhow::bail; -use deno_core::anyhow::Context; -use deno_core::error::AnyError; use deno_npm::registry::NpmPackageVersionDistInfo; use deno_npm::registry::NpmPackageVersionDistInfoIntegrity; use deno_semver::package::PackageNv; @@ -18,8 +19,6 @@ use flate2::read::GzDecoder; use tar::Archive; use tar::EntryType; -use crate::util::path::get_atomic_dir_path; - #[derive(Debug, Copy, Clone)] pub enum TarballExtractionMode { /// Overwrites the destination directory without deleting any files. @@ -206,10 +205,30 @@ fn extract_tarball(data: &[u8], output_folder: &Path) -> Result<(), AnyError> { Ok(()) } +fn get_atomic_dir_path(file_path: &Path) -> PathBuf { + let rand = gen_rand_path_component(); + let new_file_name = format!( + ".{}_{}", + file_path + .file_name() + .map(|f| f.to_string_lossy()) + .unwrap_or(Cow::Borrowed("")), + rand + ); + file_path.with_file_name(new_file_name) +} + +fn gen_rand_path_component() -> String { + (0..4).fold(String::new(), |mut output, _| { + output.push_str(&format!("{:02x}", rand::random::())); + output + }) +} + #[cfg(test)] mod test { use deno_semver::Version; - use test_util::TempDir; + use tempfile::TempDir; use super::*; @@ -303,21 +322,21 @@ mod test { #[test] fn rename_with_retries_succeeds_exists() { - let temp_dir = TempDir::new(); + let temp_dir = TempDir::new().unwrap(); let folder_1 = temp_dir.path().join("folder_1"); let folder_2 = temp_dir.path().join("folder_2"); - folder_1.create_dir_all(); - folder_1.join("a.txt").write("test"); - folder_2.create_dir_all(); + std::fs::create_dir_all(&folder_1).unwrap(); + std::fs::write(folder_1.join("a.txt"), "test").unwrap(); + std::fs::create_dir_all(&folder_2).unwrap(); // this will not end up in the output as rename_with_retries assumes // the folders ending up at the destination are the same - folder_2.join("b.txt").write("test2"); + std::fs::write(folder_2.join("b.txt"), "test2").unwrap(); let dest_folder = temp_dir.path().join("dest_folder"); - rename_with_retries(folder_1.as_path(), dest_folder.as_path()).unwrap(); - rename_with_retries(folder_2.as_path(), dest_folder.as_path()).unwrap(); + rename_with_retries(folder_1.as_path(), &dest_folder).unwrap(); + rename_with_retries(folder_2.as_path(), &dest_folder).unwrap(); assert!(dest_folder.join("a.txt").exists()); assert!(!dest_folder.join("b.txt").exists()); } diff --git a/resolvers/npm_cache/todo.md b/resolvers/npm_cache/todo.md new file mode 100644 index 0000000000..e10b1cfd89 --- /dev/null +++ b/resolvers/npm_cache/todo.md @@ -0,0 +1,9 @@ +This crate is a work in progress: + +1. Remove `deno_core` dependency. +1. Remove `anyhow` dependency. +1. Add a clippy.toml file that bans accessing the file system directory and + instead does it through a trait. +1. Make this crate work in Wasm. +1. Refactor to store npm packument in a single place: + https://github.com/denoland/deno/issues/27198