@uploadista/observability 0.0.7 → 0.0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +1 -1
- package/dist/{index.d.ts → index.d.mts} +51 -51
- package/dist/index.d.mts.map +1 -0
- package/dist/{index.js → index.mjs} +1 -1
- package/dist/index.mjs.map +1 -0
- package/package.json +11 -11
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var e=Object.create,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,o=(e,i,o,s)=>{if(i&&typeof i==`object`||typeof i==`function`)for(var c=r(i),l=0,u=c.length,d;l<u;l++)d=c[l],!a.call(e,d)&&d!==o&&t(e,d,{get:(e=>i[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},s=(n,r,a)=>(a=n==null?{}:e(i(n)),o(r||!n||!n.__esModule?t(a,`default`,{value:n,enumerable:!0}):a,n));let c=require(`effect`);c=s(c);let l=require(`@effect/opentelemetry`);l=s(l);let u=require(`@opentelemetry/sdk-trace-base`);u=s(u);const d=e=>{if(!e||typeof e!=`object`)return`unknown_error`;let t=`code`in e?e.code:void 0,n=`name`in e?e.name:void 0,r=e instanceof Error?e.message.toLowerCase():``;return t===`NetworkError`||t===`ECONNRESET`||t===`ENOTFOUND`||t===`ETIMEDOUT`||r.indexOf(`network`)>=0||r.indexOf(`timeout`)>=0?`network_error`:t===`InvalidAccessKeyId`||t===`SignatureDoesNotMatch`||t===`TokenRefreshRequired`||t===`AuthenticationFailed`||n===`AuthenticationError`||r.indexOf(`authentication`)>=0||r.indexOf(`unauthorized`)>=0?`authentication_error`:t===`AccessDenied`||t===`AccountProblem`||t===`Forbidden`||n===`AuthorizationError`||r.indexOf(`forbidden`)>=0||r.indexOf(`permission`)>=0?`authorization_error`:t===`SlowDown`||t===`RequestTimeTooSkewed`||t===`TooManyRequests`||n===`ThrottlingError`||r.indexOf(`throttl`)>=0||r.indexOf(`rate limit`)>=0?`throttling_error`:t===`InternalError`||t===`ServiceUnavailable`||t===`InternalServerError`||n===`ServerError`||r.indexOf(`server error`)>=0||r.indexOf(`service unavailable`)>=0?`server_error`:t===`InvalidRequest`||t===`MalformedXML`||t===`RequestEntityTooLarge`||t===`BadRequest`||n===`ClientError`||r.indexOf(`bad request`)>=0||r.indexOf(`invalid`)>=0?`client_error`:`unknown_error`},ee=(e,t)=>e=>{if(t){let n=t(e);if(n!==null)return n}return d(e)},te=(e,t,n,r,i={},a=d)=>c.Effect.gen(function*(){let o=a(r);yield*t.uploadErrorsTotal.pipe(c.Metric.tagged(`operation`,n),c.Metric.tagged(`error_category`,o))(c.Effect.succeed(1));let s={storage_type:e,operation:n,error_category:o,error_type:typeof r,error_message:r instanceof Error?r.message:String(r),error_code:r&&typeof r==`object`&&`code`in r?r.code:void 0,error_name:r&&typeof r==`object`&&`name`in r?r.name:void 0,...i};yield*c.Effect.logError(`${e.toUpperCase()} ${n} failed`).pipe(c.Effect.annotateLogs(s))}),f=(e,t,n)=>{let r=ee(e,n);return(n,i,a={})=>te(e,t,n,i,a,r)};var p=class extends c.Context.Tag(`Observability`)(){},m=class extends c.Context.Tag(`StorageObservability`)(){},h=class extends c.Context.Tag(`UploadObservability`)(){},g=class extends c.Context.Tag(`FlowObservability`)(){};const ne=(e,t=!0)=>c.Layer.succeed(p,{serviceName:e,enabled:t}),re=(e,t,n=!0)=>c.Layer.succeed(m,{serviceName:`uploadista-${e}-store`,storageType:e,metrics:t,enabled:n}),_=(e=!0)=>c.Layer.succeed(h,{serviceName:`uploadista-upload-server`,enabled:e,metrics:{uploadCreated:c.Effect.void,uploadCompleted:c.Effect.void,uploadFailed:c.Effect.void,chunkUploaded:c.Effect.void}}),v=(e=!0)=>c.Layer.succeed(g,{serviceName:`uploadista-flow-engine`,enabled:e,metrics:{flowStarted:c.Effect.void,flowCompleted:c.Effect.void,flowFailed:c.Effect.void,nodeExecuted:c.Effect.void}}),ie=ne(`uploadista-disabled`,!1),ae=e=>re(e,{},!1),oe=_(!1),se=v(!1),y=c.Effect.gen(function*(){let e=yield*c.Effect.serviceOption(p);return c.Option.match(e,{onNone:()=>!1,onSome:e=>e.enabled})}),ce=e=>c.Effect.gen(function*(){if(yield*y){let t=yield*e;return c.Option.some(t)}return c.Option.none()}),b=(e,t)=>c.Effect.log(e).pipe(c.Effect.annotateLogs(t)),x=(e,t,n)=>b(`Upload progress`,{storage_type:e,upload_id:t,uploaded_bytes:n.uploadedBytes,total_bytes:n.totalBytes,progress_percentage:Math.round(n.uploadedBytes/n.totalBytes*100),...n.partNumber&&{part_number:n.partNumber},...n.speed&&{upload_speed_bps:n.speed}}),S=(e,t,n,r)=>b(`${e.toUpperCase()} ${t}`,{storage_type:e,operation:t,upload_id:n,...r}),C=(e,t,n)=>{let r=n.throughputBps?n.throughputBps/(1024*1024):0;return b(`${e.toUpperCase()} upload completed`,{storage_type:e,upload_id:t,file_size_bytes:n.fileSize,file_size_mb:Math.round(n.fileSize/(1024*1024)*100)/100,total_duration_ms:n.totalDurationMs,total_duration_seconds:Math.round(n.totalDurationMs/1e3*100)/100,throughput_bps:n.throughputBps,throughput_mbps:Math.round(r*100)/100,...n.partsCount&&{parts_count:n.partsCount},...n.averagePartSize&&{average_part_size_bytes:n.averagePartSize,average_part_size_mb:Math.round(n.averagePartSize/(1024*1024)*100)/100},...n.retryCount&&{retry_count:n.retryCount}})},w=e=>({uploadRequestsTotal:c.Metric.counter(`${e}_upload_requests_total`,{description:`Total number of upload requests for ${e}`}),uploadPartsTotal:c.Metric.counter(`${e}_upload_parts_total`,{description:`Total number of individual parts uploaded for ${e}`}),uploadSuccessTotal:c.Metric.counter(`${e}_upload_success_total`,{description:`Total number of successful uploads for ${e}`}),uploadErrorsTotal:c.Metric.counter(`${e}_upload_errors_total`,{description:`Total number of upload errors for ${e}`}),apiCallsTotal:c.Metric.counter(`${e}_api_calls_total`,{description:`Total number of API calls for ${e}`})}),T=e=>({uploadDurationHistogram:c.Metric.histogram(`${e}_upload_duration_seconds`,c.MetricBoundaries.exponential({start:.01,factor:2,count:20}),`Duration of upload operations in seconds for ${e}`),partUploadDurationHistogram:c.Metric.histogram(`${e}_part_upload_duration_seconds`,c.MetricBoundaries.exponential({start:.001,factor:2,count:15}),`Duration of individual part uploads in seconds for ${e}`),fileSizeHistogram:c.Metric.histogram(`${e}_file_size_bytes`,c.MetricBoundaries.exponential({start:1024,factor:2,count:25}),`Size of uploaded files in bytes for ${e}`),partSizeHistogram:c.Metric.histogram(`${e}_part_size_bytes`,c.MetricBoundaries.linear({start:5242880,width:1048576,count:20}),`Size of upload parts in bytes for ${e}`)}),le=e=>({activeUploadsGauge:c.Metric.gauge(`${e}_active_uploads`,{description:`Number of currently active uploads for ${e}`}),uploadThroughputGauge:c.Metric.gauge(`${e}_upload_throughput_bytes_per_second`,{description:`Current upload throughput in bytes per second for ${e}`})}),ue=e=>({uploadLatencySummary:c.Metric.summary({name:`${e}_upload_latency_seconds`,maxAge:`10 minutes`,maxSize:1e3,error:.01,quantiles:[.5,.9,.95,.99],description:`Upload latency percentiles for ${e}`})}),E=e=>({...w(e),...T(e),...le(e),...ue(e)}),D=e=>{let t=E(e),n={serviceName:`test-${e}-store`,storageType:e,metrics:t,enabled:!0};return c.Layer.succeed(m,n)},O=()=>{let e={serviceName:`test-upload-server`,enabled:!0,metrics:{uploadCreated:c.Effect.void,uploadCompleted:c.Effect.void,uploadFailed:c.Effect.void,chunkUploaded:c.Effect.void}};return c.Layer.succeed(h,e)},k=()=>{let e={serviceName:`test-flow-engine`,enabled:!0,metrics:{flowStarted:c.Effect.void,flowCompleted:c.Effect.void,flowFailed:c.Effect.void,nodeExecuted:c.Effect.void}};return c.Layer.succeed(g,e)},de=e=>c.Effect.gen(function*(){let t=yield*e;return yield*c.Metric.snapshot,t}),fe=e=>c.Effect.gen(function*(){yield*c.Metric.snapshot;let t=yield*e;return yield*c.Metric.snapshot,t}),A=(e=`test-storage`)=>({storageObservability:D(e),uploadObservability:O(),flowObservability:k()}),pe=(e,t=`test-storage`)=>{let n=A(t);return e.pipe(c.Effect.provide(n.storageObservability),c.Effect.provide(n.uploadObservability),c.Effect.provide(n.flowObservability))},me=c.Context.GenericTag(`TracingService`),he=e=>{let t=e?.serviceName??`uploadista-storage`;return c.Layer.succeed(me,{serviceName:t})},j=e=>he({serviceName:`uploadista-${e}-store`}),M=(e,t,n)=>r=>r.pipe(c.Effect.withSpan(`${t}-${e}`,{attributes:{"storage.type":t,operation:e,...n}})),ge=l.WebSdk.layer(()=>({resource:{serviceName:`uploadista-storage`},spanProcessor:new u.BatchSpanProcessor(new u.ConsoleSpanExporter)})),_e=l.NodeSdk.layer(()=>({resource:{serviceName:`uploadista-storage`},spanProcessor:new u.BatchSpanProcessor(new u.ConsoleSpanExporter)})),ve=l.WebSdk.layer(()=>({resource:{serviceName:`uploadista-storage-workers`},spanProcessor:new u.BatchSpanProcessor(new u.ConsoleSpanExporter)})),N=(e,t,n)=>n.pipe(c.Effect.tap(()=>e.uploadRequestsTotal.pipe(c.Metric.tagged(`upload_id`,t))(c.Effect.succeed(1))),c.Effect.tapError(()=>e.uploadErrorsTotal.pipe(c.Metric.tagged(`upload_id`,t))(c.Effect.succeed(1))),c.Effect.tap(()=>e.uploadSuccessTotal.pipe(c.Metric.tagged(`upload_id`,t))(c.Effect.succeed(1)))),P=(e,t,n)=>n.pipe(c.Effect.tap(()=>e.apiCallsTotal.pipe(c.Metric.tagged(`operation`,t))(c.Effect.succeed(1)))),F=(e,t)=>c.Effect.gen(function*(){let n=yield*c.Effect.sync(()=>Date.now()),r=yield*t,i=((yield*c.Effect.sync(()=>Date.now()))-n)/1e3;return yield*e(c.Effect.succeed(i)),r}),I=(e,t,n)=>n.pipe(c.Effect.tap(()=>e.fileSizeHistogram(c.Effect.succeed(t)))),ye=(e,t,n)=>n.pipe(c.Effect.tap(()=>e.partSizeHistogram(c.Effect.succeed(t)))),L=(e,t)=>t.pipe(c.Effect.tap(()=>e.activeUploadsGauge(c.Effect.succeed(1))),c.Effect.ensuring(e.activeUploadsGauge(c.Effect.succeed(-1)))),R=(e,t,n)=>c.Effect.gen(function*(){let r=yield*c.Effect.sync(()=>Date.now()),i=yield*n,a=((yield*c.Effect.sync(()=>Date.now()))-r)/1e3,o=a>0?t/a:0;return yield*e.uploadThroughputGauge(c.Effect.succeed(o)),i}),z=(e,t,n,r,i)=>{let a=r.pipe(n=>P(e,t,n),t=>N(e,n,t),t=>F(e.uploadDurationHistogram,t),t=>L(e,t));return i!==void 0&&(a=a.pipe(t=>I(e,i,t),t=>R(e,i,t))),a},B=()=>({flowStartedTotal:c.Metric.counter(`flow_started_total`,{description:`Total number of flows started`}),flowCompletedTotal:c.Metric.counter(`flow_completed_total`,{description:`Total number of flows completed successfully`}),flowFailedTotal:c.Metric.counter(`flow_failed_total`,{description:`Total number of flows that failed`}),flowPausedTotal:c.Metric.counter(`flow_paused_total`,{description:`Total number of flows that were paused`}),flowResumedTotal:c.Metric.counter(`flow_resumed_total`,{description:`Total number of flows that were resumed`}),nodeExecutedTotal:c.Metric.counter(`node_executed_total`,{description:`Total number of nodes executed`}),nodeSuccessTotal:c.Metric.counter(`node_success_total`,{description:`Total number of nodes executed successfully`}),nodeFailedTotal:c.Metric.counter(`node_failed_total`,{description:`Total number of nodes that failed`}),nodeSkippedTotal:c.Metric.counter(`node_skipped_total`,{description:`Total number of nodes skipped (conditional)`}),flowDurationHistogram:c.Metric.histogram(`flow_duration_seconds`,c.MetricBoundaries.exponential({start:.1,factor:2,count:20}),`Duration of complete flow execution in seconds`),nodeDurationHistogram:c.Metric.histogram(`node_duration_seconds`,c.MetricBoundaries.exponential({start:.01,factor:2,count:18}),`Duration of individual node execution in seconds`),flowNodeCountHistogram:c.Metric.histogram(`flow_node_count`,c.MetricBoundaries.linear({start:1,width:5,count:20}),`Number of nodes in a flow`),parallelNodesHistogram:c.Metric.histogram(`parallel_nodes_count`,c.MetricBoundaries.linear({start:1,width:2,count:15}),`Number of nodes executed in parallel`),activeFlowsGauge:c.Metric.gauge(`active_flows`,{description:`Number of currently active flows`}),activeNodesGauge:c.Metric.gauge(`active_nodes`,{description:`Number of currently executing nodes`}),pausedFlowsGauge:c.Metric.gauge(`paused_flows`,{description:`Number of currently paused flows`}),flowLatencySummary:c.Metric.summary({name:`flow_latency_seconds`,maxAge:`10 minutes`,maxSize:1e3,error:.01,quantiles:[.5,.9,.95,.99],description:`Flow execution latency percentiles`}),nodeLatencySummary:c.Metric.summary({name:`node_latency_seconds`,maxAge:`10 minutes`,maxSize:1e3,error:.01,quantiles:[.5,.9,.95,.99],description:`Node execution latency percentiles`})}),be=B(),xe=(e,t)=>n=>n.pipe(c.Effect.withSpan(`flow-${e}`,{attributes:{"flow.operation":e,...t}})),Se=e=>c.Effect.annotateCurrentSpan({"flow.id":e.flowId??`unknown`,"flow.name":e.flowName??`unknown`,"flow.job_id":e.jobId??`unknown`,"flow.node_count":e.nodeCount?.toString()??`0`,"flow.storage_id":e.storageId??`unknown`}),Ce=e=>c.Effect.annotateCurrentSpan({"node.id":e.nodeId,"node.type":e.nodeType,"node.name":e.nodeName??`unknown`,"node.flow_id":e.flowId??`unknown`,"node.job_id":e.jobId??`unknown`}),we=e=>c.Effect.annotateCurrentSpan({"execution.order":e.executionOrder?.join(`,`)??``,"execution.current_index":e.currentIndex?.toString()??`0`,"execution.total_nodes":e.totalNodes?.toString()??`0`,"execution.parallel_count":e.parallelCount?.toString()??`0`}),V=(e=`uploadista-flow-engine`)=>{let t=B();return c.Layer.succeed(g,{serviceName:e,enabled:!0,metrics:{flowStarted:c.Metric.increment(t.flowStartedTotal),flowCompleted:c.Metric.increment(t.flowCompletedTotal),flowFailed:c.Metric.increment(t.flowFailedTotal),nodeExecuted:c.Metric.increment(t.nodeExecutedTotal)}})},Te=V(),Ee=v(!1),De=c.Effect.gen(function*(){return(yield*g).metrics}),Oe=e=>{let t=B();return c.Effect.gen(function*(){let n=Date.now(),r=yield*e,i=(Date.now()-n)/1e3;return yield*c.Metric.update(t.flowDurationHistogram,i),yield*c.Metric.update(t.flowLatencySummary,i),r}).pipe(c.Effect.withSpan(`flow-execution`))},ke=(e,t,n)=>{let r=B();return c.Effect.gen(function*(){let e=Date.now(),t=yield*n,i=(Date.now()-e)/1e3;return yield*c.Metric.update(r.nodeDurationHistogram,i),yield*c.Metric.update(r.nodeLatencySummary,i),t}).pipe(c.Effect.withSpan(`node-${t}`,{attributes:{"node.id":e,"node.type":t}}))},Ae=e=>{let t=B();return c.Effect.gen(function*(){return yield*c.Metric.increment(t.activeFlowsGauge),yield*c.Effect.acquireUseRelease(c.Effect.void,()=>e,()=>c.Metric.set(t.activeFlowsGauge,-1))})},je=e=>{let t=B();return c.Effect.gen(function*(){return yield*c.Metric.increment(t.activeNodesGauge),yield*c.Effect.acquireUseRelease(c.Effect.void,()=>e,()=>c.Metric.set(t.activeNodesGauge,-1))})},H=e=>{if(!e||typeof e!=`object`)return`unknown_flow_error`;let t=`code`in e?e.code:void 0;if(!t)return`unknown_flow_error`;switch(t){case`FLOW_VALIDATION_ERROR`:case`FLOW_INVALID_INPUT`:case`FLOW_INVALID_OUTPUT`:return`flow_validation_error`;case`FLOW_NODE_NOT_FOUND`:case`FLOW_EDGE_INVALID`:return`node_not_found_error`;case`FLOW_NODE_EXECUTION_FAILED`:case`FLOW_NODE_ERROR`:return`node_execution_error`;case`FLOW_TIMEOUT`:return`flow_timeout_error`;case`FLOW_CANCELLED`:case`ABORTED`:return`flow_cancelled_error`;default:return`unknown_flow_error`}},Me=e=>{let t=B(),n=H(e);return c.Effect.gen(function*(){yield*c.Metric.increment(t.flowFailedTotal),yield*c.Effect.logError(`Flow execution failed`).pipe(c.Effect.annotateLogs({"error.category":n,"error.message":String(e)}))})},Ne=(e,t,n)=>{let r=B(),i=H(n);return c.Effect.gen(function*(){yield*c.Metric.increment(r.nodeFailedTotal),yield*c.Effect.logError(`Node execution failed`).pipe(c.Effect.annotateLogs({"node.id":e,"node.type":t,"error.category":i,"error.message":String(n)}))})},U=()=>{let e={serviceName:`test-flow-engine`,enabled:!0,metrics:{flowStarted:c.Effect.void,flowCompleted:c.Effect.void,flowFailed:c.Effect.void,nodeExecuted:c.Effect.void}};return c.Layer.succeed(g,e)},Pe=e=>e.pipe(c.Effect.provide(U()));var W=class extends c.Context.Tag(`MetricsService`)(){};const Fe=c.Layer.succeed(W,{recordUpload:(e,t)=>c.Effect.void}),Ie=`s3`,G=E(`s3`),K=j(`s3`),Le=e=>{if(!e||typeof e!=`object`)return null;let t=`code`in e?e.code:void 0;if(!t)return null;switch(t){case`NoSuchKey`:case`NoSuchBucket`:case`NoSuchUpload`:return`client_error`;case`BucketAlreadyExists`:case`BucketNotEmpty`:return`client_error`;case`InvalidBucketName`:case`InvalidPart`:case`InvalidPartOrder`:return`client_error`;case`EntityTooSmall`:case`EntityTooLarge`:return`client_error`;case`ExpiredToken`:case`TokenRefreshRequired`:return`authentication_error`;case`RequestTimeTooSkewed`:case`SlowDown`:return`throttling_error`;default:return null}},Re=f(`s3`,G,Le),ze=c.Layer.mergeAll(K),Be=(e,t)=>N(G,e,t),Ve=(e,t)=>P(G,e,t),He=F,Ue=(e,t,n,r)=>z(G,e,t,n,r),We=(e,t)=>n=>M(e,`s3`,t)(n),Ge=S.bind(null,`s3`),Ke=x.bind(null,`s3`),qe=C.bind(null,`s3`),Je=b,{uploadRequestsTotal:Ye,uploadPartsTotal:Xe,uploadSuccessTotal:Ze,uploadErrorsTotal:Qe,apiCallsTotal:$e,uploadDurationHistogram:et,partUploadDurationHistogram:tt,fileSizeHistogram:nt,partSizeHistogram:rt,activeUploadsGauge:it,uploadThroughputGauge:at,uploadLatencySummary:ot}=G,q=`azure`,J=E(q),st=j(q),ct=e=>{if(!e||typeof e!=`object`)return null;let t=`code`in e?e.code:`statusCode`in e?e.statusCode:void 0;if(!t)return null;switch(t){case`BlobNotFound`:case`ContainerNotFound`:case`InvalidBlobOrBlock`:return`client_error`;case`ContainerAlreadyExists`:case`BlobAlreadyExists`:return`client_error`;case`InvalidBlockId`:case`InvalidBlockList`:case`InvalidBlobType`:return`client_error`;case`RequestBodyTooLarge`:case`InvalidHeaderValue`:return`client_error`;case`AuthenticationFailed`:case`InvalidAuthenticationInfo`:return`authentication_error`;case`AccountIsDisabled`:return`authorization_error`;case`InsufficientAccountPermissions`:return`authorization_error`;case`OperationTimedOut`:case`ServerBusy`:case`InternalError`:return`server_error`;default:if(typeof t==`number`){if(t>=500)return`server_error`;if(t===429)return`throttling_error`;if(t===403)return`authorization_error`;if(t===401)return`authentication_error`;if(t>=400)return`client_error`}return null}},lt=f(q,J,ct),ut=c.Layer.mergeAll(st),dt=(e,t)=>N(J,e,t),ft=(e,t)=>P(J,e,t),pt=F,mt=(e,t,n,r)=>z(J,e,t,n,r),ht=(e,t)=>n=>M(e,q,t)(n),gt=S.bind(null,q),_t=x.bind(null,q),vt=C.bind(null,q),yt=b,{uploadRequestsTotal:bt,uploadPartsTotal:xt,uploadSuccessTotal:St,uploadErrorsTotal:Ct,apiCallsTotal:wt,uploadDurationHistogram:Tt,partUploadDurationHistogram:Et,fileSizeHistogram:Dt,partSizeHistogram:Ot,activeUploadsGauge:kt,uploadThroughputGauge:At,uploadLatencySummary:jt}=J,Mt=`gcs`,Y=E(`gcs`),Nt=j(`gcs`),Pt=e=>{if(!e||typeof e!=`object`)return null;let t=`code`in e?e.code:`status`in e?e.status:void 0;if(!t)return null;switch(t){case`NoSuchBucket`:case`NoSuchKey`:case`NoSuchUpload`:return`client_error`;case`BucketAlreadyOwnedByYou`:case`BucketNotEmpty`:return`client_error`;case`InvalidBucketName`:case`InvalidArgument`:case`InvalidPart`:case`InvalidPartOrder`:return`client_error`;case`EntityTooSmall`:case`EntityTooLarge`:return`client_error`;case`MalformedPolicy`:return`client_error`;case`Unauthorized`:case`AuthenticationRequired`:return`authentication_error`;case`Forbidden`:case`AccessDenied`:return`authorization_error`;case`TooManyRequests`:case`RateLimitExceeded`:return`throttling_error`;case`InternalError`:case`ServiceUnavailable`:case`BackendError`:return`server_error`;default:if(typeof t==`number`){if(t>=500)return`server_error`;if(t===429)return`throttling_error`;if(t===403)return`authorization_error`;if(t===401)return`authentication_error`;if(t>=400)return`client_error`}return null}},Ft=f(`gcs`,Y,Pt),It=c.Layer.mergeAll(Nt),Lt=(e,t)=>N(Y,e,t),Rt=(e,t)=>P(Y,e,t),zt=F,Bt=(e,t,n,r)=>z(Y,e,t,n,r),Vt=(e,t)=>n=>M(e,`gcs`,t)(n),Ht=S.bind(null,`gcs`),Ut=x.bind(null,`gcs`),Wt=C.bind(null,`gcs`),Gt=b,{uploadRequestsTotal:Kt,uploadPartsTotal:qt,uploadSuccessTotal:Jt,uploadErrorsTotal:Yt,apiCallsTotal:Xt,uploadDurationHistogram:Zt,partUploadDurationHistogram:Qt,fileSizeHistogram:$t,partSizeHistogram:en,activeUploadsGauge:tn,uploadThroughputGauge:nn,uploadLatencySummary:rn}=Y,X=`filesystem`,Z=E(X),an=j(X),on=e=>{if(!e||typeof e!=`object`)return null;let t=`code`in e?e.code:void 0;if(!t)return null;switch(t){case`ENOENT`:case`ENOTDIR`:return`client_error`;case`EEXIST`:return`client_error`;case`EISDIR`:return`client_error`;case`EINVAL`:case`ENAMETOOLONG`:return`client_error`;case`EACCES`:case`EPERM`:return`authorization_error`;case`ENOSPC`:case`EDQUOT`:return`server_error`;case`EIO`:case`EROFS`:case`EMFILE`:case`ENFILE`:return`server_error`;case`EBUSY`:return`throttling_error`;default:return null}},sn=f(X,Z,on),cn=c.Layer.mergeAll(an),ln=(e,t)=>N(Z,e,t),un=(e,t)=>P(Z,e,t),dn=F,fn=(e,t,n,r)=>z(Z,e,t,n,r),pn=(e,t)=>n=>M(e,X,t)(n),mn=S.bind(null,X),hn=x.bind(null,X),gn=C.bind(null,X),_n=b,{uploadRequestsTotal:vn,uploadPartsTotal:yn,uploadSuccessTotal:bn,uploadErrorsTotal:xn,apiCallsTotal:Sn,uploadDurationHistogram:Cn,partUploadDurationHistogram:wn,fileSizeHistogram:Tn,partSizeHistogram:En,activeUploadsGauge:Dn,uploadThroughputGauge:On,uploadLatencySummary:kn}=Z,Q=()=>({uploadCreatedTotal:c.Metric.counter(`upload_created_total`,{description:`Total number of uploads created`}),uploadCompletedTotal:c.Metric.counter(`upload_completed_total`,{description:`Total number of uploads completed successfully`}),uploadFailedTotal:c.Metric.counter(`upload_failed_total`,{description:`Total number of uploads that failed`}),chunkUploadedTotal:c.Metric.counter(`chunk_uploaded_total`,{description:`Total number of chunks uploaded`}),uploadFromUrlTotal:c.Metric.counter(`upload_from_url_total`,{description:`Total number of URL-based uploads`}),uploadFromUrlSuccessTotal:c.Metric.counter(`upload_from_url_success_total`,{description:`Total number of successful URL-based uploads`}),uploadFromUrlFailedTotal:c.Metric.counter(`upload_from_url_failed_total`,{description:`Total number of failed URL-based uploads`}),uploadDurationHistogram:c.Metric.histogram(`upload_duration_seconds`,c.MetricBoundaries.exponential({start:.01,factor:2,count:20}),`Duration of complete upload operations in seconds`),chunkUploadDurationHistogram:c.Metric.histogram(`chunk_upload_duration_seconds`,c.MetricBoundaries.exponential({start:.001,factor:2,count:15}),`Duration of individual chunk uploads in seconds`),uploadFileSizeHistogram:c.Metric.histogram(`upload_file_size_bytes`,c.MetricBoundaries.exponential({start:1024,factor:2,count:25}),`Size of uploaded files in bytes`),chunkSizeHistogram:c.Metric.histogram(`chunk_size_bytes`,c.MetricBoundaries.linear({start:262144,width:262144,count:20}),`Size of uploaded chunks in bytes`),activeUploadsGauge:c.Metric.gauge(`active_uploads`,{description:`Number of currently active uploads`}),uploadThroughputGauge:c.Metric.gauge(`upload_throughput_bytes_per_second`,{description:`Current upload throughput in bytes per second`}),uploadLatencySummary:c.Metric.summary({name:`upload_latency_seconds`,maxAge:`10 minutes`,maxSize:1e3,error:.01,quantiles:[.5,.9,.95,.99],description:`Upload operation latency percentiles`}),chunkLatencySummary:c.Metric.summary({name:`chunk_latency_seconds`,maxAge:`10 minutes`,maxSize:1e3,error:.01,quantiles:[.5,.9,.95,.99],description:`Chunk upload latency percentiles`})}),An=Q(),jn=(e,t)=>n=>n.pipe(c.Effect.withSpan(`upload-${e}`,{attributes:{"upload.operation":e,...t}})),Mn=e=>c.Effect.annotateCurrentSpan({"upload.id":e.uploadId??`unknown`,"upload.file_name":e.fileName??`unknown`,"upload.file_size":e.fileSize?.toString()??`0`,"upload.storage_id":e.storageId??`unknown`,"upload.mime_type":e.mimeType??`unknown`}),Nn=e=>c.Effect.annotateCurrentSpan({"chunk.upload_id":e.uploadId,"chunk.size":e.chunkSize.toString(),"chunk.offset":e.offset.toString(),"chunk.total_size":e.totalSize?.toString()??`0`,"chunk.progress":e.totalSize&&e.totalSize>0?(e.offset/e.totalSize*100).toFixed(2):`0`}),Pn=(e=`uploadista-upload-server`)=>{let t=Q();return c.Layer.succeed(h,{serviceName:e,enabled:!0,metrics:{uploadCreated:c.Effect.succeed(t.uploadCreatedTotal).pipe(c.Effect.flatMap(e=>c.Metric.increment(e))),uploadCompleted:c.Effect.succeed(t.uploadCompletedTotal).pipe(c.Effect.flatMap(e=>c.Metric.increment(e))),uploadFailed:c.Effect.succeed(t.uploadFailedTotal).pipe(c.Effect.flatMap(e=>c.Metric.increment(e))),chunkUploaded:c.Effect.succeed(t.chunkUploadedTotal).pipe(c.Effect.flatMap(e=>c.Metric.increment(e)))}})},Fn=Pn(),In=_(!1),Ln=c.Effect.gen(function*(){return(yield*h).metrics}),Rn=e=>{let t=Q();return c.Effect.gen(function*(){let n=Date.now(),r=yield*e,i=(Date.now()-n)/1e3;return yield*c.Metric.update(t.uploadDurationHistogram,i),r}).pipe(c.Effect.withSpan(`upload-operation`))},zn=e=>{let t=Q();return c.Effect.gen(function*(){let n=Date.now(),r=yield*e,i=(Date.now()-n)/1e3;return yield*c.Metric.update(t.chunkUploadDurationHistogram,i),r}).pipe(c.Effect.withSpan(`chunk-upload`))},$=e=>{if(!e||typeof e!=`object`)return`unknown_error`;let t=`code`in e?e.code:void 0,n=`name`in e?e.name:void 0,r=e instanceof Error?e.message.toLowerCase():``;return t===`ABORTED`||n===`AbortError`||r.includes(`abort`)?`abort_error`:t===`FILE_TOO_LARGE`||t===`LIMIT_FILE_SIZE`||t===`RequestEntityTooLarge`||r.includes(`too large`)||r.includes(`size limit`)||r.includes(`max size`)?`size_limit_error`:t===`INVALID_FILE`||t===`INVALID_METADATA`||t===`VALIDATION_ERROR`||r.includes(`validation`)||r.includes(`invalid`)?`validation_error`:t===`NetworkError`||t===`ECONNRESET`||t===`ENOTFOUND`||t===`ETIMEDOUT`||r.includes(`network`)||r.includes(`timeout`)?`network_error`:t===`UNAUTHORIZED`||t===`AuthenticationFailed`||n===`AuthenticationError`||r.includes(`authentication`)||r.includes(`unauthorized`)?`authentication_error`:t===`FORBIDDEN`||t===`AccessDenied`||n===`AuthorizationError`||r.includes(`forbidden`)||r.includes(`permission`)?`authorization_error`:t===`FILE_WRITE_ERROR`||t===`STORAGE_ERROR`||r.includes(`storage`)||r.includes(`write error`)?`storage_error`:`unknown_error`},Bn=(e,t,n,r={})=>c.Effect.gen(function*(){let i=$(n);yield*e.uploadFailedTotal.pipe(c.Metric.tagged(`operation`,t),c.Metric.tagged(`error_category`,i))(c.Effect.succeed(1));let a={operation:t,error_category:i,error_type:typeof n,error_message:n instanceof Error?n.message:String(n),error_code:n&&typeof n==`object`&&`code`in n?String(n.code):void 0,error_name:n&&typeof n==`object`&&`name`in n?String(n.name):void 0,...r};yield*c.Effect.logError(`Upload ${t} failed`).pipe(c.Effect.annotateLogs(a))}),Vn=e=>t=>{if(e){let n=e(t);if(n!==null)return n}return $(t)},Hn=c.Layer.succeed(h,{serviceName:`uploadista-upload-server-test`,enabled:!0,metrics:{uploadCreated:()=>Promise.resolve(),uploadCompleted:()=>Promise.resolve(),uploadFailed:()=>Promise.resolve(),chunkUploaded:()=>Promise.resolve()}}),Un=()=>Q(),Wn=()=>{let e=Un(),t=[`uploadCreatedTotal`,`uploadCompletedTotal`,`uploadFailedTotal`,`chunkUploadedTotal`,`uploadFromUrlTotal`,`uploadFromUrlSuccessTotal`,`uploadFromUrlFailedTotal`,`uploadDurationHistogram`,`chunkUploadDurationHistogram`,`uploadFileSizeHistogram`,`chunkSizeHistogram`,`activeUploadsGauge`,`uploadThroughputGauge`,`uploadLatencySummary`,`chunkLatencySummary`].filter(t=>!(t in e));if(t.length>0)throw Error(`Missing required metrics: ${t.join(`, `)}`);return!0};exports.AzureObservabilityLayer=ut,exports.AzureTracingLayer=st,exports.FilesystemObservabilityLayer=cn,exports.FilesystemTracingLayer=an,exports.FlowObservability=g,exports.FlowObservabilityDisabled=se,exports.FlowObservabilityLive=Te,exports.GCSObservabilityLayer=It,exports.GCSTracingLayer=Nt,exports.MetricsService=W,exports.NoOpMetricsServiceLive=Fe,exports.NodeSdkLive=_e,exports.Observability=p,exports.ObservabilityDisabled=ie,exports.S3ObservabilityLayer=ze,exports.S3TracingLayer=K,exports.StorageObservability=m,exports.StorageObservabilityDisabled=ae,exports.TracingService=me,exports.UploadObservability=h,exports.UploadObservabilityDisabled=oe,exports.UploadObservabilityLive=Fn,exports.UploadObservabilityTest=Hn,exports.WebSdkLive=ge,exports.WorkersSdkLive=ve,exports.azureActiveUploadsGauge=kt,exports.azureApiCallsTotal=wt,exports.azureFileSizeHistogram=Dt,exports.azureMetrics=J,exports.azurePartSizeHistogram=Ot,exports.azurePartUploadDurationHistogram=Et,exports.azureUploadDurationHistogram=Tt,exports.azureUploadErrorsTotal=Ct,exports.azureUploadLatencySummary=jt,exports.azureUploadPartsTotal=xt,exports.azureUploadRequestsTotal=bt,exports.azureUploadSuccessTotal=St,exports.azureUploadThroughputGauge=At,exports.captureMetrics=de,exports.classifyFlowError=H,exports.classifyStorageError=d,exports.classifyUploadError=$,exports.createFlowMetrics=B,exports.createStorageErrorClassifier=ee,exports.createStorageErrorTracker=f,exports.createStorageMetrics=E,exports.createStorageTracingLayer=j,exports.createTestFixture=A,exports.createTracingLayer=he,exports.createUploadErrorClassifier=Vn,exports.createUploadGauges=le,exports.createUploadHistograms=T,exports.createUploadMetrics=w,exports.createUploadServerMetrics=Q,exports.createUploadSummaries=ue,exports.filesystemActiveUploadsGauge=Dn,exports.filesystemApiCallsTotal=Sn,exports.filesystemFileSizeHistogram=Tn,exports.filesystemMetrics=Z,exports.filesystemPartSizeHistogram=En,exports.filesystemPartUploadDurationHistogram=wn,exports.filesystemUploadDurationHistogram=Cn,exports.filesystemUploadErrorsTotal=xn,exports.filesystemUploadLatencySummary=kn,exports.filesystemUploadPartsTotal=yn,exports.filesystemUploadRequestsTotal=vn,exports.filesystemUploadSuccessTotal=bn,exports.filesystemUploadThroughputGauge=On,exports.flowMetrics=be,exports.gcsActiveUploadsGauge=tn,exports.gcsApiCallsTotal=Xt,exports.gcsFileSizeHistogram=$t,exports.gcsMetrics=Y,exports.gcsPartSizeHistogram=en,exports.gcsPartUploadDurationHistogram=Qt,exports.gcsUploadDurationHistogram=Zt,exports.gcsUploadErrorsTotal=Yt,exports.gcsUploadLatencySummary=rn,exports.gcsUploadPartsTotal=qt,exports.gcsUploadRequestsTotal=Kt,exports.gcsUploadSuccessTotal=Jt,exports.gcsUploadThroughputGauge=nn,exports.getFlowMetrics=De,exports.getTestMetrics=Un,exports.getUploadMetrics=Ln,exports.isObservabilityEnabled=y,exports.logAzureContext=yt,exports.logAzureOperation=gt,exports.logAzureUploadCompletion=vt,exports.logAzureUploadProgress=_t,exports.logFilesystemContext=_n,exports.logFilesystemOperation=mn,exports.logFilesystemUploadCompletion=gn,exports.logFilesystemUploadProgress=hn,exports.logGCSContext=Gt,exports.logGCSOperation=Ht,exports.logGCSUploadCompletion=Wt,exports.logGCSUploadProgress=Ut,exports.logS3Context=Je,exports.logS3Operation=Ge,exports.logS3UploadCompletion=qe,exports.logS3UploadProgress=Ke,exports.logStorageOperation=S,exports.logUploadCompletion=C,exports.logUploadProgress=x,exports.logWithContext=b,exports.makeFlowObservabilityLayer=v,exports.makeFlowObservabilityLive=V,exports.makeObservabilityLayer=ne,exports.makeStorageObservabilityLayer=re,exports.makeTestFlowObservability=k,exports.makeTestFlowObservabilityUtil=U,exports.makeTestStorageObservability=D,exports.makeTestUploadObservability=O,exports.makeUploadObservabilityLayer=_,exports.makeUploadObservabilityLive=Pn,exports.runWithTestFlowObservability=Pe,exports.runWithTestObservability=pe,exports.s3ActiveUploadsGauge=it,exports.s3ApiCallsTotal=$e,exports.s3FileSizeHistogram=nt,exports.s3Metrics=G,exports.s3PartSizeHistogram=rt,exports.s3PartUploadDurationHistogram=tt,exports.s3UploadDurationHistogram=et,exports.s3UploadErrorsTotal=Qe,exports.s3UploadLatencySummary=ot,exports.s3UploadPartsTotal=Xe,exports.s3UploadRequestsTotal=Ye,exports.s3UploadSuccessTotal=Ze,exports.s3UploadThroughputGauge=at,exports.trackActiveFlow=Ae,exports.trackActiveNode=je,exports.trackAzureError=lt,exports.trackFileSize=I,exports.trackFilesystemError=sn,exports.trackFlowError=Me,exports.trackGCSError=Ft,exports.trackNodeError=Ne,exports.trackPartSize=ye,exports.trackS3Error=Re,exports.trackStorageError=te,exports.trackUploadError=Bn,exports.uploadServerMetrics=An,exports.validateMetricsExist=Wn,exports.whenObservabilityEnabled=ce,exports.withActiveUploadTracking=L,exports.withApiMetrics=P,exports.withAzureApiMetrics=ft,exports.withAzureOperationMetrics=mt,exports.withAzureSpan=ht,exports.withAzureTimingMetrics=pt,exports.withAzureUploadMetrics=dt,exports.withChunkContext=Nn,exports.withChunkDuration=zn,exports.withExecutionContext=we,exports.withFilesystemApiMetrics=un,exports.withFilesystemOperationMetrics=fn,exports.withFilesystemSpan=pn,exports.withFilesystemTimingMetrics=dn,exports.withFilesystemUploadMetrics=ln,exports.withFlowContext=Se,exports.withFlowDuration=Oe,exports.withFlowSpan=xe,exports.withGCSApiMetrics=Rt,exports.withGCSOperationMetrics=Bt,exports.withGCSSpan=Vt,exports.withGCSTimingMetrics=zt,exports.withGCSUploadMetrics=Lt,exports.withMetricTracking=fe,exports.withNodeContext=Ce,exports.withNodeDuration=ke,exports.withS3ApiMetrics=Ve,exports.withS3OperationMetrics=Ue,exports.withS3Span=We,exports.withS3TimingMetrics=He,exports.withS3UploadMetrics=Be,exports.withStorageOperationMetrics=z,exports.withStorageSpan=M,exports.withThroughputTracking=R,exports.withTimingMetrics=F,exports.withUploadContext=Mn,exports.withUploadDuration=Rn,exports.withUploadMetrics=N,exports.withUploadSpan=jn;
|
|
1
|
+
let e=require(`effect`),t=require(`@effect/opentelemetry`),n=require(`@opentelemetry/sdk-trace-base`);const r=e=>{if(!e||typeof e!=`object`)return`unknown_error`;let t=`code`in e?e.code:void 0,n=`name`in e?e.name:void 0,r=e instanceof Error?e.message.toLowerCase():``;return t===`NetworkError`||t===`ECONNRESET`||t===`ENOTFOUND`||t===`ETIMEDOUT`||r.indexOf(`network`)>=0||r.indexOf(`timeout`)>=0?`network_error`:t===`InvalidAccessKeyId`||t===`SignatureDoesNotMatch`||t===`TokenRefreshRequired`||t===`AuthenticationFailed`||n===`AuthenticationError`||r.indexOf(`authentication`)>=0||r.indexOf(`unauthorized`)>=0?`authentication_error`:t===`AccessDenied`||t===`AccountProblem`||t===`Forbidden`||n===`AuthorizationError`||r.indexOf(`forbidden`)>=0||r.indexOf(`permission`)>=0?`authorization_error`:t===`SlowDown`||t===`RequestTimeTooSkewed`||t===`TooManyRequests`||n===`ThrottlingError`||r.indexOf(`throttl`)>=0||r.indexOf(`rate limit`)>=0?`throttling_error`:t===`InternalError`||t===`ServiceUnavailable`||t===`InternalServerError`||n===`ServerError`||r.indexOf(`server error`)>=0||r.indexOf(`service unavailable`)>=0?`server_error`:t===`InvalidRequest`||t===`MalformedXML`||t===`RequestEntityTooLarge`||t===`BadRequest`||n===`ClientError`||r.indexOf(`bad request`)>=0||r.indexOf(`invalid`)>=0?`client_error`:`unknown_error`},i=(e,t)=>e=>{if(t){let n=t(e);if(n!==null)return n}return r(e)},a=(t,n,i,a,o={},s=r)=>e.Effect.gen(function*(){let r=s(a);yield*n.uploadErrorsTotal.pipe(e.Metric.tagged(`operation`,i),e.Metric.tagged(`error_category`,r))(e.Effect.succeed(1));let c={storage_type:t,operation:i,error_category:r,error_type:typeof a,error_message:a instanceof Error?a.message:String(a),error_code:a&&typeof a==`object`&&`code`in a?a.code:void 0,error_name:a&&typeof a==`object`&&`name`in a?a.name:void 0,...o};yield*e.Effect.logError(`${t.toUpperCase()} ${i} failed`).pipe(e.Effect.annotateLogs(c))}),o=(e,t,n)=>{let r=i(e,n);return(n,i,o={})=>a(e,t,n,i,o,r)};var s=class extends e.Context.Tag(`Observability`)(){},c=class extends e.Context.Tag(`StorageObservability`)(){},l=class extends e.Context.Tag(`UploadObservability`)(){},u=class extends e.Context.Tag(`FlowObservability`)(){};const d=(t,n=!0)=>e.Layer.succeed(s,{serviceName:t,enabled:n}),ee=(t,n,r=!0)=>e.Layer.succeed(c,{serviceName:`uploadista-${t}-store`,storageType:t,metrics:n,enabled:r}),f=(t=!0)=>e.Layer.succeed(l,{serviceName:`uploadista-upload-server`,enabled:t,metrics:{uploadCreated:e.Effect.void,uploadCompleted:e.Effect.void,uploadFailed:e.Effect.void,chunkUploaded:e.Effect.void}}),p=(t=!0)=>e.Layer.succeed(u,{serviceName:`uploadista-flow-engine`,enabled:t,metrics:{flowStarted:e.Effect.void,flowCompleted:e.Effect.void,flowFailed:e.Effect.void,nodeExecuted:e.Effect.void}}),te=d(`uploadista-disabled`,!1),ne=e=>ee(e,{},!1),re=f(!1),ie=p(!1),m=e.Effect.gen(function*(){let t=yield*e.Effect.serviceOption(s);return e.Option.match(t,{onNone:()=>!1,onSome:e=>e.enabled})}),ae=t=>e.Effect.gen(function*(){if(yield*m){let n=yield*t;return e.Option.some(n)}return e.Option.none()}),h=(t,n)=>e.Effect.log(t).pipe(e.Effect.annotateLogs(n)),g=(e,t,n)=>h(`Upload progress`,{storage_type:e,upload_id:t,uploaded_bytes:n.uploadedBytes,total_bytes:n.totalBytes,progress_percentage:Math.round(n.uploadedBytes/n.totalBytes*100),...n.partNumber&&{part_number:n.partNumber},...n.speed&&{upload_speed_bps:n.speed}}),_=(e,t,n,r)=>h(`${e.toUpperCase()} ${t}`,{storage_type:e,operation:t,upload_id:n,...r}),v=(e,t,n)=>{let r=n.throughputBps?n.throughputBps/(1024*1024):0;return h(`${e.toUpperCase()} upload completed`,{storage_type:e,upload_id:t,file_size_bytes:n.fileSize,file_size_mb:Math.round(n.fileSize/(1024*1024)*100)/100,total_duration_ms:n.totalDurationMs,total_duration_seconds:Math.round(n.totalDurationMs/1e3*100)/100,throughput_bps:n.throughputBps,throughput_mbps:Math.round(r*100)/100,...n.partsCount&&{parts_count:n.partsCount},...n.averagePartSize&&{average_part_size_bytes:n.averagePartSize,average_part_size_mb:Math.round(n.averagePartSize/(1024*1024)*100)/100},...n.retryCount&&{retry_count:n.retryCount}})},y=t=>({uploadRequestsTotal:e.Metric.counter(`${t}_upload_requests_total`,{description:`Total number of upload requests for ${t}`}),uploadPartsTotal:e.Metric.counter(`${t}_upload_parts_total`,{description:`Total number of individual parts uploaded for ${t}`}),uploadSuccessTotal:e.Metric.counter(`${t}_upload_success_total`,{description:`Total number of successful uploads for ${t}`}),uploadErrorsTotal:e.Metric.counter(`${t}_upload_errors_total`,{description:`Total number of upload errors for ${t}`}),apiCallsTotal:e.Metric.counter(`${t}_api_calls_total`,{description:`Total number of API calls for ${t}`})}),b=t=>({uploadDurationHistogram:e.Metric.histogram(`${t}_upload_duration_seconds`,e.MetricBoundaries.exponential({start:.01,factor:2,count:20}),`Duration of upload operations in seconds for ${t}`),partUploadDurationHistogram:e.Metric.histogram(`${t}_part_upload_duration_seconds`,e.MetricBoundaries.exponential({start:.001,factor:2,count:15}),`Duration of individual part uploads in seconds for ${t}`),fileSizeHistogram:e.Metric.histogram(`${t}_file_size_bytes`,e.MetricBoundaries.exponential({start:1024,factor:2,count:25}),`Size of uploaded files in bytes for ${t}`),partSizeHistogram:e.Metric.histogram(`${t}_part_size_bytes`,e.MetricBoundaries.linear({start:5242880,width:1048576,count:20}),`Size of upload parts in bytes for ${t}`)}),x=t=>({activeUploadsGauge:e.Metric.gauge(`${t}_active_uploads`,{description:`Number of currently active uploads for ${t}`}),uploadThroughputGauge:e.Metric.gauge(`${t}_upload_throughput_bytes_per_second`,{description:`Current upload throughput in bytes per second for ${t}`})}),oe=t=>({uploadLatencySummary:e.Metric.summary({name:`${t}_upload_latency_seconds`,maxAge:`10 minutes`,maxSize:1e3,error:.01,quantiles:[.5,.9,.95,.99],description:`Upload latency percentiles for ${t}`})}),S=e=>({...y(e),...b(e),...x(e),...oe(e)}),C=t=>{let n=S(t),r={serviceName:`test-${t}-store`,storageType:t,metrics:n,enabled:!0};return e.Layer.succeed(c,r)},w=()=>{let t={serviceName:`test-upload-server`,enabled:!0,metrics:{uploadCreated:e.Effect.void,uploadCompleted:e.Effect.void,uploadFailed:e.Effect.void,chunkUploaded:e.Effect.void}};return e.Layer.succeed(l,t)},T=()=>{let t={serviceName:`test-flow-engine`,enabled:!0,metrics:{flowStarted:e.Effect.void,flowCompleted:e.Effect.void,flowFailed:e.Effect.void,nodeExecuted:e.Effect.void}};return e.Layer.succeed(u,t)},se=t=>e.Effect.gen(function*(){let n=yield*t;return yield*e.Metric.snapshot,n}),ce=t=>e.Effect.gen(function*(){yield*e.Metric.snapshot;let n=yield*t;return yield*e.Metric.snapshot,n}),E=(e=`test-storage`)=>({storageObservability:C(e),uploadObservability:w(),flowObservability:T()}),le=(t,n=`test-storage`)=>{let r=E(n);return t.pipe(e.Effect.provide(r.storageObservability),e.Effect.provide(r.uploadObservability),e.Effect.provide(r.flowObservability))},D=e.Context.GenericTag(`TracingService`),O=t=>{let n=t?.serviceName??`uploadista-storage`;return e.Layer.succeed(D,{serviceName:n})},k=e=>O({serviceName:`uploadista-${e}-store`}),A=(t,n,r)=>i=>i.pipe(e.Effect.withSpan(`${n}-${t}`,{attributes:{"storage.type":n,operation:t,...r}})),ue=t.WebSdk.layer(()=>({resource:{serviceName:`uploadista-storage`},spanProcessor:new n.BatchSpanProcessor(new n.ConsoleSpanExporter)})),de=t.NodeSdk.layer(()=>({resource:{serviceName:`uploadista-storage`},spanProcessor:new n.BatchSpanProcessor(new n.ConsoleSpanExporter)})),fe=t.WebSdk.layer(()=>({resource:{serviceName:`uploadista-storage-workers`},spanProcessor:new n.BatchSpanProcessor(new n.ConsoleSpanExporter)})),j=(t,n,r)=>r.pipe(e.Effect.tap(()=>t.uploadRequestsTotal.pipe(e.Metric.tagged(`upload_id`,n))(e.Effect.succeed(1))),e.Effect.tapError(()=>t.uploadErrorsTotal.pipe(e.Metric.tagged(`upload_id`,n))(e.Effect.succeed(1))),e.Effect.tap(()=>t.uploadSuccessTotal.pipe(e.Metric.tagged(`upload_id`,n))(e.Effect.succeed(1)))),M=(t,n,r)=>r.pipe(e.Effect.tap(()=>t.apiCallsTotal.pipe(e.Metric.tagged(`operation`,n))(e.Effect.succeed(1)))),N=(t,n)=>e.Effect.gen(function*(){let r=yield*e.Effect.sync(()=>Date.now()),i=yield*n,a=((yield*e.Effect.sync(()=>Date.now()))-r)/1e3;return yield*t(e.Effect.succeed(a)),i}),P=(t,n,r)=>r.pipe(e.Effect.tap(()=>t.fileSizeHistogram(e.Effect.succeed(n)))),pe=(t,n,r)=>r.pipe(e.Effect.tap(()=>t.partSizeHistogram(e.Effect.succeed(n)))),F=(t,n)=>n.pipe(e.Effect.tap(()=>t.activeUploadsGauge(e.Effect.succeed(1))),e.Effect.ensuring(t.activeUploadsGauge(e.Effect.succeed(-1)))),I=(t,n,r)=>e.Effect.gen(function*(){let i=yield*e.Effect.sync(()=>Date.now()),a=yield*r,o=((yield*e.Effect.sync(()=>Date.now()))-i)/1e3,s=o>0?n/o:0;return yield*t.uploadThroughputGauge(e.Effect.succeed(s)),a}),L=(e,t,n,r,i)=>{let a=r.pipe(n=>M(e,t,n),t=>j(e,n,t),t=>N(e.uploadDurationHistogram,t),t=>F(e,t));return i!==void 0&&(a=a.pipe(t=>P(e,i,t),t=>I(e,i,t))),a},R=()=>({flowStartedTotal:e.Metric.counter(`flow_started_total`,{description:`Total number of flows started`}),flowCompletedTotal:e.Metric.counter(`flow_completed_total`,{description:`Total number of flows completed successfully`}),flowFailedTotal:e.Metric.counter(`flow_failed_total`,{description:`Total number of flows that failed`}),flowPausedTotal:e.Metric.counter(`flow_paused_total`,{description:`Total number of flows that were paused`}),flowResumedTotal:e.Metric.counter(`flow_resumed_total`,{description:`Total number of flows that were resumed`}),nodeExecutedTotal:e.Metric.counter(`node_executed_total`,{description:`Total number of nodes executed`}),nodeSuccessTotal:e.Metric.counter(`node_success_total`,{description:`Total number of nodes executed successfully`}),nodeFailedTotal:e.Metric.counter(`node_failed_total`,{description:`Total number of nodes that failed`}),nodeSkippedTotal:e.Metric.counter(`node_skipped_total`,{description:`Total number of nodes skipped (conditional)`}),flowDurationHistogram:e.Metric.histogram(`flow_duration_seconds`,e.MetricBoundaries.exponential({start:.1,factor:2,count:20}),`Duration of complete flow execution in seconds`),nodeDurationHistogram:e.Metric.histogram(`node_duration_seconds`,e.MetricBoundaries.exponential({start:.01,factor:2,count:18}),`Duration of individual node execution in seconds`),flowNodeCountHistogram:e.Metric.histogram(`flow_node_count`,e.MetricBoundaries.linear({start:1,width:5,count:20}),`Number of nodes in a flow`),parallelNodesHistogram:e.Metric.histogram(`parallel_nodes_count`,e.MetricBoundaries.linear({start:1,width:2,count:15}),`Number of nodes executed in parallel`),activeFlowsGauge:e.Metric.gauge(`active_flows`,{description:`Number of currently active flows`}),activeNodesGauge:e.Metric.gauge(`active_nodes`,{description:`Number of currently executing nodes`}),pausedFlowsGauge:e.Metric.gauge(`paused_flows`,{description:`Number of currently paused flows`}),flowLatencySummary:e.Metric.summary({name:`flow_latency_seconds`,maxAge:`10 minutes`,maxSize:1e3,error:.01,quantiles:[.5,.9,.95,.99],description:`Flow execution latency percentiles`}),nodeLatencySummary:e.Metric.summary({name:`node_latency_seconds`,maxAge:`10 minutes`,maxSize:1e3,error:.01,quantiles:[.5,.9,.95,.99],description:`Node execution latency percentiles`})}),me=R(),he=(t,n)=>r=>r.pipe(e.Effect.withSpan(`flow-${t}`,{attributes:{"flow.operation":t,...n}})),ge=t=>e.Effect.annotateCurrentSpan({"flow.id":t.flowId??`unknown`,"flow.name":t.flowName??`unknown`,"flow.job_id":t.jobId??`unknown`,"flow.node_count":t.nodeCount?.toString()??`0`,"flow.storage_id":t.storageId??`unknown`}),_e=t=>e.Effect.annotateCurrentSpan({"node.id":t.nodeId,"node.type":t.nodeType,"node.name":t.nodeName??`unknown`,"node.flow_id":t.flowId??`unknown`,"node.job_id":t.jobId??`unknown`}),ve=t=>e.Effect.annotateCurrentSpan({"execution.order":t.executionOrder?.join(`,`)??``,"execution.current_index":t.currentIndex?.toString()??`0`,"execution.total_nodes":t.totalNodes?.toString()??`0`,"execution.parallel_count":t.parallelCount?.toString()??`0`}),z=(t=`uploadista-flow-engine`)=>{let n=R();return e.Layer.succeed(u,{serviceName:t,enabled:!0,metrics:{flowStarted:e.Metric.increment(n.flowStartedTotal),flowCompleted:e.Metric.increment(n.flowCompletedTotal),flowFailed:e.Metric.increment(n.flowFailedTotal),nodeExecuted:e.Metric.increment(n.nodeExecutedTotal)}})},ye=z(),be=p(!1),xe=e.Effect.gen(function*(){return(yield*u).metrics}),Se=t=>{let n=R();return e.Effect.gen(function*(){let r=Date.now(),i=yield*t,a=(Date.now()-r)/1e3;return yield*e.Metric.update(n.flowDurationHistogram,a),yield*e.Metric.update(n.flowLatencySummary,a),i}).pipe(e.Effect.withSpan(`flow-execution`))},Ce=(t,n,r)=>{let i=R();return e.Effect.gen(function*(){let t=Date.now(),n=yield*r,a=(Date.now()-t)/1e3;return yield*e.Metric.update(i.nodeDurationHistogram,a),yield*e.Metric.update(i.nodeLatencySummary,a),n}).pipe(e.Effect.withSpan(`node-${n}`,{attributes:{"node.id":t,"node.type":n}}))},we=t=>{let n=R();return e.Effect.gen(function*(){return yield*e.Metric.increment(n.activeFlowsGauge),yield*e.Effect.acquireUseRelease(e.Effect.void,()=>t,()=>e.Metric.set(n.activeFlowsGauge,-1))})},Te=t=>{let n=R();return e.Effect.gen(function*(){return yield*e.Metric.increment(n.activeNodesGauge),yield*e.Effect.acquireUseRelease(e.Effect.void,()=>t,()=>e.Metric.set(n.activeNodesGauge,-1))})},B=e=>{if(!e||typeof e!=`object`)return`unknown_flow_error`;let t=`code`in e?e.code:void 0;if(!t)return`unknown_flow_error`;switch(t){case`FLOW_VALIDATION_ERROR`:case`FLOW_INVALID_INPUT`:case`FLOW_INVALID_OUTPUT`:return`flow_validation_error`;case`FLOW_NODE_NOT_FOUND`:case`FLOW_EDGE_INVALID`:return`node_not_found_error`;case`FLOW_NODE_EXECUTION_FAILED`:case`FLOW_NODE_ERROR`:return`node_execution_error`;case`FLOW_TIMEOUT`:return`flow_timeout_error`;case`FLOW_CANCELLED`:case`ABORTED`:return`flow_cancelled_error`;default:return`unknown_flow_error`}},Ee=t=>{let n=R(),r=B(t);return e.Effect.gen(function*(){yield*e.Metric.increment(n.flowFailedTotal),yield*e.Effect.logError(`Flow execution failed`).pipe(e.Effect.annotateLogs({"error.category":r,"error.message":String(t)}))})},De=(t,n,r)=>{let i=R(),a=B(r);return e.Effect.gen(function*(){yield*e.Metric.increment(i.nodeFailedTotal),yield*e.Effect.logError(`Node execution failed`).pipe(e.Effect.annotateLogs({"node.id":t,"node.type":n,"error.category":a,"error.message":String(r)}))})},V=()=>{let t={serviceName:`test-flow-engine`,enabled:!0,metrics:{flowStarted:e.Effect.void,flowCompleted:e.Effect.void,flowFailed:e.Effect.void,nodeExecuted:e.Effect.void}};return e.Layer.succeed(u,t)},Oe=t=>t.pipe(e.Effect.provide(V()));var H=class extends e.Context.Tag(`MetricsService`)(){};const ke=e.Layer.succeed(H,{recordUpload:(t,n)=>e.Effect.void}),Ae=`s3`,U=S(`s3`),W=k(`s3`),je=e=>{if(!e||typeof e!=`object`)return null;let t=`code`in e?e.code:void 0;if(!t)return null;switch(t){case`NoSuchKey`:case`NoSuchBucket`:case`NoSuchUpload`:return`client_error`;case`BucketAlreadyExists`:case`BucketNotEmpty`:return`client_error`;case`InvalidBucketName`:case`InvalidPart`:case`InvalidPartOrder`:return`client_error`;case`EntityTooSmall`:case`EntityTooLarge`:return`client_error`;case`ExpiredToken`:case`TokenRefreshRequired`:return`authentication_error`;case`RequestTimeTooSkewed`:case`SlowDown`:return`throttling_error`;default:return null}},Me=o(`s3`,U,je),Ne=e.Layer.mergeAll(W),Pe=(e,t)=>j(U,e,t),Fe=(e,t)=>M(U,e,t),Ie=N,Le=(e,t,n,r)=>L(U,e,t,n,r),Re=(e,t)=>n=>A(e,`s3`,t)(n),ze=_.bind(null,`s3`),Be=g.bind(null,`s3`),Ve=v.bind(null,`s3`),He=h,{uploadRequestsTotal:Ue,uploadPartsTotal:We,uploadSuccessTotal:Ge,uploadErrorsTotal:Ke,apiCallsTotal:qe,uploadDurationHistogram:Je,partUploadDurationHistogram:Ye,fileSizeHistogram:Xe,partSizeHistogram:Ze,activeUploadsGauge:Qe,uploadThroughputGauge:$e,uploadLatencySummary:et}=U,G=`azure`,K=S(G),q=k(G),tt=e=>{if(!e||typeof e!=`object`)return null;let t=`code`in e?e.code:`statusCode`in e?e.statusCode:void 0;if(!t)return null;switch(t){case`BlobNotFound`:case`ContainerNotFound`:case`InvalidBlobOrBlock`:return`client_error`;case`ContainerAlreadyExists`:case`BlobAlreadyExists`:return`client_error`;case`InvalidBlockId`:case`InvalidBlockList`:case`InvalidBlobType`:return`client_error`;case`RequestBodyTooLarge`:case`InvalidHeaderValue`:return`client_error`;case`AuthenticationFailed`:case`InvalidAuthenticationInfo`:return`authentication_error`;case`AccountIsDisabled`:return`authorization_error`;case`InsufficientAccountPermissions`:return`authorization_error`;case`OperationTimedOut`:case`ServerBusy`:case`InternalError`:return`server_error`;default:if(typeof t==`number`){if(t>=500)return`server_error`;if(t===429)return`throttling_error`;if(t===403)return`authorization_error`;if(t===401)return`authentication_error`;if(t>=400)return`client_error`}return null}},nt=o(G,K,tt),rt=e.Layer.mergeAll(q),it=(e,t)=>j(K,e,t),at=(e,t)=>M(K,e,t),ot=N,st=(e,t,n,r)=>L(K,e,t,n,r),ct=(e,t)=>n=>A(e,G,t)(n),lt=_.bind(null,G),ut=g.bind(null,G),dt=v.bind(null,G),ft=h,{uploadRequestsTotal:pt,uploadPartsTotal:mt,uploadSuccessTotal:ht,uploadErrorsTotal:gt,apiCallsTotal:_t,uploadDurationHistogram:vt,partUploadDurationHistogram:yt,fileSizeHistogram:bt,partSizeHistogram:xt,activeUploadsGauge:St,uploadThroughputGauge:Ct,uploadLatencySummary:wt}=K,Tt=`gcs`,J=S(`gcs`),Y=k(`gcs`),Et=e=>{if(!e||typeof e!=`object`)return null;let t=`code`in e?e.code:`status`in e?e.status:void 0;if(!t)return null;switch(t){case`NoSuchBucket`:case`NoSuchKey`:case`NoSuchUpload`:return`client_error`;case`BucketAlreadyOwnedByYou`:case`BucketNotEmpty`:return`client_error`;case`InvalidBucketName`:case`InvalidArgument`:case`InvalidPart`:case`InvalidPartOrder`:return`client_error`;case`EntityTooSmall`:case`EntityTooLarge`:return`client_error`;case`MalformedPolicy`:return`client_error`;case`Unauthorized`:case`AuthenticationRequired`:return`authentication_error`;case`Forbidden`:case`AccessDenied`:return`authorization_error`;case`TooManyRequests`:case`RateLimitExceeded`:return`throttling_error`;case`InternalError`:case`ServiceUnavailable`:case`BackendError`:return`server_error`;default:if(typeof t==`number`){if(t>=500)return`server_error`;if(t===429)return`throttling_error`;if(t===403)return`authorization_error`;if(t===401)return`authentication_error`;if(t>=400)return`client_error`}return null}},Dt=o(`gcs`,J,Et),Ot=e.Layer.mergeAll(Y),kt=(e,t)=>j(J,e,t),At=(e,t)=>M(J,e,t),jt=N,Mt=(e,t,n,r)=>L(J,e,t,n,r),Nt=(e,t)=>n=>A(e,`gcs`,t)(n),Pt=_.bind(null,`gcs`),Ft=g.bind(null,`gcs`),It=v.bind(null,`gcs`),Lt=h,{uploadRequestsTotal:Rt,uploadPartsTotal:zt,uploadSuccessTotal:Bt,uploadErrorsTotal:Vt,apiCallsTotal:Ht,uploadDurationHistogram:Ut,partUploadDurationHistogram:Wt,fileSizeHistogram:Gt,partSizeHistogram:Kt,activeUploadsGauge:qt,uploadThroughputGauge:Jt,uploadLatencySummary:Yt}=J,X=`filesystem`,Z=S(X),Xt=k(X),Zt=e=>{if(!e||typeof e!=`object`)return null;let t=`code`in e?e.code:void 0;if(!t)return null;switch(t){case`ENOENT`:case`ENOTDIR`:return`client_error`;case`EEXIST`:return`client_error`;case`EISDIR`:return`client_error`;case`EINVAL`:case`ENAMETOOLONG`:return`client_error`;case`EACCES`:case`EPERM`:return`authorization_error`;case`ENOSPC`:case`EDQUOT`:return`server_error`;case`EIO`:case`EROFS`:case`EMFILE`:case`ENFILE`:return`server_error`;case`EBUSY`:return`throttling_error`;default:return null}},Qt=o(X,Z,Zt),$t=e.Layer.mergeAll(Xt),en=(e,t)=>j(Z,e,t),tn=(e,t)=>M(Z,e,t),nn=N,rn=(e,t,n,r)=>L(Z,e,t,n,r),an=(e,t)=>n=>A(e,X,t)(n),on=_.bind(null,X),sn=g.bind(null,X),cn=v.bind(null,X),ln=h,{uploadRequestsTotal:un,uploadPartsTotal:dn,uploadSuccessTotal:fn,uploadErrorsTotal:pn,apiCallsTotal:mn,uploadDurationHistogram:hn,partUploadDurationHistogram:gn,fileSizeHistogram:_n,partSizeHistogram:vn,activeUploadsGauge:yn,uploadThroughputGauge:bn,uploadLatencySummary:xn}=Z,Q=()=>({uploadCreatedTotal:e.Metric.counter(`upload_created_total`,{description:`Total number of uploads created`}),uploadCompletedTotal:e.Metric.counter(`upload_completed_total`,{description:`Total number of uploads completed successfully`}),uploadFailedTotal:e.Metric.counter(`upload_failed_total`,{description:`Total number of uploads that failed`}),chunkUploadedTotal:e.Metric.counter(`chunk_uploaded_total`,{description:`Total number of chunks uploaded`}),uploadFromUrlTotal:e.Metric.counter(`upload_from_url_total`,{description:`Total number of URL-based uploads`}),uploadFromUrlSuccessTotal:e.Metric.counter(`upload_from_url_success_total`,{description:`Total number of successful URL-based uploads`}),uploadFromUrlFailedTotal:e.Metric.counter(`upload_from_url_failed_total`,{description:`Total number of failed URL-based uploads`}),uploadDurationHistogram:e.Metric.histogram(`upload_duration_seconds`,e.MetricBoundaries.exponential({start:.01,factor:2,count:20}),`Duration of complete upload operations in seconds`),chunkUploadDurationHistogram:e.Metric.histogram(`chunk_upload_duration_seconds`,e.MetricBoundaries.exponential({start:.001,factor:2,count:15}),`Duration of individual chunk uploads in seconds`),uploadFileSizeHistogram:e.Metric.histogram(`upload_file_size_bytes`,e.MetricBoundaries.exponential({start:1024,factor:2,count:25}),`Size of uploaded files in bytes`),chunkSizeHistogram:e.Metric.histogram(`chunk_size_bytes`,e.MetricBoundaries.linear({start:262144,width:262144,count:20}),`Size of uploaded chunks in bytes`),activeUploadsGauge:e.Metric.gauge(`active_uploads`,{description:`Number of currently active uploads`}),uploadThroughputGauge:e.Metric.gauge(`upload_throughput_bytes_per_second`,{description:`Current upload throughput in bytes per second`}),uploadLatencySummary:e.Metric.summary({name:`upload_latency_seconds`,maxAge:`10 minutes`,maxSize:1e3,error:.01,quantiles:[.5,.9,.95,.99],description:`Upload operation latency percentiles`}),chunkLatencySummary:e.Metric.summary({name:`chunk_latency_seconds`,maxAge:`10 minutes`,maxSize:1e3,error:.01,quantiles:[.5,.9,.95,.99],description:`Chunk upload latency percentiles`})}),Sn=Q(),Cn=(t,n)=>r=>r.pipe(e.Effect.withSpan(`upload-${t}`,{attributes:{"upload.operation":t,...n}})),wn=t=>e.Effect.annotateCurrentSpan({"upload.id":t.uploadId??`unknown`,"upload.file_name":t.fileName??`unknown`,"upload.file_size":t.fileSize?.toString()??`0`,"upload.storage_id":t.storageId??`unknown`,"upload.mime_type":t.mimeType??`unknown`}),Tn=t=>e.Effect.annotateCurrentSpan({"chunk.upload_id":t.uploadId,"chunk.size":t.chunkSize.toString(),"chunk.offset":t.offset.toString(),"chunk.total_size":t.totalSize?.toString()??`0`,"chunk.progress":t.totalSize&&t.totalSize>0?(t.offset/t.totalSize*100).toFixed(2):`0`}),En=(t=`uploadista-upload-server`)=>{let n=Q();return e.Layer.succeed(l,{serviceName:t,enabled:!0,metrics:{uploadCreated:e.Effect.succeed(n.uploadCreatedTotal).pipe(e.Effect.flatMap(t=>e.Metric.increment(t))),uploadCompleted:e.Effect.succeed(n.uploadCompletedTotal).pipe(e.Effect.flatMap(t=>e.Metric.increment(t))),uploadFailed:e.Effect.succeed(n.uploadFailedTotal).pipe(e.Effect.flatMap(t=>e.Metric.increment(t))),chunkUploaded:e.Effect.succeed(n.chunkUploadedTotal).pipe(e.Effect.flatMap(t=>e.Metric.increment(t)))}})},Dn=En(),On=f(!1),kn=e.Effect.gen(function*(){return(yield*l).metrics}),An=t=>{let n=Q();return e.Effect.gen(function*(){let r=Date.now(),i=yield*t,a=(Date.now()-r)/1e3;return yield*e.Metric.update(n.uploadDurationHistogram,a),i}).pipe(e.Effect.withSpan(`upload-operation`))},jn=t=>{let n=Q();return e.Effect.gen(function*(){let r=Date.now(),i=yield*t,a=(Date.now()-r)/1e3;return yield*e.Metric.update(n.chunkUploadDurationHistogram,a),i}).pipe(e.Effect.withSpan(`chunk-upload`))},$=e=>{if(!e||typeof e!=`object`)return`unknown_error`;let t=`code`in e?e.code:void 0,n=`name`in e?e.name:void 0,r=e instanceof Error?e.message.toLowerCase():``;return t===`ABORTED`||n===`AbortError`||r.includes(`abort`)?`abort_error`:t===`FILE_TOO_LARGE`||t===`LIMIT_FILE_SIZE`||t===`RequestEntityTooLarge`||r.includes(`too large`)||r.includes(`size limit`)||r.includes(`max size`)?`size_limit_error`:t===`INVALID_FILE`||t===`INVALID_METADATA`||t===`VALIDATION_ERROR`||r.includes(`validation`)||r.includes(`invalid`)?`validation_error`:t===`NetworkError`||t===`ECONNRESET`||t===`ENOTFOUND`||t===`ETIMEDOUT`||r.includes(`network`)||r.includes(`timeout`)?`network_error`:t===`UNAUTHORIZED`||t===`AuthenticationFailed`||n===`AuthenticationError`||r.includes(`authentication`)||r.includes(`unauthorized`)?`authentication_error`:t===`FORBIDDEN`||t===`AccessDenied`||n===`AuthorizationError`||r.includes(`forbidden`)||r.includes(`permission`)?`authorization_error`:t===`FILE_WRITE_ERROR`||t===`STORAGE_ERROR`||r.includes(`storage`)||r.includes(`write error`)?`storage_error`:`unknown_error`},Mn=(t,n,r,i={})=>e.Effect.gen(function*(){let a=$(r);yield*t.uploadFailedTotal.pipe(e.Metric.tagged(`operation`,n),e.Metric.tagged(`error_category`,a))(e.Effect.succeed(1));let o={operation:n,error_category:a,error_type:typeof r,error_message:r instanceof Error?r.message:String(r),error_code:r&&typeof r==`object`&&`code`in r?String(r.code):void 0,error_name:r&&typeof r==`object`&&`name`in r?String(r.name):void 0,...i};yield*e.Effect.logError(`Upload ${n} failed`).pipe(e.Effect.annotateLogs(o))}),Nn=e=>t=>{if(e){let n=e(t);if(n!==null)return n}return $(t)},Pn=e.Layer.succeed(l,{serviceName:`uploadista-upload-server-test`,enabled:!0,metrics:{uploadCreated:()=>Promise.resolve(),uploadCompleted:()=>Promise.resolve(),uploadFailed:()=>Promise.resolve(),chunkUploaded:()=>Promise.resolve()}}),Fn=()=>Q(),In=()=>{let e=Fn(),t=[`uploadCreatedTotal`,`uploadCompletedTotal`,`uploadFailedTotal`,`chunkUploadedTotal`,`uploadFromUrlTotal`,`uploadFromUrlSuccessTotal`,`uploadFromUrlFailedTotal`,`uploadDurationHistogram`,`chunkUploadDurationHistogram`,`uploadFileSizeHistogram`,`chunkSizeHistogram`,`activeUploadsGauge`,`uploadThroughputGauge`,`uploadLatencySummary`,`chunkLatencySummary`].filter(t=>!(t in e));if(t.length>0)throw Error(`Missing required metrics: ${t.join(`, `)}`);return!0};exports.AzureObservabilityLayer=rt,exports.AzureTracingLayer=q,exports.FilesystemObservabilityLayer=$t,exports.FilesystemTracingLayer=Xt,exports.FlowObservability=u,exports.FlowObservabilityDisabled=ie,exports.FlowObservabilityLive=ye,exports.GCSObservabilityLayer=Ot,exports.GCSTracingLayer=Y,exports.MetricsService=H,exports.NoOpMetricsServiceLive=ke,exports.NodeSdkLive=de,exports.Observability=s,exports.ObservabilityDisabled=te,exports.S3ObservabilityLayer=Ne,exports.S3TracingLayer=W,exports.StorageObservability=c,exports.StorageObservabilityDisabled=ne,exports.TracingService=D,exports.UploadObservability=l,exports.UploadObservabilityDisabled=re,exports.UploadObservabilityLive=Dn,exports.UploadObservabilityTest=Pn,exports.WebSdkLive=ue,exports.WorkersSdkLive=fe,exports.azureActiveUploadsGauge=St,exports.azureApiCallsTotal=_t,exports.azureFileSizeHistogram=bt,exports.azureMetrics=K,exports.azurePartSizeHistogram=xt,exports.azurePartUploadDurationHistogram=yt,exports.azureUploadDurationHistogram=vt,exports.azureUploadErrorsTotal=gt,exports.azureUploadLatencySummary=wt,exports.azureUploadPartsTotal=mt,exports.azureUploadRequestsTotal=pt,exports.azureUploadSuccessTotal=ht,exports.azureUploadThroughputGauge=Ct,exports.captureMetrics=se,exports.classifyFlowError=B,exports.classifyStorageError=r,exports.classifyUploadError=$,exports.createFlowMetrics=R,exports.createStorageErrorClassifier=i,exports.createStorageErrorTracker=o,exports.createStorageMetrics=S,exports.createStorageTracingLayer=k,exports.createTestFixture=E,exports.createTracingLayer=O,exports.createUploadErrorClassifier=Nn,exports.createUploadGauges=x,exports.createUploadHistograms=b,exports.createUploadMetrics=y,exports.createUploadServerMetrics=Q,exports.createUploadSummaries=oe,exports.filesystemActiveUploadsGauge=yn,exports.filesystemApiCallsTotal=mn,exports.filesystemFileSizeHistogram=_n,exports.filesystemMetrics=Z,exports.filesystemPartSizeHistogram=vn,exports.filesystemPartUploadDurationHistogram=gn,exports.filesystemUploadDurationHistogram=hn,exports.filesystemUploadErrorsTotal=pn,exports.filesystemUploadLatencySummary=xn,exports.filesystemUploadPartsTotal=dn,exports.filesystemUploadRequestsTotal=un,exports.filesystemUploadSuccessTotal=fn,exports.filesystemUploadThroughputGauge=bn,exports.flowMetrics=me,exports.gcsActiveUploadsGauge=qt,exports.gcsApiCallsTotal=Ht,exports.gcsFileSizeHistogram=Gt,exports.gcsMetrics=J,exports.gcsPartSizeHistogram=Kt,exports.gcsPartUploadDurationHistogram=Wt,exports.gcsUploadDurationHistogram=Ut,exports.gcsUploadErrorsTotal=Vt,exports.gcsUploadLatencySummary=Yt,exports.gcsUploadPartsTotal=zt,exports.gcsUploadRequestsTotal=Rt,exports.gcsUploadSuccessTotal=Bt,exports.gcsUploadThroughputGauge=Jt,exports.getFlowMetrics=xe,exports.getTestMetrics=Fn,exports.getUploadMetrics=kn,exports.isObservabilityEnabled=m,exports.logAzureContext=ft,exports.logAzureOperation=lt,exports.logAzureUploadCompletion=dt,exports.logAzureUploadProgress=ut,exports.logFilesystemContext=ln,exports.logFilesystemOperation=on,exports.logFilesystemUploadCompletion=cn,exports.logFilesystemUploadProgress=sn,exports.logGCSContext=Lt,exports.logGCSOperation=Pt,exports.logGCSUploadCompletion=It,exports.logGCSUploadProgress=Ft,exports.logS3Context=He,exports.logS3Operation=ze,exports.logS3UploadCompletion=Ve,exports.logS3UploadProgress=Be,exports.logStorageOperation=_,exports.logUploadCompletion=v,exports.logUploadProgress=g,exports.logWithContext=h,exports.makeFlowObservabilityLayer=p,exports.makeFlowObservabilityLive=z,exports.makeObservabilityLayer=d,exports.makeStorageObservabilityLayer=ee,exports.makeTestFlowObservability=T,exports.makeTestFlowObservabilityUtil=V,exports.makeTestStorageObservability=C,exports.makeTestUploadObservability=w,exports.makeUploadObservabilityLayer=f,exports.makeUploadObservabilityLive=En,exports.runWithTestFlowObservability=Oe,exports.runWithTestObservability=le,exports.s3ActiveUploadsGauge=Qe,exports.s3ApiCallsTotal=qe,exports.s3FileSizeHistogram=Xe,exports.s3Metrics=U,exports.s3PartSizeHistogram=Ze,exports.s3PartUploadDurationHistogram=Ye,exports.s3UploadDurationHistogram=Je,exports.s3UploadErrorsTotal=Ke,exports.s3UploadLatencySummary=et,exports.s3UploadPartsTotal=We,exports.s3UploadRequestsTotal=Ue,exports.s3UploadSuccessTotal=Ge,exports.s3UploadThroughputGauge=$e,exports.trackActiveFlow=we,exports.trackActiveNode=Te,exports.trackAzureError=nt,exports.trackFileSize=P,exports.trackFilesystemError=Qt,exports.trackFlowError=Ee,exports.trackGCSError=Dt,exports.trackNodeError=De,exports.trackPartSize=pe,exports.trackS3Error=Me,exports.trackStorageError=a,exports.trackUploadError=Mn,exports.uploadServerMetrics=Sn,exports.validateMetricsExist=In,exports.whenObservabilityEnabled=ae,exports.withActiveUploadTracking=F,exports.withApiMetrics=M,exports.withAzureApiMetrics=at,exports.withAzureOperationMetrics=st,exports.withAzureSpan=ct,exports.withAzureTimingMetrics=ot,exports.withAzureUploadMetrics=it,exports.withChunkContext=Tn,exports.withChunkDuration=jn,exports.withExecutionContext=ve,exports.withFilesystemApiMetrics=tn,exports.withFilesystemOperationMetrics=rn,exports.withFilesystemSpan=an,exports.withFilesystemTimingMetrics=nn,exports.withFilesystemUploadMetrics=en,exports.withFlowContext=ge,exports.withFlowDuration=Se,exports.withFlowSpan=he,exports.withGCSApiMetrics=At,exports.withGCSOperationMetrics=Mt,exports.withGCSSpan=Nt,exports.withGCSTimingMetrics=jt,exports.withGCSUploadMetrics=kt,exports.withMetricTracking=ce,exports.withNodeContext=_e,exports.withNodeDuration=Ce,exports.withS3ApiMetrics=Fe,exports.withS3OperationMetrics=Le,exports.withS3Span=Re,exports.withS3TimingMetrics=Ie,exports.withS3UploadMetrics=Pe,exports.withStorageOperationMetrics=L,exports.withStorageSpan=A,exports.withThroughputTracking=I,exports.withTimingMetrics=N,exports.withUploadContext=wn,exports.withUploadDuration=An,exports.withUploadMetrics=j,exports.withUploadSpan=Cn;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Context, Effect, Layer, Metric, Option } from "effect";
|
|
2
|
-
import * as
|
|
3
|
-
import * as
|
|
2
|
+
import * as effect_MetricKeyType43 from "effect/MetricKeyType";
|
|
3
|
+
import * as effect_MetricState43 from "effect/MetricState";
|
|
4
4
|
import * as effect_Tracer0 from "effect/Tracer";
|
|
5
5
|
import * as _effect_opentelemetry_Resource0 from "@effect/opentelemetry/Resource";
|
|
6
6
|
import * as effect_Metric0 from "effect/Metric";
|
|
@@ -14,10 +14,10 @@ declare const createUploadMetrics: (storageType: string) => {
|
|
|
14
14
|
apiCallsTotal: Metric.Metric.Counter<number>;
|
|
15
15
|
};
|
|
16
16
|
declare const createUploadHistograms: (storageType: string) => {
|
|
17
|
-
uploadDurationHistogram: Metric.Metric<
|
|
18
|
-
partUploadDurationHistogram: Metric.Metric<
|
|
19
|
-
fileSizeHistogram: Metric.Metric<
|
|
20
|
-
partSizeHistogram: Metric.Metric<
|
|
17
|
+
uploadDurationHistogram: Metric.Metric<effect_MetricKeyType43.MetricKeyType.Histogram, number, effect_MetricState43.MetricState.Histogram>;
|
|
18
|
+
partUploadDurationHistogram: Metric.Metric<effect_MetricKeyType43.MetricKeyType.Histogram, number, effect_MetricState43.MetricState.Histogram>;
|
|
19
|
+
fileSizeHistogram: Metric.Metric<effect_MetricKeyType43.MetricKeyType.Histogram, number, effect_MetricState43.MetricState.Histogram>;
|
|
20
|
+
partSizeHistogram: Metric.Metric<effect_MetricKeyType43.MetricKeyType.Histogram, number, effect_MetricState43.MetricState.Histogram>;
|
|
21
21
|
};
|
|
22
22
|
declare const createUploadGauges: (storageType: string) => {
|
|
23
23
|
activeUploadsGauge: Metric.Metric.Gauge<number>;
|
|
@@ -30,10 +30,10 @@ declare const createStorageMetrics: (storageType: string) => {
|
|
|
30
30
|
uploadLatencySummary: Metric.Metric.Summary<number>;
|
|
31
31
|
activeUploadsGauge: Metric.Metric.Gauge<number>;
|
|
32
32
|
uploadThroughputGauge: Metric.Metric.Gauge<number>;
|
|
33
|
-
uploadDurationHistogram: Metric.Metric<
|
|
34
|
-
partUploadDurationHistogram: Metric.Metric<
|
|
35
|
-
fileSizeHistogram: Metric.Metric<
|
|
36
|
-
partSizeHistogram: Metric.Metric<
|
|
33
|
+
uploadDurationHistogram: Metric.Metric<effect_MetricKeyType43.MetricKeyType.Histogram, number, effect_MetricState43.MetricState.Histogram>;
|
|
34
|
+
partUploadDurationHistogram: Metric.Metric<effect_MetricKeyType43.MetricKeyType.Histogram, number, effect_MetricState43.MetricState.Histogram>;
|
|
35
|
+
fileSizeHistogram: Metric.Metric<effect_MetricKeyType43.MetricKeyType.Histogram, number, effect_MetricState43.MetricState.Histogram>;
|
|
36
|
+
partSizeHistogram: Metric.Metric<effect_MetricKeyType43.MetricKeyType.Histogram, number, effect_MetricState43.MetricState.Histogram>;
|
|
37
37
|
uploadRequestsTotal: Metric.Metric.Counter<number>;
|
|
38
38
|
uploadPartsTotal: Metric.Metric.Counter<number>;
|
|
39
39
|
uploadSuccessTotal: Metric.Metric.Counter<number>;
|
|
@@ -250,10 +250,10 @@ declare const createFlowMetrics: () => {
|
|
|
250
250
|
nodeSuccessTotal: Metric.Metric.Counter<number>;
|
|
251
251
|
nodeFailedTotal: Metric.Metric.Counter<number>;
|
|
252
252
|
nodeSkippedTotal: Metric.Metric.Counter<number>;
|
|
253
|
-
flowDurationHistogram: Metric.Metric<
|
|
254
|
-
nodeDurationHistogram: Metric.Metric<
|
|
255
|
-
flowNodeCountHistogram: Metric.Metric<
|
|
256
|
-
parallelNodesHistogram: Metric.Metric<
|
|
253
|
+
flowDurationHistogram: Metric.Metric<effect_MetricKeyType43.MetricKeyType.Histogram, number, effect_MetricState43.MetricState.Histogram>;
|
|
254
|
+
nodeDurationHistogram: Metric.Metric<effect_MetricKeyType43.MetricKeyType.Histogram, number, effect_MetricState43.MetricState.Histogram>;
|
|
255
|
+
flowNodeCountHistogram: Metric.Metric<effect_MetricKeyType43.MetricKeyType.Histogram, number, effect_MetricState43.MetricState.Histogram>;
|
|
256
|
+
parallelNodesHistogram: Metric.Metric<effect_MetricKeyType43.MetricKeyType.Histogram, number, effect_MetricState43.MetricState.Histogram>;
|
|
257
257
|
activeFlowsGauge: Metric.Metric.Gauge<number>;
|
|
258
258
|
activeNodesGauge: Metric.Metric.Gauge<number>;
|
|
259
259
|
pausedFlowsGauge: Metric.Metric.Gauge<number>;
|
|
@@ -277,10 +277,10 @@ declare const flowMetrics: {
|
|
|
277
277
|
nodeSuccessTotal: Metric.Metric.Counter<number>;
|
|
278
278
|
nodeFailedTotal: Metric.Metric.Counter<number>;
|
|
279
279
|
nodeSkippedTotal: Metric.Metric.Counter<number>;
|
|
280
|
-
flowDurationHistogram: Metric.Metric<
|
|
281
|
-
nodeDurationHistogram: Metric.Metric<
|
|
282
|
-
flowNodeCountHistogram: Metric.Metric<
|
|
283
|
-
parallelNodesHistogram: Metric.Metric<
|
|
280
|
+
flowDurationHistogram: Metric.Metric<effect_MetricKeyType43.MetricKeyType.Histogram, number, effect_MetricState43.MetricState.Histogram>;
|
|
281
|
+
nodeDurationHistogram: Metric.Metric<effect_MetricKeyType43.MetricKeyType.Histogram, number, effect_MetricState43.MetricState.Histogram>;
|
|
282
|
+
flowNodeCountHistogram: Metric.Metric<effect_MetricKeyType43.MetricKeyType.Histogram, number, effect_MetricState43.MetricState.Histogram>;
|
|
283
|
+
parallelNodesHistogram: Metric.Metric<effect_MetricKeyType43.MetricKeyType.Histogram, number, effect_MetricState43.MetricState.Histogram>;
|
|
284
284
|
activeFlowsGauge: Metric.Metric.Gauge<number>;
|
|
285
285
|
activeNodesGauge: Metric.Metric.Gauge<number>;
|
|
286
286
|
pausedFlowsGauge: Metric.Metric.Gauge<number>;
|
|
@@ -409,10 +409,10 @@ declare const s3Metrics: {
|
|
|
409
409
|
uploadLatencySummary: effect_Metric0.Metric.Summary<number>;
|
|
410
410
|
activeUploadsGauge: effect_Metric0.Metric.Gauge<number>;
|
|
411
411
|
uploadThroughputGauge: effect_Metric0.Metric.Gauge<number>;
|
|
412
|
-
uploadDurationHistogram: effect_Metric0.Metric<
|
|
413
|
-
partUploadDurationHistogram: effect_Metric0.Metric<
|
|
414
|
-
fileSizeHistogram: effect_Metric0.Metric<
|
|
415
|
-
partSizeHistogram: effect_Metric0.Metric<
|
|
412
|
+
uploadDurationHistogram: effect_Metric0.Metric<effect_MetricKeyType43.MetricKeyType.Histogram, number, effect_MetricState43.MetricState.Histogram>;
|
|
413
|
+
partUploadDurationHistogram: effect_Metric0.Metric<effect_MetricKeyType43.MetricKeyType.Histogram, number, effect_MetricState43.MetricState.Histogram>;
|
|
414
|
+
fileSizeHistogram: effect_Metric0.Metric<effect_MetricKeyType43.MetricKeyType.Histogram, number, effect_MetricState43.MetricState.Histogram>;
|
|
415
|
+
partSizeHistogram: effect_Metric0.Metric<effect_MetricKeyType43.MetricKeyType.Histogram, number, effect_MetricState43.MetricState.Histogram>;
|
|
416
416
|
uploadRequestsTotal: effect_Metric0.Metric.Counter<number>;
|
|
417
417
|
uploadPartsTotal: effect_Metric0.Metric.Counter<number>;
|
|
418
418
|
uploadSuccessTotal: effect_Metric0.Metric.Counter<number>;
|
|
@@ -447,7 +447,7 @@ declare const logS3UploadCompletion: (uploadId: string, metrics: {
|
|
|
447
447
|
retryCount?: number;
|
|
448
448
|
}) => Effect.Effect<void, never, never>;
|
|
449
449
|
declare const logS3Context: (message: string, context: Record<string, unknown>) => Effect.Effect<void, never, never>;
|
|
450
|
-
declare const s3UploadRequestsTotal: effect_Metric0.Metric.Counter<number>, s3UploadPartsTotal: effect_Metric0.Metric.Counter<number>, s3UploadSuccessTotal: effect_Metric0.Metric.Counter<number>, s3UploadErrorsTotal: effect_Metric0.Metric.Counter<number>, s3ApiCallsTotal: effect_Metric0.Metric.Counter<number>, s3UploadDurationHistogram: effect_Metric0.Metric<
|
|
450
|
+
declare const s3UploadRequestsTotal: effect_Metric0.Metric.Counter<number>, s3UploadPartsTotal: effect_Metric0.Metric.Counter<number>, s3UploadSuccessTotal: effect_Metric0.Metric.Counter<number>, s3UploadErrorsTotal: effect_Metric0.Metric.Counter<number>, s3ApiCallsTotal: effect_Metric0.Metric.Counter<number>, s3UploadDurationHistogram: effect_Metric0.Metric<effect_MetricKeyType43.MetricKeyType.Histogram, number, effect_MetricState43.MetricState.Histogram>, s3PartUploadDurationHistogram: effect_Metric0.Metric<effect_MetricKeyType43.MetricKeyType.Histogram, number, effect_MetricState43.MetricState.Histogram>, s3FileSizeHistogram: effect_Metric0.Metric<effect_MetricKeyType43.MetricKeyType.Histogram, number, effect_MetricState43.MetricState.Histogram>, s3PartSizeHistogram: effect_Metric0.Metric<effect_MetricKeyType43.MetricKeyType.Histogram, number, effect_MetricState43.MetricState.Histogram>, s3ActiveUploadsGauge: effect_Metric0.Metric.Gauge<number>, s3UploadThroughputGauge: effect_Metric0.Metric.Gauge<number>, s3UploadLatencySummary: effect_Metric0.Metric.Summary<number>;
|
|
451
451
|
type S3Metrics = StorageMetrics;
|
|
452
452
|
//#endregion
|
|
453
453
|
//#region src/storage/azure.d.ts
|
|
@@ -455,10 +455,10 @@ declare const azureMetrics: {
|
|
|
455
455
|
uploadLatencySummary: effect_Metric0.Metric.Summary<number>;
|
|
456
456
|
activeUploadsGauge: effect_Metric0.Metric.Gauge<number>;
|
|
457
457
|
uploadThroughputGauge: effect_Metric0.Metric.Gauge<number>;
|
|
458
|
-
uploadDurationHistogram: effect_Metric0.Metric<
|
|
459
|
-
partUploadDurationHistogram: effect_Metric0.Metric<
|
|
460
|
-
fileSizeHistogram: effect_Metric0.Metric<
|
|
461
|
-
partSizeHistogram: effect_Metric0.Metric<
|
|
458
|
+
uploadDurationHistogram: effect_Metric0.Metric<effect_MetricKeyType43.MetricKeyType.Histogram, number, effect_MetricState43.MetricState.Histogram>;
|
|
459
|
+
partUploadDurationHistogram: effect_Metric0.Metric<effect_MetricKeyType43.MetricKeyType.Histogram, number, effect_MetricState43.MetricState.Histogram>;
|
|
460
|
+
fileSizeHistogram: effect_Metric0.Metric<effect_MetricKeyType43.MetricKeyType.Histogram, number, effect_MetricState43.MetricState.Histogram>;
|
|
461
|
+
partSizeHistogram: effect_Metric0.Metric<effect_MetricKeyType43.MetricKeyType.Histogram, number, effect_MetricState43.MetricState.Histogram>;
|
|
462
462
|
uploadRequestsTotal: effect_Metric0.Metric.Counter<number>;
|
|
463
463
|
uploadPartsTotal: effect_Metric0.Metric.Counter<number>;
|
|
464
464
|
uploadSuccessTotal: effect_Metric0.Metric.Counter<number>;
|
|
@@ -493,7 +493,7 @@ declare const logAzureUploadCompletion: (uploadId: string, metrics: {
|
|
|
493
493
|
retryCount?: number;
|
|
494
494
|
}) => Effect.Effect<void, never, never>;
|
|
495
495
|
declare const logAzureContext: (message: string, context: Record<string, unknown>) => Effect.Effect<void, never, never>;
|
|
496
|
-
declare const azureUploadRequestsTotal: effect_Metric0.Metric.Counter<number>, azureUploadPartsTotal: effect_Metric0.Metric.Counter<number>, azureUploadSuccessTotal: effect_Metric0.Metric.Counter<number>, azureUploadErrorsTotal: effect_Metric0.Metric.Counter<number>, azureApiCallsTotal: effect_Metric0.Metric.Counter<number>, azureUploadDurationHistogram: effect_Metric0.Metric<
|
|
496
|
+
declare const azureUploadRequestsTotal: effect_Metric0.Metric.Counter<number>, azureUploadPartsTotal: effect_Metric0.Metric.Counter<number>, azureUploadSuccessTotal: effect_Metric0.Metric.Counter<number>, azureUploadErrorsTotal: effect_Metric0.Metric.Counter<number>, azureApiCallsTotal: effect_Metric0.Metric.Counter<number>, azureUploadDurationHistogram: effect_Metric0.Metric<effect_MetricKeyType43.MetricKeyType.Histogram, number, effect_MetricState43.MetricState.Histogram>, azurePartUploadDurationHistogram: effect_Metric0.Metric<effect_MetricKeyType43.MetricKeyType.Histogram, number, effect_MetricState43.MetricState.Histogram>, azureFileSizeHistogram: effect_Metric0.Metric<effect_MetricKeyType43.MetricKeyType.Histogram, number, effect_MetricState43.MetricState.Histogram>, azurePartSizeHistogram: effect_Metric0.Metric<effect_MetricKeyType43.MetricKeyType.Histogram, number, effect_MetricState43.MetricState.Histogram>, azureActiveUploadsGauge: effect_Metric0.Metric.Gauge<number>, azureUploadThroughputGauge: effect_Metric0.Metric.Gauge<number>, azureUploadLatencySummary: effect_Metric0.Metric.Summary<number>;
|
|
497
497
|
type AzureMetrics = StorageMetrics;
|
|
498
498
|
//#endregion
|
|
499
499
|
//#region src/storage/gcs.d.ts
|
|
@@ -501,10 +501,10 @@ declare const gcsMetrics: {
|
|
|
501
501
|
uploadLatencySummary: effect_Metric0.Metric.Summary<number>;
|
|
502
502
|
activeUploadsGauge: effect_Metric0.Metric.Gauge<number>;
|
|
503
503
|
uploadThroughputGauge: effect_Metric0.Metric.Gauge<number>;
|
|
504
|
-
uploadDurationHistogram: effect_Metric0.Metric<
|
|
505
|
-
partUploadDurationHistogram: effect_Metric0.Metric<
|
|
506
|
-
fileSizeHistogram: effect_Metric0.Metric<
|
|
507
|
-
partSizeHistogram: effect_Metric0.Metric<
|
|
504
|
+
uploadDurationHistogram: effect_Metric0.Metric<effect_MetricKeyType43.MetricKeyType.Histogram, number, effect_MetricState43.MetricState.Histogram>;
|
|
505
|
+
partUploadDurationHistogram: effect_Metric0.Metric<effect_MetricKeyType43.MetricKeyType.Histogram, number, effect_MetricState43.MetricState.Histogram>;
|
|
506
|
+
fileSizeHistogram: effect_Metric0.Metric<effect_MetricKeyType43.MetricKeyType.Histogram, number, effect_MetricState43.MetricState.Histogram>;
|
|
507
|
+
partSizeHistogram: effect_Metric0.Metric<effect_MetricKeyType43.MetricKeyType.Histogram, number, effect_MetricState43.MetricState.Histogram>;
|
|
508
508
|
uploadRequestsTotal: effect_Metric0.Metric.Counter<number>;
|
|
509
509
|
uploadPartsTotal: effect_Metric0.Metric.Counter<number>;
|
|
510
510
|
uploadSuccessTotal: effect_Metric0.Metric.Counter<number>;
|
|
@@ -539,7 +539,7 @@ declare const logGCSUploadCompletion: (uploadId: string, metrics: {
|
|
|
539
539
|
retryCount?: number;
|
|
540
540
|
}) => Effect.Effect<void, never, never>;
|
|
541
541
|
declare const logGCSContext: (message: string, context: Record<string, unknown>) => Effect.Effect<void, never, never>;
|
|
542
|
-
declare const gcsUploadRequestsTotal: effect_Metric0.Metric.Counter<number>, gcsUploadPartsTotal: effect_Metric0.Metric.Counter<number>, gcsUploadSuccessTotal: effect_Metric0.Metric.Counter<number>, gcsUploadErrorsTotal: effect_Metric0.Metric.Counter<number>, gcsApiCallsTotal: effect_Metric0.Metric.Counter<number>, gcsUploadDurationHistogram: effect_Metric0.Metric<
|
|
542
|
+
declare const gcsUploadRequestsTotal: effect_Metric0.Metric.Counter<number>, gcsUploadPartsTotal: effect_Metric0.Metric.Counter<number>, gcsUploadSuccessTotal: effect_Metric0.Metric.Counter<number>, gcsUploadErrorsTotal: effect_Metric0.Metric.Counter<number>, gcsApiCallsTotal: effect_Metric0.Metric.Counter<number>, gcsUploadDurationHistogram: effect_Metric0.Metric<effect_MetricKeyType43.MetricKeyType.Histogram, number, effect_MetricState43.MetricState.Histogram>, gcsPartUploadDurationHistogram: effect_Metric0.Metric<effect_MetricKeyType43.MetricKeyType.Histogram, number, effect_MetricState43.MetricState.Histogram>, gcsFileSizeHistogram: effect_Metric0.Metric<effect_MetricKeyType43.MetricKeyType.Histogram, number, effect_MetricState43.MetricState.Histogram>, gcsPartSizeHistogram: effect_Metric0.Metric<effect_MetricKeyType43.MetricKeyType.Histogram, number, effect_MetricState43.MetricState.Histogram>, gcsActiveUploadsGauge: effect_Metric0.Metric.Gauge<number>, gcsUploadThroughputGauge: effect_Metric0.Metric.Gauge<number>, gcsUploadLatencySummary: effect_Metric0.Metric.Summary<number>;
|
|
543
543
|
type GCSMetrics = StorageMetrics;
|
|
544
544
|
//#endregion
|
|
545
545
|
//#region src/storage/filesystem.d.ts
|
|
@@ -547,10 +547,10 @@ declare const filesystemMetrics: {
|
|
|
547
547
|
uploadLatencySummary: effect_Metric0.Metric.Summary<number>;
|
|
548
548
|
activeUploadsGauge: effect_Metric0.Metric.Gauge<number>;
|
|
549
549
|
uploadThroughputGauge: effect_Metric0.Metric.Gauge<number>;
|
|
550
|
-
uploadDurationHistogram: effect_Metric0.Metric<
|
|
551
|
-
partUploadDurationHistogram: effect_Metric0.Metric<
|
|
552
|
-
fileSizeHistogram: effect_Metric0.Metric<
|
|
553
|
-
partSizeHistogram: effect_Metric0.Metric<
|
|
550
|
+
uploadDurationHistogram: effect_Metric0.Metric<effect_MetricKeyType43.MetricKeyType.Histogram, number, effect_MetricState43.MetricState.Histogram>;
|
|
551
|
+
partUploadDurationHistogram: effect_Metric0.Metric<effect_MetricKeyType43.MetricKeyType.Histogram, number, effect_MetricState43.MetricState.Histogram>;
|
|
552
|
+
fileSizeHistogram: effect_Metric0.Metric<effect_MetricKeyType43.MetricKeyType.Histogram, number, effect_MetricState43.MetricState.Histogram>;
|
|
553
|
+
partSizeHistogram: effect_Metric0.Metric<effect_MetricKeyType43.MetricKeyType.Histogram, number, effect_MetricState43.MetricState.Histogram>;
|
|
554
554
|
uploadRequestsTotal: effect_Metric0.Metric.Counter<number>;
|
|
555
555
|
uploadPartsTotal: effect_Metric0.Metric.Counter<number>;
|
|
556
556
|
uploadSuccessTotal: effect_Metric0.Metric.Counter<number>;
|
|
@@ -585,7 +585,7 @@ declare const logFilesystemUploadCompletion: (uploadId: string, metrics: {
|
|
|
585
585
|
retryCount?: number;
|
|
586
586
|
}) => Effect.Effect<void, never, never>;
|
|
587
587
|
declare const logFilesystemContext: (message: string, context: Record<string, unknown>) => Effect.Effect<void, never, never>;
|
|
588
|
-
declare const filesystemUploadRequestsTotal: effect_Metric0.Metric.Counter<number>, filesystemUploadPartsTotal: effect_Metric0.Metric.Counter<number>, filesystemUploadSuccessTotal: effect_Metric0.Metric.Counter<number>, filesystemUploadErrorsTotal: effect_Metric0.Metric.Counter<number>, filesystemApiCallsTotal: effect_Metric0.Metric.Counter<number>, filesystemUploadDurationHistogram: effect_Metric0.Metric<
|
|
588
|
+
declare const filesystemUploadRequestsTotal: effect_Metric0.Metric.Counter<number>, filesystemUploadPartsTotal: effect_Metric0.Metric.Counter<number>, filesystemUploadSuccessTotal: effect_Metric0.Metric.Counter<number>, filesystemUploadErrorsTotal: effect_Metric0.Metric.Counter<number>, filesystemApiCallsTotal: effect_Metric0.Metric.Counter<number>, filesystemUploadDurationHistogram: effect_Metric0.Metric<effect_MetricKeyType43.MetricKeyType.Histogram, number, effect_MetricState43.MetricState.Histogram>, filesystemPartUploadDurationHistogram: effect_Metric0.Metric<effect_MetricKeyType43.MetricKeyType.Histogram, number, effect_MetricState43.MetricState.Histogram>, filesystemFileSizeHistogram: effect_Metric0.Metric<effect_MetricKeyType43.MetricKeyType.Histogram, number, effect_MetricState43.MetricState.Histogram>, filesystemPartSizeHistogram: effect_Metric0.Metric<effect_MetricKeyType43.MetricKeyType.Histogram, number, effect_MetricState43.MetricState.Histogram>, filesystemActiveUploadsGauge: effect_Metric0.Metric.Gauge<number>, filesystemUploadThroughputGauge: effect_Metric0.Metric.Gauge<number>, filesystemUploadLatencySummary: effect_Metric0.Metric.Summary<number>;
|
|
589
589
|
type FilesystemMetrics = StorageMetrics;
|
|
590
590
|
//#endregion
|
|
591
591
|
//#region src/upload/metrics.d.ts
|
|
@@ -600,10 +600,10 @@ declare const createUploadServerMetrics: () => {
|
|
|
600
600
|
uploadFromUrlTotal: Metric.Metric.Counter<number>;
|
|
601
601
|
uploadFromUrlSuccessTotal: Metric.Metric.Counter<number>;
|
|
602
602
|
uploadFromUrlFailedTotal: Metric.Metric.Counter<number>;
|
|
603
|
-
uploadDurationHistogram: Metric.Metric<
|
|
604
|
-
chunkUploadDurationHistogram: Metric.Metric<
|
|
605
|
-
uploadFileSizeHistogram: Metric.Metric<
|
|
606
|
-
chunkSizeHistogram: Metric.Metric<
|
|
603
|
+
uploadDurationHistogram: Metric.Metric<effect_MetricKeyType43.MetricKeyType.Histogram, number, effect_MetricState43.MetricState.Histogram>;
|
|
604
|
+
chunkUploadDurationHistogram: Metric.Metric<effect_MetricKeyType43.MetricKeyType.Histogram, number, effect_MetricState43.MetricState.Histogram>;
|
|
605
|
+
uploadFileSizeHistogram: Metric.Metric<effect_MetricKeyType43.MetricKeyType.Histogram, number, effect_MetricState43.MetricState.Histogram>;
|
|
606
|
+
chunkSizeHistogram: Metric.Metric<effect_MetricKeyType43.MetricKeyType.Histogram, number, effect_MetricState43.MetricState.Histogram>;
|
|
607
607
|
activeUploadsGauge: Metric.Metric.Gauge<number>;
|
|
608
608
|
uploadThroughputGauge: Metric.Metric.Gauge<number>;
|
|
609
609
|
uploadLatencySummary: Metric.Metric.Summary<number>;
|
|
@@ -624,10 +624,10 @@ declare const uploadServerMetrics: {
|
|
|
624
624
|
uploadFromUrlTotal: Metric.Metric.Counter<number>;
|
|
625
625
|
uploadFromUrlSuccessTotal: Metric.Metric.Counter<number>;
|
|
626
626
|
uploadFromUrlFailedTotal: Metric.Metric.Counter<number>;
|
|
627
|
-
uploadDurationHistogram: Metric.Metric<
|
|
628
|
-
chunkUploadDurationHistogram: Metric.Metric<
|
|
629
|
-
uploadFileSizeHistogram: Metric.Metric<
|
|
630
|
-
chunkSizeHistogram: Metric.Metric<
|
|
627
|
+
uploadDurationHistogram: Metric.Metric<effect_MetricKeyType43.MetricKeyType.Histogram, number, effect_MetricState43.MetricState.Histogram>;
|
|
628
|
+
chunkUploadDurationHistogram: Metric.Metric<effect_MetricKeyType43.MetricKeyType.Histogram, number, effect_MetricState43.MetricState.Histogram>;
|
|
629
|
+
uploadFileSizeHistogram: Metric.Metric<effect_MetricKeyType43.MetricKeyType.Histogram, number, effect_MetricState43.MetricState.Histogram>;
|
|
630
|
+
chunkSizeHistogram: Metric.Metric<effect_MetricKeyType43.MetricKeyType.Histogram, number, effect_MetricState43.MetricState.Histogram>;
|
|
631
631
|
activeUploadsGauge: Metric.Metric.Gauge<number>;
|
|
632
632
|
uploadThroughputGauge: Metric.Metric.Gauge<number>;
|
|
633
633
|
uploadLatencySummary: Metric.Metric.Summary<number>;
|
|
@@ -718,10 +718,10 @@ declare const getTestMetrics: () => {
|
|
|
718
718
|
uploadFromUrlTotal: effect_Metric0.Metric.Counter<number>;
|
|
719
719
|
uploadFromUrlSuccessTotal: effect_Metric0.Metric.Counter<number>;
|
|
720
720
|
uploadFromUrlFailedTotal: effect_Metric0.Metric.Counter<number>;
|
|
721
|
-
uploadDurationHistogram: effect_Metric0.Metric<
|
|
722
|
-
chunkUploadDurationHistogram: effect_Metric0.Metric<
|
|
723
|
-
uploadFileSizeHistogram: effect_Metric0.Metric<
|
|
724
|
-
chunkSizeHistogram: effect_Metric0.Metric<
|
|
721
|
+
uploadDurationHistogram: effect_Metric0.Metric<effect_MetricKeyType43.MetricKeyType.Histogram, number, effect_MetricState43.MetricState.Histogram>;
|
|
722
|
+
chunkUploadDurationHistogram: effect_Metric0.Metric<effect_MetricKeyType43.MetricKeyType.Histogram, number, effect_MetricState43.MetricState.Histogram>;
|
|
723
|
+
uploadFileSizeHistogram: effect_Metric0.Metric<effect_MetricKeyType43.MetricKeyType.Histogram, number, effect_MetricState43.MetricState.Histogram>;
|
|
724
|
+
chunkSizeHistogram: effect_Metric0.Metric<effect_MetricKeyType43.MetricKeyType.Histogram, number, effect_MetricState43.MetricState.Histogram>;
|
|
725
725
|
activeUploadsGauge: effect_Metric0.Metric.Gauge<number>;
|
|
726
726
|
uploadThroughputGauge: effect_Metric0.Metric.Gauge<number>;
|
|
727
727
|
uploadLatencySummary: effect_Metric0.Metric.Summary<number>;
|
|
@@ -733,4 +733,4 @@ declare const getTestMetrics: () => {
|
|
|
733
733
|
declare const validateMetricsExist: () => boolean;
|
|
734
734
|
//#endregion
|
|
735
735
|
export { AzureMetrics, AzureObservabilityLayer, AzureTracingLayer, FilesystemMetrics, FilesystemObservabilityLayer, FilesystemTracingLayer, FlowErrorCategory, FlowMetrics, FlowObservability, FlowObservabilityDisabled, FlowObservabilityLive, FlowObservabilityService, GCSMetrics, GCSObservabilityLayer, GCSTracingLayer, MetricsService, NoOpMetricsServiceLive, NodeSdkLive, Observability, ObservabilityDisabled, ObservabilityService, ObservabilityTestFixture, S3Metrics, S3ObservabilityLayer, S3TracingLayer, StorageErrorCategory, StorageMetrics, StorageObservability, StorageObservabilityDisabled, StorageObservabilityService, TracingService, UploadErrorCategory, UploadObservability, UploadObservabilityDisabled, UploadObservabilityLive, UploadObservabilityService, UploadObservabilityTest, UploadServerMetrics, WebSdkLive, WorkersSdkLive, azureActiveUploadsGauge, azureApiCallsTotal, azureFileSizeHistogram, azureMetrics, azurePartSizeHistogram, azurePartUploadDurationHistogram, azureUploadDurationHistogram, azureUploadErrorsTotal, azureUploadLatencySummary, azureUploadPartsTotal, azureUploadRequestsTotal, azureUploadSuccessTotal, azureUploadThroughputGauge, captureMetrics, classifyFlowError, classifyStorageError, classifyUploadError, createFlowMetrics, createStorageErrorClassifier, createStorageErrorTracker, createStorageMetrics, createStorageTracingLayer, createTestFixture, createTracingLayer, createUploadErrorClassifier, createUploadGauges, createUploadHistograms, createUploadMetrics, createUploadServerMetrics, createUploadSummaries, filesystemActiveUploadsGauge, filesystemApiCallsTotal, filesystemFileSizeHistogram, filesystemMetrics, filesystemPartSizeHistogram, filesystemPartUploadDurationHistogram, filesystemUploadDurationHistogram, filesystemUploadErrorsTotal, filesystemUploadLatencySummary, filesystemUploadPartsTotal, filesystemUploadRequestsTotal, filesystemUploadSuccessTotal, filesystemUploadThroughputGauge, flowMetrics, gcsActiveUploadsGauge, gcsApiCallsTotal, gcsFileSizeHistogram, gcsMetrics, gcsPartSizeHistogram, gcsPartUploadDurationHistogram, gcsUploadDurationHistogram, gcsUploadErrorsTotal, gcsUploadLatencySummary, gcsUploadPartsTotal, gcsUploadRequestsTotal, gcsUploadSuccessTotal, gcsUploadThroughputGauge, getFlowMetrics, getTestMetrics, getUploadMetrics, isObservabilityEnabled, logAzureContext, logAzureOperation, logAzureUploadCompletion, logAzureUploadProgress, logFilesystemContext, logFilesystemOperation, logFilesystemUploadCompletion, logFilesystemUploadProgress, logGCSContext, logGCSOperation, logGCSUploadCompletion, logGCSUploadProgress, logS3Context, logS3Operation, logS3UploadCompletion, logS3UploadProgress, logStorageOperation, logUploadCompletion, logUploadProgress, logWithContext, makeFlowObservabilityLayer, makeFlowObservabilityLive, makeObservabilityLayer, makeStorageObservabilityLayer, makeTestFlowObservability, makeTestFlowObservability$1 as makeTestFlowObservabilityUtil, makeTestStorageObservability, makeTestUploadObservability, makeUploadObservabilityLayer, makeUploadObservabilityLive, runWithTestFlowObservability, runWithTestObservability, s3ActiveUploadsGauge, s3ApiCallsTotal, s3FileSizeHistogram, s3Metrics, s3PartSizeHistogram, s3PartUploadDurationHistogram, s3UploadDurationHistogram, s3UploadErrorsTotal, s3UploadLatencySummary, s3UploadPartsTotal, s3UploadRequestsTotal, s3UploadSuccessTotal, s3UploadThroughputGauge, trackActiveFlow, trackActiveNode, trackAzureError, trackFileSize, trackFilesystemError, trackFlowError, trackGCSError, trackNodeError, trackPartSize, trackS3Error, trackStorageError, trackUploadError, uploadServerMetrics, validateMetricsExist, whenObservabilityEnabled, withActiveUploadTracking, withApiMetrics, withAzureApiMetrics, withAzureOperationMetrics, withAzureSpan, withAzureTimingMetrics, withAzureUploadMetrics, withChunkContext, withChunkDuration, withExecutionContext, withFilesystemApiMetrics, withFilesystemOperationMetrics, withFilesystemSpan, withFilesystemTimingMetrics, withFilesystemUploadMetrics, withFlowContext, withFlowDuration, withFlowSpan, withGCSApiMetrics, withGCSOperationMetrics, withGCSSpan, withGCSTimingMetrics, withGCSUploadMetrics, withMetricTracking, withNodeContext, withNodeDuration, withS3ApiMetrics, withS3OperationMetrics, withS3Span, withS3TimingMetrics, withS3UploadMetrics, withStorageOperationMetrics, withStorageSpan, withThroughputTracking, withTimingMetrics, withUploadContext, withUploadDuration, withUploadMetrics, withUploadSpan };
|
|
736
|
-
//# sourceMappingURL=index.d.
|
|
736
|
+
//# sourceMappingURL=index.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/core/metrics.ts","../src/core/errors.ts","../src/core/layers.ts","../src/core/logging.ts","../src/core/testing.ts","../src/core/tracing.ts","../src/core/utilities.ts","../src/flow/metrics.ts","../src/flow/tracing.ts","../src/flow/layers.ts","../src/flow/errors.ts","../src/flow/testing.ts","../src/service/metrics.ts","../src/storage/s3.ts","../src/storage/azure.ts","../src/storage/gcs.ts","../src/storage/filesystem.ts","../src/upload/metrics.ts","../src/upload/tracing.ts","../src/upload/layers.ts","../src/upload/errors.ts","../src/upload/testing.ts"],"sourcesContent":[],"mappings":";;;;;;;;cAOa;;;;;;;AAAA,cAuBA,sBAHX,EAAA,CAAA,WAAA,EAAA,MAAA,EAAA,GAAA;;;;;;cA8CW;EA3CA,kBAAA,EAsDX,MAAA,CAAA,MAAA,CAAA,KAdA,CAAA,MAAA,CAAA;yBAcA,MAAA,CAAA,MAAA,CAAA;;cAGW;wBASX,MAAA,CAAA,MAAA,CAAA;;cAGW;;;;;;;;EA1BA,mBAAA,uBAWX,CAAA,MAAA,CAAA;EAGW,gBAAA,uBASX,CAAA,MAAA,CAAA;EAGW,kBAAA,uBAKX,CAAA,MAAA,CAAA;;;;KAGU,cAAA,GAAiB,kBAAkB;;;KCpGnC,oBAAA;cAUC,0CAAyC;cAsFzC,6FAE8B,oDAEhB;cAad,kDAEF,6DAGA,+DA5G2C,yBA6Gd,MAAA,CAAA;cAqC3B,0DAEF,4DACmC,8EAUjC,4BAA4B,MAAA,CAAA;;;;;;UCtKxB,oBAAA;;;AFHjB;cEMC;;;;cAKY,aAAA,SAAsB,kBAAA;AFYnC;;;UEJiB,2BAAA,SAAoC;;oBAEjC;;cACnB;;;;cAKY,oBAAA,SAA6B,yBAAA;;AFuC1C;AAcA;AAYa,UEzDI,0BAAA,SAAmC,oBF8DlD,CAAA;;mBE5DiB,MAAA,CAAO;qBACL,MAAA,CAAO;kBACV,MAAA,CAAO;mBACN,MAAA,CAAO;;;cAEzB;;;;cAKY,mBAAA,SAA4B,wBAAA;;;;UAQxB,wBAAA,SAAiC;;iBAEjC,MAAA,CAAO;mBACL,MAAA,CAAO;gBACV,MAAA,CAAO;IFyCX,YAAA,EExCM,MAAA,CAAO,MFwCsB,CAAA,IAAA,CAAA;;;cEtC9C;AD9DD;AAUA;AAsFA;AAiBa,cC9CA,iBAAA,SAA0B,sBAAA,CDsFnC;;;;AAlCoC,cCxC3B,sBDwC2B,EAAA,CAAA,WAAA,EAAA,MAAA,EAAA,OAAA,CAAA,EAAA,OAAA,EAAA,GCrCrC,KAAA,CAAM,KDqC+B,CCrCzB,aDqCyB,CAAA;AAqCxC;;;AAaa,cC9EA,6BD8EA,EAAA,CAAA,WAAA,EAAA,MAAA,EAAA,OAAA,EC5EF,cD4EE,EAAA,OAAA,CAAA,EAAA,OAAA,EAAA,GC1EV,KAAA,CAAM,KD0EI,CC1EE,oBD0EF,CAAA;;;;cC/DA,qDAEV,KAAA,CAAM,MAAM;;AAzGf;AAGC;cAqHY,mDAEV,KAAA,CAAM,MAAM;;;;AAlHF,cAqIA,qBArIsB,EAqID,KAAA,CAAA,KAlI/B,CAkI+B,aAlI/B,EAAA,KAAA,EAAA,KAAA,CAAA;AAKH;AAGC;;cAkIY,uDAAmD,KAAA,CAAA,MAAA;;;AA7HhE;AAQiB,cA+HJ,2BA/H+B,EA+HJ,KAAA,CAAA,KA/HI,CA+HJ,mBA/HI,EAAA,KAAA,EAAA,KAAA,CAAA;;;;AAKzB,cA+HN,yBA/Ha,EA+HY,KAAA,CAAA,KA/HZ,CA+HY,iBA/HZ,EAAA,KAAA,EAAA,KAAA,CAAA;;;AAEzB;cAsIY,wBAAsB,MAAA,CAAA;;;;AAjItB,cA4IA,wBA5I4B,EAAA,CAAA,CAAA,EAAA,CAAA,EAAA,CAAA,CAAA,CAAA,MAAA,EA6I/B,MAAA,CAAO,MA1Id,CA0IqB,CA1IrB,EA0IwB,CA1IxB,EA0I2B,CA1I3B,CAAA,EAAA,GA2IA,MAAA,CAAO,MA3IP,CA2Ic,MAAA,CAAO,MA3IrB,CA2I4B,CA3I5B,CAAA,EA2IgC,CA3IhC,EA2ImC,CA3InC,GA2IuC,aA3IvC,CAAA;;;cCnDU,2CAEF,4BAAuB,MAAA,CAAA;cAGrB;;;;;MAQV,MAAA,CAAA;AHZU,cG0BA,mBHNX,EAAA,CAAA,WAAA,EAAA,MAAA,EAAA,SAAA,EAAA,MAAA,EAAA,QAAA,EAAA,MAAA,EAAA,QAAA,CAAA,EGUW,MHVX,CAAA,MAAA,EAAA,OAAA,CAAA,EAAA,GGUkC,MAAA,CAAA,MHVlC,CAAA,IAAA,EAAA,KAAA,EAAA,KAAA,CAAA;cGmBW;;;;;;EHhBA,UAAA,CAAA,EAAA,MAAA;MG0BV,MAAA,CAAA;;;;;;cCpCU,uDAEV,KAAA,CAAM,MAAM;;;AJff;cI6Ba,mCACP,KAAA,CAAM,MAAM;;;;cAiBL,iCAAgC,KAAA,CAAM,MAAM;;AJxBzD;;;;cI+Ca,kCACH,MAAA,CAAO,OAAO,GAAG,GAAG,OAC3B,MAAA,CAAO,OAAO,GAAG,GAAG;;;;;;cAaV,sCACH,MAAA,CAAO,OAAO,GAAG,GAAG,OAC3B,MAAA,CAAO,OAAO,GAAG,GAAG;;;;AJrBV,UIkCI,wBAAA,CJvBf;EAGW,SAAA,oBASX,EIY+B,KAAA,CAAM,KJZrC,CIY2C,oBJZ3C,CAAA;EAGW,SAAA,mBAKX,EIK8B,KAAA,CAAM,KJLpC,CIK0C,mBJL1C,CAAA;8BIM4B,KAAA,CAAM,MAAM;;;;;cAM7B,6CAEV;;;;cASU,yCACH,MAAA,CAAO,OACb,GACA,GACA,uBAAuB,sBAAsB,6CAG9C,MAAA,CAAO,OAAO,GAAG;;;cC1HP,gBAAc,OAAA,CAAA;;;;;cAKd,4BLVb;;AAAA,CAAA,EAAA,GKUqE,KAAA,CAAA,KLVxD,CAAA;;;cKkBA,oDAAgD,KAAA,CAAA;;;cAMhD,gFAII,qCAEN,MAAA,CAAO,OAAO,GAAG,GAAG,OAAE,MAAA,CAAA,OAAA,GAAA,GAAA,QAAA,GAAA,cAAA,CAAA,UAAA;ALPpB,cKmBA,ULqBX,EKrBqB,KAAA,CAAA,KLqBrB,CKjBC,+BAAA,CAJoB,QAAA,ELqBrB,KAAA,EAAA,KAAA,CAAA;cKfW,aAAW,KAAA,CAAA,MAIrB,+BAAA,CAJqB,QAAA;cAOX,gBAAc,KAAA,CAAA,MAIxB,+BAAA,CAJwB,QAAA;;;cCtDd,sCACF,0CAED,MAAA,CAAO,OAAO,GAAG,GAAG,OAC3B,MAAA,CAAO,OAAO,GAAG,GAAG;cAoBV,mCACF,2CAED,MAAA,CAAO,OAAO,GAAG,GAAG,OAC3B,MAAA,CAAO,OAAO,GAAG,GAAG;cAUV,qCACH,MAAA,CAAO,MAAA,CAAO,2BACd,MAAA,CAAO,OAAO,GAAG,GAAG,OAC3B,MAAA,CAAO,OAAO,GAAG,GAAG;cAaV,kCACF,0CAED,MAAA,CAAO,OAAO,GAAG,GAAG,OAC3B,MAAA,CAAO,OAAO,GAAG,GAAG;cAMV,kCACF,0CAED,MAAA,CAAO,OAAO,GAAG,GAAG,OAC3B,MAAA,CAAO,OAAO,GAAG,GAAG;cAMV,6CACF,wBACD,MAAA,CAAO,OAAO,GAAG,GAAG,OAC3B,MAAA,CAAO,OAAO,GAAG,GAAG;AN9EV,cMqFA,sBNjEX,EAAA,CAAA,CAAA,EAAA,CAAA,EAAA,CAAA,CAAA,CAAA,OAAA,EMkES,cNlET,EAAA,KAAA,EAAA,MAAA,EAAA,MAAA,EMoEQ,MAAA,CAAO,MNpEf,CMoEsB,CNpEtB,EMoEyB,CNpEzB,EMoE4B,CNpE5B,CAAA,EAAA,GMqEC,MAAA,CAAO,MNrER,CMqEe,CNrEf,EMqEkB,CNrElB,EMqEqB,CNrErB,CAAA;cMmFW,gDACF,6DAGD,MAAA,CAAO,OAAO,GAAG,GAAG,0BAE3B,MAAA,CAAO,OAAO,GAAG,GAAG;;;;;;cC3GV;;;;EPFA,eAAA,uBAoBX,CAAA,MAAA,CAAA;;;;;;;EAGW,qBAAA,eAwCX,iDAAA,MAAA,6CAAA;;;;;;;;;;;;KOsDU,WAAA,GAAc,kBAAkB;;APnD5C;AAcA;AAYa,cO8BA,WPzBX,EAAA;;;;;;;;;;;;;;;;;;;;;;;;;cQ/FW,wDAC+B,qCACjC,MAAA,CAAO,OAAO,GAAG,GAAG,OAAK,MAAA,CAAO,OAAO,GAAG,GAAG;;;;ARJ3C,cQiBA,eRGX,EAAA,CAAA,OAAA,EAAA;;;;;;MQGD,MAAA,CAAA;ARAD;;;cQYa;;;;;;MAMZ,MAAA,CAAA;;;;cAYY;ERaA,cAAA,CAAA,EAAA,MAWX,EAAA;EAGW,YAAA,CAAA,EAAA,MAAA;EAYA,UAAA,CAAA,EAAA,MAAA;;MQlCZ,MAAA,CAAA;;;;;;cCnDY,qDAEV,KAAA,CAAM,MAAM;;;ATTf;cS2Ba,uBAAqB,KAAA,CAAA,MAAA;;ATJlC;;cSca,gBAAc,MAAA,CAAA;;;;;;;;;cAQd,oCACH,MAAA,CAAO,OAAO,GAAG,GAAG,OAC3B,MAAA,CAAO,OAAO,GAAG,GAAG;;;ATmBvB;AAca,cSlBA,gBT2BX,EAAA,CAAA,CAAA,EAAA,CAAA,EAAA,CAAA,CAAA,CAAA,MAAA,EAAA,MAAA,EAAA,QAAA,EAAA,MAAA,EAAA,MAAA,ESxBQ,MAAA,CAAO,MTwBf,CSxBsB,CTwBtB,ESxByB,CTwBzB,ESxB4B,CTwB5B,CAAA,EAAA,GSvBC,MAAA,CAAO,MTuBR,CSvBe,CTuBf,ESvBkB,CTuBlB,ESvBqB,CTuBrB,CAAA;AAGF;;;cSJa,mCACH,MAAA,CAAO,OAAO,GAAG,GAAG,OAC3B,MAAA,CAAO,OAAO,GAAG,GAAG;;;;cAkBV,mCACH,MAAA,CAAO,OAAO,GAAG,GAAG,OAC3B,MAAA,CAAO,OAAO,GAAG,GAAG;;;KC9GX,iBAAA;;;;cAWC,uCAAsC;;;AVXnD;cU0Ca,2BACJ,MACN,MAAA,CAAO;;;;cAqBG,6DAGJ,MACN,MAAA,CAAO;;;;;;cCjEG,mCAAgC,KAAA,CAAM,MAAM;;;AXJzD;cWqBa,6CACH,MAAA,CAAO,OAAO,GAAG,GAAG,uBAC3B,MAAA,CAAO,OAAO,GAAG;;;cC9B4B;;;;sEAkB/B,4BACR,MAAA,CAAO;;;AZZhB;;;;;;cYEa,cAAA,SAAuB,mBAAA;;;;;cAkBvB,wBAAwB,KAAA,CAAM,MAAM;;;cCApC;;;;;;EbpBA,iBAAA,uBAoBX,iDAAA,MAAA,6CAAA;;;;;;;AAGF,CAAA;caAa,gBAAc,KAAA,CAAA;;;cAqCd,4DAAY,4BAAA,MAAA,CAAA;cAOZ,sBAAoB,KAAA,CAAA;;;cASpB,yDAEH,MAAA,CAAO,OAAO,GAAG,GAAG,OAAE,MAAA,CAAA,OAAA,GAAA,GAAA;cAGnB,uDAEH,MAAA,CAAO,OAAO,GAAG,GAAG,OAAE,MAAA,CAAA,OAAA,GAAA,GAAA;cAGnB,uCAAmB,cAAA,CAAA,MAAA,CAAA,2BAAA,MAAA,CAAA,OAAA,GAAA,GAAA,OAAA,MAAA,CAAA,OAAA,GAAA,GAAA;cAEnB,+EAGH,MAAA,CAAO,OAAO,GAAG,GAAG,0BACX,MAAA,CAAA,OAAA,GAAA,GAAA;cAKN,sDAC+B,qCACjC,MAAA,CAAO,OAAO,GAAG,GAAG,OAAE,MAAA,CAAA;cAIpB,iEAAc,wCAAA,MAAA,CAAA;AbrCd,casCA,mBb3BX,EAAA,CAAA,QAAA,EAAA,MAAA,EAAA,QAAA,EAAA;EAGW,aAAA,EAAA,MAAA;EAYA,UAAA,EAAA,MAAA;;;MaYgE,MAAA,CAAA;cAChE;;;;;;;MAGZ,MAAA,CAAA;cACY,yCAAY,4BAAA,MAAA,CAAA;cAIF,uBAAqB,cAAA,CAAA,MAAA,CAAA,qCACN,cAAA,CAAA,MAAA,CAAA,uCACI,cAAA,CAAA,MAAA,CAAA,sCACF,cAAA,CAAA,MAAA,CAAA,kCACR,cAAA,CAAA,MAAA,CAAA,4CACoB,cAAA,CAAA,OAAA,sBAAA,CAAA,aAAA,CAAA,SAAA,UAAA,oBAAA,CAAA,WAAA,CAAA,SAAA,kCACQ,cAAA,CAAA,OAAA,sBAAA,CAAA,aAAA,CAAA,SAAA,UAAA,oBAAA,CAAA,WAAA,CAAA,SAAA,wBACpB,cAAA,CAAA,OAAA,sBAAA,CAAA,aAAA,CAAA,SAAA,UAAA,oBAAA,CAAA,WAAA,CAAA,SAAA,wBACA,cAAA,CAAA,OAAA,sBAAA,CAAA,aAAA,CAAA,SAAA,UAAA,oBAAA,CAAA,WAAA,CAAA,SAAA,yBACE,cAAA,CAAA,MAAA,CAAA,wCACM,cAAA,CAAA,MAAA,CAAA,uCACF,cAAA,CAAA,MAAA,CAAA;KAIlC,SAAA,GAAY;;;cC5GX;;;;;;EdpBA,iBAAA,uBAoBX,iDAAA,MAAA,6CAAA;;;;;;;AAGF,CAAA;ccAa,mBAAiB,KAAA,CAAA;;;cAuDjB,+DAAe,4BAAA,MAAA,CAAA;cAOf,yBAAuB,KAAA,CAAA;;;cASvB,4DAEH,MAAA,CAAO,OAAO,GAAG,GAAG,OAAE,MAAA,CAAA,OAAA,GAAA,GAAA;cAGnB,0DAEH,MAAA,CAAO,OAAO,GAAG,GAAG,OAAE,MAAA,CAAA,OAAA,GAAA,GAAA;cAGnB,0CAAsB,cAAA,CAAA,MAAA,CAAA,2BAAA,MAAA,CAAA,OAAA,GAAA,GAAA,OAAA,MAAA,CAAA,OAAA,GAAA,GAAA;cAEtB,kFAGH,MAAA,CAAO,OAAO,GAAG,GAAG,0BACX,MAAA,CAAA,OAAA,GAAA,GAAA;cAWN,yDAC+B,qCACjC,MAAA,CAAO,OAAO,GAAG,GAAG,OAAE,MAAA,CAAA;cAIpB,oEAAiB,wCAAA,MAAA,CAAA;Ad7DjB,cc8DA,sBdnDX,EAAA,CAAA,QAAA,EAAA,MAAA,EAAA,QAAA,EAAA;EAGW,aAAA,EAAA,MAAA;EAYA,UAAA,EAAA,MAAA;;;McuCZ,MAAA,CAAA;cACY;;;;;;;MAGZ,MAAA,CAAA;cACY,4CAAe,4BAAA,MAAA,CAAA;cAIL,0BAAwB,cAAA,CAAA,MAAA,CAAA,wCACN,cAAA,CAAA,MAAA,CAAA,0CACI,cAAA,CAAA,MAAA,CAAA,yCACF,cAAA,CAAA,MAAA,CAAA,qCACR,cAAA,CAAA,MAAA,CAAA,+CACoB,cAAA,CAAA,OAAA,sBAAA,CAAA,aAAA,CAAA,SAAA,UAAA,oBAAA,CAAA,WAAA,CAAA,SAAA,qCACQ,cAAA,CAAA,OAAA,sBAAA,CAAA,aAAA,CAAA,SAAA,UAAA,oBAAA,CAAA,WAAA,CAAA,SAAA,2BACpB,cAAA,CAAA,OAAA,sBAAA,CAAA,aAAA,CAAA,SAAA,UAAA,oBAAA,CAAA,WAAA,CAAA,SAAA,2BACA,cAAA,CAAA,OAAA,sBAAA,CAAA,aAAA,CAAA,SAAA,UAAA,oBAAA,CAAA,WAAA,CAAA,SAAA,4BACE,cAAA,CAAA,MAAA,CAAA,2CACM,cAAA,CAAA,MAAA,CAAA,0CACF,cAAA,CAAA,MAAA,CAAA;KAIrC,YAAA,GAAe;;;cCvId;;;;;;EfpBA,iBAAA,uBAoBX,iDAAA,MAAA,6CAAA;;;;;;;AAGF,CAAA;ceAa,iBAAe,KAAA,CAAA;;;cAwDf,6DAAa,4BAAA,MAAA,CAAA;cAOb,uBAAqB,KAAA,CAAA;;;cASrB,0DAEH,MAAA,CAAO,OAAO,GAAG,GAAG,OAAE,MAAA,CAAA,OAAA,GAAA,GAAA;cAGnB,wDAEH,MAAA,CAAO,OAAO,GAAG,GAAG,OAAE,MAAA,CAAA,OAAA,GAAA,GAAA;cAGnB,wCAAoB,cAAA,CAAA,MAAA,CAAA,2BAAA,MAAA,CAAA,OAAA,GAAA,GAAA,OAAA,MAAA,CAAA,OAAA,GAAA,GAAA;cAEpB,gFAGH,MAAA,CAAO,OAAO,GAAG,GAAG,0BACX,MAAA,CAAA,OAAA,GAAA,GAAA;cAWN,uDAC+B,qCACjC,MAAA,CAAO,OAAO,GAAG,GAAG,OAAE,MAAA,CAAA;cAIpB,kEAAe,wCAAA,MAAA,CAAA;Af9Df,ce+DA,oBfpDX,EAAA,CAAA,QAAA,EAAA,MAAA,EAAA,QAAA,EAAA;EAGW,aAAA,EAAA,MAAA;EAYA,UAAA,EAAA,MAAA;;;MeqCiE,MAAA,CAAA;cACjE;;;;;;;MAGZ,MAAA,CAAA;cACY,0CAAa,4BAAA,MAAA,CAAA;cAIH,wBAAsB,cAAA,CAAA,MAAA,CAAA,sCACN,cAAA,CAAA,MAAA,CAAA,wCACI,cAAA,CAAA,MAAA,CAAA,uCACF,cAAA,CAAA,MAAA,CAAA,mCACR,cAAA,CAAA,MAAA,CAAA,6CACoB,cAAA,CAAA,OAAA,sBAAA,CAAA,aAAA,CAAA,SAAA,UAAA,oBAAA,CAAA,WAAA,CAAA,SAAA,mCACQ,cAAA,CAAA,OAAA,sBAAA,CAAA,aAAA,CAAA,SAAA,UAAA,oBAAA,CAAA,WAAA,CAAA,SAAA,yBACpB,cAAA,CAAA,OAAA,sBAAA,CAAA,aAAA,CAAA,SAAA,UAAA,oBAAA,CAAA,WAAA,CAAA,SAAA,yBACA,cAAA,CAAA,OAAA,sBAAA,CAAA,aAAA,CAAA,SAAA,UAAA,oBAAA,CAAA,WAAA,CAAA,SAAA,0BACE,cAAA,CAAA,MAAA,CAAA,yCACM,cAAA,CAAA,MAAA,CAAA,wCACF,cAAA,CAAA,MAAA,CAAA;KAInC,UAAA,GAAa;;;cCrIZ;;;;;;EhBpBA,iBAAA,uBAoBX,iDAAA,MAAA,6CAAA;;;;;;;AAGF,CAAA;cgBAa,wBAAsB,KAAA,CAAA;;;cA0CtB,oEAAoB,4BAAA,MAAA,CAAA;cAOpB,8BAA4B,KAAA,CAAA;;;cAS5B,iEAEH,MAAA,CAAO,OAAO,GAAG,GAAG,OAAE,MAAA,CAAA,OAAA,GAAA,GAAA;cAGnB,+DAEH,MAAA,CAAO,OAAO,GAAG,GAAG,OAAE,MAAA,CAAA,OAAA,GAAA,GAAA;cAGnB,+CAA2B,cAAA,CAAA,MAAA,CAAA,2BAAA,MAAA,CAAA,OAAA,GAAA,GAAA,OAAA,MAAA,CAAA,OAAA,GAAA,GAAA;cAE3B,uFAGH,MAAA,CAAO,OAAO,GAAG,GAAG,0BACX,MAAA,CAAA,OAAA,GAAA,GAAA;cAWN,8DAC+B,qCACjC,MAAA,CAAO,OAAO,GAAG,GAAG,OAAE,MAAA,CAAA;cAIpB,yEAAsB,wCAAA,MAAA,CAAA;AhBhDtB,cgBoDA,2BhBzCX,EAAA,CAAA,QAAA,EAAA,MAAA,EAAA,QAAA,EAAA;EAGW,aAAA,EAAA,MAAA;EAYA,UAAA,EAAA,MAAA;;;MgB6BZ,MAAA,CAAA;cACY;;;;;;;MAGZ,MAAA,CAAA;cACY,iDAAoB,4BAAA,MAAA,CAAA;cAIV,+BAA6B,cAAA,CAAA,MAAA,CAAA,6CACN,cAAA,CAAA,MAAA,CAAA,+CACI,cAAA,CAAA,MAAA,CAAA,8CACF,cAAA,CAAA,MAAA,CAAA,0CACR,cAAA,CAAA,MAAA,CAAA,oDACoB,cAAA,CAAA,OAAA,sBAAA,CAAA,aAAA,CAAA,SAAA,UAAA,oBAAA,CAAA,WAAA,CAAA,SAAA,0CACQ,cAAA,CAAA,OAAA,sBAAA,CAAA,aAAA,CAAA,SAAA,UAAA,oBAAA,CAAA,WAAA,CAAA,SAAA,gCACpB,cAAA,CAAA,OAAA,sBAAA,CAAA,aAAA,CAAA,SAAA,UAAA,oBAAA,CAAA,WAAA,CAAA,SAAA,gCACA,cAAA,CAAA,OAAA,sBAAA,CAAA,aAAA,CAAA,SAAA,UAAA,oBAAA,CAAA,WAAA,CAAA,SAAA,iCACE,cAAA,CAAA,MAAA,CAAA,gDACM,cAAA,CAAA,MAAA,CAAA,+CACF,cAAA,CAAA,MAAA,CAAA;KAI1C,iBAAA,GAAoB;;;;;;cC/InB;;;;EjBFA,kBAAA,uBAoBX,CAAA,MAAA,CAAA;;;;;;;EAGW,kBAAA,eAwCX,iDAAA,MAAA,6CAAA;;;;;;;;;KiB0CU,mBAAA,GAAsB,kBAAkB;;;;cAKvC;EjB5CA,kBAAA,uBAWX,CAAA,MAAA,CAAA;EAGW,oBAAA,uBASX,CAAA,MAAA,CAAA;EAGW,iBAAA,uBAKX,CAAA,MAAA,CAAA;;;;;;;;;;;;;;;;;;;ckB/FW,0DAC+B,qCACjC,MAAA,CAAO,OAAO,GAAG,GAAG,OAAK,MAAA,CAAO,OAAO,GAAG,GAAG;;;;AlBJ3C,ckBiBA,iBlBGX,EAAA,CAAA,OAAA,EAAA;;;;;;MkBGD,MAAA,CAAA;AlBAD;;;ckBYa;;;;;MAKZ,MAAA,CAAA;;;;;;cCjCY,uDAEV,KAAA,CAAM,MAAM;;;AnBTf;cmBmCa,yBAAuB,KAAA,CAAA,MAAA;;AnBZpC;;cmBsBa,kBAAgB,MAAA,CAAA;;;;;;;;;cAQhB,sCACH,MAAA,CAAO,OAAO,GAAG,GAAG,OAC3B,MAAA,CAAO,OAAO,GAAG,GAAG,IAAI;;;AnBW3B;AAca,cmBXA,iBnBoBX,EAAA,CAAA,CAAA,EAAA,CAAA,EAAA,CAAA,CAAA,CAAA,MAAA,EmBnBQ,MAAA,CAAO,MnBmBf,CmBnBsB,CnBmBtB,EmBnByB,CnBmBzB,EmBnB4B,CnBmB5B,CAAA,EAAA,GmBlBC,MAAA,CAAO,MnBkBR,CmBlBe,CnBkBf,EmBlBkB,CnBkBlB,EmBlBqB,CnBkBrB,CAAA;;;KoBzFU,mBAAA;;;;cAaC,yCAAwC;;ApBbrD;;coBuGa,4BACF,kEAGA,4BAA4B,MAAA,CAAA;;;;cAsC1B,uEAC8B,mDAEhB;;;;;;;cC/Id,yBAAuB,KAAA,CAAA,MAAA;;ArBLpC;;cqBmBa;;;;;ErBIA,kBAAA,+BAwCX,CAAA,MAAA,CAAA;;;;;;;;;;;;;;AAGF;AAca,cqBxDA,oBrBiEX,EAAA,GAAA,GAAA,OAAA"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import{Context as e,Effect as t,Layer as n,Metric as r,MetricBoundaries as i,Option as a}from"effect";import{NodeSdk as o,WebSdk as s}from"@effect/opentelemetry";import{BatchSpanProcessor as c,ConsoleSpanExporter as l}from"@opentelemetry/sdk-trace-base";const u=e=>{if(!e||typeof e!=`object`)return`unknown_error`;let t=`code`in e?e.code:void 0,n=`name`in e?e.name:void 0,r=e instanceof Error?e.message.toLowerCase():``;return t===`NetworkError`||t===`ECONNRESET`||t===`ENOTFOUND`||t===`ETIMEDOUT`||r.indexOf(`network`)>=0||r.indexOf(`timeout`)>=0?`network_error`:t===`InvalidAccessKeyId`||t===`SignatureDoesNotMatch`||t===`TokenRefreshRequired`||t===`AuthenticationFailed`||n===`AuthenticationError`||r.indexOf(`authentication`)>=0||r.indexOf(`unauthorized`)>=0?`authentication_error`:t===`AccessDenied`||t===`AccountProblem`||t===`Forbidden`||n===`AuthorizationError`||r.indexOf(`forbidden`)>=0||r.indexOf(`permission`)>=0?`authorization_error`:t===`SlowDown`||t===`RequestTimeTooSkewed`||t===`TooManyRequests`||n===`ThrottlingError`||r.indexOf(`throttl`)>=0||r.indexOf(`rate limit`)>=0?`throttling_error`:t===`InternalError`||t===`ServiceUnavailable`||t===`InternalServerError`||n===`ServerError`||r.indexOf(`server error`)>=0||r.indexOf(`service unavailable`)>=0?`server_error`:t===`InvalidRequest`||t===`MalformedXML`||t===`RequestEntityTooLarge`||t===`BadRequest`||n===`ClientError`||r.indexOf(`bad request`)>=0||r.indexOf(`invalid`)>=0?`client_error`:`unknown_error`},d=(e,t)=>e=>{if(t){let n=t(e);if(n!==null)return n}return u(e)},ee=(e,n,i,a,o={},s=u)=>t.gen(function*(){let c=s(a);yield*n.uploadErrorsTotal.pipe(r.tagged(`operation`,i),r.tagged(`error_category`,c))(t.succeed(1));let l={storage_type:e,operation:i,error_category:c,error_type:typeof a,error_message:a instanceof Error?a.message:String(a),error_code:a&&typeof a==`object`&&`code`in a?a.code:void 0,error_name:a&&typeof a==`object`&&`name`in a?a.name:void 0,...o};yield*t.logError(`${e.toUpperCase()} ${i} failed`).pipe(t.annotateLogs(l))}),f=(e,t,n)=>{let r=d(e,n);return(n,i,a={})=>ee(e,t,n,i,a,r)};var p=class extends e.Tag(`Observability`)(){},m=class extends e.Tag(`StorageObservability`)(){},h=class extends e.Tag(`UploadObservability`)(){},g=class extends e.Tag(`FlowObservability`)(){};const te=(e,t=!0)=>n.succeed(p,{serviceName:e,enabled:t}),ne=(e,t,r=!0)=>n.succeed(m,{serviceName:`uploadista-${e}-store`,storageType:e,metrics:t,enabled:r}),_=(e=!0)=>n.succeed(h,{serviceName:`uploadista-upload-server`,enabled:e,metrics:{uploadCreated:t.void,uploadCompleted:t.void,uploadFailed:t.void,chunkUploaded:t.void}}),v=(e=!0)=>n.succeed(g,{serviceName:`uploadista-flow-engine`,enabled:e,metrics:{flowStarted:t.void,flowCompleted:t.void,flowFailed:t.void,nodeExecuted:t.void}}),re=te(`uploadista-disabled`,!1),ie=e=>ne(e,{},!1),ae=_(!1),oe=v(!1),y=t.gen(function*(){let e=yield*t.serviceOption(p);return a.match(e,{onNone:()=>!1,onSome:e=>e.enabled})}),se=e=>t.gen(function*(){if(yield*y){let t=yield*e;return a.some(t)}return a.none()}),b=(e,n)=>t.log(e).pipe(t.annotateLogs(n)),x=(e,t,n)=>b(`Upload progress`,{storage_type:e,upload_id:t,uploaded_bytes:n.uploadedBytes,total_bytes:n.totalBytes,progress_percentage:Math.round(n.uploadedBytes/n.totalBytes*100),...n.partNumber&&{part_number:n.partNumber},...n.speed&&{upload_speed_bps:n.speed}}),S=(e,t,n,r)=>b(`${e.toUpperCase()} ${t}`,{storage_type:e,operation:t,upload_id:n,...r}),C=(e,t,n)=>{let r=n.throughputBps?n.throughputBps/(1024*1024):0;return b(`${e.toUpperCase()} upload completed`,{storage_type:e,upload_id:t,file_size_bytes:n.fileSize,file_size_mb:Math.round(n.fileSize/(1024*1024)*100)/100,total_duration_ms:n.totalDurationMs,total_duration_seconds:Math.round(n.totalDurationMs/1e3*100)/100,throughput_bps:n.throughputBps,throughput_mbps:Math.round(r*100)/100,...n.partsCount&&{parts_count:n.partsCount},...n.averagePartSize&&{average_part_size_bytes:n.averagePartSize,average_part_size_mb:Math.round(n.averagePartSize/(1024*1024)*100)/100},...n.retryCount&&{retry_count:n.retryCount}})},w=e=>({uploadRequestsTotal:r.counter(`${e}_upload_requests_total`,{description:`Total number of upload requests for ${e}`}),uploadPartsTotal:r.counter(`${e}_upload_parts_total`,{description:`Total number of individual parts uploaded for ${e}`}),uploadSuccessTotal:r.counter(`${e}_upload_success_total`,{description:`Total number of successful uploads for ${e}`}),uploadErrorsTotal:r.counter(`${e}_upload_errors_total`,{description:`Total number of upload errors for ${e}`}),apiCallsTotal:r.counter(`${e}_api_calls_total`,{description:`Total number of API calls for ${e}`})}),T=e=>({uploadDurationHistogram:r.histogram(`${e}_upload_duration_seconds`,i.exponential({start:.01,factor:2,count:20}),`Duration of upload operations in seconds for ${e}`),partUploadDurationHistogram:r.histogram(`${e}_part_upload_duration_seconds`,i.exponential({start:.001,factor:2,count:15}),`Duration of individual part uploads in seconds for ${e}`),fileSizeHistogram:r.histogram(`${e}_file_size_bytes`,i.exponential({start:1024,factor:2,count:25}),`Size of uploaded files in bytes for ${e}`),partSizeHistogram:r.histogram(`${e}_part_size_bytes`,i.linear({start:5242880,width:1048576,count:20}),`Size of upload parts in bytes for ${e}`)}),E=e=>({activeUploadsGauge:r.gauge(`${e}_active_uploads`,{description:`Number of currently active uploads for ${e}`}),uploadThroughputGauge:r.gauge(`${e}_upload_throughput_bytes_per_second`,{description:`Current upload throughput in bytes per second for ${e}`})}),D=e=>({uploadLatencySummary:r.summary({name:`${e}_upload_latency_seconds`,maxAge:`10 minutes`,maxSize:1e3,error:.01,quantiles:[.5,.9,.95,.99],description:`Upload latency percentiles for ${e}`})}),O=e=>({...w(e),...T(e),...E(e),...D(e)}),k=e=>{let t=O(e),r={serviceName:`test-${e}-store`,storageType:e,metrics:t,enabled:!0};return n.succeed(m,r)},ce=()=>{let e={serviceName:`test-upload-server`,enabled:!0,metrics:{uploadCreated:t.void,uploadCompleted:t.void,uploadFailed:t.void,chunkUploaded:t.void}};return n.succeed(h,e)},le=()=>{let e={serviceName:`test-flow-engine`,enabled:!0,metrics:{flowStarted:t.void,flowCompleted:t.void,flowFailed:t.void,nodeExecuted:t.void}};return n.succeed(g,e)},ue=e=>t.gen(function*(){let t=yield*e;return yield*r.snapshot,t}),de=e=>t.gen(function*(){yield*r.snapshot;let t=yield*e;return yield*r.snapshot,t}),fe=(e=`test-storage`)=>({storageObservability:k(e),uploadObservability:ce(),flowObservability:le()}),pe=(e,n=`test-storage`)=>{let r=fe(n);return e.pipe(t.provide(r.storageObservability),t.provide(r.uploadObservability),t.provide(r.flowObservability))},me=e.GenericTag(`TracingService`),he=e=>{let t=e?.serviceName??`uploadista-storage`;return n.succeed(me,{serviceName:t})},A=e=>he({serviceName:`uploadista-${e}-store`}),j=(e,n,r)=>i=>i.pipe(t.withSpan(`${n}-${e}`,{attributes:{"storage.type":n,operation:e,...r}})),ge=s.layer(()=>({resource:{serviceName:`uploadista-storage`},spanProcessor:new c(new l)})),_e=o.layer(()=>({resource:{serviceName:`uploadista-storage`},spanProcessor:new c(new l)})),ve=s.layer(()=>({resource:{serviceName:`uploadista-storage-workers`},spanProcessor:new c(new l)})),M=(e,n,i)=>i.pipe(t.tap(()=>e.uploadRequestsTotal.pipe(r.tagged(`upload_id`,n))(t.succeed(1))),t.tapError(()=>e.uploadErrorsTotal.pipe(r.tagged(`upload_id`,n))(t.succeed(1))),t.tap(()=>e.uploadSuccessTotal.pipe(r.tagged(`upload_id`,n))(t.succeed(1)))),N=(e,n,i)=>i.pipe(t.tap(()=>e.apiCallsTotal.pipe(r.tagged(`operation`,n))(t.succeed(1)))),P=(e,n)=>t.gen(function*(){let r=yield*t.sync(()=>Date.now()),i=yield*n,a=((yield*t.sync(()=>Date.now()))-r)/1e3;return yield*e(t.succeed(a)),i}),F=(e,n,r)=>r.pipe(t.tap(()=>e.fileSizeHistogram(t.succeed(n)))),ye=(e,n,r)=>r.pipe(t.tap(()=>e.partSizeHistogram(t.succeed(n)))),I=(e,n)=>n.pipe(t.tap(()=>e.activeUploadsGauge(t.succeed(1))),t.ensuring(e.activeUploadsGauge(t.succeed(-1)))),L=(e,n,r)=>t.gen(function*(){let i=yield*t.sync(()=>Date.now()),a=yield*r,o=((yield*t.sync(()=>Date.now()))-i)/1e3,s=o>0?n/o:0;return yield*e.uploadThroughputGauge(t.succeed(s)),a}),R=(e,t,n,r,i)=>{let a=r.pipe(n=>N(e,t,n),t=>M(e,n,t),t=>P(e.uploadDurationHistogram,t),t=>I(e,t));return i!==void 0&&(a=a.pipe(t=>F(e,i,t),t=>L(e,i,t))),a},z=()=>({flowStartedTotal:r.counter(`flow_started_total`,{description:`Total number of flows started`}),flowCompletedTotal:r.counter(`flow_completed_total`,{description:`Total number of flows completed successfully`}),flowFailedTotal:r.counter(`flow_failed_total`,{description:`Total number of flows that failed`}),flowPausedTotal:r.counter(`flow_paused_total`,{description:`Total number of flows that were paused`}),flowResumedTotal:r.counter(`flow_resumed_total`,{description:`Total number of flows that were resumed`}),nodeExecutedTotal:r.counter(`node_executed_total`,{description:`Total number of nodes executed`}),nodeSuccessTotal:r.counter(`node_success_total`,{description:`Total number of nodes executed successfully`}),nodeFailedTotal:r.counter(`node_failed_total`,{description:`Total number of nodes that failed`}),nodeSkippedTotal:r.counter(`node_skipped_total`,{description:`Total number of nodes skipped (conditional)`}),flowDurationHistogram:r.histogram(`flow_duration_seconds`,i.exponential({start:.1,factor:2,count:20}),`Duration of complete flow execution in seconds`),nodeDurationHistogram:r.histogram(`node_duration_seconds`,i.exponential({start:.01,factor:2,count:18}),`Duration of individual node execution in seconds`),flowNodeCountHistogram:r.histogram(`flow_node_count`,i.linear({start:1,width:5,count:20}),`Number of nodes in a flow`),parallelNodesHistogram:r.histogram(`parallel_nodes_count`,i.linear({start:1,width:2,count:15}),`Number of nodes executed in parallel`),activeFlowsGauge:r.gauge(`active_flows`,{description:`Number of currently active flows`}),activeNodesGauge:r.gauge(`active_nodes`,{description:`Number of currently executing nodes`}),pausedFlowsGauge:r.gauge(`paused_flows`,{description:`Number of currently paused flows`}),flowLatencySummary:r.summary({name:`flow_latency_seconds`,maxAge:`10 minutes`,maxSize:1e3,error:.01,quantiles:[.5,.9,.95,.99],description:`Flow execution latency percentiles`}),nodeLatencySummary:r.summary({name:`node_latency_seconds`,maxAge:`10 minutes`,maxSize:1e3,error:.01,quantiles:[.5,.9,.95,.99],description:`Node execution latency percentiles`})}),be=z(),xe=(e,n)=>r=>r.pipe(t.withSpan(`flow-${e}`,{attributes:{"flow.operation":e,...n}})),Se=e=>t.annotateCurrentSpan({"flow.id":e.flowId??`unknown`,"flow.name":e.flowName??`unknown`,"flow.job_id":e.jobId??`unknown`,"flow.node_count":e.nodeCount?.toString()??`0`,"flow.storage_id":e.storageId??`unknown`}),Ce=e=>t.annotateCurrentSpan({"node.id":e.nodeId,"node.type":e.nodeType,"node.name":e.nodeName??`unknown`,"node.flow_id":e.flowId??`unknown`,"node.job_id":e.jobId??`unknown`}),we=e=>t.annotateCurrentSpan({"execution.order":e.executionOrder?.join(`,`)??``,"execution.current_index":e.currentIndex?.toString()??`0`,"execution.total_nodes":e.totalNodes?.toString()??`0`,"execution.parallel_count":e.parallelCount?.toString()??`0`}),B=(e=`uploadista-flow-engine`)=>{let t=z();return n.succeed(g,{serviceName:e,enabled:!0,metrics:{flowStarted:r.increment(t.flowStartedTotal),flowCompleted:r.increment(t.flowCompletedTotal),flowFailed:r.increment(t.flowFailedTotal),nodeExecuted:r.increment(t.nodeExecutedTotal)}})},Te=B();v(!1);const Ee=t.gen(function*(){return(yield*g).metrics}),De=e=>{let n=z();return t.gen(function*(){let t=Date.now(),i=yield*e,a=(Date.now()-t)/1e3;return yield*r.update(n.flowDurationHistogram,a),yield*r.update(n.flowLatencySummary,a),i}).pipe(t.withSpan(`flow-execution`))},Oe=(e,n,i)=>{let a=z();return t.gen(function*(){let e=Date.now(),t=yield*i,n=(Date.now()-e)/1e3;return yield*r.update(a.nodeDurationHistogram,n),yield*r.update(a.nodeLatencySummary,n),t}).pipe(t.withSpan(`node-${n}`,{attributes:{"node.id":e,"node.type":n}}))},ke=e=>{let n=z();return t.gen(function*(){return yield*r.increment(n.activeFlowsGauge),yield*t.acquireUseRelease(t.void,()=>e,()=>r.set(n.activeFlowsGauge,-1))})},Ae=e=>{let n=z();return t.gen(function*(){return yield*r.increment(n.activeNodesGauge),yield*t.acquireUseRelease(t.void,()=>e,()=>r.set(n.activeNodesGauge,-1))})},V=e=>{if(!e||typeof e!=`object`)return`unknown_flow_error`;let t=`code`in e?e.code:void 0;if(!t)return`unknown_flow_error`;switch(t){case`FLOW_VALIDATION_ERROR`:case`FLOW_INVALID_INPUT`:case`FLOW_INVALID_OUTPUT`:return`flow_validation_error`;case`FLOW_NODE_NOT_FOUND`:case`FLOW_EDGE_INVALID`:return`node_not_found_error`;case`FLOW_NODE_EXECUTION_FAILED`:case`FLOW_NODE_ERROR`:return`node_execution_error`;case`FLOW_TIMEOUT`:return`flow_timeout_error`;case`FLOW_CANCELLED`:case`ABORTED`:return`flow_cancelled_error`;default:return`unknown_flow_error`}},je=e=>{let n=z(),i=V(e);return t.gen(function*(){yield*r.increment(n.flowFailedTotal),yield*t.logError(`Flow execution failed`).pipe(t.annotateLogs({"error.category":i,"error.message":String(e)}))})},Me=(e,n,i)=>{let a=z(),o=V(i);return t.gen(function*(){yield*r.increment(a.nodeFailedTotal),yield*t.logError(`Node execution failed`).pipe(t.annotateLogs({"node.id":e,"node.type":n,"error.category":o,"error.message":String(i)}))})},H=()=>{let e={serviceName:`test-flow-engine`,enabled:!0,metrics:{flowStarted:t.void,flowCompleted:t.void,flowFailed:t.void,nodeExecuted:t.void}};return n.succeed(g,e)},Ne=e=>e.pipe(t.provide(H()));var U=class extends e.Tag(`MetricsService`)(){};const Pe=n.succeed(U,{recordUpload:(e,n)=>t.void}),W=O(`s3`),G=A(`s3`),Fe=f(`s3`,W,e=>{if(!e||typeof e!=`object`)return null;let t=`code`in e?e.code:void 0;if(!t)return null;switch(t){case`NoSuchKey`:case`NoSuchBucket`:case`NoSuchUpload`:return`client_error`;case`BucketAlreadyExists`:case`BucketNotEmpty`:return`client_error`;case`InvalidBucketName`:case`InvalidPart`:case`InvalidPartOrder`:return`client_error`;case`EntityTooSmall`:case`EntityTooLarge`:return`client_error`;case`ExpiredToken`:case`TokenRefreshRequired`:return`authentication_error`;case`RequestTimeTooSkewed`:case`SlowDown`:return`throttling_error`;default:return null}}),Ie=n.mergeAll(G),Le=(e,t)=>M(W,e,t),Re=(e,t)=>N(W,e,t),ze=P,Be=(e,t,n,r)=>R(W,e,t,n,r),Ve=(e,t)=>n=>j(e,`s3`,t)(n),He=S.bind(null,`s3`),Ue=x.bind(null,`s3`),We=C.bind(null,`s3`),Ge=b,{uploadRequestsTotal:Ke,uploadPartsTotal:qe,uploadSuccessTotal:Je,uploadErrorsTotal:Ye,apiCallsTotal:Xe,uploadDurationHistogram:Ze,partUploadDurationHistogram:Qe,fileSizeHistogram:$e,partSizeHistogram:et,activeUploadsGauge:tt,uploadThroughputGauge:nt,uploadLatencySummary:rt}=W,K=`azure`,q=O(K),it=A(K),at=f(K,q,e=>{if(!e||typeof e!=`object`)return null;let t=`code`in e?e.code:`statusCode`in e?e.statusCode:void 0;if(!t)return null;switch(t){case`BlobNotFound`:case`ContainerNotFound`:case`InvalidBlobOrBlock`:return`client_error`;case`ContainerAlreadyExists`:case`BlobAlreadyExists`:return`client_error`;case`InvalidBlockId`:case`InvalidBlockList`:case`InvalidBlobType`:return`client_error`;case`RequestBodyTooLarge`:case`InvalidHeaderValue`:return`client_error`;case`AuthenticationFailed`:case`InvalidAuthenticationInfo`:return`authentication_error`;case`AccountIsDisabled`:return`authorization_error`;case`InsufficientAccountPermissions`:return`authorization_error`;case`OperationTimedOut`:case`ServerBusy`:case`InternalError`:return`server_error`;default:if(typeof t==`number`){if(t>=500)return`server_error`;if(t===429)return`throttling_error`;if(t===403)return`authorization_error`;if(t===401)return`authentication_error`;if(t>=400)return`client_error`}return null}}),ot=n.mergeAll(it),st=(e,t)=>M(q,e,t),ct=(e,t)=>N(q,e,t),lt=P,ut=(e,t,n,r)=>R(q,e,t,n,r),dt=(e,t)=>n=>j(e,K,t)(n),ft=S.bind(null,K),pt=x.bind(null,K),mt=C.bind(null,K),ht=b,{uploadRequestsTotal:gt,uploadPartsTotal:_t,uploadSuccessTotal:vt,uploadErrorsTotal:yt,apiCallsTotal:bt,uploadDurationHistogram:xt,partUploadDurationHistogram:St,fileSizeHistogram:Ct,partSizeHistogram:wt,activeUploadsGauge:Tt,uploadThroughputGauge:Et,uploadLatencySummary:Dt}=q,J=O(`gcs`),Ot=A(`gcs`),kt=f(`gcs`,J,e=>{if(!e||typeof e!=`object`)return null;let t=`code`in e?e.code:`status`in e?e.status:void 0;if(!t)return null;switch(t){case`NoSuchBucket`:case`NoSuchKey`:case`NoSuchUpload`:return`client_error`;case`BucketAlreadyOwnedByYou`:case`BucketNotEmpty`:return`client_error`;case`InvalidBucketName`:case`InvalidArgument`:case`InvalidPart`:case`InvalidPartOrder`:return`client_error`;case`EntityTooSmall`:case`EntityTooLarge`:return`client_error`;case`MalformedPolicy`:return`client_error`;case`Unauthorized`:case`AuthenticationRequired`:return`authentication_error`;case`Forbidden`:case`AccessDenied`:return`authorization_error`;case`TooManyRequests`:case`RateLimitExceeded`:return`throttling_error`;case`InternalError`:case`ServiceUnavailable`:case`BackendError`:return`server_error`;default:if(typeof t==`number`){if(t>=500)return`server_error`;if(t===429)return`throttling_error`;if(t===403)return`authorization_error`;if(t===401)return`authentication_error`;if(t>=400)return`client_error`}return null}}),At=n.mergeAll(Ot),jt=(e,t)=>M(J,e,t),Mt=(e,t)=>N(J,e,t),Nt=P,Pt=(e,t,n,r)=>R(J,e,t,n,r),Ft=(e,t)=>n=>j(e,`gcs`,t)(n),It=S.bind(null,`gcs`),Lt=x.bind(null,`gcs`),Rt=C.bind(null,`gcs`),zt=b,{uploadRequestsTotal:Bt,uploadPartsTotal:Vt,uploadSuccessTotal:Ht,uploadErrorsTotal:Ut,apiCallsTotal:Wt,uploadDurationHistogram:Gt,partUploadDurationHistogram:Kt,fileSizeHistogram:qt,partSizeHistogram:Jt,activeUploadsGauge:Yt,uploadThroughputGauge:Xt,uploadLatencySummary:Zt}=J,Y=`filesystem`,X=O(Y),Qt=A(Y),$t=f(Y,X,e=>{if(!e||typeof e!=`object`)return null;let t=`code`in e?e.code:void 0;if(!t)return null;switch(t){case`ENOENT`:case`ENOTDIR`:return`client_error`;case`EEXIST`:return`client_error`;case`EISDIR`:return`client_error`;case`EINVAL`:case`ENAMETOOLONG`:return`client_error`;case`EACCES`:case`EPERM`:return`authorization_error`;case`ENOSPC`:case`EDQUOT`:return`server_error`;case`EIO`:case`EROFS`:case`EMFILE`:case`ENFILE`:return`server_error`;case`EBUSY`:return`throttling_error`;default:return null}}),en=n.mergeAll(Qt),tn=(e,t)=>M(X,e,t),nn=(e,t)=>N(X,e,t),rn=P,an=(e,t,n,r)=>R(X,e,t,n,r),on=(e,t)=>n=>j(e,Y,t)(n),sn=S.bind(null,Y),cn=x.bind(null,Y),ln=C.bind(null,Y),un=b,{uploadRequestsTotal:dn,uploadPartsTotal:fn,uploadSuccessTotal:pn,uploadErrorsTotal:mn,apiCallsTotal:hn,uploadDurationHistogram:gn,partUploadDurationHistogram:_n,fileSizeHistogram:vn,partSizeHistogram:yn,activeUploadsGauge:bn,uploadThroughputGauge:xn,uploadLatencySummary:Sn}=X,Z=()=>({uploadCreatedTotal:r.counter(`upload_created_total`,{description:`Total number of uploads created`}),uploadCompletedTotal:r.counter(`upload_completed_total`,{description:`Total number of uploads completed successfully`}),uploadFailedTotal:r.counter(`upload_failed_total`,{description:`Total number of uploads that failed`}),chunkUploadedTotal:r.counter(`chunk_uploaded_total`,{description:`Total number of chunks uploaded`}),uploadFromUrlTotal:r.counter(`upload_from_url_total`,{description:`Total number of URL-based uploads`}),uploadFromUrlSuccessTotal:r.counter(`upload_from_url_success_total`,{description:`Total number of successful URL-based uploads`}),uploadFromUrlFailedTotal:r.counter(`upload_from_url_failed_total`,{description:`Total number of failed URL-based uploads`}),uploadDurationHistogram:r.histogram(`upload_duration_seconds`,i.exponential({start:.01,factor:2,count:20}),`Duration of complete upload operations in seconds`),chunkUploadDurationHistogram:r.histogram(`chunk_upload_duration_seconds`,i.exponential({start:.001,factor:2,count:15}),`Duration of individual chunk uploads in seconds`),uploadFileSizeHistogram:r.histogram(`upload_file_size_bytes`,i.exponential({start:1024,factor:2,count:25}),`Size of uploaded files in bytes`),chunkSizeHistogram:r.histogram(`chunk_size_bytes`,i.linear({start:262144,width:262144,count:20}),`Size of uploaded chunks in bytes`),activeUploadsGauge:r.gauge(`active_uploads`,{description:`Number of currently active uploads`}),uploadThroughputGauge:r.gauge(`upload_throughput_bytes_per_second`,{description:`Current upload throughput in bytes per second`}),uploadLatencySummary:r.summary({name:`upload_latency_seconds`,maxAge:`10 minutes`,maxSize:1e3,error:.01,quantiles:[.5,.9,.95,.99],description:`Upload operation latency percentiles`}),chunkLatencySummary:r.summary({name:`chunk_latency_seconds`,maxAge:`10 minutes`,maxSize:1e3,error:.01,quantiles:[.5,.9,.95,.99],description:`Chunk upload latency percentiles`})}),Cn=Z(),wn=(e,n)=>r=>r.pipe(t.withSpan(`upload-${e}`,{attributes:{"upload.operation":e,...n}})),Tn=e=>t.annotateCurrentSpan({"upload.id":e.uploadId??`unknown`,"upload.file_name":e.fileName??`unknown`,"upload.file_size":e.fileSize?.toString()??`0`,"upload.storage_id":e.storageId??`unknown`,"upload.mime_type":e.mimeType??`unknown`}),En=e=>t.annotateCurrentSpan({"chunk.upload_id":e.uploadId,"chunk.size":e.chunkSize.toString(),"chunk.offset":e.offset.toString(),"chunk.total_size":e.totalSize?.toString()??`0`,"chunk.progress":e.totalSize&&e.totalSize>0?(e.offset/e.totalSize*100).toFixed(2):`0`}),Q=(e=`uploadista-upload-server`)=>{let i=Z();return n.succeed(h,{serviceName:e,enabled:!0,metrics:{uploadCreated:t.succeed(i.uploadCreatedTotal).pipe(t.flatMap(e=>r.increment(e))),uploadCompleted:t.succeed(i.uploadCompletedTotal).pipe(t.flatMap(e=>r.increment(e))),uploadFailed:t.succeed(i.uploadFailedTotal).pipe(t.flatMap(e=>r.increment(e))),chunkUploaded:t.succeed(i.chunkUploadedTotal).pipe(t.flatMap(e=>r.increment(e)))}})},Dn=Q();_(!1);const On=t.gen(function*(){return(yield*h).metrics}),kn=e=>{let n=Z();return t.gen(function*(){let t=Date.now(),i=yield*e,a=(Date.now()-t)/1e3;return yield*r.update(n.uploadDurationHistogram,a),i}).pipe(t.withSpan(`upload-operation`))},An=e=>{let n=Z();return t.gen(function*(){let t=Date.now(),i=yield*e,a=(Date.now()-t)/1e3;return yield*r.update(n.chunkUploadDurationHistogram,a),i}).pipe(t.withSpan(`chunk-upload`))},$=e=>{if(!e||typeof e!=`object`)return`unknown_error`;let t=`code`in e?e.code:void 0,n=`name`in e?e.name:void 0,r=e instanceof Error?e.message.toLowerCase():``;return t===`ABORTED`||n===`AbortError`||r.includes(`abort`)?`abort_error`:t===`FILE_TOO_LARGE`||t===`LIMIT_FILE_SIZE`||t===`RequestEntityTooLarge`||r.includes(`too large`)||r.includes(`size limit`)||r.includes(`max size`)?`size_limit_error`:t===`INVALID_FILE`||t===`INVALID_METADATA`||t===`VALIDATION_ERROR`||r.includes(`validation`)||r.includes(`invalid`)?`validation_error`:t===`NetworkError`||t===`ECONNRESET`||t===`ENOTFOUND`||t===`ETIMEDOUT`||r.includes(`network`)||r.includes(`timeout`)?`network_error`:t===`UNAUTHORIZED`||t===`AuthenticationFailed`||n===`AuthenticationError`||r.includes(`authentication`)||r.includes(`unauthorized`)?`authentication_error`:t===`FORBIDDEN`||t===`AccessDenied`||n===`AuthorizationError`||r.includes(`forbidden`)||r.includes(`permission`)?`authorization_error`:t===`FILE_WRITE_ERROR`||t===`STORAGE_ERROR`||r.includes(`storage`)||r.includes(`write error`)?`storage_error`:`unknown_error`},jn=(e,n,i,a={})=>t.gen(function*(){let o=$(i);yield*e.uploadFailedTotal.pipe(r.tagged(`operation`,n),r.tagged(`error_category`,o))(t.succeed(1));let s={operation:n,error_category:o,error_type:typeof i,error_message:i instanceof Error?i.message:String(i),error_code:i&&typeof i==`object`&&`code`in i?String(i.code):void 0,error_name:i&&typeof i==`object`&&`name`in i?String(i.name):void 0,...a};yield*t.logError(`Upload ${n} failed`).pipe(t.annotateLogs(s))}),Mn=e=>t=>{if(e){let n=e(t);if(n!==null)return n}return $(t)},Nn=n.succeed(h,{serviceName:`uploadista-upload-server-test`,enabled:!0,metrics:{uploadCreated:()=>Promise.resolve(),uploadCompleted:()=>Promise.resolve(),uploadFailed:()=>Promise.resolve(),chunkUploaded:()=>Promise.resolve()}}),Pn=()=>Z(),Fn=()=>{let e=Pn(),t=[`uploadCreatedTotal`,`uploadCompletedTotal`,`uploadFailedTotal`,`chunkUploadedTotal`,`uploadFromUrlTotal`,`uploadFromUrlSuccessTotal`,`uploadFromUrlFailedTotal`,`uploadDurationHistogram`,`chunkUploadDurationHistogram`,`uploadFileSizeHistogram`,`chunkSizeHistogram`,`activeUploadsGauge`,`uploadThroughputGauge`,`uploadLatencySummary`,`chunkLatencySummary`].filter(t=>!(t in e));if(t.length>0)throw Error(`Missing required metrics: ${t.join(`, `)}`);return!0};export{ot as AzureObservabilityLayer,it as AzureTracingLayer,en as FilesystemObservabilityLayer,Qt as FilesystemTracingLayer,g as FlowObservability,oe as FlowObservabilityDisabled,Te as FlowObservabilityLive,At as GCSObservabilityLayer,Ot as GCSTracingLayer,U as MetricsService,Pe as NoOpMetricsServiceLive,_e as NodeSdkLive,p as Observability,re as ObservabilityDisabled,Ie as S3ObservabilityLayer,G as S3TracingLayer,m as StorageObservability,ie as StorageObservabilityDisabled,me as TracingService,h as UploadObservability,ae as UploadObservabilityDisabled,Dn as UploadObservabilityLive,Nn as UploadObservabilityTest,ge as WebSdkLive,ve as WorkersSdkLive,Tt as azureActiveUploadsGauge,bt as azureApiCallsTotal,Ct as azureFileSizeHistogram,q as azureMetrics,wt as azurePartSizeHistogram,St as azurePartUploadDurationHistogram,xt as azureUploadDurationHistogram,yt as azureUploadErrorsTotal,Dt as azureUploadLatencySummary,_t as azureUploadPartsTotal,gt as azureUploadRequestsTotal,vt as azureUploadSuccessTotal,Et as azureUploadThroughputGauge,ue as captureMetrics,V as classifyFlowError,u as classifyStorageError,$ as classifyUploadError,z as createFlowMetrics,d as createStorageErrorClassifier,f as createStorageErrorTracker,O as createStorageMetrics,A as createStorageTracingLayer,fe as createTestFixture,he as createTracingLayer,Mn as createUploadErrorClassifier,E as createUploadGauges,T as createUploadHistograms,w as createUploadMetrics,Z as createUploadServerMetrics,D as createUploadSummaries,bn as filesystemActiveUploadsGauge,hn as filesystemApiCallsTotal,vn as filesystemFileSizeHistogram,X as filesystemMetrics,yn as filesystemPartSizeHistogram,_n as filesystemPartUploadDurationHistogram,gn as filesystemUploadDurationHistogram,mn as filesystemUploadErrorsTotal,Sn as filesystemUploadLatencySummary,fn as filesystemUploadPartsTotal,dn as filesystemUploadRequestsTotal,pn as filesystemUploadSuccessTotal,xn as filesystemUploadThroughputGauge,be as flowMetrics,Yt as gcsActiveUploadsGauge,Wt as gcsApiCallsTotal,qt as gcsFileSizeHistogram,J as gcsMetrics,Jt as gcsPartSizeHistogram,Kt as gcsPartUploadDurationHistogram,Gt as gcsUploadDurationHistogram,Ut as gcsUploadErrorsTotal,Zt as gcsUploadLatencySummary,Vt as gcsUploadPartsTotal,Bt as gcsUploadRequestsTotal,Ht as gcsUploadSuccessTotal,Xt as gcsUploadThroughputGauge,Ee as getFlowMetrics,Pn as getTestMetrics,On as getUploadMetrics,y as isObservabilityEnabled,ht as logAzureContext,ft as logAzureOperation,mt as logAzureUploadCompletion,pt as logAzureUploadProgress,un as logFilesystemContext,sn as logFilesystemOperation,ln as logFilesystemUploadCompletion,cn as logFilesystemUploadProgress,zt as logGCSContext,It as logGCSOperation,Rt as logGCSUploadCompletion,Lt as logGCSUploadProgress,Ge as logS3Context,He as logS3Operation,We as logS3UploadCompletion,Ue as logS3UploadProgress,S as logStorageOperation,C as logUploadCompletion,x as logUploadProgress,b as logWithContext,v as makeFlowObservabilityLayer,B as makeFlowObservabilityLive,te as makeObservabilityLayer,ne as makeStorageObservabilityLayer,le as makeTestFlowObservability,H as makeTestFlowObservabilityUtil,k as makeTestStorageObservability,ce as makeTestUploadObservability,_ as makeUploadObservabilityLayer,Q as makeUploadObservabilityLive,Ne as runWithTestFlowObservability,pe as runWithTestObservability,tt as s3ActiveUploadsGauge,Xe as s3ApiCallsTotal,$e as s3FileSizeHistogram,W as s3Metrics,et as s3PartSizeHistogram,Qe as s3PartUploadDurationHistogram,Ze as s3UploadDurationHistogram,Ye as s3UploadErrorsTotal,rt as s3UploadLatencySummary,qe as s3UploadPartsTotal,Ke as s3UploadRequestsTotal,Je as s3UploadSuccessTotal,nt as s3UploadThroughputGauge,ke as trackActiveFlow,Ae as trackActiveNode,at as trackAzureError,F as trackFileSize,$t as trackFilesystemError,je as trackFlowError,kt as trackGCSError,Me as trackNodeError,ye as trackPartSize,Fe as trackS3Error,ee as trackStorageError,jn as trackUploadError,Cn as uploadServerMetrics,Fn as validateMetricsExist,se as whenObservabilityEnabled,I as withActiveUploadTracking,N as withApiMetrics,ct as withAzureApiMetrics,ut as withAzureOperationMetrics,dt as withAzureSpan,lt as withAzureTimingMetrics,st as withAzureUploadMetrics,En as withChunkContext,An as withChunkDuration,we as withExecutionContext,nn as withFilesystemApiMetrics,an as withFilesystemOperationMetrics,on as withFilesystemSpan,rn as withFilesystemTimingMetrics,tn as withFilesystemUploadMetrics,Se as withFlowContext,De as withFlowDuration,xe as withFlowSpan,Mt as withGCSApiMetrics,Pt as withGCSOperationMetrics,Ft as withGCSSpan,Nt as withGCSTimingMetrics,jt as withGCSUploadMetrics,de as withMetricTracking,Ce as withNodeContext,Oe as withNodeDuration,Re as withS3ApiMetrics,Be as withS3OperationMetrics,Ve as withS3Span,ze as withS3TimingMetrics,Le as withS3UploadMetrics,R as withStorageOperationMetrics,j as withStorageSpan,L as withThroughputTracking,P as withTimingMetrics,Tn as withUploadContext,kn as withUploadDuration,M as withUploadMetrics,wn as withUploadSpan};
|
|
2
|
-
//# sourceMappingURL=index.
|
|
2
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","names":["service: StorageObservabilityService","service: UploadObservabilityService","service: FlowObservabilityService","FlowObservabilityDisabled","makeTestFlowObservability","service: FlowObservabilityService","NoOpMetricsServiceLive: Layer.Layer<MetricsService>","STORAGE_TYPE","STORAGE_TYPE","STORAGE_TYPE","UploadObservabilityDisabled"],"sources":["../src/core/errors.ts","../src/core/layers.ts","../src/core/logging.ts","../src/core/metrics.ts","../src/core/testing.ts","../src/core/tracing.ts","../src/core/utilities.ts","../src/flow/metrics.ts","../src/flow/tracing.ts","../src/flow/layers.ts","../src/flow/errors.ts","../src/flow/testing.ts","../src/service/metrics.ts","../src/storage/s3.ts","../src/storage/azure.ts","../src/storage/gcs.ts","../src/storage/filesystem.ts","../src/upload/metrics.ts","../src/upload/tracing.ts","../src/upload/layers.ts","../src/upload/errors.ts","../src/upload/testing.ts"],"sourcesContent":["import { Effect, Metric } from \"effect\";\nimport type { StorageMetrics } from \"./metrics.js\";\n\n// ============================================================================\n// Generic Storage Error Classification and Tracking\n// ============================================================================\n\nexport type StorageErrorCategory =\n | \"network_error\"\n | \"authentication_error\"\n | \"authorization_error\"\n | \"throttling_error\"\n | \"server_error\"\n | \"client_error\"\n | \"unknown_error\";\n\n// Generic error classifier - can be extended per storage type\nexport const classifyStorageError = (error: unknown): StorageErrorCategory => {\n if (!error || typeof error !== \"object\") return \"unknown_error\";\n\n const errorCode = \"code\" in error ? error.code : undefined;\n const errorName = \"name\" in error ? error.name : undefined;\n const errorMessage =\n error instanceof Error ? error.message.toLowerCase() : \"\";\n\n // Network errors (common across all storage types)\n if (\n errorCode === \"NetworkError\" ||\n errorCode === \"ECONNRESET\" ||\n errorCode === \"ENOTFOUND\" ||\n errorCode === \"ETIMEDOUT\" ||\n errorMessage.indexOf(\"network\") >= 0 ||\n errorMessage.indexOf(\"timeout\") >= 0\n ) {\n return \"network_error\";\n }\n\n // Authentication errors (common patterns)\n if (\n errorCode === \"InvalidAccessKeyId\" ||\n errorCode === \"SignatureDoesNotMatch\" ||\n errorCode === \"TokenRefreshRequired\" ||\n errorCode === \"AuthenticationFailed\" ||\n errorName === \"AuthenticationError\" ||\n errorMessage.indexOf(\"authentication\") >= 0 ||\n errorMessage.indexOf(\"unauthorized\") >= 0\n ) {\n return \"authentication_error\";\n }\n\n // Authorization errors\n if (\n errorCode === \"AccessDenied\" ||\n errorCode === \"AccountProblem\" ||\n errorCode === \"Forbidden\" ||\n errorName === \"AuthorizationError\" ||\n errorMessage.indexOf(\"forbidden\") >= 0 ||\n errorMessage.indexOf(\"permission\") >= 0\n ) {\n return \"authorization_error\";\n }\n\n // Throttling errors\n if (\n errorCode === \"SlowDown\" ||\n errorCode === \"RequestTimeTooSkewed\" ||\n errorCode === \"TooManyRequests\" ||\n errorName === \"ThrottlingError\" ||\n errorMessage.indexOf(\"throttl\") >= 0 ||\n errorMessage.indexOf(\"rate limit\") >= 0\n ) {\n return \"throttling_error\";\n }\n\n // Server errors\n if (\n errorCode === \"InternalError\" ||\n errorCode === \"ServiceUnavailable\" ||\n errorCode === \"InternalServerError\" ||\n errorName === \"ServerError\" ||\n errorMessage.indexOf(\"server error\") >= 0 ||\n errorMessage.indexOf(\"service unavailable\") >= 0\n ) {\n return \"server_error\";\n }\n\n // Client errors\n if (\n errorCode === \"InvalidRequest\" ||\n errorCode === \"MalformedXML\" ||\n errorCode === \"RequestEntityTooLarge\" ||\n errorCode === \"BadRequest\" ||\n errorName === \"ClientError\" ||\n errorMessage.indexOf(\"bad request\") >= 0 ||\n errorMessage.indexOf(\"invalid\") >= 0\n ) {\n return \"client_error\";\n }\n\n return \"unknown_error\";\n};\n\n// Storage-specific error classifier factory\nexport const createStorageErrorClassifier = (\n storageType: string,\n customErrorMapping?: (error: unknown) => StorageErrorCategory | null,\n) => {\n return (error: unknown): StorageErrorCategory => {\n // Try custom mapping first\n if (customErrorMapping) {\n const customResult = customErrorMapping(error);\n if (customResult !== null) return customResult;\n }\n\n // Fall back to generic classification\n return classifyStorageError(error);\n };\n};\n\n// Generic error tracking function\nexport const trackStorageError = (\n storageType: string,\n metrics: StorageMetrics,\n operation: string,\n error: unknown,\n context: Record<string, unknown> = {},\n errorClassifier = classifyStorageError,\n) =>\n Effect.gen(function* () {\n const errorCategory = errorClassifier(error);\n\n // Record error metrics\n const errorMetric = metrics.uploadErrorsTotal.pipe(\n Metric.tagged(\"operation\", operation),\n Metric.tagged(\"error_category\", errorCategory),\n );\n yield* errorMetric(Effect.succeed(1));\n\n // Create detailed error context\n const errorDetails = {\n storage_type: storageType,\n operation,\n error_category: errorCategory,\n error_type: typeof error,\n error_message: error instanceof Error ? error.message : String(error),\n error_code:\n error && typeof error === \"object\" && \"code\" in error\n ? error.code\n : undefined,\n error_name:\n error && typeof error === \"object\" && \"name\" in error\n ? error.name\n : undefined,\n ...context,\n };\n\n // Log structured error\n yield* Effect.logError(\n `${storageType.toUpperCase()} ${operation} failed`,\n ).pipe(Effect.annotateLogs(errorDetails));\n });\n\n// Factory for storage-specific error tracking\nexport const createStorageErrorTracker = (\n storageType: string,\n metrics: StorageMetrics,\n customErrorClassifier?: (error: unknown) => StorageErrorCategory | null,\n) => {\n const errorClassifier = createStorageErrorClassifier(\n storageType,\n customErrorClassifier,\n );\n\n return (\n operation: string,\n error: unknown,\n context: Record<string, unknown> = {},\n ) =>\n trackStorageError(\n storageType,\n metrics,\n operation,\n error,\n context,\n errorClassifier,\n );\n};\n","import { Context, Effect, Layer, Option } from \"effect\";\nimport type { StorageMetrics } from \"./metrics.js\";\n\n// ============================================================================\n// Observability Layer Interfaces\n// ============================================================================\n\n/**\n * Core observability service providing tracing, metrics, and logging capabilities\n */\nexport interface ObservabilityService {\n readonly serviceName: string;\n readonly enabled: boolean;\n}\n\n/**\n * Observability service tag for Effect Context\n */\nexport class Observability extends Context.Tag(\"Observability\")<\n Observability,\n ObservabilityService\n>() {}\n\n/**\n * Storage observability service extending base observability with storage-specific metrics\n */\nexport interface StorageObservabilityService extends ObservabilityService {\n readonly storageType: string;\n readonly metrics: StorageMetrics;\n}\n\n/**\n * Storage observability service tag\n */\nexport class StorageObservability extends Context.Tag(\"StorageObservability\")<\n StorageObservability,\n StorageObservabilityService\n>() {}\n\n/**\n * Upload observability service for upload-specific operations\n */\nexport interface UploadObservabilityService extends ObservabilityService {\n readonly metrics: {\n uploadCreated: Effect.Effect<void>;\n uploadCompleted: Effect.Effect<void>;\n uploadFailed: Effect.Effect<void>;\n chunkUploaded: Effect.Effect<void>;\n };\n}\n\n/**\n * Upload observability service tag\n */\nexport class UploadObservability extends Context.Tag(\"UploadObservability\")<\n UploadObservability,\n UploadObservabilityService\n>() {}\n\n/**\n * Flow observability service for flow execution operations\n */\nexport interface FlowObservabilityService extends ObservabilityService {\n readonly metrics: {\n flowStarted: Effect.Effect<void>;\n flowCompleted: Effect.Effect<void>;\n flowFailed: Effect.Effect<void>;\n nodeExecuted: Effect.Effect<void>;\n };\n}\n\n/**\n * Flow observability service tag\n */\nexport class FlowObservability extends Context.Tag(\"FlowObservability\")<\n FlowObservability,\n FlowObservabilityService\n>() {}\n\n// ============================================================================\n// Layer Factories\n// ============================================================================\n\n/**\n * Create a base observability layer\n */\nexport const makeObservabilityLayer = (\n serviceName: string,\n enabled = true,\n): Layer.Layer<Observability> =>\n Layer.succeed(Observability, {\n serviceName,\n enabled,\n });\n\n/**\n * Create a storage observability layer\n */\nexport const makeStorageObservabilityLayer = (\n storageType: string,\n metrics: StorageMetrics,\n enabled = true,\n): Layer.Layer<StorageObservability> =>\n Layer.succeed(StorageObservability, {\n serviceName: `uploadista-${storageType}-store`,\n storageType,\n metrics,\n enabled,\n });\n\n/**\n * Create an upload observability layer\n */\nexport const makeUploadObservabilityLayer = (\n enabled = true,\n): Layer.Layer<UploadObservability> =>\n Layer.succeed(UploadObservability, {\n serviceName: \"uploadista-upload-server\",\n enabled,\n metrics: {\n uploadCreated: Effect.void,\n uploadCompleted: Effect.void,\n uploadFailed: Effect.void,\n chunkUploaded: Effect.void,\n },\n });\n\n/**\n * Create a flow observability layer\n */\nexport const makeFlowObservabilityLayer = (\n enabled = true,\n): Layer.Layer<FlowObservability> =>\n Layer.succeed(FlowObservability, {\n serviceName: \"uploadista-flow-engine\",\n enabled,\n metrics: {\n flowStarted: Effect.void,\n flowCompleted: Effect.void,\n flowFailed: Effect.void,\n nodeExecuted: Effect.void,\n },\n });\n\n// ============================================================================\n// No-op Layers (for testing and opt-out)\n// ============================================================================\n\n/**\n * No-op observability layer (disabled)\n */\nexport const ObservabilityDisabled = makeObservabilityLayer(\n \"uploadista-disabled\",\n false,\n);\n\n/**\n * No-op storage observability layer\n */\nexport const StorageObservabilityDisabled = (storageType: string) =>\n makeStorageObservabilityLayer(\n storageType,\n {} as StorageMetrics, // No-op metrics\n false,\n );\n\n/**\n * No-op upload observability layer\n */\nexport const UploadObservabilityDisabled = makeUploadObservabilityLayer(false);\n\n/**\n * No-op flow observability layer\n */\nexport const FlowObservabilityDisabled = makeFlowObservabilityLayer(false);\n\n// ============================================================================\n// Helper Functions\n// ============================================================================\n\n/**\n * Check if observability is enabled in the current context\n */\nexport const isObservabilityEnabled = Effect.gen(function* () {\n const observability = yield* Effect.serviceOption(Observability);\n return Option.match(observability, {\n onNone: () => false,\n onSome: (obs) => obs.enabled,\n });\n});\n\n/**\n * Execute an effect only if observability is enabled\n */\nexport const whenObservabilityEnabled = <A, E, R>(\n effect: Effect.Effect<A, E, R>,\n): Effect.Effect<Option.Option<A>, E, R | Observability> =>\n Effect.gen(function* () {\n const enabled = yield* isObservabilityEnabled;\n if (enabled) {\n const result = yield* effect;\n return Option.some(result);\n }\n return Option.none();\n });\n","import { Effect } from \"effect\";\n\n// ============================================================================\n// Enhanced Logging Helpers (Storage-agnostic)\n// ============================================================================\n\nexport const logWithContext = (\n message: string,\n context: Record<string, unknown>,\n) => Effect.log(message).pipe(Effect.annotateLogs(context));\n\nexport const logUploadProgress = (\n storageType: string,\n uploadId: string,\n progress: {\n uploadedBytes: number;\n totalBytes: number;\n partNumber?: number;\n speed?: number;\n },\n) =>\n logWithContext(\"Upload progress\", {\n storage_type: storageType,\n upload_id: uploadId,\n uploaded_bytes: progress.uploadedBytes,\n total_bytes: progress.totalBytes,\n progress_percentage: Math.round(\n (progress.uploadedBytes / progress.totalBytes) * 100,\n ),\n ...(progress.partNumber && { part_number: progress.partNumber }),\n ...(progress.speed && { upload_speed_bps: progress.speed }),\n });\n\nexport const logStorageOperation = (\n storageType: string,\n operation: string,\n uploadId: string,\n metadata?: Record<string, unknown>,\n) =>\n logWithContext(`${storageType.toUpperCase()} ${operation}`, {\n storage_type: storageType,\n operation,\n upload_id: uploadId,\n ...metadata,\n });\n\nexport const logUploadCompletion = (\n storageType: string,\n uploadId: string,\n metrics: {\n fileSize: number;\n totalDurationMs: number;\n partsCount?: number;\n averagePartSize?: number;\n throughputBps?: number;\n retryCount?: number;\n },\n) => {\n const throughputMBps = metrics.throughputBps\n ? metrics.throughputBps / (1024 * 1024)\n : 0;\n\n return logWithContext(`${storageType.toUpperCase()} upload completed`, {\n storage_type: storageType,\n upload_id: uploadId,\n file_size_bytes: metrics.fileSize,\n file_size_mb: Math.round((metrics.fileSize / (1024 * 1024)) * 100) / 100,\n total_duration_ms: metrics.totalDurationMs,\n total_duration_seconds:\n Math.round((metrics.totalDurationMs / 1000) * 100) / 100,\n throughput_bps: metrics.throughputBps,\n throughput_mbps: Math.round(throughputMBps * 100) / 100,\n ...(metrics.partsCount && { parts_count: metrics.partsCount }),\n ...(metrics.averagePartSize && {\n average_part_size_bytes: metrics.averagePartSize,\n average_part_size_mb:\n Math.round((metrics.averagePartSize / (1024 * 1024)) * 100) / 100,\n }),\n ...(metrics.retryCount && { retry_count: metrics.retryCount }),\n });\n};\n","import { Metric, MetricBoundaries } from \"effect\";\n\n// ============================================================================\n// Core Storage Metrics (reusable across all storage types)\n// ============================================================================\n\n// Counter metrics\nexport const createUploadMetrics = (storageType: string) => ({\n uploadRequestsTotal: Metric.counter(`${storageType}_upload_requests_total`, {\n description: `Total number of upload requests for ${storageType}`,\n }),\n\n uploadPartsTotal: Metric.counter(`${storageType}_upload_parts_total`, {\n description: `Total number of individual parts uploaded for ${storageType}`,\n }),\n\n uploadSuccessTotal: Metric.counter(`${storageType}_upload_success_total`, {\n description: `Total number of successful uploads for ${storageType}`,\n }),\n\n uploadErrorsTotal: Metric.counter(`${storageType}_upload_errors_total`, {\n description: `Total number of upload errors for ${storageType}`,\n }),\n\n apiCallsTotal: Metric.counter(`${storageType}_api_calls_total`, {\n description: `Total number of API calls for ${storageType}`,\n }),\n});\n\n// Histogram metrics for timing and sizes (reusable)\nexport const createUploadHistograms = (storageType: string) => ({\n uploadDurationHistogram: Metric.histogram(\n `${storageType}_upload_duration_seconds`,\n MetricBoundaries.exponential({\n start: 0.01, // 10ms\n factor: 2,\n count: 20, // Up to ~10 seconds\n }),\n `Duration of upload operations in seconds for ${storageType}`,\n ),\n\n partUploadDurationHistogram: Metric.histogram(\n `${storageType}_part_upload_duration_seconds`,\n MetricBoundaries.exponential({\n start: 0.001, // 1ms\n factor: 2,\n count: 15, // Up to ~32 seconds\n }),\n `Duration of individual part uploads in seconds for ${storageType}`,\n ),\n\n fileSizeHistogram: Metric.histogram(\n `${storageType}_file_size_bytes`,\n MetricBoundaries.exponential({\n start: 1024, // 1KB\n factor: 2,\n count: 25, // Up to ~33GB\n }),\n `Size of uploaded files in bytes for ${storageType}`,\n ),\n\n partSizeHistogram: Metric.histogram(\n `${storageType}_part_size_bytes`,\n MetricBoundaries.linear({\n start: 5_242_880, // 5MB (minimum part size)\n width: 1_048_576, // 1MB increments\n count: 20, // Up to ~25MB\n }),\n `Size of upload parts in bytes for ${storageType}`,\n ),\n});\n\n// Gauge metrics for current state (reusable)\nexport const createUploadGauges = (storageType: string) => ({\n activeUploadsGauge: Metric.gauge(`${storageType}_active_uploads`, {\n description: `Number of currently active uploads for ${storageType}`,\n }),\n\n uploadThroughputGauge: Metric.gauge(\n `${storageType}_upload_throughput_bytes_per_second`,\n {\n description: `Current upload throughput in bytes per second for ${storageType}`,\n },\n ),\n});\n\n// Summary metrics for percentiles (reusable)\nexport const createUploadSummaries = (storageType: string) => ({\n uploadLatencySummary: Metric.summary({\n name: `${storageType}_upload_latency_seconds`,\n maxAge: \"10 minutes\",\n maxSize: 1000,\n error: 0.01,\n quantiles: [0.5, 0.9, 0.95, 0.99],\n description: `Upload latency percentiles for ${storageType}`,\n }),\n});\n\n// Combined metrics factory\nexport const createStorageMetrics = (storageType: string) => ({\n ...createUploadMetrics(storageType),\n ...createUploadHistograms(storageType),\n ...createUploadGauges(storageType),\n ...createUploadSummaries(storageType),\n});\n\n// Type for storage metrics\nexport type StorageMetrics = ReturnType<typeof createStorageMetrics>;\n","import { Effect, Layer, Metric } from \"effect\";\nimport type {\n FlowObservabilityService,\n StorageObservabilityService,\n UploadObservabilityService,\n} from \"./layers.js\";\nimport {\n FlowObservability,\n StorageObservability,\n UploadObservability,\n} from \"./layers.js\";\nimport { createStorageMetrics } from \"./metrics.js\";\n\n// ============================================================================\n// Test Observability Layers\n// ============================================================================\n\n/**\n * Mock storage observability for testing\n */\nexport const makeTestStorageObservability = (\n storageType: string,\n): Layer.Layer<StorageObservability> => {\n const metrics = createStorageMetrics(storageType);\n const service: StorageObservabilityService = {\n serviceName: `test-${storageType}-store`,\n storageType,\n metrics,\n enabled: true,\n };\n return Layer.succeed(StorageObservability, service);\n};\n\n/**\n * Mock upload observability for testing\n */\nexport const makeTestUploadObservability =\n (): Layer.Layer<UploadObservability> => {\n const service: UploadObservabilityService = {\n serviceName: \"test-upload-server\",\n enabled: true,\n metrics: {\n uploadCreated: Effect.void,\n uploadCompleted: Effect.void,\n uploadFailed: Effect.void,\n chunkUploaded: Effect.void,\n },\n };\n return Layer.succeed(UploadObservability, service);\n };\n\n/**\n * Mock flow observability for testing\n */\nexport const makeTestFlowObservability = (): Layer.Layer<FlowObservability> => {\n const service: FlowObservabilityService = {\n serviceName: \"test-flow-engine\",\n enabled: true,\n metrics: {\n flowStarted: Effect.void,\n flowCompleted: Effect.void,\n flowFailed: Effect.void,\n nodeExecuted: Effect.void,\n },\n };\n return Layer.succeed(FlowObservability, service);\n};\n\n// ============================================================================\n// Test Utilities\n// ============================================================================\n\n/**\n * Capture metrics snapshot from an effect for testing\n * Note: Metric snapshots are simplified - for full metric testing,\n * use Effect's built-in metric testing utilities\n */\nexport const captureMetrics = <A, E, R>(\n effect: Effect.Effect<A, E, R>,\n): Effect.Effect<A, E, R> =>\n Effect.gen(function* () {\n const result = yield* effect;\n // Metrics are automatically captured by Effect runtime\n yield* Metric.snapshot;\n return result;\n });\n\n/**\n * Test helper to capture metrics around effect execution\n * This is a simplified version - for production testing,\n * use Effect's metric testing utilities\n */\nexport const withMetricTracking = <A, E, R>(\n effect: Effect.Effect<A, E, R>,\n): Effect.Effect<A, E, R> =>\n Effect.gen(function* () {\n // Track metric before execution\n yield* Metric.snapshot;\n const result = yield* effect;\n // Track metric after execution\n yield* Metric.snapshot;\n return result;\n });\n\n/**\n * Test fixture for observability testing\n */\nexport interface ObservabilityTestFixture {\n readonly storageObservability: Layer.Layer<StorageObservability>;\n readonly uploadObservability: Layer.Layer<UploadObservability>;\n readonly flowObservability: Layer.Layer<FlowObservability>;\n}\n\n/**\n * Create a complete test fixture with all observability layers\n */\nexport const createTestFixture = (\n storageType = \"test-storage\",\n): ObservabilityTestFixture => ({\n storageObservability: makeTestStorageObservability(storageType),\n uploadObservability: makeTestUploadObservability(),\n flowObservability: makeTestFlowObservability(),\n});\n\n/**\n * Run an effect with test observability layers\n */\nexport const runWithTestObservability = <A, E>(\n effect: Effect.Effect<\n A,\n E,\n StorageObservability | UploadObservability | FlowObservability\n >,\n storageType = \"test-storage\",\n): Effect.Effect<A, E> => {\n const fixture = createTestFixture(storageType);\n return effect.pipe(\n Effect.provide(fixture.storageObservability),\n Effect.provide(fixture.uploadObservability),\n Effect.provide(fixture.flowObservability),\n );\n};\n","import { NodeSdk, WebSdk } from \"@effect/opentelemetry\";\nimport {\n BatchSpanProcessor,\n ConsoleSpanExporter,\n} from \"@opentelemetry/sdk-trace-base\";\nimport { Context, Effect, Layer } from \"effect\";\n\n// ============================================================================\n// Universal Tracing (Environment-agnostic)\n// ============================================================================\n\n// Generic service tag for tracing context\nexport const TracingService = Context.GenericTag<{ serviceName: string }>(\n \"TracingService\",\n);\n\n// Create a tracing layer using Effect's native tracing (works in all environments)\nexport const createTracingLayer = (options?: { serviceName?: string }) => {\n const serviceName = options?.serviceName ?? \"uploadista-storage\";\n\n // Return a layer that provides tracing service context\n return Layer.succeed(TracingService, { serviceName });\n};\n\n// Storage-specific tracing layers\nexport const createStorageTracingLayer = (storageType: string) =>\n createTracingLayer({\n serviceName: `uploadista-${storageType}-store`,\n });\n\n// Utility to add storage context to spans\nexport const withStorageSpan =\n <A, E, R>(\n operation: string,\n storageType: string,\n attributes?: Record<string, unknown>,\n ) =>\n (effect: Effect.Effect<A, E, R>) =>\n effect.pipe(\n Effect.withSpan(`${storageType}-${operation}`, {\n attributes: {\n \"storage.type\": storageType,\n operation: operation,\n ...attributes,\n },\n }),\n );\n\n// Set up tracing with the OpenTelemetry SDK\nexport const WebSdkLive = WebSdk.layer(() => ({\n resource: { serviceName: \"uploadista-storage\" },\n // Export span data to the console\n spanProcessor: new BatchSpanProcessor(new ConsoleSpanExporter()),\n}));\n\nexport const NodeSdkLive = NodeSdk.layer(() => ({\n resource: { serviceName: \"uploadista-storage\" },\n // Export span data to the console\n spanProcessor: new BatchSpanProcessor(new ConsoleSpanExporter()),\n}));\n\n// Cloudflare Workers SDK (uses WebSdk as base)\nexport const WorkersSdkLive = WebSdk.layer(() => ({\n resource: { serviceName: \"uploadista-storage-workers\" },\n // Export span data to the console in Workers environment\n spanProcessor: new BatchSpanProcessor(new ConsoleSpanExporter()),\n}));\n","import { Effect, Metric } from \"effect\";\nimport type { StorageMetrics } from \"./metrics.js\";\n\n// ============================================================================\n// Storage Observability Utility Functions\n// ============================================================================\n\n// Generic upload metrics wrapper\nexport const withUploadMetrics = <A, E, R>(\n metrics: StorageMetrics,\n uploadId: string,\n effect: Effect.Effect<A, E, R>,\n): Effect.Effect<A, E, R> =>\n effect.pipe(\n Effect.tap(() =>\n metrics.uploadRequestsTotal.pipe(Metric.tagged(\"upload_id\", uploadId))(\n Effect.succeed(1),\n ),\n ),\n Effect.tapError(() =>\n metrics.uploadErrorsTotal.pipe(Metric.tagged(\"upload_id\", uploadId))(\n Effect.succeed(1),\n ),\n ),\n Effect.tap(() =>\n metrics.uploadSuccessTotal.pipe(Metric.tagged(\"upload_id\", uploadId))(\n Effect.succeed(1),\n ),\n ),\n );\n\n// Generic API call metrics wrapper\nexport const withApiMetrics = <A, E, R>(\n metrics: StorageMetrics,\n operation: string,\n effect: Effect.Effect<A, E, R>,\n): Effect.Effect<A, E, R> =>\n effect.pipe(\n Effect.tap(() =>\n metrics.apiCallsTotal.pipe(Metric.tagged(\"operation\", operation))(\n Effect.succeed(1),\n ),\n ),\n );\n\n// Generic timing metrics wrapper\nexport const withTimingMetrics = <A, E, R>(\n metric: Metric.Metric.Histogram<number>,\n effect: Effect.Effect<A, E, R>,\n): Effect.Effect<A, E, R> =>\n Effect.gen(function* () {\n const startTime = yield* Effect.sync(() => Date.now());\n const result = yield* effect;\n const endTime = yield* Effect.sync(() => Date.now());\n const duration = (endTime - startTime) / 1000; // Convert to seconds\n\n yield* metric(Effect.succeed(duration));\n\n return result;\n });\n\n// File size tracking\nexport const trackFileSize = <A, E, R>(\n metrics: StorageMetrics,\n fileSize: number,\n effect: Effect.Effect<A, E, R>,\n): Effect.Effect<A, E, R> =>\n effect.pipe(\n Effect.tap(() => metrics.fileSizeHistogram(Effect.succeed(fileSize))),\n );\n\n// Part size tracking\nexport const trackPartSize = <A, E, R>(\n metrics: StorageMetrics,\n partSize: number,\n effect: Effect.Effect<A, E, R>,\n): Effect.Effect<A, E, R> =>\n effect.pipe(\n Effect.tap(() => metrics.partSizeHistogram(Effect.succeed(partSize))),\n );\n\n// Active uploads tracking\nexport const withActiveUploadTracking = <A, E, R>(\n metrics: StorageMetrics,\n effect: Effect.Effect<A, E, R>,\n): Effect.Effect<A, E, R> =>\n effect.pipe(\n Effect.tap(() => metrics.activeUploadsGauge(Effect.succeed(1))),\n Effect.ensuring(metrics.activeUploadsGauge(Effect.succeed(-1))),\n );\n\n// Throughput calculation and tracking\nexport const withThroughputTracking = <A, E, R>(\n metrics: StorageMetrics,\n bytes: number,\n effect: Effect.Effect<A, E, R>,\n): Effect.Effect<A, E, R> =>\n Effect.gen(function* () {\n const startTime = yield* Effect.sync(() => Date.now());\n const result = yield* effect;\n const endTime = yield* Effect.sync(() => Date.now());\n const durationSeconds = (endTime - startTime) / 1000;\n const throughputBps = durationSeconds > 0 ? bytes / durationSeconds : 0;\n\n yield* metrics.uploadThroughputGauge(Effect.succeed(throughputBps));\n\n return result;\n });\n\n// Combined metrics wrapper for common upload operations\nexport const withStorageOperationMetrics = <A, E, R>(\n metrics: StorageMetrics,\n operation: string,\n uploadId: string,\n effect: Effect.Effect<A, E, R>,\n fileSize?: number,\n): Effect.Effect<A, E, R> => {\n let wrappedEffect = effect.pipe(\n (eff) => withApiMetrics(metrics, operation, eff),\n (eff) => withUploadMetrics(metrics, uploadId, eff),\n (eff) => withTimingMetrics(metrics.uploadDurationHistogram, eff),\n (eff) => withActiveUploadTracking(metrics, eff),\n );\n\n if (fileSize !== undefined) {\n wrappedEffect = wrappedEffect.pipe(\n (eff) => trackFileSize(metrics, fileSize, eff),\n (eff) => withThroughputTracking(metrics, fileSize, eff),\n );\n }\n\n return wrappedEffect;\n};\n","import { Metric, MetricBoundaries } from \"effect\";\n\n// ============================================================================\n// Flow Engine Metrics\n// ============================================================================\n\n/**\n * Flow engine metrics for tracking flow execution operations\n */\nexport const createFlowMetrics = () => ({\n // Counter metrics\n flowStartedTotal: Metric.counter(\"flow_started_total\", {\n description: \"Total number of flows started\",\n }),\n\n flowCompletedTotal: Metric.counter(\"flow_completed_total\", {\n description: \"Total number of flows completed successfully\",\n }),\n\n flowFailedTotal: Metric.counter(\"flow_failed_total\", {\n description: \"Total number of flows that failed\",\n }),\n\n flowPausedTotal: Metric.counter(\"flow_paused_total\", {\n description: \"Total number of flows that were paused\",\n }),\n\n flowResumedTotal: Metric.counter(\"flow_resumed_total\", {\n description: \"Total number of flows that were resumed\",\n }),\n\n nodeExecutedTotal: Metric.counter(\"node_executed_total\", {\n description: \"Total number of nodes executed\",\n }),\n\n nodeSuccessTotal: Metric.counter(\"node_success_total\", {\n description: \"Total number of nodes executed successfully\",\n }),\n\n nodeFailedTotal: Metric.counter(\"node_failed_total\", {\n description: \"Total number of nodes that failed\",\n }),\n\n nodeSkippedTotal: Metric.counter(\"node_skipped_total\", {\n description: \"Total number of nodes skipped (conditional)\",\n }),\n\n // Histogram metrics\n flowDurationHistogram: Metric.histogram(\n \"flow_duration_seconds\",\n MetricBoundaries.exponential({\n start: 0.1, // 100ms\n factor: 2,\n count: 20, // Up to ~100 seconds\n }),\n \"Duration of complete flow execution in seconds\",\n ),\n\n nodeDurationHistogram: Metric.histogram(\n \"node_duration_seconds\",\n MetricBoundaries.exponential({\n start: 0.01, // 10ms\n factor: 2,\n count: 18, // Up to ~26 seconds\n }),\n \"Duration of individual node execution in seconds\",\n ),\n\n flowNodeCountHistogram: Metric.histogram(\n \"flow_node_count\",\n MetricBoundaries.linear({\n start: 1,\n width: 5,\n count: 20, // Up to 100 nodes\n }),\n \"Number of nodes in a flow\",\n ),\n\n parallelNodesHistogram: Metric.histogram(\n \"parallel_nodes_count\",\n MetricBoundaries.linear({\n start: 1,\n width: 2,\n count: 15, // Up to 30 parallel nodes\n }),\n \"Number of nodes executed in parallel\",\n ),\n\n // Gauge metrics\n activeFlowsGauge: Metric.gauge(\"active_flows\", {\n description: \"Number of currently active flows\",\n }),\n\n activeNodesGauge: Metric.gauge(\"active_nodes\", {\n description: \"Number of currently executing nodes\",\n }),\n\n pausedFlowsGauge: Metric.gauge(\"paused_flows\", {\n description: \"Number of currently paused flows\",\n }),\n\n // Summary metrics for latency percentiles\n flowLatencySummary: Metric.summary({\n name: \"flow_latency_seconds\",\n maxAge: \"10 minutes\",\n maxSize: 1000,\n error: 0.01,\n quantiles: [0.5, 0.9, 0.95, 0.99],\n description: \"Flow execution latency percentiles\",\n }),\n\n nodeLatencySummary: Metric.summary({\n name: \"node_latency_seconds\",\n maxAge: \"10 minutes\",\n maxSize: 1000,\n error: 0.01,\n quantiles: [0.5, 0.9, 0.95, 0.99],\n description: \"Node execution latency percentiles\",\n }),\n});\n\n/**\n * Type for flow metrics\n */\nexport type FlowMetrics = ReturnType<typeof createFlowMetrics>;\n\n/**\n * Default flow metrics instance\n */\nexport const flowMetrics = createFlowMetrics();\n","import { Effect } from \"effect\";\n\n// ============================================================================\n// Flow Tracing Utilities\n// ============================================================================\n\n/**\n * Wrap an Effect with a flow operation span\n */\nexport const withFlowSpan =\n <A, E, R>(operation: string, attributes?: Record<string, unknown>) =>\n (effect: Effect.Effect<A, E, R>): Effect.Effect<A, E, R> =>\n effect.pipe(\n Effect.withSpan(`flow-${operation}`, {\n attributes: {\n \"flow.operation\": operation,\n ...attributes,\n },\n }),\n );\n\n/**\n * Add flow context to the current span\n */\nexport const withFlowContext = (context: {\n flowId?: string;\n flowName?: string;\n jobId?: string;\n nodeCount?: number;\n storageId?: string;\n}) =>\n Effect.annotateCurrentSpan({\n \"flow.id\": context.flowId ?? \"unknown\",\n \"flow.name\": context.flowName ?? \"unknown\",\n \"flow.job_id\": context.jobId ?? \"unknown\",\n \"flow.node_count\": context.nodeCount?.toString() ?? \"0\",\n \"flow.storage_id\": context.storageId ?? \"unknown\",\n });\n\n/**\n * Add node context to the current span\n */\nexport const withNodeContext = (context: {\n nodeId: string;\n nodeType: string;\n nodeName?: string;\n flowId?: string;\n jobId?: string;\n}) =>\n Effect.annotateCurrentSpan({\n \"node.id\": context.nodeId,\n \"node.type\": context.nodeType,\n \"node.name\": context.nodeName ?? \"unknown\",\n \"node.flow_id\": context.flowId ?? \"unknown\",\n \"node.job_id\": context.jobId ?? \"unknown\",\n });\n\n/**\n * Add execution state context to the current span\n */\nexport const withExecutionContext = (context: {\n executionOrder?: string[];\n currentIndex?: number;\n totalNodes?: number;\n parallelCount?: number;\n}) =>\n Effect.annotateCurrentSpan({\n \"execution.order\": context.executionOrder?.join(\",\") ?? \"\",\n \"execution.current_index\": context.currentIndex?.toString() ?? \"0\",\n \"execution.total_nodes\": context.totalNodes?.toString() ?? \"0\",\n \"execution.parallel_count\": context.parallelCount?.toString() ?? \"0\",\n });\n","import { Effect, Layer, Metric } from \"effect\";\nimport {\n FlowObservability,\n makeFlowObservabilityLayer,\n} from \"../core/layers.js\";\nimport { createFlowMetrics, type FlowMetrics } from \"./metrics.js\";\n\n// ============================================================================\n// Flow Observability Layer Implementation\n// ============================================================================\n\n/**\n * Create a live flow observability layer with full metrics\n */\nexport const makeFlowObservabilityLive = (\n serviceName = \"uploadista-flow-engine\",\n): Layer.Layer<FlowObservability> => {\n const metrics = createFlowMetrics();\n\n return Layer.succeed(FlowObservability, {\n serviceName,\n enabled: true,\n metrics: {\n flowStarted: Metric.increment(metrics.flowStartedTotal),\n flowCompleted: Metric.increment(metrics.flowCompletedTotal),\n flowFailed: Metric.increment(metrics.flowFailedTotal),\n nodeExecuted: Metric.increment(metrics.nodeExecutedTotal),\n },\n });\n};\n\n/**\n * Default live flow observability layer\n */\nexport const FlowObservabilityLive = makeFlowObservabilityLive();\n\n/**\n * No-op flow observability layer (for testing or disabled observability)\n */\nexport const FlowObservabilityDisabled = makeFlowObservabilityLayer(false);\n\n/**\n * Helper to get flow metrics from context\n */\nexport const getFlowMetrics = Effect.gen(function* () {\n const obs = yield* FlowObservability;\n return obs.metrics;\n});\n\n/**\n * Helper to track flow duration\n */\nexport const withFlowDuration = <A, E, R>(\n effect: Effect.Effect<A, E, R>,\n): Effect.Effect<A, E, R> => {\n const metrics = createFlowMetrics();\n return Effect.gen(function* () {\n const startTime = Date.now();\n const result = yield* effect;\n const duration = (Date.now() - startTime) / 1000; // Convert to seconds\n yield* Metric.update(metrics.flowDurationHistogram, duration);\n yield* Metric.update(metrics.flowLatencySummary, duration);\n return result;\n }).pipe(Effect.withSpan(\"flow-execution\"));\n};\n\n/**\n * Helper to track node duration\n */\nexport const withNodeDuration = <A, E, R>(\n nodeId: string,\n nodeType: string,\n effect: Effect.Effect<A, E, R>,\n): Effect.Effect<A, E, R> => {\n const metrics = createFlowMetrics();\n return Effect.gen(function* () {\n const startTime = Date.now();\n const result = yield* effect;\n const duration = (Date.now() - startTime) / 1000; // Convert to seconds\n yield* Metric.update(metrics.nodeDurationHistogram, duration);\n yield* Metric.update(metrics.nodeLatencySummary, duration);\n return result;\n }).pipe(\n Effect.withSpan(`node-${nodeType}`, {\n attributes: {\n \"node.id\": nodeId,\n \"node.type\": nodeType,\n },\n }),\n );\n};\n\n/**\n * Helper to track active flows\n */\nexport const trackActiveFlow = <A, E, R>(\n effect: Effect.Effect<A, E, R>,\n): Effect.Effect<A, E, R> => {\n const metrics = createFlowMetrics();\n return Effect.gen(function* () {\n // Increment active flows\n yield* Metric.increment(metrics.activeFlowsGauge);\n\n // Use acquireUseRelease for proper cleanup\n return yield* Effect.acquireUseRelease(\n Effect.void,\n () => effect,\n () => Metric.set(metrics.activeFlowsGauge, -1),\n );\n });\n};\n\n/**\n * Helper to track active nodes\n */\nexport const trackActiveNode = <A, E, R>(\n effect: Effect.Effect<A, E, R>,\n): Effect.Effect<A, E, R> => {\n const metrics = createFlowMetrics();\n return Effect.gen(function* () {\n // Increment active nodes\n yield* Metric.increment(metrics.activeNodesGauge);\n\n // Use acquireUseRelease for proper cleanup\n return yield* Effect.acquireUseRelease(\n Effect.void,\n () => effect,\n () => Metric.set(metrics.activeNodesGauge, -1),\n );\n });\n};\n","import { Effect, Metric } from \"effect\";\nimport { createFlowMetrics } from \"./metrics.js\";\n\n// ============================================================================\n// Flow Error Classification\n// ============================================================================\n\nexport type FlowErrorCategory =\n | \"flow_validation_error\"\n | \"node_execution_error\"\n | \"node_not_found_error\"\n | \"flow_timeout_error\"\n | \"flow_cancelled_error\"\n | \"unknown_flow_error\";\n\n/**\n * Classify flow execution errors\n */\nexport const classifyFlowError = (error: unknown): FlowErrorCategory => {\n if (!error || typeof error !== \"object\") return \"unknown_flow_error\";\n\n const errorCode = \"code\" in error ? error.code : undefined;\n if (!errorCode) return \"unknown_flow_error\";\n\n // Flow-specific error codes\n switch (errorCode) {\n case \"FLOW_VALIDATION_ERROR\":\n case \"FLOW_INVALID_INPUT\":\n case \"FLOW_INVALID_OUTPUT\":\n return \"flow_validation_error\";\n case \"FLOW_NODE_NOT_FOUND\":\n case \"FLOW_EDGE_INVALID\":\n return \"node_not_found_error\";\n case \"FLOW_NODE_EXECUTION_FAILED\":\n case \"FLOW_NODE_ERROR\":\n return \"node_execution_error\";\n case \"FLOW_TIMEOUT\":\n return \"flow_timeout_error\";\n case \"FLOW_CANCELLED\":\n case \"ABORTED\":\n return \"flow_cancelled_error\";\n default:\n return \"unknown_flow_error\";\n }\n};\n\n/**\n * Track flow errors with classification\n */\nexport const trackFlowError = <E>(\n error: E,\n): Effect.Effect<void, never, never> => {\n const metrics = createFlowMetrics();\n const category = classifyFlowError(error);\n\n return Effect.gen(function* () {\n // Increment total failed flows\n yield* Metric.increment(metrics.flowFailedTotal);\n\n // Log error with classification\n yield* Effect.logError(\"Flow execution failed\").pipe(\n Effect.annotateLogs({\n \"error.category\": category,\n \"error.message\": String(error),\n }),\n );\n });\n};\n\n/**\n * Track node errors with classification\n */\nexport const trackNodeError = <E>(\n nodeId: string,\n nodeType: string,\n error: E,\n): Effect.Effect<void, never, never> => {\n const metrics = createFlowMetrics();\n const category = classifyFlowError(error);\n\n return Effect.gen(function* () {\n // Increment node failed counter\n yield* Metric.increment(metrics.nodeFailedTotal);\n\n // Log error with node context\n yield* Effect.logError(\"Node execution failed\").pipe(\n Effect.annotateLogs({\n \"node.id\": nodeId,\n \"node.type\": nodeType,\n \"error.category\": category,\n \"error.message\": String(error),\n }),\n );\n });\n};\n","import { Effect, Layer } from \"effect\";\nimport { FlowObservability } from \"../core/layers.js\";\nimport type { FlowObservabilityService } from \"../core/layers.js\";\n\n// ============================================================================\n// Test Flow Observability Layers\n// ============================================================================\n\n/**\n * Mock flow observability for testing\n */\nexport const makeTestFlowObservability = (): Layer.Layer<FlowObservability> => {\n const service: FlowObservabilityService = {\n serviceName: \"test-flow-engine\",\n enabled: true,\n metrics: {\n flowStarted: Effect.void,\n flowCompleted: Effect.void,\n flowFailed: Effect.void,\n nodeExecuted: Effect.void,\n },\n };\n return Layer.succeed(FlowObservability, service);\n};\n\n/**\n * Run an effect with test flow observability\n */\nexport const runWithTestFlowObservability = <A, E>(\n effect: Effect.Effect<A, E, FlowObservability>,\n): Effect.Effect<A, E> => {\n return effect.pipe(Effect.provide(makeTestFlowObservability()));\n};\n","import { Context, Effect, Layer } from \"effect\";\n\n/**\n * Metrics Recording Service\n *\n * Provides access to metrics recording functionality throughout\n * the upload and flow processing pipeline. The service is provided\n * via Effect Layer and can be accessed using Effect.service().\n */\nexport class MetricsService extends Context.Tag(\"MetricsService\")<\n MetricsService,\n {\n /**\n * Record upload metrics for an organization\n */\n readonly recordUpload: (\n clientId: string,\n bytes: number,\n metadata?: Record<string, unknown>,\n ) => Effect.Effect<void, never>;\n }\n>() {}\n\n/**\n * No-op implementation of MetricsService that does nothing.\n * Used when metrics are disabled or database is not available.\n */\nexport const NoOpMetricsServiceLive: Layer.Layer<MetricsService> =\n Layer.succeed(MetricsService, {\n recordUpload: (_organizationId: string, _bytes: number) => Effect.void,\n });\n","import { type Effect, Layer } from \"effect\";\nimport {\n createStorageErrorTracker,\n type StorageErrorCategory,\n} from \"../core/errors.js\";\nimport {\n logStorageOperation,\n logUploadCompletion,\n logUploadProgress,\n logWithContext,\n} from \"../core/logging.js\";\nimport { createStorageMetrics, type StorageMetrics } from \"../core/metrics.js\";\nimport { createStorageTracingLayer, withStorageSpan } from \"../core/tracing.js\";\nimport {\n withApiMetrics,\n withStorageOperationMetrics,\n withTimingMetrics,\n withUploadMetrics,\n} from \"../core/utilities.js\";\n\n// ============================================================================\n// S3-Specific Observability\n// ============================================================================\n\nconst STORAGE_TYPE = \"s3\";\n\n// S3-specific metrics\nexport const s3Metrics = createStorageMetrics(STORAGE_TYPE);\n\n// S3-specific tracing layer\nexport const S3TracingLayer = createStorageTracingLayer(STORAGE_TYPE);\n\n// S3-specific error classification\nconst classifyS3Error = (error: unknown): StorageErrorCategory | null => {\n if (!error || typeof error !== \"object\") return null;\n\n const errorCode = \"code\" in error ? error.code : undefined;\n if (!errorCode) return null;\n\n // S3-specific error codes\n switch (errorCode) {\n case \"NoSuchKey\":\n case \"NoSuchBucket\":\n case \"NoSuchUpload\":\n return \"client_error\";\n case \"BucketAlreadyExists\":\n case \"BucketNotEmpty\":\n return \"client_error\";\n case \"InvalidBucketName\":\n case \"InvalidPart\":\n case \"InvalidPartOrder\":\n return \"client_error\";\n case \"EntityTooSmall\":\n case \"EntityTooLarge\":\n return \"client_error\";\n case \"ExpiredToken\":\n case \"TokenRefreshRequired\":\n return \"authentication_error\";\n case \"RequestTimeTooSkewed\":\n case \"SlowDown\":\n return \"throttling_error\";\n default:\n return null; // Fall back to generic classification\n }\n};\n\n// S3-specific error tracker\nexport const trackS3Error = createStorageErrorTracker(\n STORAGE_TYPE,\n s3Metrics,\n classifyS3Error,\n);\n\n// S3-specific observability layer\nexport const S3ObservabilityLayer = Layer.mergeAll(\n S3TracingLayer,\n // Metrics are automatically available through Effect\n);\n\n// ============================================================================\n// S3 Utility Functions\n// ============================================================================\n\nexport const withS3UploadMetrics = <A, E, R>(\n uploadId: string,\n effect: Effect.Effect<A, E, R>,\n) => withUploadMetrics(s3Metrics, uploadId, effect);\n\nexport const withS3ApiMetrics = <A, E, R>(\n operation: string,\n effect: Effect.Effect<A, E, R>,\n) => withApiMetrics(s3Metrics, operation, effect);\n\nexport const withS3TimingMetrics = withTimingMetrics;\n\nexport const withS3OperationMetrics = <A, E, R>(\n operation: string,\n uploadId: string,\n effect: Effect.Effect<A, E, R>,\n fileSize?: number,\n) =>\n withStorageOperationMetrics(s3Metrics, operation, uploadId, effect, fileSize);\n\n// S3-specific span wrapper\nexport const withS3Span =\n <A, E, R>(operation: string, attributes?: Record<string, unknown>) =>\n (effect: Effect.Effect<A, E, R>) =>\n withStorageSpan(operation, STORAGE_TYPE, attributes)(effect);\n\n// S3-specific logging functions\nexport const logS3Operation = logStorageOperation.bind(null, STORAGE_TYPE);\nexport const logS3UploadProgress = logUploadProgress.bind(null, STORAGE_TYPE);\nexport const logS3UploadCompletion = logUploadCompletion.bind(\n null,\n STORAGE_TYPE,\n);\nexport const logS3Context = logWithContext;\n\n// Export metrics for external access\nexport const {\n uploadRequestsTotal: s3UploadRequestsTotal,\n uploadPartsTotal: s3UploadPartsTotal,\n uploadSuccessTotal: s3UploadSuccessTotal,\n uploadErrorsTotal: s3UploadErrorsTotal,\n apiCallsTotal: s3ApiCallsTotal,\n uploadDurationHistogram: s3UploadDurationHistogram,\n partUploadDurationHistogram: s3PartUploadDurationHistogram,\n fileSizeHistogram: s3FileSizeHistogram,\n partSizeHistogram: s3PartSizeHistogram,\n activeUploadsGauge: s3ActiveUploadsGauge,\n uploadThroughputGauge: s3UploadThroughputGauge,\n uploadLatencySummary: s3UploadLatencySummary,\n} = s3Metrics;\n\n// Type exports\nexport type S3Metrics = StorageMetrics;\n","import { type Effect, Layer } from \"effect\";\nimport {\n createStorageErrorTracker,\n type StorageErrorCategory,\n} from \"../core/errors.js\";\nimport {\n logStorageOperation,\n logUploadCompletion,\n logUploadProgress,\n logWithContext,\n} from \"../core/logging.js\";\nimport { createStorageMetrics, type StorageMetrics } from \"../core/metrics.js\";\nimport { createStorageTracingLayer, withStorageSpan } from \"../core/tracing.js\";\nimport {\n withApiMetrics,\n withStorageOperationMetrics,\n withTimingMetrics,\n withUploadMetrics,\n} from \"../core/utilities.js\";\n\n// ============================================================================\n// Azure Blob Storage-Specific Observability\n// ============================================================================\n\nconst STORAGE_TYPE = \"azure\";\n\n// Azure-specific metrics\nexport const azureMetrics = createStorageMetrics(STORAGE_TYPE);\n\n// Azure-specific tracing layer\nexport const AzureTracingLayer = createStorageTracingLayer(STORAGE_TYPE);\n\n// Azure-specific error classification\nconst classifyAzureError = (error: unknown): StorageErrorCategory | null => {\n if (!error || typeof error !== \"object\") return null;\n\n const errorCode =\n \"code\" in error\n ? error.code\n : \"statusCode\" in error\n ? error.statusCode\n : undefined;\n if (!errorCode) return null;\n\n // Azure-specific error codes\n switch (errorCode) {\n case \"BlobNotFound\":\n case \"ContainerNotFound\":\n case \"InvalidBlobOrBlock\":\n return \"client_error\";\n case \"ContainerAlreadyExists\":\n case \"BlobAlreadyExists\":\n return \"client_error\";\n case \"InvalidBlockId\":\n case \"InvalidBlockList\":\n case \"InvalidBlobType\":\n return \"client_error\";\n case \"RequestBodyTooLarge\":\n case \"InvalidHeaderValue\":\n return \"client_error\";\n case \"AuthenticationFailed\":\n case \"InvalidAuthenticationInfo\":\n return \"authentication_error\";\n case \"AccountIsDisabled\":\n return \"authorization_error\";\n case \"InsufficientAccountPermissions\":\n return \"authorization_error\";\n case \"OperationTimedOut\":\n case \"ServerBusy\":\n case \"InternalError\":\n return \"server_error\";\n default:\n // Check for HTTP status codes\n if (typeof errorCode === \"number\") {\n if (errorCode >= 500) return \"server_error\";\n if (errorCode === 429) return \"throttling_error\";\n if (errorCode === 403) return \"authorization_error\";\n if (errorCode === 401) return \"authentication_error\";\n if (errorCode >= 400) return \"client_error\";\n }\n return null; // Fall back to generic classification\n }\n};\n\n// Azure-specific error tracker\nexport const trackAzureError = createStorageErrorTracker(\n STORAGE_TYPE,\n azureMetrics,\n classifyAzureError,\n);\n\n// Azure-specific observability layer\nexport const AzureObservabilityLayer = Layer.mergeAll(\n AzureTracingLayer,\n // Metrics are automatically available through Effect\n);\n\n// ============================================================================\n// Azure Utility Functions\n// ============================================================================\n\nexport const withAzureUploadMetrics = <A, E, R>(\n uploadId: string,\n effect: Effect.Effect<A, E, R>,\n) => withUploadMetrics(azureMetrics, uploadId, effect);\n\nexport const withAzureApiMetrics = <A, E, R>(\n operation: string,\n effect: Effect.Effect<A, E, R>,\n) => withApiMetrics(azureMetrics, operation, effect);\n\nexport const withAzureTimingMetrics = withTimingMetrics;\n\nexport const withAzureOperationMetrics = <A, E, R>(\n operation: string,\n uploadId: string,\n effect: Effect.Effect<A, E, R>,\n fileSize?: number,\n) =>\n withStorageOperationMetrics(\n azureMetrics,\n operation,\n uploadId,\n effect,\n fileSize,\n );\n\n// Azure-specific span wrapper\nexport const withAzureSpan =\n <A, E, R>(operation: string, attributes?: Record<string, unknown>) =>\n (effect: Effect.Effect<A, E, R>) =>\n withStorageSpan(operation, STORAGE_TYPE, attributes)(effect);\n\n// Azure-specific logging functions\nexport const logAzureOperation = logStorageOperation.bind(null, STORAGE_TYPE);\nexport const logAzureUploadProgress = logUploadProgress.bind(\n null,\n STORAGE_TYPE,\n);\nexport const logAzureUploadCompletion = logUploadCompletion.bind(\n null,\n STORAGE_TYPE,\n);\nexport const logAzureContext = logWithContext;\n\n// Export metrics for external access\nexport const {\n uploadRequestsTotal: azureUploadRequestsTotal,\n uploadPartsTotal: azureUploadPartsTotal,\n uploadSuccessTotal: azureUploadSuccessTotal,\n uploadErrorsTotal: azureUploadErrorsTotal,\n apiCallsTotal: azureApiCallsTotal,\n uploadDurationHistogram: azureUploadDurationHistogram,\n partUploadDurationHistogram: azurePartUploadDurationHistogram,\n fileSizeHistogram: azureFileSizeHistogram,\n partSizeHistogram: azurePartSizeHistogram,\n activeUploadsGauge: azureActiveUploadsGauge,\n uploadThroughputGauge: azureUploadThroughputGauge,\n uploadLatencySummary: azureUploadLatencySummary,\n} = azureMetrics;\n\n// Type exports\nexport type AzureMetrics = StorageMetrics;\n","import { type Effect, Layer } from \"effect\";\nimport {\n createStorageErrorTracker,\n type StorageErrorCategory,\n} from \"../core/errors.js\";\nimport {\n logStorageOperation,\n logUploadCompletion,\n logUploadProgress,\n logWithContext,\n} from \"../core/logging.js\";\nimport { createStorageMetrics, type StorageMetrics } from \"../core/metrics.js\";\nimport { createStorageTracingLayer, withStorageSpan } from \"../core/tracing.js\";\nimport {\n withApiMetrics,\n withStorageOperationMetrics,\n withTimingMetrics,\n withUploadMetrics,\n} from \"../core/utilities.js\";\n\n// ============================================================================\n// Google Cloud Storage-Specific Observability\n// ============================================================================\n\nconst STORAGE_TYPE = \"gcs\";\n\n// GCS-specific metrics\nexport const gcsMetrics = createStorageMetrics(STORAGE_TYPE);\n\n// GCS-specific tracing layer\nexport const GCSTracingLayer = createStorageTracingLayer(STORAGE_TYPE);\n\n// GCS-specific error classification\nconst classifyGCSError = (error: unknown): StorageErrorCategory | null => {\n if (!error || typeof error !== \"object\") return null;\n\n const errorCode =\n \"code\" in error ? error.code : \"status\" in error ? error.status : undefined;\n if (!errorCode) return null;\n\n // GCS-specific error codes\n switch (errorCode) {\n case \"NoSuchBucket\":\n case \"NoSuchKey\":\n case \"NoSuchUpload\":\n return \"client_error\";\n case \"BucketAlreadyOwnedByYou\":\n case \"BucketNotEmpty\":\n return \"client_error\";\n case \"InvalidBucketName\":\n case \"InvalidArgument\":\n case \"InvalidPart\":\n case \"InvalidPartOrder\":\n return \"client_error\";\n case \"EntityTooSmall\":\n case \"EntityTooLarge\":\n return \"client_error\";\n case \"MalformedPolicy\":\n return \"client_error\";\n case \"Unauthorized\":\n case \"AuthenticationRequired\":\n return \"authentication_error\";\n case \"Forbidden\":\n case \"AccessDenied\":\n return \"authorization_error\";\n case \"TooManyRequests\":\n case \"RateLimitExceeded\":\n return \"throttling_error\";\n case \"InternalError\":\n case \"ServiceUnavailable\":\n case \"BackendError\":\n return \"server_error\";\n default:\n // Check for HTTP status codes\n if (typeof errorCode === \"number\") {\n if (errorCode >= 500) return \"server_error\";\n if (errorCode === 429) return \"throttling_error\";\n if (errorCode === 403) return \"authorization_error\";\n if (errorCode === 401) return \"authentication_error\";\n if (errorCode >= 400) return \"client_error\";\n }\n return null; // Fall back to generic classification\n }\n};\n\n// GCS-specific error tracker\nexport const trackGCSError = createStorageErrorTracker(\n STORAGE_TYPE,\n gcsMetrics,\n classifyGCSError,\n);\n\n// GCS-specific observability layer\nexport const GCSObservabilityLayer = Layer.mergeAll(\n GCSTracingLayer,\n // Metrics are automatically available through Effect\n);\n\n// ============================================================================\n// GCS Utility Functions\n// ============================================================================\n\nexport const withGCSUploadMetrics = <A, E, R>(\n uploadId: string,\n effect: Effect.Effect<A, E, R>,\n) => withUploadMetrics(gcsMetrics, uploadId, effect);\n\nexport const withGCSApiMetrics = <A, E, R>(\n operation: string,\n effect: Effect.Effect<A, E, R>,\n) => withApiMetrics(gcsMetrics, operation, effect);\n\nexport const withGCSTimingMetrics = withTimingMetrics;\n\nexport const withGCSOperationMetrics = <A, E, R>(\n operation: string,\n uploadId: string,\n effect: Effect.Effect<A, E, R>,\n fileSize?: number,\n) =>\n withStorageOperationMetrics(\n gcsMetrics,\n operation,\n uploadId,\n effect,\n fileSize,\n );\n\n// GCS-specific span wrapper\nexport const withGCSSpan =\n <A, E, R>(operation: string, attributes?: Record<string, unknown>) =>\n (effect: Effect.Effect<A, E, R>) =>\n withStorageSpan(operation, STORAGE_TYPE, attributes)(effect);\n\n// GCS-specific logging functions\nexport const logGCSOperation = logStorageOperation.bind(null, STORAGE_TYPE);\nexport const logGCSUploadProgress = logUploadProgress.bind(null, STORAGE_TYPE);\nexport const logGCSUploadCompletion = logUploadCompletion.bind(\n null,\n STORAGE_TYPE,\n);\nexport const logGCSContext = logWithContext;\n\n// Export metrics for external access\nexport const {\n uploadRequestsTotal: gcsUploadRequestsTotal,\n uploadPartsTotal: gcsUploadPartsTotal,\n uploadSuccessTotal: gcsUploadSuccessTotal,\n uploadErrorsTotal: gcsUploadErrorsTotal,\n apiCallsTotal: gcsApiCallsTotal,\n uploadDurationHistogram: gcsUploadDurationHistogram,\n partUploadDurationHistogram: gcsPartUploadDurationHistogram,\n fileSizeHistogram: gcsFileSizeHistogram,\n partSizeHistogram: gcsPartSizeHistogram,\n activeUploadsGauge: gcsActiveUploadsGauge,\n uploadThroughputGauge: gcsUploadThroughputGauge,\n uploadLatencySummary: gcsUploadLatencySummary,\n} = gcsMetrics;\n\n// Type exports\nexport type GCSMetrics = StorageMetrics;\n","import { type Effect, Layer } from \"effect\";\nimport {\n createStorageErrorTracker,\n type StorageErrorCategory,\n} from \"../core/errors.js\";\nimport {\n logStorageOperation,\n logUploadCompletion,\n logUploadProgress,\n logWithContext,\n} from \"../core/logging.js\";\nimport { createStorageMetrics, type StorageMetrics } from \"../core/metrics.js\";\nimport { createStorageTracingLayer, withStorageSpan } from \"../core/tracing.js\";\nimport {\n withApiMetrics,\n withStorageOperationMetrics,\n withTimingMetrics,\n withUploadMetrics,\n} from \"../core/utilities.js\";\n\n// ============================================================================\n// Filesystem Storage-Specific Observability\n// ============================================================================\n\nconst STORAGE_TYPE = \"filesystem\";\n\n// Filesystem-specific metrics\nexport const filesystemMetrics = createStorageMetrics(STORAGE_TYPE);\n\n// Filesystem-specific tracing layer\nexport const FilesystemTracingLayer = createStorageTracingLayer(STORAGE_TYPE);\n\n// Filesystem-specific error classification\nconst classifyFilesystemError = (\n error: unknown,\n): StorageErrorCategory | null => {\n if (!error || typeof error !== \"object\") return null;\n\n const errorCode = \"code\" in error ? error.code : undefined;\n if (!errorCode) return null;\n\n // Node.js filesystem error codes\n switch (errorCode) {\n case \"ENOENT\": // File/directory not found\n case \"ENOTDIR\": // Not a directory\n return \"client_error\";\n case \"EEXIST\": // File/directory already exists\n return \"client_error\";\n case \"EISDIR\": // Is a directory\n return \"client_error\";\n case \"EINVAL\": // Invalid argument\n case \"ENAMETOOLONG\": // Filename too long\n return \"client_error\";\n case \"EACCES\": // Permission denied\n case \"EPERM\": // Operation not permitted\n return \"authorization_error\";\n case \"ENOSPC\": // No space left on device\n case \"EDQUOT\": // Disk quota exceeded\n return \"server_error\";\n case \"EIO\": // I/O error\n case \"EROFS\": // Read-only filesystem\n case \"EMFILE\": // Too many open files\n case \"ENFILE\": // File table overflow\n return \"server_error\";\n case \"EBUSY\": // Device or resource busy\n return \"throttling_error\";\n default:\n return null; // Fall back to generic classification\n }\n};\n\n// Filesystem-specific error tracker\nexport const trackFilesystemError = createStorageErrorTracker(\n STORAGE_TYPE,\n filesystemMetrics,\n classifyFilesystemError,\n);\n\n// Filesystem-specific observability layer\nexport const FilesystemObservabilityLayer = Layer.mergeAll(\n FilesystemTracingLayer,\n // Metrics are automatically available through Effect\n);\n\n// ============================================================================\n// Filesystem Utility Functions\n// ============================================================================\n\nexport const withFilesystemUploadMetrics = <A, E, R>(\n uploadId: string,\n effect: Effect.Effect<A, E, R>,\n) => withUploadMetrics(filesystemMetrics, uploadId, effect);\n\nexport const withFilesystemApiMetrics = <A, E, R>(\n operation: string,\n effect: Effect.Effect<A, E, R>,\n) => withApiMetrics(filesystemMetrics, operation, effect);\n\nexport const withFilesystemTimingMetrics = withTimingMetrics;\n\nexport const withFilesystemOperationMetrics = <A, E, R>(\n operation: string,\n uploadId: string,\n effect: Effect.Effect<A, E, R>,\n fileSize?: number,\n) =>\n withStorageOperationMetrics(\n filesystemMetrics,\n operation,\n uploadId,\n effect,\n fileSize,\n );\n\n// Filesystem-specific span wrapper\nexport const withFilesystemSpan =\n <A, E, R>(operation: string, attributes?: Record<string, unknown>) =>\n (effect: Effect.Effect<A, E, R>) =>\n withStorageSpan(operation, STORAGE_TYPE, attributes)(effect);\n\n// Filesystem-specific logging functions\nexport const logFilesystemOperation = logStorageOperation.bind(\n null,\n STORAGE_TYPE,\n);\nexport const logFilesystemUploadProgress = logUploadProgress.bind(\n null,\n STORAGE_TYPE,\n);\nexport const logFilesystemUploadCompletion = logUploadCompletion.bind(\n null,\n STORAGE_TYPE,\n);\nexport const logFilesystemContext = logWithContext;\n\n// Export metrics for external access\nexport const {\n uploadRequestsTotal: filesystemUploadRequestsTotal,\n uploadPartsTotal: filesystemUploadPartsTotal,\n uploadSuccessTotal: filesystemUploadSuccessTotal,\n uploadErrorsTotal: filesystemUploadErrorsTotal,\n apiCallsTotal: filesystemApiCallsTotal,\n uploadDurationHistogram: filesystemUploadDurationHistogram,\n partUploadDurationHistogram: filesystemPartUploadDurationHistogram,\n fileSizeHistogram: filesystemFileSizeHistogram,\n partSizeHistogram: filesystemPartSizeHistogram,\n activeUploadsGauge: filesystemActiveUploadsGauge,\n uploadThroughputGauge: filesystemUploadThroughputGauge,\n uploadLatencySummary: filesystemUploadLatencySummary,\n} = filesystemMetrics;\n\n// Type exports\nexport type FilesystemMetrics = StorageMetrics;\n","import { Metric, MetricBoundaries } from \"effect\";\n\n// ============================================================================\n// Upload Server Metrics\n// ============================================================================\n\n/**\n * Upload server metrics for tracking upload operations\n */\nexport const createUploadServerMetrics = () => ({\n // Counter metrics\n uploadCreatedTotal: Metric.counter(\"upload_created_total\", {\n description: \"Total number of uploads created\",\n }),\n\n uploadCompletedTotal: Metric.counter(\"upload_completed_total\", {\n description: \"Total number of uploads completed successfully\",\n }),\n\n uploadFailedTotal: Metric.counter(\"upload_failed_total\", {\n description: \"Total number of uploads that failed\",\n }),\n\n chunkUploadedTotal: Metric.counter(\"chunk_uploaded_total\", {\n description: \"Total number of chunks uploaded\",\n }),\n\n uploadFromUrlTotal: Metric.counter(\"upload_from_url_total\", {\n description: \"Total number of URL-based uploads\",\n }),\n\n uploadFromUrlSuccessTotal: Metric.counter(\"upload_from_url_success_total\", {\n description: \"Total number of successful URL-based uploads\",\n }),\n\n uploadFromUrlFailedTotal: Metric.counter(\"upload_from_url_failed_total\", {\n description: \"Total number of failed URL-based uploads\",\n }),\n\n // Histogram metrics\n uploadDurationHistogram: Metric.histogram(\n \"upload_duration_seconds\",\n MetricBoundaries.exponential({\n start: 0.01, // 10ms\n factor: 2,\n count: 20, // Up to ~10 seconds\n }),\n \"Duration of complete upload operations in seconds\",\n ),\n\n chunkUploadDurationHistogram: Metric.histogram(\n \"chunk_upload_duration_seconds\",\n MetricBoundaries.exponential({\n start: 0.001, // 1ms\n factor: 2,\n count: 15, // Up to ~32 seconds\n }),\n \"Duration of individual chunk uploads in seconds\",\n ),\n\n uploadFileSizeHistogram: Metric.histogram(\n \"upload_file_size_bytes\",\n MetricBoundaries.exponential({\n start: 1024, // 1KB\n factor: 2,\n count: 25, // Up to ~33GB\n }),\n \"Size of uploaded files in bytes\",\n ),\n\n chunkSizeHistogram: Metric.histogram(\n \"chunk_size_bytes\",\n MetricBoundaries.linear({\n start: 262_144, // 256KB\n width: 262_144, // 256KB increments\n count: 20, // Up to ~5MB\n }),\n \"Size of uploaded chunks in bytes\",\n ),\n\n // Gauge metrics\n activeUploadsGauge: Metric.gauge(\"active_uploads\", {\n description: \"Number of currently active uploads\",\n }),\n\n uploadThroughputGauge: Metric.gauge(\"upload_throughput_bytes_per_second\", {\n description: \"Current upload throughput in bytes per second\",\n }),\n\n // Summary metrics for latency percentiles\n uploadLatencySummary: Metric.summary({\n name: \"upload_latency_seconds\",\n maxAge: \"10 minutes\",\n maxSize: 1000,\n error: 0.01,\n quantiles: [0.5, 0.9, 0.95, 0.99],\n description: \"Upload operation latency percentiles\",\n }),\n\n chunkLatencySummary: Metric.summary({\n name: \"chunk_latency_seconds\",\n maxAge: \"10 minutes\",\n maxSize: 1000,\n error: 0.01,\n quantiles: [0.5, 0.9, 0.95, 0.99],\n description: \"Chunk upload latency percentiles\",\n }),\n});\n\n/**\n * Type for upload server metrics\n */\nexport type UploadServerMetrics = ReturnType<typeof createUploadServerMetrics>;\n\n/**\n * Default upload server metrics instance\n */\nexport const uploadServerMetrics = createUploadServerMetrics();\n","import { Effect } from \"effect\";\n\n// ============================================================================\n// Upload Tracing Utilities\n// ============================================================================\n\n/**\n * Wrap an Effect with an upload operation span\n */\nexport const withUploadSpan =\n <A, E, R>(operation: string, attributes?: Record<string, unknown>) =>\n (effect: Effect.Effect<A, E, R>): Effect.Effect<A, E, R> =>\n effect.pipe(\n Effect.withSpan(`upload-${operation}`, {\n attributes: {\n \"upload.operation\": operation,\n ...attributes,\n },\n }),\n );\n\n/**\n * Add upload context to the current span\n */\nexport const withUploadContext = (context: {\n uploadId?: string;\n fileName?: string;\n fileSize?: number;\n storageId?: string;\n mimeType?: string;\n}) =>\n Effect.annotateCurrentSpan({\n \"upload.id\": context.uploadId ?? \"unknown\",\n \"upload.file_name\": context.fileName ?? \"unknown\",\n \"upload.file_size\": context.fileSize?.toString() ?? \"0\",\n \"upload.storage_id\": context.storageId ?? \"unknown\",\n \"upload.mime_type\": context.mimeType ?? \"unknown\",\n });\n\n/**\n * Add chunk context to the current span\n */\nexport const withChunkContext = (context: {\n uploadId: string;\n chunkSize: number;\n offset: number;\n totalSize?: number;\n}) =>\n Effect.annotateCurrentSpan({\n \"chunk.upload_id\": context.uploadId,\n \"chunk.size\": context.chunkSize.toString(),\n \"chunk.offset\": context.offset.toString(),\n \"chunk.total_size\": context.totalSize?.toString() ?? \"0\",\n \"chunk.progress\":\n context.totalSize && context.totalSize > 0\n ? ((context.offset / context.totalSize) * 100).toFixed(2)\n : \"0\",\n });\n","import { Effect, Layer, Metric } from \"effect\";\nimport {\n makeUploadObservabilityLayer,\n UploadObservability,\n} from \"../core/layers.js\";\nimport { createUploadServerMetrics } from \"./metrics.js\";\n\n// ============================================================================\n// Upload Observability Layer Implementation\n// ============================================================================\n\n/**\n * Create a live upload observability layer with full metrics\n */\nexport const makeUploadObservabilityLive = (\n serviceName = \"uploadista-upload-server\",\n): Layer.Layer<UploadObservability> => {\n const metrics = createUploadServerMetrics();\n\n return Layer.succeed(UploadObservability, {\n serviceName,\n enabled: true,\n metrics: {\n uploadCreated: Effect.succeed(metrics.uploadCreatedTotal).pipe(\n Effect.flatMap((metric) => Metric.increment(metric)),\n ),\n uploadCompleted: Effect.succeed(metrics.uploadCompletedTotal).pipe(\n Effect.flatMap((metric) => Metric.increment(metric)),\n ),\n uploadFailed: Effect.succeed(metrics.uploadFailedTotal).pipe(\n Effect.flatMap((metric) => Metric.increment(metric)),\n ),\n chunkUploaded: Effect.succeed(metrics.chunkUploadedTotal).pipe(\n Effect.flatMap((metric) => Metric.increment(metric)),\n ),\n },\n });\n};\n\n/**\n * Default live upload observability layer\n */\nexport const UploadObservabilityLive = makeUploadObservabilityLive();\n\n/**\n * No-op upload observability layer (for testing or disabled observability)\n */\nexport const UploadObservabilityDisabled = makeUploadObservabilityLayer(false);\n\n/**\n * Helper to get upload metrics from context\n */\nexport const getUploadMetrics = Effect.gen(function* () {\n const obs = yield* UploadObservability;\n return obs.metrics;\n});\n\n/**\n * Helper to track upload duration\n */\nexport const withUploadDuration = <A, E, R>(\n effect: Effect.Effect<A, E, R>,\n): Effect.Effect<A, E, R | UploadObservability> => {\n const metrics = createUploadServerMetrics();\n return Effect.gen(function* () {\n const startTime = Date.now();\n const result = yield* effect;\n const duration = (Date.now() - startTime) / 1000; // Convert to seconds\n yield* Metric.update(metrics.uploadDurationHistogram, duration);\n return result;\n }).pipe(Effect.withSpan(\"upload-operation\"));\n};\n\n/**\n * Helper to track chunk upload duration\n */\nexport const withChunkDuration = <A, E, R>(\n effect: Effect.Effect<A, E, R>,\n): Effect.Effect<A, E, R> => {\n const metrics = createUploadServerMetrics();\n return Effect.gen(function* () {\n const startTime = Date.now();\n const result = yield* effect;\n const duration = (Date.now() - startTime) / 1000; // Convert to seconds\n yield* Metric.update(metrics.chunkUploadDurationHistogram, duration);\n return result;\n }).pipe(Effect.withSpan(\"chunk-upload\"));\n};\n","import { Effect, Metric } from \"effect\";\nimport type { UploadServerMetrics } from \"./metrics.js\";\n\n// ============================================================================\n// Upload Error Classification and Tracking\n// ============================================================================\n\nexport type UploadErrorCategory =\n | \"network_error\"\n | \"authentication_error\"\n | \"authorization_error\"\n | \"validation_error\"\n | \"size_limit_error\"\n | \"storage_error\"\n | \"abort_error\"\n | \"unknown_error\";\n\n/**\n * Classify upload errors into standard categories\n */\nexport const classifyUploadError = (error: unknown): UploadErrorCategory => {\n if (!error || typeof error !== \"object\") return \"unknown_error\";\n\n const errorCode = \"code\" in error ? error.code : undefined;\n const errorName = \"name\" in error ? error.name : undefined;\n const errorMessage =\n error instanceof Error ? error.message.toLowerCase() : \"\";\n\n // Abort errors\n if (\n errorCode === \"ABORTED\" ||\n errorName === \"AbortError\" ||\n errorMessage.includes(\"abort\")\n ) {\n return \"abort_error\";\n }\n\n // Size limit errors\n if (\n errorCode === \"FILE_TOO_LARGE\" ||\n errorCode === \"LIMIT_FILE_SIZE\" ||\n errorCode === \"RequestEntityTooLarge\" ||\n errorMessage.includes(\"too large\") ||\n errorMessage.includes(\"size limit\") ||\n errorMessage.includes(\"max size\")\n ) {\n return \"size_limit_error\";\n }\n\n // Validation errors\n if (\n errorCode === \"INVALID_FILE\" ||\n errorCode === \"INVALID_METADATA\" ||\n errorCode === \"VALIDATION_ERROR\" ||\n errorMessage.includes(\"validation\") ||\n errorMessage.includes(\"invalid\")\n ) {\n return \"validation_error\";\n }\n\n // Network errors\n if (\n errorCode === \"NetworkError\" ||\n errorCode === \"ECONNRESET\" ||\n errorCode === \"ENOTFOUND\" ||\n errorCode === \"ETIMEDOUT\" ||\n errorMessage.includes(\"network\") ||\n errorMessage.includes(\"timeout\")\n ) {\n return \"network_error\";\n }\n\n // Authentication errors\n if (\n errorCode === \"UNAUTHORIZED\" ||\n errorCode === \"AuthenticationFailed\" ||\n errorName === \"AuthenticationError\" ||\n errorMessage.includes(\"authentication\") ||\n errorMessage.includes(\"unauthorized\")\n ) {\n return \"authentication_error\";\n }\n\n // Authorization errors\n if (\n errorCode === \"FORBIDDEN\" ||\n errorCode === \"AccessDenied\" ||\n errorName === \"AuthorizationError\" ||\n errorMessage.includes(\"forbidden\") ||\n errorMessage.includes(\"permission\")\n ) {\n return \"authorization_error\";\n }\n\n // Storage errors\n if (\n errorCode === \"FILE_WRITE_ERROR\" ||\n errorCode === \"STORAGE_ERROR\" ||\n errorMessage.includes(\"storage\") ||\n errorMessage.includes(\"write error\")\n ) {\n return \"storage_error\";\n }\n\n return \"unknown_error\";\n};\n\n/**\n * Track upload errors with metrics and structured logging\n */\nexport const trackUploadError = (\n metrics: UploadServerMetrics,\n operation: string,\n error: unknown,\n context: Record<string, unknown> = {},\n) =>\n Effect.gen(function* () {\n const errorCategory = classifyUploadError(error);\n\n // Record error metrics\n const errorMetric = metrics.uploadFailedTotal.pipe(\n Metric.tagged(\"operation\", operation),\n Metric.tagged(\"error_category\", errorCategory),\n );\n yield* errorMetric(Effect.succeed(1));\n\n // Create detailed error context\n const errorDetails = {\n operation,\n error_category: errorCategory,\n error_type: typeof error,\n error_message: error instanceof Error ? error.message : String(error),\n error_code:\n error && typeof error === \"object\" && \"code\" in error\n ? String(error.code)\n : undefined,\n error_name:\n error && typeof error === \"object\" && \"name\" in error\n ? String(error.name)\n : undefined,\n ...context,\n };\n\n // Log structured error\n yield* Effect.logError(`Upload ${operation} failed`).pipe(\n Effect.annotateLogs(errorDetails),\n );\n });\n\n/**\n * Create a custom error classifier for upload operations\n */\nexport const createUploadErrorClassifier = (\n customErrorMapping?: (error: unknown) => UploadErrorCategory | null,\n) => {\n return (error: unknown): UploadErrorCategory => {\n // Try custom mapping first\n if (customErrorMapping) {\n const customResult = customErrorMapping(error);\n if (customResult !== null) return customResult;\n }\n\n // Fall back to generic classification\n return classifyUploadError(error);\n };\n};\n","import { Layer } from \"effect\";\nimport { UploadObservability } from \"../core/layers.js\";\nimport { createUploadServerMetrics } from \"./metrics.js\";\n\n// ============================================================================\n// Upload Observability Testing Utilities\n// ============================================================================\n\n/**\n * Create a test upload observability layer that doesn't actually emit metrics\n * but validates that the observability system is wired correctly\n */\nexport const UploadObservabilityTest = Layer.succeed(UploadObservability, {\n serviceName: \"uploadista-upload-server-test\",\n enabled: true,\n metrics: {\n uploadCreated: () => Promise.resolve(),\n uploadCompleted: () => Promise.resolve(),\n uploadFailed: () => Promise.resolve(),\n chunkUploaded: () => Promise.resolve(),\n } as any,\n});\n\n/**\n * Get metrics for validation (useful for testing metric definitions)\n */\nexport const getTestMetrics = () => createUploadServerMetrics();\n\n/**\n * Validate that all required metrics exist\n */\nexport const validateMetricsExist = () => {\n const metrics = getTestMetrics();\n\n const requiredMetrics = [\n \"uploadCreatedTotal\",\n \"uploadCompletedTotal\",\n \"uploadFailedTotal\",\n \"chunkUploadedTotal\",\n \"uploadFromUrlTotal\",\n \"uploadFromUrlSuccessTotal\",\n \"uploadFromUrlFailedTotal\",\n \"uploadDurationHistogram\",\n \"chunkUploadDurationHistogram\",\n \"uploadFileSizeHistogram\",\n \"chunkSizeHistogram\",\n \"activeUploadsGauge\",\n \"uploadThroughputGauge\",\n \"uploadLatencySummary\",\n \"chunkLatencySummary\",\n ];\n\n const missingMetrics = requiredMetrics.filter((name) => !(name in metrics));\n\n if (missingMetrics.length > 0) {\n throw new Error(`Missing required metrics: ${missingMetrics.join(\", \")}`);\n }\n\n return true;\n};\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@uploadista/observability",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.9",
|
|
5
5
|
"description": "Observability package for Uploadista",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"author": "Uploadista",
|
|
@@ -13,20 +13,20 @@
|
|
|
13
13
|
}
|
|
14
14
|
},
|
|
15
15
|
"dependencies": {
|
|
16
|
-
"@effect/opentelemetry": "0.
|
|
17
|
-
"@opentelemetry/sdk-logs": "0.
|
|
18
|
-
"@opentelemetry/sdk-metrics": "2.
|
|
19
|
-
"@opentelemetry/sdk-trace-base": "2.
|
|
20
|
-
"@opentelemetry/sdk-trace-node": "2.
|
|
21
|
-
"@opentelemetry/sdk-trace-web": "2.
|
|
22
|
-
"effect": "3.
|
|
16
|
+
"@effect/opentelemetry": "0.59.0",
|
|
17
|
+
"@opentelemetry/sdk-logs": "0.207.0",
|
|
18
|
+
"@opentelemetry/sdk-metrics": "2.2.0",
|
|
19
|
+
"@opentelemetry/sdk-trace-base": "2.2.0",
|
|
20
|
+
"@opentelemetry/sdk-trace-node": "2.2.0",
|
|
21
|
+
"@opentelemetry/sdk-trace-web": "2.2.0",
|
|
22
|
+
"effect": "3.19.0"
|
|
23
23
|
},
|
|
24
24
|
"devDependencies": {
|
|
25
25
|
"@cloudflare/workers-types": "4.20251014.0",
|
|
26
|
-
"@types/node": "24.
|
|
27
|
-
"tsdown": "0.
|
|
26
|
+
"@types/node": "24.10.0",
|
|
27
|
+
"tsdown": "0.16.0",
|
|
28
28
|
"typescript": "5.9.3",
|
|
29
|
-
"@uploadista/typescript-config": "0.0.
|
|
29
|
+
"@uploadista/typescript-config": "0.0.9"
|
|
30
30
|
},
|
|
31
31
|
"scripts": {
|
|
32
32
|
"build": "tsdown",
|
package/dist/index.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/core/metrics.ts","../src/core/errors.ts","../src/core/layers.ts","../src/core/logging.ts","../src/core/testing.ts","../src/core/tracing.ts","../src/core/utilities.ts","../src/flow/metrics.ts","../src/flow/tracing.ts","../src/flow/layers.ts","../src/flow/errors.ts","../src/flow/testing.ts","../src/service/metrics.ts","../src/storage/s3.ts","../src/storage/azure.ts","../src/storage/gcs.ts","../src/storage/filesystem.ts","../src/upload/metrics.ts","../src/upload/tracing.ts","../src/upload/layers.ts","../src/upload/errors.ts","../src/upload/testing.ts"],"sourcesContent":[],"mappings":"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"}
|
package/dist/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["service: StorageObservabilityService","service: UploadObservabilityService","service: FlowObservabilityService","FlowObservabilityDisabled","makeTestFlowObservability","service: FlowObservabilityService","NoOpMetricsServiceLive: Layer.Layer<MetricsService>","STORAGE_TYPE","STORAGE_TYPE","STORAGE_TYPE","UploadObservabilityDisabled"],"sources":["../src/core/errors.ts","../src/core/layers.ts","../src/core/logging.ts","../src/core/metrics.ts","../src/core/testing.ts","../src/core/tracing.ts","../src/core/utilities.ts","../src/flow/metrics.ts","../src/flow/tracing.ts","../src/flow/layers.ts","../src/flow/errors.ts","../src/flow/testing.ts","../src/service/metrics.ts","../src/storage/s3.ts","../src/storage/azure.ts","../src/storage/gcs.ts","../src/storage/filesystem.ts","../src/upload/metrics.ts","../src/upload/tracing.ts","../src/upload/layers.ts","../src/upload/errors.ts","../src/upload/testing.ts"],"sourcesContent":["import { Effect, Metric } from \"effect\";\nimport type { StorageMetrics } from \"./metrics.js\";\n\n// ============================================================================\n// Generic Storage Error Classification and Tracking\n// ============================================================================\n\nexport type StorageErrorCategory =\n | \"network_error\"\n | \"authentication_error\"\n | \"authorization_error\"\n | \"throttling_error\"\n | \"server_error\"\n | \"client_error\"\n | \"unknown_error\";\n\n// Generic error classifier - can be extended per storage type\nexport const classifyStorageError = (error: unknown): StorageErrorCategory => {\n if (!error || typeof error !== \"object\") return \"unknown_error\";\n\n const errorCode = \"code\" in error ? error.code : undefined;\n const errorName = \"name\" in error ? error.name : undefined;\n const errorMessage =\n error instanceof Error ? error.message.toLowerCase() : \"\";\n\n // Network errors (common across all storage types)\n if (\n errorCode === \"NetworkError\" ||\n errorCode === \"ECONNRESET\" ||\n errorCode === \"ENOTFOUND\" ||\n errorCode === \"ETIMEDOUT\" ||\n errorMessage.indexOf(\"network\") >= 0 ||\n errorMessage.indexOf(\"timeout\") >= 0\n ) {\n return \"network_error\";\n }\n\n // Authentication errors (common patterns)\n if (\n errorCode === \"InvalidAccessKeyId\" ||\n errorCode === \"SignatureDoesNotMatch\" ||\n errorCode === \"TokenRefreshRequired\" ||\n errorCode === \"AuthenticationFailed\" ||\n errorName === \"AuthenticationError\" ||\n errorMessage.indexOf(\"authentication\") >= 0 ||\n errorMessage.indexOf(\"unauthorized\") >= 0\n ) {\n return \"authentication_error\";\n }\n\n // Authorization errors\n if (\n errorCode === \"AccessDenied\" ||\n errorCode === \"AccountProblem\" ||\n errorCode === \"Forbidden\" ||\n errorName === \"AuthorizationError\" ||\n errorMessage.indexOf(\"forbidden\") >= 0 ||\n errorMessage.indexOf(\"permission\") >= 0\n ) {\n return \"authorization_error\";\n }\n\n // Throttling errors\n if (\n errorCode === \"SlowDown\" ||\n errorCode === \"RequestTimeTooSkewed\" ||\n errorCode === \"TooManyRequests\" ||\n errorName === \"ThrottlingError\" ||\n errorMessage.indexOf(\"throttl\") >= 0 ||\n errorMessage.indexOf(\"rate limit\") >= 0\n ) {\n return \"throttling_error\";\n }\n\n // Server errors\n if (\n errorCode === \"InternalError\" ||\n errorCode === \"ServiceUnavailable\" ||\n errorCode === \"InternalServerError\" ||\n errorName === \"ServerError\" ||\n errorMessage.indexOf(\"server error\") >= 0 ||\n errorMessage.indexOf(\"service unavailable\") >= 0\n ) {\n return \"server_error\";\n }\n\n // Client errors\n if (\n errorCode === \"InvalidRequest\" ||\n errorCode === \"MalformedXML\" ||\n errorCode === \"RequestEntityTooLarge\" ||\n errorCode === \"BadRequest\" ||\n errorName === \"ClientError\" ||\n errorMessage.indexOf(\"bad request\") >= 0 ||\n errorMessage.indexOf(\"invalid\") >= 0\n ) {\n return \"client_error\";\n }\n\n return \"unknown_error\";\n};\n\n// Storage-specific error classifier factory\nexport const createStorageErrorClassifier = (\n storageType: string,\n customErrorMapping?: (error: unknown) => StorageErrorCategory | null,\n) => {\n return (error: unknown): StorageErrorCategory => {\n // Try custom mapping first\n if (customErrorMapping) {\n const customResult = customErrorMapping(error);\n if (customResult !== null) return customResult;\n }\n\n // Fall back to generic classification\n return classifyStorageError(error);\n };\n};\n\n// Generic error tracking function\nexport const trackStorageError = (\n storageType: string,\n metrics: StorageMetrics,\n operation: string,\n error: unknown,\n context: Record<string, unknown> = {},\n errorClassifier = classifyStorageError,\n) =>\n Effect.gen(function* () {\n const errorCategory = errorClassifier(error);\n\n // Record error metrics\n const errorMetric = metrics.uploadErrorsTotal.pipe(\n Metric.tagged(\"operation\", operation),\n Metric.tagged(\"error_category\", errorCategory),\n );\n yield* errorMetric(Effect.succeed(1));\n\n // Create detailed error context\n const errorDetails = {\n storage_type: storageType,\n operation,\n error_category: errorCategory,\n error_type: typeof error,\n error_message: error instanceof Error ? error.message : String(error),\n error_code:\n error && typeof error === \"object\" && \"code\" in error\n ? error.code\n : undefined,\n error_name:\n error && typeof error === \"object\" && \"name\" in error\n ? error.name\n : undefined,\n ...context,\n };\n\n // Log structured error\n yield* Effect.logError(\n `${storageType.toUpperCase()} ${operation} failed`,\n ).pipe(Effect.annotateLogs(errorDetails));\n });\n\n// Factory for storage-specific error tracking\nexport const createStorageErrorTracker = (\n storageType: string,\n metrics: StorageMetrics,\n customErrorClassifier?: (error: unknown) => StorageErrorCategory | null,\n) => {\n const errorClassifier = createStorageErrorClassifier(\n storageType,\n customErrorClassifier,\n );\n\n return (\n operation: string,\n error: unknown,\n context: Record<string, unknown> = {},\n ) =>\n trackStorageError(\n storageType,\n metrics,\n operation,\n error,\n context,\n errorClassifier,\n );\n};\n","import { Context, Effect, Layer, Option } from \"effect\";\nimport type { StorageMetrics } from \"./metrics.js\";\n\n// ============================================================================\n// Observability Layer Interfaces\n// ============================================================================\n\n/**\n * Core observability service providing tracing, metrics, and logging capabilities\n */\nexport interface ObservabilityService {\n readonly serviceName: string;\n readonly enabled: boolean;\n}\n\n/**\n * Observability service tag for Effect Context\n */\nexport class Observability extends Context.Tag(\"Observability\")<\n Observability,\n ObservabilityService\n>() {}\n\n/**\n * Storage observability service extending base observability with storage-specific metrics\n */\nexport interface StorageObservabilityService extends ObservabilityService {\n readonly storageType: string;\n readonly metrics: StorageMetrics;\n}\n\n/**\n * Storage observability service tag\n */\nexport class StorageObservability extends Context.Tag(\"StorageObservability\")<\n StorageObservability,\n StorageObservabilityService\n>() {}\n\n/**\n * Upload observability service for upload-specific operations\n */\nexport interface UploadObservabilityService extends ObservabilityService {\n readonly metrics: {\n uploadCreated: Effect.Effect<void>;\n uploadCompleted: Effect.Effect<void>;\n uploadFailed: Effect.Effect<void>;\n chunkUploaded: Effect.Effect<void>;\n };\n}\n\n/**\n * Upload observability service tag\n */\nexport class UploadObservability extends Context.Tag(\"UploadObservability\")<\n UploadObservability,\n UploadObservabilityService\n>() {}\n\n/**\n * Flow observability service for flow execution operations\n */\nexport interface FlowObservabilityService extends ObservabilityService {\n readonly metrics: {\n flowStarted: Effect.Effect<void>;\n flowCompleted: Effect.Effect<void>;\n flowFailed: Effect.Effect<void>;\n nodeExecuted: Effect.Effect<void>;\n };\n}\n\n/**\n * Flow observability service tag\n */\nexport class FlowObservability extends Context.Tag(\"FlowObservability\")<\n FlowObservability,\n FlowObservabilityService\n>() {}\n\n// ============================================================================\n// Layer Factories\n// ============================================================================\n\n/**\n * Create a base observability layer\n */\nexport const makeObservabilityLayer = (\n serviceName: string,\n enabled = true,\n): Layer.Layer<Observability> =>\n Layer.succeed(Observability, {\n serviceName,\n enabled,\n });\n\n/**\n * Create a storage observability layer\n */\nexport const makeStorageObservabilityLayer = (\n storageType: string,\n metrics: StorageMetrics,\n enabled = true,\n): Layer.Layer<StorageObservability> =>\n Layer.succeed(StorageObservability, {\n serviceName: `uploadista-${storageType}-store`,\n storageType,\n metrics,\n enabled,\n });\n\n/**\n * Create an upload observability layer\n */\nexport const makeUploadObservabilityLayer = (\n enabled = true,\n): Layer.Layer<UploadObservability> =>\n Layer.succeed(UploadObservability, {\n serviceName: \"uploadista-upload-server\",\n enabled,\n metrics: {\n uploadCreated: Effect.void,\n uploadCompleted: Effect.void,\n uploadFailed: Effect.void,\n chunkUploaded: Effect.void,\n },\n });\n\n/**\n * Create a flow observability layer\n */\nexport const makeFlowObservabilityLayer = (\n enabled = true,\n): Layer.Layer<FlowObservability> =>\n Layer.succeed(FlowObservability, {\n serviceName: \"uploadista-flow-engine\",\n enabled,\n metrics: {\n flowStarted: Effect.void,\n flowCompleted: Effect.void,\n flowFailed: Effect.void,\n nodeExecuted: Effect.void,\n },\n });\n\n// ============================================================================\n// No-op Layers (for testing and opt-out)\n// ============================================================================\n\n/**\n * No-op observability layer (disabled)\n */\nexport const ObservabilityDisabled = makeObservabilityLayer(\n \"uploadista-disabled\",\n false,\n);\n\n/**\n * No-op storage observability layer\n */\nexport const StorageObservabilityDisabled = (storageType: string) =>\n makeStorageObservabilityLayer(\n storageType,\n {} as StorageMetrics, // No-op metrics\n false,\n );\n\n/**\n * No-op upload observability layer\n */\nexport const UploadObservabilityDisabled = makeUploadObservabilityLayer(false);\n\n/**\n * No-op flow observability layer\n */\nexport const FlowObservabilityDisabled = makeFlowObservabilityLayer(false);\n\n// ============================================================================\n// Helper Functions\n// ============================================================================\n\n/**\n * Check if observability is enabled in the current context\n */\nexport const isObservabilityEnabled = Effect.gen(function* () {\n const observability = yield* Effect.serviceOption(Observability);\n return Option.match(observability, {\n onNone: () => false,\n onSome: (obs) => obs.enabled,\n });\n});\n\n/**\n * Execute an effect only if observability is enabled\n */\nexport const whenObservabilityEnabled = <A, E, R>(\n effect: Effect.Effect<A, E, R>,\n): Effect.Effect<Option.Option<A>, E, R | Observability> =>\n Effect.gen(function* () {\n const enabled = yield* isObservabilityEnabled;\n if (enabled) {\n const result = yield* effect;\n return Option.some(result);\n }\n return Option.none();\n });\n","import { Effect } from \"effect\";\n\n// ============================================================================\n// Enhanced Logging Helpers (Storage-agnostic)\n// ============================================================================\n\nexport const logWithContext = (\n message: string,\n context: Record<string, unknown>,\n) => Effect.log(message).pipe(Effect.annotateLogs(context));\n\nexport const logUploadProgress = (\n storageType: string,\n uploadId: string,\n progress: {\n uploadedBytes: number;\n totalBytes: number;\n partNumber?: number;\n speed?: number;\n },\n) =>\n logWithContext(\"Upload progress\", {\n storage_type: storageType,\n upload_id: uploadId,\n uploaded_bytes: progress.uploadedBytes,\n total_bytes: progress.totalBytes,\n progress_percentage: Math.round(\n (progress.uploadedBytes / progress.totalBytes) * 100,\n ),\n ...(progress.partNumber && { part_number: progress.partNumber }),\n ...(progress.speed && { upload_speed_bps: progress.speed }),\n });\n\nexport const logStorageOperation = (\n storageType: string,\n operation: string,\n uploadId: string,\n metadata?: Record<string, unknown>,\n) =>\n logWithContext(`${storageType.toUpperCase()} ${operation}`, {\n storage_type: storageType,\n operation,\n upload_id: uploadId,\n ...metadata,\n });\n\nexport const logUploadCompletion = (\n storageType: string,\n uploadId: string,\n metrics: {\n fileSize: number;\n totalDurationMs: number;\n partsCount?: number;\n averagePartSize?: number;\n throughputBps?: number;\n retryCount?: number;\n },\n) => {\n const throughputMBps = metrics.throughputBps\n ? metrics.throughputBps / (1024 * 1024)\n : 0;\n\n return logWithContext(`${storageType.toUpperCase()} upload completed`, {\n storage_type: storageType,\n upload_id: uploadId,\n file_size_bytes: metrics.fileSize,\n file_size_mb: Math.round((metrics.fileSize / (1024 * 1024)) * 100) / 100,\n total_duration_ms: metrics.totalDurationMs,\n total_duration_seconds:\n Math.round((metrics.totalDurationMs / 1000) * 100) / 100,\n throughput_bps: metrics.throughputBps,\n throughput_mbps: Math.round(throughputMBps * 100) / 100,\n ...(metrics.partsCount && { parts_count: metrics.partsCount }),\n ...(metrics.averagePartSize && {\n average_part_size_bytes: metrics.averagePartSize,\n average_part_size_mb:\n Math.round((metrics.averagePartSize / (1024 * 1024)) * 100) / 100,\n }),\n ...(metrics.retryCount && { retry_count: metrics.retryCount }),\n });\n};\n","import { Metric, MetricBoundaries } from \"effect\";\n\n// ============================================================================\n// Core Storage Metrics (reusable across all storage types)\n// ============================================================================\n\n// Counter metrics\nexport const createUploadMetrics = (storageType: string) => ({\n uploadRequestsTotal: Metric.counter(`${storageType}_upload_requests_total`, {\n description: `Total number of upload requests for ${storageType}`,\n }),\n\n uploadPartsTotal: Metric.counter(`${storageType}_upload_parts_total`, {\n description: `Total number of individual parts uploaded for ${storageType}`,\n }),\n\n uploadSuccessTotal: Metric.counter(`${storageType}_upload_success_total`, {\n description: `Total number of successful uploads for ${storageType}`,\n }),\n\n uploadErrorsTotal: Metric.counter(`${storageType}_upload_errors_total`, {\n description: `Total number of upload errors for ${storageType}`,\n }),\n\n apiCallsTotal: Metric.counter(`${storageType}_api_calls_total`, {\n description: `Total number of API calls for ${storageType}`,\n }),\n});\n\n// Histogram metrics for timing and sizes (reusable)\nexport const createUploadHistograms = (storageType: string) => ({\n uploadDurationHistogram: Metric.histogram(\n `${storageType}_upload_duration_seconds`,\n MetricBoundaries.exponential({\n start: 0.01, // 10ms\n factor: 2,\n count: 20, // Up to ~10 seconds\n }),\n `Duration of upload operations in seconds for ${storageType}`,\n ),\n\n partUploadDurationHistogram: Metric.histogram(\n `${storageType}_part_upload_duration_seconds`,\n MetricBoundaries.exponential({\n start: 0.001, // 1ms\n factor: 2,\n count: 15, // Up to ~32 seconds\n }),\n `Duration of individual part uploads in seconds for ${storageType}`,\n ),\n\n fileSizeHistogram: Metric.histogram(\n `${storageType}_file_size_bytes`,\n MetricBoundaries.exponential({\n start: 1024, // 1KB\n factor: 2,\n count: 25, // Up to ~33GB\n }),\n `Size of uploaded files in bytes for ${storageType}`,\n ),\n\n partSizeHistogram: Metric.histogram(\n `${storageType}_part_size_bytes`,\n MetricBoundaries.linear({\n start: 5_242_880, // 5MB (minimum part size)\n width: 1_048_576, // 1MB increments\n count: 20, // Up to ~25MB\n }),\n `Size of upload parts in bytes for ${storageType}`,\n ),\n});\n\n// Gauge metrics for current state (reusable)\nexport const createUploadGauges = (storageType: string) => ({\n activeUploadsGauge: Metric.gauge(`${storageType}_active_uploads`, {\n description: `Number of currently active uploads for ${storageType}`,\n }),\n\n uploadThroughputGauge: Metric.gauge(\n `${storageType}_upload_throughput_bytes_per_second`,\n {\n description: `Current upload throughput in bytes per second for ${storageType}`,\n },\n ),\n});\n\n// Summary metrics for percentiles (reusable)\nexport const createUploadSummaries = (storageType: string) => ({\n uploadLatencySummary: Metric.summary({\n name: `${storageType}_upload_latency_seconds`,\n maxAge: \"10 minutes\",\n maxSize: 1000,\n error: 0.01,\n quantiles: [0.5, 0.9, 0.95, 0.99],\n description: `Upload latency percentiles for ${storageType}`,\n }),\n});\n\n// Combined metrics factory\nexport const createStorageMetrics = (storageType: string) => ({\n ...createUploadMetrics(storageType),\n ...createUploadHistograms(storageType),\n ...createUploadGauges(storageType),\n ...createUploadSummaries(storageType),\n});\n\n// Type for storage metrics\nexport type StorageMetrics = ReturnType<typeof createStorageMetrics>;\n","import { Effect, Layer, Metric } from \"effect\";\nimport type {\n FlowObservabilityService,\n StorageObservabilityService,\n UploadObservabilityService,\n} from \"./layers.js\";\nimport {\n FlowObservability,\n StorageObservability,\n UploadObservability,\n} from \"./layers.js\";\nimport { createStorageMetrics } from \"./metrics.js\";\n\n// ============================================================================\n// Test Observability Layers\n// ============================================================================\n\n/**\n * Mock storage observability for testing\n */\nexport const makeTestStorageObservability = (\n storageType: string,\n): Layer.Layer<StorageObservability> => {\n const metrics = createStorageMetrics(storageType);\n const service: StorageObservabilityService = {\n serviceName: `test-${storageType}-store`,\n storageType,\n metrics,\n enabled: true,\n };\n return Layer.succeed(StorageObservability, service);\n};\n\n/**\n * Mock upload observability for testing\n */\nexport const makeTestUploadObservability =\n (): Layer.Layer<UploadObservability> => {\n const service: UploadObservabilityService = {\n serviceName: \"test-upload-server\",\n enabled: true,\n metrics: {\n uploadCreated: Effect.void,\n uploadCompleted: Effect.void,\n uploadFailed: Effect.void,\n chunkUploaded: Effect.void,\n },\n };\n return Layer.succeed(UploadObservability, service);\n };\n\n/**\n * Mock flow observability for testing\n */\nexport const makeTestFlowObservability = (): Layer.Layer<FlowObservability> => {\n const service: FlowObservabilityService = {\n serviceName: \"test-flow-engine\",\n enabled: true,\n metrics: {\n flowStarted: Effect.void,\n flowCompleted: Effect.void,\n flowFailed: Effect.void,\n nodeExecuted: Effect.void,\n },\n };\n return Layer.succeed(FlowObservability, service);\n};\n\n// ============================================================================\n// Test Utilities\n// ============================================================================\n\n/**\n * Capture metrics snapshot from an effect for testing\n * Note: Metric snapshots are simplified - for full metric testing,\n * use Effect's built-in metric testing utilities\n */\nexport const captureMetrics = <A, E, R>(\n effect: Effect.Effect<A, E, R>,\n): Effect.Effect<A, E, R> =>\n Effect.gen(function* () {\n const result = yield* effect;\n // Metrics are automatically captured by Effect runtime\n yield* Metric.snapshot;\n return result;\n });\n\n/**\n * Test helper to capture metrics around effect execution\n * This is a simplified version - for production testing,\n * use Effect's metric testing utilities\n */\nexport const withMetricTracking = <A, E, R>(\n effect: Effect.Effect<A, E, R>,\n): Effect.Effect<A, E, R> =>\n Effect.gen(function* () {\n // Track metric before execution\n yield* Metric.snapshot;\n const result = yield* effect;\n // Track metric after execution\n yield* Metric.snapshot;\n return result;\n });\n\n/**\n * Test fixture for observability testing\n */\nexport interface ObservabilityTestFixture {\n readonly storageObservability: Layer.Layer<StorageObservability>;\n readonly uploadObservability: Layer.Layer<UploadObservability>;\n readonly flowObservability: Layer.Layer<FlowObservability>;\n}\n\n/**\n * Create a complete test fixture with all observability layers\n */\nexport const createTestFixture = (\n storageType = \"test-storage\",\n): ObservabilityTestFixture => ({\n storageObservability: makeTestStorageObservability(storageType),\n uploadObservability: makeTestUploadObservability(),\n flowObservability: makeTestFlowObservability(),\n});\n\n/**\n * Run an effect with test observability layers\n */\nexport const runWithTestObservability = <A, E>(\n effect: Effect.Effect<\n A,\n E,\n StorageObservability | UploadObservability | FlowObservability\n >,\n storageType = \"test-storage\",\n): Effect.Effect<A, E> => {\n const fixture = createTestFixture(storageType);\n return effect.pipe(\n Effect.provide(fixture.storageObservability),\n Effect.provide(fixture.uploadObservability),\n Effect.provide(fixture.flowObservability),\n );\n};\n","import { NodeSdk, WebSdk } from \"@effect/opentelemetry\";\nimport {\n BatchSpanProcessor,\n ConsoleSpanExporter,\n} from \"@opentelemetry/sdk-trace-base\";\nimport { Context, Effect, Layer } from \"effect\";\n\n// ============================================================================\n// Universal Tracing (Environment-agnostic)\n// ============================================================================\n\n// Generic service tag for tracing context\nexport const TracingService = Context.GenericTag<{ serviceName: string }>(\n \"TracingService\",\n);\n\n// Create a tracing layer using Effect's native tracing (works in all environments)\nexport const createTracingLayer = (options?: { serviceName?: string }) => {\n const serviceName = options?.serviceName ?? \"uploadista-storage\";\n\n // Return a layer that provides tracing service context\n return Layer.succeed(TracingService, { serviceName });\n};\n\n// Storage-specific tracing layers\nexport const createStorageTracingLayer = (storageType: string) =>\n createTracingLayer({\n serviceName: `uploadista-${storageType}-store`,\n });\n\n// Utility to add storage context to spans\nexport const withStorageSpan =\n <A, E, R>(\n operation: string,\n storageType: string,\n attributes?: Record<string, unknown>,\n ) =>\n (effect: Effect.Effect<A, E, R>) =>\n effect.pipe(\n Effect.withSpan(`${storageType}-${operation}`, {\n attributes: {\n \"storage.type\": storageType,\n operation: operation,\n ...attributes,\n },\n }),\n );\n\n// Set up tracing with the OpenTelemetry SDK\nexport const WebSdkLive = WebSdk.layer(() => ({\n resource: { serviceName: \"uploadista-storage\" },\n // Export span data to the console\n spanProcessor: new BatchSpanProcessor(new ConsoleSpanExporter()),\n}));\n\nexport const NodeSdkLive = NodeSdk.layer(() => ({\n resource: { serviceName: \"uploadista-storage\" },\n // Export span data to the console\n spanProcessor: new BatchSpanProcessor(new ConsoleSpanExporter()),\n}));\n\n// Cloudflare Workers SDK (uses WebSdk as base)\nexport const WorkersSdkLive = WebSdk.layer(() => ({\n resource: { serviceName: \"uploadista-storage-workers\" },\n // Export span data to the console in Workers environment\n spanProcessor: new BatchSpanProcessor(new ConsoleSpanExporter()),\n}));\n","import { Effect, Metric } from \"effect\";\nimport type { StorageMetrics } from \"./metrics.js\";\n\n// ============================================================================\n// Storage Observability Utility Functions\n// ============================================================================\n\n// Generic upload metrics wrapper\nexport const withUploadMetrics = <A, E, R>(\n metrics: StorageMetrics,\n uploadId: string,\n effect: Effect.Effect<A, E, R>,\n): Effect.Effect<A, E, R> =>\n effect.pipe(\n Effect.tap(() =>\n metrics.uploadRequestsTotal.pipe(Metric.tagged(\"upload_id\", uploadId))(\n Effect.succeed(1),\n ),\n ),\n Effect.tapError(() =>\n metrics.uploadErrorsTotal.pipe(Metric.tagged(\"upload_id\", uploadId))(\n Effect.succeed(1),\n ),\n ),\n Effect.tap(() =>\n metrics.uploadSuccessTotal.pipe(Metric.tagged(\"upload_id\", uploadId))(\n Effect.succeed(1),\n ),\n ),\n );\n\n// Generic API call metrics wrapper\nexport const withApiMetrics = <A, E, R>(\n metrics: StorageMetrics,\n operation: string,\n effect: Effect.Effect<A, E, R>,\n): Effect.Effect<A, E, R> =>\n effect.pipe(\n Effect.tap(() =>\n metrics.apiCallsTotal.pipe(Metric.tagged(\"operation\", operation))(\n Effect.succeed(1),\n ),\n ),\n );\n\n// Generic timing metrics wrapper\nexport const withTimingMetrics = <A, E, R>(\n metric: Metric.Metric.Histogram<number>,\n effect: Effect.Effect<A, E, R>,\n): Effect.Effect<A, E, R> =>\n Effect.gen(function* () {\n const startTime = yield* Effect.sync(() => Date.now());\n const result = yield* effect;\n const endTime = yield* Effect.sync(() => Date.now());\n const duration = (endTime - startTime) / 1000; // Convert to seconds\n\n yield* metric(Effect.succeed(duration));\n\n return result;\n });\n\n// File size tracking\nexport const trackFileSize = <A, E, R>(\n metrics: StorageMetrics,\n fileSize: number,\n effect: Effect.Effect<A, E, R>,\n): Effect.Effect<A, E, R> =>\n effect.pipe(\n Effect.tap(() => metrics.fileSizeHistogram(Effect.succeed(fileSize))),\n );\n\n// Part size tracking\nexport const trackPartSize = <A, E, R>(\n metrics: StorageMetrics,\n partSize: number,\n effect: Effect.Effect<A, E, R>,\n): Effect.Effect<A, E, R> =>\n effect.pipe(\n Effect.tap(() => metrics.partSizeHistogram(Effect.succeed(partSize))),\n );\n\n// Active uploads tracking\nexport const withActiveUploadTracking = <A, E, R>(\n metrics: StorageMetrics,\n effect: Effect.Effect<A, E, R>,\n): Effect.Effect<A, E, R> =>\n effect.pipe(\n Effect.tap(() => metrics.activeUploadsGauge(Effect.succeed(1))),\n Effect.ensuring(metrics.activeUploadsGauge(Effect.succeed(-1))),\n );\n\n// Throughput calculation and tracking\nexport const withThroughputTracking = <A, E, R>(\n metrics: StorageMetrics,\n bytes: number,\n effect: Effect.Effect<A, E, R>,\n): Effect.Effect<A, E, R> =>\n Effect.gen(function* () {\n const startTime = yield* Effect.sync(() => Date.now());\n const result = yield* effect;\n const endTime = yield* Effect.sync(() => Date.now());\n const durationSeconds = (endTime - startTime) / 1000;\n const throughputBps = durationSeconds > 0 ? bytes / durationSeconds : 0;\n\n yield* metrics.uploadThroughputGauge(Effect.succeed(throughputBps));\n\n return result;\n });\n\n// Combined metrics wrapper for common upload operations\nexport const withStorageOperationMetrics = <A, E, R>(\n metrics: StorageMetrics,\n operation: string,\n uploadId: string,\n effect: Effect.Effect<A, E, R>,\n fileSize?: number,\n): Effect.Effect<A, E, R> => {\n let wrappedEffect = effect.pipe(\n (eff) => withApiMetrics(metrics, operation, eff),\n (eff) => withUploadMetrics(metrics, uploadId, eff),\n (eff) => withTimingMetrics(metrics.uploadDurationHistogram, eff),\n (eff) => withActiveUploadTracking(metrics, eff),\n );\n\n if (fileSize !== undefined) {\n wrappedEffect = wrappedEffect.pipe(\n (eff) => trackFileSize(metrics, fileSize, eff),\n (eff) => withThroughputTracking(metrics, fileSize, eff),\n );\n }\n\n return wrappedEffect;\n};\n","import { Metric, MetricBoundaries } from \"effect\";\n\n// ============================================================================\n// Flow Engine Metrics\n// ============================================================================\n\n/**\n * Flow engine metrics for tracking flow execution operations\n */\nexport const createFlowMetrics = () => ({\n // Counter metrics\n flowStartedTotal: Metric.counter(\"flow_started_total\", {\n description: \"Total number of flows started\",\n }),\n\n flowCompletedTotal: Metric.counter(\"flow_completed_total\", {\n description: \"Total number of flows completed successfully\",\n }),\n\n flowFailedTotal: Metric.counter(\"flow_failed_total\", {\n description: \"Total number of flows that failed\",\n }),\n\n flowPausedTotal: Metric.counter(\"flow_paused_total\", {\n description: \"Total number of flows that were paused\",\n }),\n\n flowResumedTotal: Metric.counter(\"flow_resumed_total\", {\n description: \"Total number of flows that were resumed\",\n }),\n\n nodeExecutedTotal: Metric.counter(\"node_executed_total\", {\n description: \"Total number of nodes executed\",\n }),\n\n nodeSuccessTotal: Metric.counter(\"node_success_total\", {\n description: \"Total number of nodes executed successfully\",\n }),\n\n nodeFailedTotal: Metric.counter(\"node_failed_total\", {\n description: \"Total number of nodes that failed\",\n }),\n\n nodeSkippedTotal: Metric.counter(\"node_skipped_total\", {\n description: \"Total number of nodes skipped (conditional)\",\n }),\n\n // Histogram metrics\n flowDurationHistogram: Metric.histogram(\n \"flow_duration_seconds\",\n MetricBoundaries.exponential({\n start: 0.1, // 100ms\n factor: 2,\n count: 20, // Up to ~100 seconds\n }),\n \"Duration of complete flow execution in seconds\",\n ),\n\n nodeDurationHistogram: Metric.histogram(\n \"node_duration_seconds\",\n MetricBoundaries.exponential({\n start: 0.01, // 10ms\n factor: 2,\n count: 18, // Up to ~26 seconds\n }),\n \"Duration of individual node execution in seconds\",\n ),\n\n flowNodeCountHistogram: Metric.histogram(\n \"flow_node_count\",\n MetricBoundaries.linear({\n start: 1,\n width: 5,\n count: 20, // Up to 100 nodes\n }),\n \"Number of nodes in a flow\",\n ),\n\n parallelNodesHistogram: Metric.histogram(\n \"parallel_nodes_count\",\n MetricBoundaries.linear({\n start: 1,\n width: 2,\n count: 15, // Up to 30 parallel nodes\n }),\n \"Number of nodes executed in parallel\",\n ),\n\n // Gauge metrics\n activeFlowsGauge: Metric.gauge(\"active_flows\", {\n description: \"Number of currently active flows\",\n }),\n\n activeNodesGauge: Metric.gauge(\"active_nodes\", {\n description: \"Number of currently executing nodes\",\n }),\n\n pausedFlowsGauge: Metric.gauge(\"paused_flows\", {\n description: \"Number of currently paused flows\",\n }),\n\n // Summary metrics for latency percentiles\n flowLatencySummary: Metric.summary({\n name: \"flow_latency_seconds\",\n maxAge: \"10 minutes\",\n maxSize: 1000,\n error: 0.01,\n quantiles: [0.5, 0.9, 0.95, 0.99],\n description: \"Flow execution latency percentiles\",\n }),\n\n nodeLatencySummary: Metric.summary({\n name: \"node_latency_seconds\",\n maxAge: \"10 minutes\",\n maxSize: 1000,\n error: 0.01,\n quantiles: [0.5, 0.9, 0.95, 0.99],\n description: \"Node execution latency percentiles\",\n }),\n});\n\n/**\n * Type for flow metrics\n */\nexport type FlowMetrics = ReturnType<typeof createFlowMetrics>;\n\n/**\n * Default flow metrics instance\n */\nexport const flowMetrics = createFlowMetrics();\n","import { Effect } from \"effect\";\n\n// ============================================================================\n// Flow Tracing Utilities\n// ============================================================================\n\n/**\n * Wrap an Effect with a flow operation span\n */\nexport const withFlowSpan =\n <A, E, R>(operation: string, attributes?: Record<string, unknown>) =>\n (effect: Effect.Effect<A, E, R>): Effect.Effect<A, E, R> =>\n effect.pipe(\n Effect.withSpan(`flow-${operation}`, {\n attributes: {\n \"flow.operation\": operation,\n ...attributes,\n },\n }),\n );\n\n/**\n * Add flow context to the current span\n */\nexport const withFlowContext = (context: {\n flowId?: string;\n flowName?: string;\n jobId?: string;\n nodeCount?: number;\n storageId?: string;\n}) =>\n Effect.annotateCurrentSpan({\n \"flow.id\": context.flowId ?? \"unknown\",\n \"flow.name\": context.flowName ?? \"unknown\",\n \"flow.job_id\": context.jobId ?? \"unknown\",\n \"flow.node_count\": context.nodeCount?.toString() ?? \"0\",\n \"flow.storage_id\": context.storageId ?? \"unknown\",\n });\n\n/**\n * Add node context to the current span\n */\nexport const withNodeContext = (context: {\n nodeId: string;\n nodeType: string;\n nodeName?: string;\n flowId?: string;\n jobId?: string;\n}) =>\n Effect.annotateCurrentSpan({\n \"node.id\": context.nodeId,\n \"node.type\": context.nodeType,\n \"node.name\": context.nodeName ?? \"unknown\",\n \"node.flow_id\": context.flowId ?? \"unknown\",\n \"node.job_id\": context.jobId ?? \"unknown\",\n });\n\n/**\n * Add execution state context to the current span\n */\nexport const withExecutionContext = (context: {\n executionOrder?: string[];\n currentIndex?: number;\n totalNodes?: number;\n parallelCount?: number;\n}) =>\n Effect.annotateCurrentSpan({\n \"execution.order\": context.executionOrder?.join(\",\") ?? \"\",\n \"execution.current_index\": context.currentIndex?.toString() ?? \"0\",\n \"execution.total_nodes\": context.totalNodes?.toString() ?? \"0\",\n \"execution.parallel_count\": context.parallelCount?.toString() ?? \"0\",\n });\n","import { Effect, Layer, Metric } from \"effect\";\nimport {\n FlowObservability,\n makeFlowObservabilityLayer,\n} from \"../core/layers.js\";\nimport { createFlowMetrics, type FlowMetrics } from \"./metrics.js\";\n\n// ============================================================================\n// Flow Observability Layer Implementation\n// ============================================================================\n\n/**\n * Create a live flow observability layer with full metrics\n */\nexport const makeFlowObservabilityLive = (\n serviceName = \"uploadista-flow-engine\",\n): Layer.Layer<FlowObservability> => {\n const metrics = createFlowMetrics();\n\n return Layer.succeed(FlowObservability, {\n serviceName,\n enabled: true,\n metrics: {\n flowStarted: Metric.increment(metrics.flowStartedTotal),\n flowCompleted: Metric.increment(metrics.flowCompletedTotal),\n flowFailed: Metric.increment(metrics.flowFailedTotal),\n nodeExecuted: Metric.increment(metrics.nodeExecutedTotal),\n },\n });\n};\n\n/**\n * Default live flow observability layer\n */\nexport const FlowObservabilityLive = makeFlowObservabilityLive();\n\n/**\n * No-op flow observability layer (for testing or disabled observability)\n */\nexport const FlowObservabilityDisabled = makeFlowObservabilityLayer(false);\n\n/**\n * Helper to get flow metrics from context\n */\nexport const getFlowMetrics = Effect.gen(function* () {\n const obs = yield* FlowObservability;\n return obs.metrics;\n});\n\n/**\n * Helper to track flow duration\n */\nexport const withFlowDuration = <A, E, R>(\n effect: Effect.Effect<A, E, R>,\n): Effect.Effect<A, E, R> => {\n const metrics = createFlowMetrics();\n return Effect.gen(function* () {\n const startTime = Date.now();\n const result = yield* effect;\n const duration = (Date.now() - startTime) / 1000; // Convert to seconds\n yield* Metric.update(metrics.flowDurationHistogram, duration);\n yield* Metric.update(metrics.flowLatencySummary, duration);\n return result;\n }).pipe(Effect.withSpan(\"flow-execution\"));\n};\n\n/**\n * Helper to track node duration\n */\nexport const withNodeDuration = <A, E, R>(\n nodeId: string,\n nodeType: string,\n effect: Effect.Effect<A, E, R>,\n): Effect.Effect<A, E, R> => {\n const metrics = createFlowMetrics();\n return Effect.gen(function* () {\n const startTime = Date.now();\n const result = yield* effect;\n const duration = (Date.now() - startTime) / 1000; // Convert to seconds\n yield* Metric.update(metrics.nodeDurationHistogram, duration);\n yield* Metric.update(metrics.nodeLatencySummary, duration);\n return result;\n }).pipe(\n Effect.withSpan(`node-${nodeType}`, {\n attributes: {\n \"node.id\": nodeId,\n \"node.type\": nodeType,\n },\n }),\n );\n};\n\n/**\n * Helper to track active flows\n */\nexport const trackActiveFlow = <A, E, R>(\n effect: Effect.Effect<A, E, R>,\n): Effect.Effect<A, E, R> => {\n const metrics = createFlowMetrics();\n return Effect.gen(function* () {\n // Increment active flows\n yield* Metric.increment(metrics.activeFlowsGauge);\n\n // Use acquireUseRelease for proper cleanup\n return yield* Effect.acquireUseRelease(\n Effect.void,\n () => effect,\n () => Metric.set(metrics.activeFlowsGauge, -1),\n );\n });\n};\n\n/**\n * Helper to track active nodes\n */\nexport const trackActiveNode = <A, E, R>(\n effect: Effect.Effect<A, E, R>,\n): Effect.Effect<A, E, R> => {\n const metrics = createFlowMetrics();\n return Effect.gen(function* () {\n // Increment active nodes\n yield* Metric.increment(metrics.activeNodesGauge);\n\n // Use acquireUseRelease for proper cleanup\n return yield* Effect.acquireUseRelease(\n Effect.void,\n () => effect,\n () => Metric.set(metrics.activeNodesGauge, -1),\n );\n });\n};\n","import { Effect, Metric } from \"effect\";\nimport { createFlowMetrics } from \"./metrics.js\";\n\n// ============================================================================\n// Flow Error Classification\n// ============================================================================\n\nexport type FlowErrorCategory =\n | \"flow_validation_error\"\n | \"node_execution_error\"\n | \"node_not_found_error\"\n | \"flow_timeout_error\"\n | \"flow_cancelled_error\"\n | \"unknown_flow_error\";\n\n/**\n * Classify flow execution errors\n */\nexport const classifyFlowError = (error: unknown): FlowErrorCategory => {\n if (!error || typeof error !== \"object\") return \"unknown_flow_error\";\n\n const errorCode = \"code\" in error ? error.code : undefined;\n if (!errorCode) return \"unknown_flow_error\";\n\n // Flow-specific error codes\n switch (errorCode) {\n case \"FLOW_VALIDATION_ERROR\":\n case \"FLOW_INVALID_INPUT\":\n case \"FLOW_INVALID_OUTPUT\":\n return \"flow_validation_error\";\n case \"FLOW_NODE_NOT_FOUND\":\n case \"FLOW_EDGE_INVALID\":\n return \"node_not_found_error\";\n case \"FLOW_NODE_EXECUTION_FAILED\":\n case \"FLOW_NODE_ERROR\":\n return \"node_execution_error\";\n case \"FLOW_TIMEOUT\":\n return \"flow_timeout_error\";\n case \"FLOW_CANCELLED\":\n case \"ABORTED\":\n return \"flow_cancelled_error\";\n default:\n return \"unknown_flow_error\";\n }\n};\n\n/**\n * Track flow errors with classification\n */\nexport const trackFlowError = <E>(\n error: E,\n): Effect.Effect<void, never, never> => {\n const metrics = createFlowMetrics();\n const category = classifyFlowError(error);\n\n return Effect.gen(function* () {\n // Increment total failed flows\n yield* Metric.increment(metrics.flowFailedTotal);\n\n // Log error with classification\n yield* Effect.logError(\"Flow execution failed\").pipe(\n Effect.annotateLogs({\n \"error.category\": category,\n \"error.message\": String(error),\n }),\n );\n });\n};\n\n/**\n * Track node errors with classification\n */\nexport const trackNodeError = <E>(\n nodeId: string,\n nodeType: string,\n error: E,\n): Effect.Effect<void, never, never> => {\n const metrics = createFlowMetrics();\n const category = classifyFlowError(error);\n\n return Effect.gen(function* () {\n // Increment node failed counter\n yield* Metric.increment(metrics.nodeFailedTotal);\n\n // Log error with node context\n yield* Effect.logError(\"Node execution failed\").pipe(\n Effect.annotateLogs({\n \"node.id\": nodeId,\n \"node.type\": nodeType,\n \"error.category\": category,\n \"error.message\": String(error),\n }),\n );\n });\n};\n","import { Effect, Layer } from \"effect\";\nimport { FlowObservability } from \"../core/layers.js\";\nimport type { FlowObservabilityService } from \"../core/layers.js\";\n\n// ============================================================================\n// Test Flow Observability Layers\n// ============================================================================\n\n/**\n * Mock flow observability for testing\n */\nexport const makeTestFlowObservability = (): Layer.Layer<FlowObservability> => {\n const service: FlowObservabilityService = {\n serviceName: \"test-flow-engine\",\n enabled: true,\n metrics: {\n flowStarted: Effect.void,\n flowCompleted: Effect.void,\n flowFailed: Effect.void,\n nodeExecuted: Effect.void,\n },\n };\n return Layer.succeed(FlowObservability, service);\n};\n\n/**\n * Run an effect with test flow observability\n */\nexport const runWithTestFlowObservability = <A, E>(\n effect: Effect.Effect<A, E, FlowObservability>,\n): Effect.Effect<A, E> => {\n return effect.pipe(Effect.provide(makeTestFlowObservability()));\n};\n","import { Context, Effect, Layer } from \"effect\";\n\n/**\n * Metrics Recording Service\n *\n * Provides access to metrics recording functionality throughout\n * the upload and flow processing pipeline. The service is provided\n * via Effect Layer and can be accessed using Effect.service().\n */\nexport class MetricsService extends Context.Tag(\"MetricsService\")<\n MetricsService,\n {\n /**\n * Record upload metrics for an organization\n */\n readonly recordUpload: (\n clientId: string,\n bytes: number,\n metadata?: Record<string, unknown>,\n ) => Effect.Effect<void, never>;\n }\n>() {}\n\n/**\n * No-op implementation of MetricsService that does nothing.\n * Used when metrics are disabled or database is not available.\n */\nexport const NoOpMetricsServiceLive: Layer.Layer<MetricsService> =\n Layer.succeed(MetricsService, {\n recordUpload: (_organizationId: string, _bytes: number) => Effect.void,\n });\n","import { type Effect, Layer } from \"effect\";\nimport {\n createStorageErrorTracker,\n type StorageErrorCategory,\n} from \"../core/errors.js\";\nimport {\n logStorageOperation,\n logUploadCompletion,\n logUploadProgress,\n logWithContext,\n} from \"../core/logging.js\";\nimport { createStorageMetrics, type StorageMetrics } from \"../core/metrics.js\";\nimport { createStorageTracingLayer, withStorageSpan } from \"../core/tracing.js\";\nimport {\n withApiMetrics,\n withStorageOperationMetrics,\n withTimingMetrics,\n withUploadMetrics,\n} from \"../core/utilities.js\";\n\n// ============================================================================\n// S3-Specific Observability\n// ============================================================================\n\nconst STORAGE_TYPE = \"s3\";\n\n// S3-specific metrics\nexport const s3Metrics = createStorageMetrics(STORAGE_TYPE);\n\n// S3-specific tracing layer\nexport const S3TracingLayer = createStorageTracingLayer(STORAGE_TYPE);\n\n// S3-specific error classification\nconst classifyS3Error = (error: unknown): StorageErrorCategory | null => {\n if (!error || typeof error !== \"object\") return null;\n\n const errorCode = \"code\" in error ? error.code : undefined;\n if (!errorCode) return null;\n\n // S3-specific error codes\n switch (errorCode) {\n case \"NoSuchKey\":\n case \"NoSuchBucket\":\n case \"NoSuchUpload\":\n return \"client_error\";\n case \"BucketAlreadyExists\":\n case \"BucketNotEmpty\":\n return \"client_error\";\n case \"InvalidBucketName\":\n case \"InvalidPart\":\n case \"InvalidPartOrder\":\n return \"client_error\";\n case \"EntityTooSmall\":\n case \"EntityTooLarge\":\n return \"client_error\";\n case \"ExpiredToken\":\n case \"TokenRefreshRequired\":\n return \"authentication_error\";\n case \"RequestTimeTooSkewed\":\n case \"SlowDown\":\n return \"throttling_error\";\n default:\n return null; // Fall back to generic classification\n }\n};\n\n// S3-specific error tracker\nexport const trackS3Error = createStorageErrorTracker(\n STORAGE_TYPE,\n s3Metrics,\n classifyS3Error,\n);\n\n// S3-specific observability layer\nexport const S3ObservabilityLayer = Layer.mergeAll(\n S3TracingLayer,\n // Metrics are automatically available through Effect\n);\n\n// ============================================================================\n// S3 Utility Functions\n// ============================================================================\n\nexport const withS3UploadMetrics = <A, E, R>(\n uploadId: string,\n effect: Effect.Effect<A, E, R>,\n) => withUploadMetrics(s3Metrics, uploadId, effect);\n\nexport const withS3ApiMetrics = <A, E, R>(\n operation: string,\n effect: Effect.Effect<A, E, R>,\n) => withApiMetrics(s3Metrics, operation, effect);\n\nexport const withS3TimingMetrics = withTimingMetrics;\n\nexport const withS3OperationMetrics = <A, E, R>(\n operation: string,\n uploadId: string,\n effect: Effect.Effect<A, E, R>,\n fileSize?: number,\n) =>\n withStorageOperationMetrics(s3Metrics, operation, uploadId, effect, fileSize);\n\n// S3-specific span wrapper\nexport const withS3Span =\n <A, E, R>(operation: string, attributes?: Record<string, unknown>) =>\n (effect: Effect.Effect<A, E, R>) =>\n withStorageSpan(operation, STORAGE_TYPE, attributes)(effect);\n\n// S3-specific logging functions\nexport const logS3Operation = logStorageOperation.bind(null, STORAGE_TYPE);\nexport const logS3UploadProgress = logUploadProgress.bind(null, STORAGE_TYPE);\nexport const logS3UploadCompletion = logUploadCompletion.bind(\n null,\n STORAGE_TYPE,\n);\nexport const logS3Context = logWithContext;\n\n// Export metrics for external access\nexport const {\n uploadRequestsTotal: s3UploadRequestsTotal,\n uploadPartsTotal: s3UploadPartsTotal,\n uploadSuccessTotal: s3UploadSuccessTotal,\n uploadErrorsTotal: s3UploadErrorsTotal,\n apiCallsTotal: s3ApiCallsTotal,\n uploadDurationHistogram: s3UploadDurationHistogram,\n partUploadDurationHistogram: s3PartUploadDurationHistogram,\n fileSizeHistogram: s3FileSizeHistogram,\n partSizeHistogram: s3PartSizeHistogram,\n activeUploadsGauge: s3ActiveUploadsGauge,\n uploadThroughputGauge: s3UploadThroughputGauge,\n uploadLatencySummary: s3UploadLatencySummary,\n} = s3Metrics;\n\n// Type exports\nexport type S3Metrics = StorageMetrics;\n","import { type Effect, Layer } from \"effect\";\nimport {\n createStorageErrorTracker,\n type StorageErrorCategory,\n} from \"../core/errors.js\";\nimport {\n logStorageOperation,\n logUploadCompletion,\n logUploadProgress,\n logWithContext,\n} from \"../core/logging.js\";\nimport { createStorageMetrics, type StorageMetrics } from \"../core/metrics.js\";\nimport { createStorageTracingLayer, withStorageSpan } from \"../core/tracing.js\";\nimport {\n withApiMetrics,\n withStorageOperationMetrics,\n withTimingMetrics,\n withUploadMetrics,\n} from \"../core/utilities.js\";\n\n// ============================================================================\n// Azure Blob Storage-Specific Observability\n// ============================================================================\n\nconst STORAGE_TYPE = \"azure\";\n\n// Azure-specific metrics\nexport const azureMetrics = createStorageMetrics(STORAGE_TYPE);\n\n// Azure-specific tracing layer\nexport const AzureTracingLayer = createStorageTracingLayer(STORAGE_TYPE);\n\n// Azure-specific error classification\nconst classifyAzureError = (error: unknown): StorageErrorCategory | null => {\n if (!error || typeof error !== \"object\") return null;\n\n const errorCode =\n \"code\" in error\n ? error.code\n : \"statusCode\" in error\n ? error.statusCode\n : undefined;\n if (!errorCode) return null;\n\n // Azure-specific error codes\n switch (errorCode) {\n case \"BlobNotFound\":\n case \"ContainerNotFound\":\n case \"InvalidBlobOrBlock\":\n return \"client_error\";\n case \"ContainerAlreadyExists\":\n case \"BlobAlreadyExists\":\n return \"client_error\";\n case \"InvalidBlockId\":\n case \"InvalidBlockList\":\n case \"InvalidBlobType\":\n return \"client_error\";\n case \"RequestBodyTooLarge\":\n case \"InvalidHeaderValue\":\n return \"client_error\";\n case \"AuthenticationFailed\":\n case \"InvalidAuthenticationInfo\":\n return \"authentication_error\";\n case \"AccountIsDisabled\":\n return \"authorization_error\";\n case \"InsufficientAccountPermissions\":\n return \"authorization_error\";\n case \"OperationTimedOut\":\n case \"ServerBusy\":\n case \"InternalError\":\n return \"server_error\";\n default:\n // Check for HTTP status codes\n if (typeof errorCode === \"number\") {\n if (errorCode >= 500) return \"server_error\";\n if (errorCode === 429) return \"throttling_error\";\n if (errorCode === 403) return \"authorization_error\";\n if (errorCode === 401) return \"authentication_error\";\n if (errorCode >= 400) return \"client_error\";\n }\n return null; // Fall back to generic classification\n }\n};\n\n// Azure-specific error tracker\nexport const trackAzureError = createStorageErrorTracker(\n STORAGE_TYPE,\n azureMetrics,\n classifyAzureError,\n);\n\n// Azure-specific observability layer\nexport const AzureObservabilityLayer = Layer.mergeAll(\n AzureTracingLayer,\n // Metrics are automatically available through Effect\n);\n\n// ============================================================================\n// Azure Utility Functions\n// ============================================================================\n\nexport const withAzureUploadMetrics = <A, E, R>(\n uploadId: string,\n effect: Effect.Effect<A, E, R>,\n) => withUploadMetrics(azureMetrics, uploadId, effect);\n\nexport const withAzureApiMetrics = <A, E, R>(\n operation: string,\n effect: Effect.Effect<A, E, R>,\n) => withApiMetrics(azureMetrics, operation, effect);\n\nexport const withAzureTimingMetrics = withTimingMetrics;\n\nexport const withAzureOperationMetrics = <A, E, R>(\n operation: string,\n uploadId: string,\n effect: Effect.Effect<A, E, R>,\n fileSize?: number,\n) =>\n withStorageOperationMetrics(\n azureMetrics,\n operation,\n uploadId,\n effect,\n fileSize,\n );\n\n// Azure-specific span wrapper\nexport const withAzureSpan =\n <A, E, R>(operation: string, attributes?: Record<string, unknown>) =>\n (effect: Effect.Effect<A, E, R>) =>\n withStorageSpan(operation, STORAGE_TYPE, attributes)(effect);\n\n// Azure-specific logging functions\nexport const logAzureOperation = logStorageOperation.bind(null, STORAGE_TYPE);\nexport const logAzureUploadProgress = logUploadProgress.bind(\n null,\n STORAGE_TYPE,\n);\nexport const logAzureUploadCompletion = logUploadCompletion.bind(\n null,\n STORAGE_TYPE,\n);\nexport const logAzureContext = logWithContext;\n\n// Export metrics for external access\nexport const {\n uploadRequestsTotal: azureUploadRequestsTotal,\n uploadPartsTotal: azureUploadPartsTotal,\n uploadSuccessTotal: azureUploadSuccessTotal,\n uploadErrorsTotal: azureUploadErrorsTotal,\n apiCallsTotal: azureApiCallsTotal,\n uploadDurationHistogram: azureUploadDurationHistogram,\n partUploadDurationHistogram: azurePartUploadDurationHistogram,\n fileSizeHistogram: azureFileSizeHistogram,\n partSizeHistogram: azurePartSizeHistogram,\n activeUploadsGauge: azureActiveUploadsGauge,\n uploadThroughputGauge: azureUploadThroughputGauge,\n uploadLatencySummary: azureUploadLatencySummary,\n} = azureMetrics;\n\n// Type exports\nexport type AzureMetrics = StorageMetrics;\n","import { type Effect, Layer } from \"effect\";\nimport {\n createStorageErrorTracker,\n type StorageErrorCategory,\n} from \"../core/errors.js\";\nimport {\n logStorageOperation,\n logUploadCompletion,\n logUploadProgress,\n logWithContext,\n} from \"../core/logging.js\";\nimport { createStorageMetrics, type StorageMetrics } from \"../core/metrics.js\";\nimport { createStorageTracingLayer, withStorageSpan } from \"../core/tracing.js\";\nimport {\n withApiMetrics,\n withStorageOperationMetrics,\n withTimingMetrics,\n withUploadMetrics,\n} from \"../core/utilities.js\";\n\n// ============================================================================\n// Google Cloud Storage-Specific Observability\n// ============================================================================\n\nconst STORAGE_TYPE = \"gcs\";\n\n// GCS-specific metrics\nexport const gcsMetrics = createStorageMetrics(STORAGE_TYPE);\n\n// GCS-specific tracing layer\nexport const GCSTracingLayer = createStorageTracingLayer(STORAGE_TYPE);\n\n// GCS-specific error classification\nconst classifyGCSError = (error: unknown): StorageErrorCategory | null => {\n if (!error || typeof error !== \"object\") return null;\n\n const errorCode =\n \"code\" in error ? error.code : \"status\" in error ? error.status : undefined;\n if (!errorCode) return null;\n\n // GCS-specific error codes\n switch (errorCode) {\n case \"NoSuchBucket\":\n case \"NoSuchKey\":\n case \"NoSuchUpload\":\n return \"client_error\";\n case \"BucketAlreadyOwnedByYou\":\n case \"BucketNotEmpty\":\n return \"client_error\";\n case \"InvalidBucketName\":\n case \"InvalidArgument\":\n case \"InvalidPart\":\n case \"InvalidPartOrder\":\n return \"client_error\";\n case \"EntityTooSmall\":\n case \"EntityTooLarge\":\n return \"client_error\";\n case \"MalformedPolicy\":\n return \"client_error\";\n case \"Unauthorized\":\n case \"AuthenticationRequired\":\n return \"authentication_error\";\n case \"Forbidden\":\n case \"AccessDenied\":\n return \"authorization_error\";\n case \"TooManyRequests\":\n case \"RateLimitExceeded\":\n return \"throttling_error\";\n case \"InternalError\":\n case \"ServiceUnavailable\":\n case \"BackendError\":\n return \"server_error\";\n default:\n // Check for HTTP status codes\n if (typeof errorCode === \"number\") {\n if (errorCode >= 500) return \"server_error\";\n if (errorCode === 429) return \"throttling_error\";\n if (errorCode === 403) return \"authorization_error\";\n if (errorCode === 401) return \"authentication_error\";\n if (errorCode >= 400) return \"client_error\";\n }\n return null; // Fall back to generic classification\n }\n};\n\n// GCS-specific error tracker\nexport const trackGCSError = createStorageErrorTracker(\n STORAGE_TYPE,\n gcsMetrics,\n classifyGCSError,\n);\n\n// GCS-specific observability layer\nexport const GCSObservabilityLayer = Layer.mergeAll(\n GCSTracingLayer,\n // Metrics are automatically available through Effect\n);\n\n// ============================================================================\n// GCS Utility Functions\n// ============================================================================\n\nexport const withGCSUploadMetrics = <A, E, R>(\n uploadId: string,\n effect: Effect.Effect<A, E, R>,\n) => withUploadMetrics(gcsMetrics, uploadId, effect);\n\nexport const withGCSApiMetrics = <A, E, R>(\n operation: string,\n effect: Effect.Effect<A, E, R>,\n) => withApiMetrics(gcsMetrics, operation, effect);\n\nexport const withGCSTimingMetrics = withTimingMetrics;\n\nexport const withGCSOperationMetrics = <A, E, R>(\n operation: string,\n uploadId: string,\n effect: Effect.Effect<A, E, R>,\n fileSize?: number,\n) =>\n withStorageOperationMetrics(\n gcsMetrics,\n operation,\n uploadId,\n effect,\n fileSize,\n );\n\n// GCS-specific span wrapper\nexport const withGCSSpan =\n <A, E, R>(operation: string, attributes?: Record<string, unknown>) =>\n (effect: Effect.Effect<A, E, R>) =>\n withStorageSpan(operation, STORAGE_TYPE, attributes)(effect);\n\n// GCS-specific logging functions\nexport const logGCSOperation = logStorageOperation.bind(null, STORAGE_TYPE);\nexport const logGCSUploadProgress = logUploadProgress.bind(null, STORAGE_TYPE);\nexport const logGCSUploadCompletion = logUploadCompletion.bind(\n null,\n STORAGE_TYPE,\n);\nexport const logGCSContext = logWithContext;\n\n// Export metrics for external access\nexport const {\n uploadRequestsTotal: gcsUploadRequestsTotal,\n uploadPartsTotal: gcsUploadPartsTotal,\n uploadSuccessTotal: gcsUploadSuccessTotal,\n uploadErrorsTotal: gcsUploadErrorsTotal,\n apiCallsTotal: gcsApiCallsTotal,\n uploadDurationHistogram: gcsUploadDurationHistogram,\n partUploadDurationHistogram: gcsPartUploadDurationHistogram,\n fileSizeHistogram: gcsFileSizeHistogram,\n partSizeHistogram: gcsPartSizeHistogram,\n activeUploadsGauge: gcsActiveUploadsGauge,\n uploadThroughputGauge: gcsUploadThroughputGauge,\n uploadLatencySummary: gcsUploadLatencySummary,\n} = gcsMetrics;\n\n// Type exports\nexport type GCSMetrics = StorageMetrics;\n","import { type Effect, Layer } from \"effect\";\nimport {\n createStorageErrorTracker,\n type StorageErrorCategory,\n} from \"../core/errors.js\";\nimport {\n logStorageOperation,\n logUploadCompletion,\n logUploadProgress,\n logWithContext,\n} from \"../core/logging.js\";\nimport { createStorageMetrics, type StorageMetrics } from \"../core/metrics.js\";\nimport { createStorageTracingLayer, withStorageSpan } from \"../core/tracing.js\";\nimport {\n withApiMetrics,\n withStorageOperationMetrics,\n withTimingMetrics,\n withUploadMetrics,\n} from \"../core/utilities.js\";\n\n// ============================================================================\n// Filesystem Storage-Specific Observability\n// ============================================================================\n\nconst STORAGE_TYPE = \"filesystem\";\n\n// Filesystem-specific metrics\nexport const filesystemMetrics = createStorageMetrics(STORAGE_TYPE);\n\n// Filesystem-specific tracing layer\nexport const FilesystemTracingLayer = createStorageTracingLayer(STORAGE_TYPE);\n\n// Filesystem-specific error classification\nconst classifyFilesystemError = (\n error: unknown,\n): StorageErrorCategory | null => {\n if (!error || typeof error !== \"object\") return null;\n\n const errorCode = \"code\" in error ? error.code : undefined;\n if (!errorCode) return null;\n\n // Node.js filesystem error codes\n switch (errorCode) {\n case \"ENOENT\": // File/directory not found\n case \"ENOTDIR\": // Not a directory\n return \"client_error\";\n case \"EEXIST\": // File/directory already exists\n return \"client_error\";\n case \"EISDIR\": // Is a directory\n return \"client_error\";\n case \"EINVAL\": // Invalid argument\n case \"ENAMETOOLONG\": // Filename too long\n return \"client_error\";\n case \"EACCES\": // Permission denied\n case \"EPERM\": // Operation not permitted\n return \"authorization_error\";\n case \"ENOSPC\": // No space left on device\n case \"EDQUOT\": // Disk quota exceeded\n return \"server_error\";\n case \"EIO\": // I/O error\n case \"EROFS\": // Read-only filesystem\n case \"EMFILE\": // Too many open files\n case \"ENFILE\": // File table overflow\n return \"server_error\";\n case \"EBUSY\": // Device or resource busy\n return \"throttling_error\";\n default:\n return null; // Fall back to generic classification\n }\n};\n\n// Filesystem-specific error tracker\nexport const trackFilesystemError = createStorageErrorTracker(\n STORAGE_TYPE,\n filesystemMetrics,\n classifyFilesystemError,\n);\n\n// Filesystem-specific observability layer\nexport const FilesystemObservabilityLayer = Layer.mergeAll(\n FilesystemTracingLayer,\n // Metrics are automatically available through Effect\n);\n\n// ============================================================================\n// Filesystem Utility Functions\n// ============================================================================\n\nexport const withFilesystemUploadMetrics = <A, E, R>(\n uploadId: string,\n effect: Effect.Effect<A, E, R>,\n) => withUploadMetrics(filesystemMetrics, uploadId, effect);\n\nexport const withFilesystemApiMetrics = <A, E, R>(\n operation: string,\n effect: Effect.Effect<A, E, R>,\n) => withApiMetrics(filesystemMetrics, operation, effect);\n\nexport const withFilesystemTimingMetrics = withTimingMetrics;\n\nexport const withFilesystemOperationMetrics = <A, E, R>(\n operation: string,\n uploadId: string,\n effect: Effect.Effect<A, E, R>,\n fileSize?: number,\n) =>\n withStorageOperationMetrics(\n filesystemMetrics,\n operation,\n uploadId,\n effect,\n fileSize,\n );\n\n// Filesystem-specific span wrapper\nexport const withFilesystemSpan =\n <A, E, R>(operation: string, attributes?: Record<string, unknown>) =>\n (effect: Effect.Effect<A, E, R>) =>\n withStorageSpan(operation, STORAGE_TYPE, attributes)(effect);\n\n// Filesystem-specific logging functions\nexport const logFilesystemOperation = logStorageOperation.bind(\n null,\n STORAGE_TYPE,\n);\nexport const logFilesystemUploadProgress = logUploadProgress.bind(\n null,\n STORAGE_TYPE,\n);\nexport const logFilesystemUploadCompletion = logUploadCompletion.bind(\n null,\n STORAGE_TYPE,\n);\nexport const logFilesystemContext = logWithContext;\n\n// Export metrics for external access\nexport const {\n uploadRequestsTotal: filesystemUploadRequestsTotal,\n uploadPartsTotal: filesystemUploadPartsTotal,\n uploadSuccessTotal: filesystemUploadSuccessTotal,\n uploadErrorsTotal: filesystemUploadErrorsTotal,\n apiCallsTotal: filesystemApiCallsTotal,\n uploadDurationHistogram: filesystemUploadDurationHistogram,\n partUploadDurationHistogram: filesystemPartUploadDurationHistogram,\n fileSizeHistogram: filesystemFileSizeHistogram,\n partSizeHistogram: filesystemPartSizeHistogram,\n activeUploadsGauge: filesystemActiveUploadsGauge,\n uploadThroughputGauge: filesystemUploadThroughputGauge,\n uploadLatencySummary: filesystemUploadLatencySummary,\n} = filesystemMetrics;\n\n// Type exports\nexport type FilesystemMetrics = StorageMetrics;\n","import { Metric, MetricBoundaries } from \"effect\";\n\n// ============================================================================\n// Upload Server Metrics\n// ============================================================================\n\n/**\n * Upload server metrics for tracking upload operations\n */\nexport const createUploadServerMetrics = () => ({\n // Counter metrics\n uploadCreatedTotal: Metric.counter(\"upload_created_total\", {\n description: \"Total number of uploads created\",\n }),\n\n uploadCompletedTotal: Metric.counter(\"upload_completed_total\", {\n description: \"Total number of uploads completed successfully\",\n }),\n\n uploadFailedTotal: Metric.counter(\"upload_failed_total\", {\n description: \"Total number of uploads that failed\",\n }),\n\n chunkUploadedTotal: Metric.counter(\"chunk_uploaded_total\", {\n description: \"Total number of chunks uploaded\",\n }),\n\n uploadFromUrlTotal: Metric.counter(\"upload_from_url_total\", {\n description: \"Total number of URL-based uploads\",\n }),\n\n uploadFromUrlSuccessTotal: Metric.counter(\"upload_from_url_success_total\", {\n description: \"Total number of successful URL-based uploads\",\n }),\n\n uploadFromUrlFailedTotal: Metric.counter(\"upload_from_url_failed_total\", {\n description: \"Total number of failed URL-based uploads\",\n }),\n\n // Histogram metrics\n uploadDurationHistogram: Metric.histogram(\n \"upload_duration_seconds\",\n MetricBoundaries.exponential({\n start: 0.01, // 10ms\n factor: 2,\n count: 20, // Up to ~10 seconds\n }),\n \"Duration of complete upload operations in seconds\",\n ),\n\n chunkUploadDurationHistogram: Metric.histogram(\n \"chunk_upload_duration_seconds\",\n MetricBoundaries.exponential({\n start: 0.001, // 1ms\n factor: 2,\n count: 15, // Up to ~32 seconds\n }),\n \"Duration of individual chunk uploads in seconds\",\n ),\n\n uploadFileSizeHistogram: Metric.histogram(\n \"upload_file_size_bytes\",\n MetricBoundaries.exponential({\n start: 1024, // 1KB\n factor: 2,\n count: 25, // Up to ~33GB\n }),\n \"Size of uploaded files in bytes\",\n ),\n\n chunkSizeHistogram: Metric.histogram(\n \"chunk_size_bytes\",\n MetricBoundaries.linear({\n start: 262_144, // 256KB\n width: 262_144, // 256KB increments\n count: 20, // Up to ~5MB\n }),\n \"Size of uploaded chunks in bytes\",\n ),\n\n // Gauge metrics\n activeUploadsGauge: Metric.gauge(\"active_uploads\", {\n description: \"Number of currently active uploads\",\n }),\n\n uploadThroughputGauge: Metric.gauge(\"upload_throughput_bytes_per_second\", {\n description: \"Current upload throughput in bytes per second\",\n }),\n\n // Summary metrics for latency percentiles\n uploadLatencySummary: Metric.summary({\n name: \"upload_latency_seconds\",\n maxAge: \"10 minutes\",\n maxSize: 1000,\n error: 0.01,\n quantiles: [0.5, 0.9, 0.95, 0.99],\n description: \"Upload operation latency percentiles\",\n }),\n\n chunkLatencySummary: Metric.summary({\n name: \"chunk_latency_seconds\",\n maxAge: \"10 minutes\",\n maxSize: 1000,\n error: 0.01,\n quantiles: [0.5, 0.9, 0.95, 0.99],\n description: \"Chunk upload latency percentiles\",\n }),\n});\n\n/**\n * Type for upload server metrics\n */\nexport type UploadServerMetrics = ReturnType<typeof createUploadServerMetrics>;\n\n/**\n * Default upload server metrics instance\n */\nexport const uploadServerMetrics = createUploadServerMetrics();\n","import { Effect } from \"effect\";\n\n// ============================================================================\n// Upload Tracing Utilities\n// ============================================================================\n\n/**\n * Wrap an Effect with an upload operation span\n */\nexport const withUploadSpan =\n <A, E, R>(operation: string, attributes?: Record<string, unknown>) =>\n (effect: Effect.Effect<A, E, R>): Effect.Effect<A, E, R> =>\n effect.pipe(\n Effect.withSpan(`upload-${operation}`, {\n attributes: {\n \"upload.operation\": operation,\n ...attributes,\n },\n }),\n );\n\n/**\n * Add upload context to the current span\n */\nexport const withUploadContext = (context: {\n uploadId?: string;\n fileName?: string;\n fileSize?: number;\n storageId?: string;\n mimeType?: string;\n}) =>\n Effect.annotateCurrentSpan({\n \"upload.id\": context.uploadId ?? \"unknown\",\n \"upload.file_name\": context.fileName ?? \"unknown\",\n \"upload.file_size\": context.fileSize?.toString() ?? \"0\",\n \"upload.storage_id\": context.storageId ?? \"unknown\",\n \"upload.mime_type\": context.mimeType ?? \"unknown\",\n });\n\n/**\n * Add chunk context to the current span\n */\nexport const withChunkContext = (context: {\n uploadId: string;\n chunkSize: number;\n offset: number;\n totalSize?: number;\n}) =>\n Effect.annotateCurrentSpan({\n \"chunk.upload_id\": context.uploadId,\n \"chunk.size\": context.chunkSize.toString(),\n \"chunk.offset\": context.offset.toString(),\n \"chunk.total_size\": context.totalSize?.toString() ?? \"0\",\n \"chunk.progress\":\n context.totalSize && context.totalSize > 0\n ? ((context.offset / context.totalSize) * 100).toFixed(2)\n : \"0\",\n });\n","import { Effect, Layer, Metric } from \"effect\";\nimport {\n makeUploadObservabilityLayer,\n UploadObservability,\n} from \"../core/layers.js\";\nimport { createUploadServerMetrics } from \"./metrics.js\";\n\n// ============================================================================\n// Upload Observability Layer Implementation\n// ============================================================================\n\n/**\n * Create a live upload observability layer with full metrics\n */\nexport const makeUploadObservabilityLive = (\n serviceName = \"uploadista-upload-server\",\n): Layer.Layer<UploadObservability> => {\n const metrics = createUploadServerMetrics();\n\n return Layer.succeed(UploadObservability, {\n serviceName,\n enabled: true,\n metrics: {\n uploadCreated: Effect.succeed(metrics.uploadCreatedTotal).pipe(\n Effect.flatMap((metric) => Metric.increment(metric)),\n ),\n uploadCompleted: Effect.succeed(metrics.uploadCompletedTotal).pipe(\n Effect.flatMap((metric) => Metric.increment(metric)),\n ),\n uploadFailed: Effect.succeed(metrics.uploadFailedTotal).pipe(\n Effect.flatMap((metric) => Metric.increment(metric)),\n ),\n chunkUploaded: Effect.succeed(metrics.chunkUploadedTotal).pipe(\n Effect.flatMap((metric) => Metric.increment(metric)),\n ),\n },\n });\n};\n\n/**\n * Default live upload observability layer\n */\nexport const UploadObservabilityLive = makeUploadObservabilityLive();\n\n/**\n * No-op upload observability layer (for testing or disabled observability)\n */\nexport const UploadObservabilityDisabled = makeUploadObservabilityLayer(false);\n\n/**\n * Helper to get upload metrics from context\n */\nexport const getUploadMetrics = Effect.gen(function* () {\n const obs = yield* UploadObservability;\n return obs.metrics;\n});\n\n/**\n * Helper to track upload duration\n */\nexport const withUploadDuration = <A, E, R>(\n effect: Effect.Effect<A, E, R>,\n): Effect.Effect<A, E, R | UploadObservability> => {\n const metrics = createUploadServerMetrics();\n return Effect.gen(function* () {\n const startTime = Date.now();\n const result = yield* effect;\n const duration = (Date.now() - startTime) / 1000; // Convert to seconds\n yield* Metric.update(metrics.uploadDurationHistogram, duration);\n return result;\n }).pipe(Effect.withSpan(\"upload-operation\"));\n};\n\n/**\n * Helper to track chunk upload duration\n */\nexport const withChunkDuration = <A, E, R>(\n effect: Effect.Effect<A, E, R>,\n): Effect.Effect<A, E, R> => {\n const metrics = createUploadServerMetrics();\n return Effect.gen(function* () {\n const startTime = Date.now();\n const result = yield* effect;\n const duration = (Date.now() - startTime) / 1000; // Convert to seconds\n yield* Metric.update(metrics.chunkUploadDurationHistogram, duration);\n return result;\n }).pipe(Effect.withSpan(\"chunk-upload\"));\n};\n","import { Effect, Metric } from \"effect\";\nimport type { UploadServerMetrics } from \"./metrics.js\";\n\n// ============================================================================\n// Upload Error Classification and Tracking\n// ============================================================================\n\nexport type UploadErrorCategory =\n | \"network_error\"\n | \"authentication_error\"\n | \"authorization_error\"\n | \"validation_error\"\n | \"size_limit_error\"\n | \"storage_error\"\n | \"abort_error\"\n | \"unknown_error\";\n\n/**\n * Classify upload errors into standard categories\n */\nexport const classifyUploadError = (error: unknown): UploadErrorCategory => {\n if (!error || typeof error !== \"object\") return \"unknown_error\";\n\n const errorCode = \"code\" in error ? error.code : undefined;\n const errorName = \"name\" in error ? error.name : undefined;\n const errorMessage =\n error instanceof Error ? error.message.toLowerCase() : \"\";\n\n // Abort errors\n if (\n errorCode === \"ABORTED\" ||\n errorName === \"AbortError\" ||\n errorMessage.includes(\"abort\")\n ) {\n return \"abort_error\";\n }\n\n // Size limit errors\n if (\n errorCode === \"FILE_TOO_LARGE\" ||\n errorCode === \"LIMIT_FILE_SIZE\" ||\n errorCode === \"RequestEntityTooLarge\" ||\n errorMessage.includes(\"too large\") ||\n errorMessage.includes(\"size limit\") ||\n errorMessage.includes(\"max size\")\n ) {\n return \"size_limit_error\";\n }\n\n // Validation errors\n if (\n errorCode === \"INVALID_FILE\" ||\n errorCode === \"INVALID_METADATA\" ||\n errorCode === \"VALIDATION_ERROR\" ||\n errorMessage.includes(\"validation\") ||\n errorMessage.includes(\"invalid\")\n ) {\n return \"validation_error\";\n }\n\n // Network errors\n if (\n errorCode === \"NetworkError\" ||\n errorCode === \"ECONNRESET\" ||\n errorCode === \"ENOTFOUND\" ||\n errorCode === \"ETIMEDOUT\" ||\n errorMessage.includes(\"network\") ||\n errorMessage.includes(\"timeout\")\n ) {\n return \"network_error\";\n }\n\n // Authentication errors\n if (\n errorCode === \"UNAUTHORIZED\" ||\n errorCode === \"AuthenticationFailed\" ||\n errorName === \"AuthenticationError\" ||\n errorMessage.includes(\"authentication\") ||\n errorMessage.includes(\"unauthorized\")\n ) {\n return \"authentication_error\";\n }\n\n // Authorization errors\n if (\n errorCode === \"FORBIDDEN\" ||\n errorCode === \"AccessDenied\" ||\n errorName === \"AuthorizationError\" ||\n errorMessage.includes(\"forbidden\") ||\n errorMessage.includes(\"permission\")\n ) {\n return \"authorization_error\";\n }\n\n // Storage errors\n if (\n errorCode === \"FILE_WRITE_ERROR\" ||\n errorCode === \"STORAGE_ERROR\" ||\n errorMessage.includes(\"storage\") ||\n errorMessage.includes(\"write error\")\n ) {\n return \"storage_error\";\n }\n\n return \"unknown_error\";\n};\n\n/**\n * Track upload errors with metrics and structured logging\n */\nexport const trackUploadError = (\n metrics: UploadServerMetrics,\n operation: string,\n error: unknown,\n context: Record<string, unknown> = {},\n) =>\n Effect.gen(function* () {\n const errorCategory = classifyUploadError(error);\n\n // Record error metrics\n const errorMetric = metrics.uploadFailedTotal.pipe(\n Metric.tagged(\"operation\", operation),\n Metric.tagged(\"error_category\", errorCategory),\n );\n yield* errorMetric(Effect.succeed(1));\n\n // Create detailed error context\n const errorDetails = {\n operation,\n error_category: errorCategory,\n error_type: typeof error,\n error_message: error instanceof Error ? error.message : String(error),\n error_code:\n error && typeof error === \"object\" && \"code\" in error\n ? String(error.code)\n : undefined,\n error_name:\n error && typeof error === \"object\" && \"name\" in error\n ? String(error.name)\n : undefined,\n ...context,\n };\n\n // Log structured error\n yield* Effect.logError(`Upload ${operation} failed`).pipe(\n Effect.annotateLogs(errorDetails),\n );\n });\n\n/**\n * Create a custom error classifier for upload operations\n */\nexport const createUploadErrorClassifier = (\n customErrorMapping?: (error: unknown) => UploadErrorCategory | null,\n) => {\n return (error: unknown): UploadErrorCategory => {\n // Try custom mapping first\n if (customErrorMapping) {\n const customResult = customErrorMapping(error);\n if (customResult !== null) return customResult;\n }\n\n // Fall back to generic classification\n return classifyUploadError(error);\n };\n};\n","import { Layer } from \"effect\";\nimport { UploadObservability } from \"../core/layers.js\";\nimport { createUploadServerMetrics } from \"./metrics.js\";\n\n// ============================================================================\n// Upload Observability Testing Utilities\n// ============================================================================\n\n/**\n * Create a test upload observability layer that doesn't actually emit metrics\n * but validates that the observability system is wired correctly\n */\nexport const UploadObservabilityTest = Layer.succeed(UploadObservability, {\n serviceName: \"uploadista-upload-server-test\",\n enabled: true,\n metrics: {\n uploadCreated: () => Promise.resolve(),\n uploadCompleted: () => Promise.resolve(),\n uploadFailed: () => Promise.resolve(),\n chunkUploaded: () => Promise.resolve(),\n } as any,\n});\n\n/**\n * Get metrics for validation (useful for testing metric definitions)\n */\nexport const getTestMetrics = () => createUploadServerMetrics();\n\n/**\n * Validate that all required metrics exist\n */\nexport const validateMetricsExist = () => {\n const metrics = getTestMetrics();\n\n const requiredMetrics = [\n \"uploadCreatedTotal\",\n \"uploadCompletedTotal\",\n \"uploadFailedTotal\",\n \"chunkUploadedTotal\",\n \"uploadFromUrlTotal\",\n \"uploadFromUrlSuccessTotal\",\n \"uploadFromUrlFailedTotal\",\n \"uploadDurationHistogram\",\n \"chunkUploadDurationHistogram\",\n \"uploadFileSizeHistogram\",\n \"chunkSizeHistogram\",\n \"activeUploadsGauge\",\n \"uploadThroughputGauge\",\n \"uploadLatencySummary\",\n \"chunkLatencySummary\",\n ];\n\n const missingMetrics = requiredMetrics.filter((name) => !(name in metrics));\n\n if (missingMetrics.length > 0) {\n throw new Error(`Missing required metrics: ${missingMetrics.join(\", \")}`);\n }\n\n return true;\n};\n"],"mappings":"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"}
|