@uploadista/observability 0.0.3 → 0.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. package/.turbo/turbo-build.log +19 -2
  2. package/dist/index.cjs +1 -0
  3. package/dist/index.d.cts +736 -0
  4. package/dist/index.d.cts.map +1 -0
  5. package/dist/index.d.ts +735 -7
  6. package/dist/index.d.ts.map +1 -1
  7. package/dist/index.js +2 -14
  8. package/dist/index.js.map +1 -0
  9. package/package.json +4 -3
  10. package/tsdown.config.ts +11 -0
  11. package/dist/core/errors.d.ts +0 -8
  12. package/dist/core/errors.d.ts.map +0 -1
  13. package/dist/core/errors.js +0 -108
  14. package/dist/core/index.d.ts +0 -8
  15. package/dist/core/index.d.ts.map +0 -1
  16. package/dist/core/index.js +0 -8
  17. package/dist/core/layers.d.ts +0 -104
  18. package/dist/core/layers.d.ts.map +0 -1
  19. package/dist/core/layers.js +0 -110
  20. package/dist/core/logging.d.ts +0 -18
  21. package/dist/core/logging.d.ts.map +0 -1
  22. package/dist/core/logging.js +0 -41
  23. package/dist/core/metrics.d.ts +0 -37
  24. package/dist/core/metrics.d.ts.map +0 -1
  25. package/dist/core/metrics.js +0 -72
  26. package/dist/core/testing.d.ts +0 -43
  27. package/dist/core/testing.d.ts.map +0 -1
  28. package/dist/core/testing.js +0 -93
  29. package/dist/core/tracing.d.ts +0 -19
  30. package/dist/core/tracing.d.ts.map +0 -1
  31. package/dist/core/tracing.js +0 -43
  32. package/dist/core/utilities.d.ts +0 -11
  33. package/dist/core/utilities.d.ts.map +0 -1
  34. package/dist/core/utilities.js +0 -41
  35. package/dist/flow/errors.d.ts +0 -15
  36. package/dist/flow/errors.d.ts.map +0 -1
  37. package/dist/flow/errors.js +0 -66
  38. package/dist/flow/index.d.ts +0 -6
  39. package/dist/flow/index.d.ts.map +0 -1
  40. package/dist/flow/index.js +0 -6
  41. package/dist/flow/layers.d.ts +0 -40
  42. package/dist/flow/layers.d.ts.map +0 -1
  43. package/dist/flow/layers.js +0 -94
  44. package/dist/flow/metrics.d.ts +0 -52
  45. package/dist/flow/metrics.d.ts.map +0 -1
  46. package/dist/flow/metrics.js +0 -89
  47. package/dist/flow/testing.d.ts +0 -11
  48. package/dist/flow/testing.d.ts.map +0 -1
  49. package/dist/flow/testing.js +0 -27
  50. package/dist/flow/tracing.d.ts +0 -35
  51. package/dist/flow/tracing.d.ts.map +0 -1
  52. package/dist/flow/tracing.js +0 -42
  53. package/dist/service/metrics.d.ts +0 -23
  54. package/dist/service/metrics.d.ts.map +0 -1
  55. package/dist/service/metrics.js +0 -17
  56. package/dist/storage/azure.d.ts +0 -47
  57. package/dist/storage/azure.d.ts.map +0 -1
  58. package/dist/storage/azure.js +0 -89
  59. package/dist/storage/filesystem.d.ts +0 -47
  60. package/dist/storage/filesystem.d.ts.map +0 -1
  61. package/dist/storage/filesystem.js +0 -70
  62. package/dist/storage/gcs.d.ts +0 -47
  63. package/dist/storage/gcs.d.ts.map +0 -1
  64. package/dist/storage/gcs.js +0 -90
  65. package/dist/storage/index.d.ts +0 -5
  66. package/dist/storage/index.d.ts.map +0 -1
  67. package/dist/storage/index.js +0 -5
  68. package/dist/storage/s3.d.ts +0 -47
  69. package/dist/storage/s3.d.ts.map +0 -1
  70. package/dist/storage/s3.js +0 -67
  71. package/dist/test-observability.d.ts +0 -12
  72. package/dist/test-observability.d.ts.map +0 -1
  73. package/dist/test-observability.js +0 -153
  74. package/dist/upload/errors.d.ts +0 -16
  75. package/dist/upload/errors.d.ts.map +0 -1
  76. package/dist/upload/errors.js +0 -107
  77. package/dist/upload/index.d.ts +0 -6
  78. package/dist/upload/index.d.ts.map +0 -1
  79. package/dist/upload/index.js +0 -6
  80. package/dist/upload/layers.d.ts +0 -32
  81. package/dist/upload/layers.d.ts.map +0 -1
  82. package/dist/upload/layers.js +0 -63
  83. package/dist/upload/metrics.d.ts +0 -46
  84. package/dist/upload/metrics.d.ts.map +0 -1
  85. package/dist/upload/metrics.js +0 -80
  86. package/dist/upload/testing.d.ts +0 -32
  87. package/dist/upload/testing.d.ts.map +0 -1
  88. package/dist/upload/testing.js +0 -52
  89. package/dist/upload/tracing.d.ts +0 -25
  90. package/dist/upload/tracing.d.ts.map +0 -1
  91. package/dist/upload/tracing.js +0 -35
@@ -1,104 +0,0 @@
1
- import { Context, Effect, Layer, Option } from "effect";
2
- import type { StorageMetrics } from "./metrics.js";
3
- /**
4
- * Core observability service providing tracing, metrics, and logging capabilities
5
- */
6
- export interface ObservabilityService {
7
- readonly serviceName: string;
8
- readonly enabled: boolean;
9
- }
10
- declare const Observability_base: Context.TagClass<Observability, "Observability", ObservabilityService>;
11
- /**
12
- * Observability service tag for Effect Context
13
- */
14
- export declare class Observability extends Observability_base {
15
- }
16
- /**
17
- * Storage observability service extending base observability with storage-specific metrics
18
- */
19
- export interface StorageObservabilityService extends ObservabilityService {
20
- readonly storageType: string;
21
- readonly metrics: StorageMetrics;
22
- }
23
- declare const StorageObservability_base: Context.TagClass<StorageObservability, "StorageObservability", StorageObservabilityService>;
24
- /**
25
- * Storage observability service tag
26
- */
27
- export declare class StorageObservability extends StorageObservability_base {
28
- }
29
- /**
30
- * Upload observability service for upload-specific operations
31
- */
32
- export interface UploadObservabilityService extends ObservabilityService {
33
- readonly metrics: {
34
- uploadCreated: Effect.Effect<void>;
35
- uploadCompleted: Effect.Effect<void>;
36
- uploadFailed: Effect.Effect<void>;
37
- chunkUploaded: Effect.Effect<void>;
38
- };
39
- }
40
- declare const UploadObservability_base: Context.TagClass<UploadObservability, "UploadObservability", UploadObservabilityService>;
41
- /**
42
- * Upload observability service tag
43
- */
44
- export declare class UploadObservability extends UploadObservability_base {
45
- }
46
- /**
47
- * Flow observability service for flow execution operations
48
- */
49
- export interface FlowObservabilityService extends ObservabilityService {
50
- readonly metrics: {
51
- flowStarted: Effect.Effect<void>;
52
- flowCompleted: Effect.Effect<void>;
53
- flowFailed: Effect.Effect<void>;
54
- nodeExecuted: Effect.Effect<void>;
55
- };
56
- }
57
- declare const FlowObservability_base: Context.TagClass<FlowObservability, "FlowObservability", FlowObservabilityService>;
58
- /**
59
- * Flow observability service tag
60
- */
61
- export declare class FlowObservability extends FlowObservability_base {
62
- }
63
- /**
64
- * Create a base observability layer
65
- */
66
- export declare const makeObservabilityLayer: (serviceName: string, enabled?: boolean) => Layer.Layer<Observability>;
67
- /**
68
- * Create a storage observability layer
69
- */
70
- export declare const makeStorageObservabilityLayer: (storageType: string, metrics: StorageMetrics, enabled?: boolean) => Layer.Layer<StorageObservability>;
71
- /**
72
- * Create an upload observability layer
73
- */
74
- export declare const makeUploadObservabilityLayer: (enabled?: boolean) => Layer.Layer<UploadObservability>;
75
- /**
76
- * Create a flow observability layer
77
- */
78
- export declare const makeFlowObservabilityLayer: (enabled?: boolean) => Layer.Layer<FlowObservability>;
79
- /**
80
- * No-op observability layer (disabled)
81
- */
82
- export declare const ObservabilityDisabled: Layer.Layer<Observability, never, never>;
83
- /**
84
- * No-op storage observability layer
85
- */
86
- export declare const StorageObservabilityDisabled: (storageType: string) => Layer.Layer<StorageObservability, never, never>;
87
- /**
88
- * No-op upload observability layer
89
- */
90
- export declare const UploadObservabilityDisabled: Layer.Layer<UploadObservability, never, never>;
91
- /**
92
- * No-op flow observability layer
93
- */
94
- export declare const FlowObservabilityDisabled: Layer.Layer<FlowObservability, never, never>;
95
- /**
96
- * Check if observability is enabled in the current context
97
- */
98
- export declare const isObservabilityEnabled: Effect.Effect<boolean, never, never>;
99
- /**
100
- * Execute an effect only if observability is enabled
101
- */
102
- export declare const whenObservabilityEnabled: <A, E, R>(effect: Effect.Effect<A, E, R>) => Effect.Effect<Option.Option<A>, E, R | Observability>;
103
- export {};
104
- //# sourceMappingURL=layers.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"layers.d.ts","sourceRoot":"","sources":["../../src/core/layers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AACxD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAMnD;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;CAC3B;;AAED;;GAEG;AACH,qBAAa,aAAc,SAAQ,kBAGhC;CAAG;AAEN;;GAEG;AACH,MAAM,WAAW,2BAA4B,SAAQ,oBAAoB;IACvE,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,OAAO,EAAE,cAAc,CAAC;CAClC;;AAED;;GAEG;AACH,qBAAa,oBAAqB,SAAQ,yBAGvC;CAAG;AAEN;;GAEG;AACH,MAAM,WAAW,0BAA2B,SAAQ,oBAAoB;IACtE,QAAQ,CAAC,OAAO,EAAE;QAChB,aAAa,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACnC,eAAe,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACrC,YAAY,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAClC,aAAa,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;KACpC,CAAC;CACH;;AAED;;GAEG;AACH,qBAAa,mBAAoB,SAAQ,wBAGtC;CAAG;AAEN;;GAEG;AACH,MAAM,WAAW,wBAAyB,SAAQ,oBAAoB;IACpE,QAAQ,CAAC,OAAO,EAAE;QAChB,WAAW,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACjC,aAAa,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACnC,UAAU,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAChC,YAAY,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;KACnC,CAAC;CACH;;AAED;;GAEG;AACH,qBAAa,iBAAkB,SAAQ,sBAGpC;CAAG;AAMN;;GAEG;AACH,eAAO,MAAM,sBAAsB,GACjC,aAAa,MAAM,EACnB,iBAAc,KACb,KAAK,CAAC,KAAK,CAAC,aAAa,CAIxB,CAAC;AAEL;;GAEG;AACH,eAAO,MAAM,6BAA6B,GACxC,aAAa,MAAM,EACnB,SAAS,cAAc,EACvB,iBAAc,KACb,KAAK,CAAC,KAAK,CAAC,oBAAoB,CAM/B,CAAC;AAEL;;GAEG;AACH,eAAO,MAAM,4BAA4B,GACvC,iBAAc,KACb,KAAK,CAAC,KAAK,CAAC,mBAAmB,CAU9B,CAAC;AAEL;;GAEG;AACH,eAAO,MAAM,0BAA0B,GACrC,iBAAc,KACb,KAAK,CAAC,KAAK,CAAC,iBAAiB,CAU5B,CAAC;AAML;;GAEG;AACH,eAAO,MAAM,qBAAqB,0CAGjC,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,4BAA4B,GAAI,aAAa,MAAM,oDAK7D,CAAC;AAEJ;;GAEG;AACH,eAAO,MAAM,2BAA2B,gDAAsC,CAAC;AAE/E;;GAEG;AACH,eAAO,MAAM,yBAAyB,8CAAoC,CAAC;AAM3E;;GAEG;AACH,eAAO,MAAM,sBAAsB,sCAMjC,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,wBAAwB,GAAI,CAAC,EAAE,CAAC,EAAE,CAAC,EAC9C,QAAQ,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,KAC7B,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,aAAa,CAQnD,CAAC"}
@@ -1,110 +0,0 @@
1
- import { Context, Effect, Layer, Option } from "effect";
2
- /**
3
- * Observability service tag for Effect Context
4
- */
5
- export class Observability extends Context.Tag("Observability")() {
6
- }
7
- /**
8
- * Storage observability service tag
9
- */
10
- export class StorageObservability extends Context.Tag("StorageObservability")() {
11
- }
12
- /**
13
- * Upload observability service tag
14
- */
15
- export class UploadObservability extends Context.Tag("UploadObservability")() {
16
- }
17
- /**
18
- * Flow observability service tag
19
- */
20
- export class FlowObservability extends Context.Tag("FlowObservability")() {
21
- }
22
- // ============================================================================
23
- // Layer Factories
24
- // ============================================================================
25
- /**
26
- * Create a base observability layer
27
- */
28
- export const makeObservabilityLayer = (serviceName, enabled = true) => Layer.succeed(Observability, {
29
- serviceName,
30
- enabled,
31
- });
32
- /**
33
- * Create a storage observability layer
34
- */
35
- export const makeStorageObservabilityLayer = (storageType, metrics, enabled = true) => Layer.succeed(StorageObservability, {
36
- serviceName: `uploadista-${storageType}-store`,
37
- storageType,
38
- metrics,
39
- enabled,
40
- });
41
- /**
42
- * Create an upload observability layer
43
- */
44
- export const makeUploadObservabilityLayer = (enabled = true) => Layer.succeed(UploadObservability, {
45
- serviceName: "uploadista-upload-server",
46
- enabled,
47
- metrics: {
48
- uploadCreated: Effect.void,
49
- uploadCompleted: Effect.void,
50
- uploadFailed: Effect.void,
51
- chunkUploaded: Effect.void,
52
- },
53
- });
54
- /**
55
- * Create a flow observability layer
56
- */
57
- export const makeFlowObservabilityLayer = (enabled = true) => Layer.succeed(FlowObservability, {
58
- serviceName: "uploadista-flow-engine",
59
- enabled,
60
- metrics: {
61
- flowStarted: Effect.void,
62
- flowCompleted: Effect.void,
63
- flowFailed: Effect.void,
64
- nodeExecuted: Effect.void,
65
- },
66
- });
67
- // ============================================================================
68
- // No-op Layers (for testing and opt-out)
69
- // ============================================================================
70
- /**
71
- * No-op observability layer (disabled)
72
- */
73
- export const ObservabilityDisabled = makeObservabilityLayer("uploadista-disabled", false);
74
- /**
75
- * No-op storage observability layer
76
- */
77
- export const StorageObservabilityDisabled = (storageType) => makeStorageObservabilityLayer(storageType, {}, // No-op metrics
78
- false);
79
- /**
80
- * No-op upload observability layer
81
- */
82
- export const UploadObservabilityDisabled = makeUploadObservabilityLayer(false);
83
- /**
84
- * No-op flow observability layer
85
- */
86
- export const FlowObservabilityDisabled = makeFlowObservabilityLayer(false);
87
- // ============================================================================
88
- // Helper Functions
89
- // ============================================================================
90
- /**
91
- * Check if observability is enabled in the current context
92
- */
93
- export const isObservabilityEnabled = Effect.gen(function* () {
94
- const observability = yield* Effect.serviceOption(Observability);
95
- return Option.match(observability, {
96
- onNone: () => false,
97
- onSome: (obs) => obs.enabled,
98
- });
99
- });
100
- /**
101
- * Execute an effect only if observability is enabled
102
- */
103
- export const whenObservabilityEnabled = (effect) => Effect.gen(function* () {
104
- const enabled = yield* isObservabilityEnabled;
105
- if (enabled) {
106
- const result = yield* effect;
107
- return Option.some(result);
108
- }
109
- return Option.none();
110
- });
@@ -1,18 +0,0 @@
1
- import { Effect } from "effect";
2
- export declare const logWithContext: (message: string, context: Record<string, unknown>) => Effect.Effect<void, never, never>;
3
- export declare const logUploadProgress: (storageType: string, uploadId: string, progress: {
4
- uploadedBytes: number;
5
- totalBytes: number;
6
- partNumber?: number;
7
- speed?: number;
8
- }) => Effect.Effect<void, never, never>;
9
- export declare const logStorageOperation: (storageType: string, operation: string, uploadId: string, metadata?: Record<string, unknown>) => Effect.Effect<void, never, never>;
10
- export declare const logUploadCompletion: (storageType: string, uploadId: string, metrics: {
11
- fileSize: number;
12
- totalDurationMs: number;
13
- partsCount?: number;
14
- averagePartSize?: number;
15
- throughputBps?: number;
16
- retryCount?: number;
17
- }) => Effect.Effect<void, never, never>;
18
- //# sourceMappingURL=logging.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"logging.d.ts","sourceRoot":"","sources":["../../src/core/logging.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAMhC,eAAO,MAAM,cAAc,GACzB,SAAS,MAAM,EACf,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,sCACyB,CAAC;AAE5D,eAAO,MAAM,iBAAiB,GAC5B,aAAa,MAAM,EACnB,UAAU,MAAM,EAChB,UAAU;IACR,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,sCAYC,CAAC;AAEL,eAAO,MAAM,mBAAmB,GAC9B,aAAa,MAAM,EACnB,WAAW,MAAM,EACjB,UAAU,MAAM,EAChB,WAAW,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,sCAOhC,CAAC;AAEL,eAAO,MAAM,mBAAmB,GAC9B,aAAa,MAAM,EACnB,UAAU,MAAM,EAChB,SAAS;IACP,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,EAAE,MAAM,CAAC;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,sCAwBF,CAAC"}
@@ -1,41 +0,0 @@
1
- import { Effect } from "effect";
2
- // ============================================================================
3
- // Enhanced Logging Helpers (Storage-agnostic)
4
- // ============================================================================
5
- export const logWithContext = (message, context) => Effect.log(message).pipe(Effect.annotateLogs(context));
6
- export const logUploadProgress = (storageType, uploadId, progress) => logWithContext("Upload progress", {
7
- storage_type: storageType,
8
- upload_id: uploadId,
9
- uploaded_bytes: progress.uploadedBytes,
10
- total_bytes: progress.totalBytes,
11
- progress_percentage: Math.round((progress.uploadedBytes / progress.totalBytes) * 100),
12
- ...(progress.partNumber && { part_number: progress.partNumber }),
13
- ...(progress.speed && { upload_speed_bps: progress.speed }),
14
- });
15
- export const logStorageOperation = (storageType, operation, uploadId, metadata) => logWithContext(`${storageType.toUpperCase()} ${operation}`, {
16
- storage_type: storageType,
17
- operation,
18
- upload_id: uploadId,
19
- ...metadata,
20
- });
21
- export const logUploadCompletion = (storageType, uploadId, metrics) => {
22
- const throughputMBps = metrics.throughputBps
23
- ? metrics.throughputBps / (1024 * 1024)
24
- : 0;
25
- return logWithContext(`${storageType.toUpperCase()} upload completed`, {
26
- storage_type: storageType,
27
- upload_id: uploadId,
28
- file_size_bytes: metrics.fileSize,
29
- file_size_mb: Math.round((metrics.fileSize / (1024 * 1024)) * 100) / 100,
30
- total_duration_ms: metrics.totalDurationMs,
31
- total_duration_seconds: Math.round((metrics.totalDurationMs / 1000) * 100) / 100,
32
- throughput_bps: metrics.throughputBps,
33
- throughput_mbps: Math.round(throughputMBps * 100) / 100,
34
- ...(metrics.partsCount && { parts_count: metrics.partsCount }),
35
- ...(metrics.averagePartSize && {
36
- average_part_size_bytes: metrics.averagePartSize,
37
- average_part_size_mb: Math.round((metrics.averagePartSize / (1024 * 1024)) * 100) / 100,
38
- }),
39
- ...(metrics.retryCount && { retry_count: metrics.retryCount }),
40
- });
41
- };
@@ -1,37 +0,0 @@
1
- import { Metric } from "effect";
2
- export declare const createUploadMetrics: (storageType: string) => {
3
- uploadRequestsTotal: Metric.Metric.Counter<number>;
4
- uploadPartsTotal: Metric.Metric.Counter<number>;
5
- uploadSuccessTotal: Metric.Metric.Counter<number>;
6
- uploadErrorsTotal: Metric.Metric.Counter<number>;
7
- apiCallsTotal: Metric.Metric.Counter<number>;
8
- };
9
- export declare const createUploadHistograms: (storageType: string) => {
10
- uploadDurationHistogram: Metric.Metric<import("effect/MetricKeyType").MetricKeyType.Histogram, number, import("effect/MetricState").MetricState.Histogram>;
11
- partUploadDurationHistogram: Metric.Metric<import("effect/MetricKeyType").MetricKeyType.Histogram, number, import("effect/MetricState").MetricState.Histogram>;
12
- fileSizeHistogram: Metric.Metric<import("effect/MetricKeyType").MetricKeyType.Histogram, number, import("effect/MetricState").MetricState.Histogram>;
13
- partSizeHistogram: Metric.Metric<import("effect/MetricKeyType").MetricKeyType.Histogram, number, import("effect/MetricState").MetricState.Histogram>;
14
- };
15
- export declare const createUploadGauges: (storageType: string) => {
16
- activeUploadsGauge: Metric.Metric.Gauge<number>;
17
- uploadThroughputGauge: Metric.Metric.Gauge<number>;
18
- };
19
- export declare const createUploadSummaries: (storageType: string) => {
20
- uploadLatencySummary: Metric.Metric.Summary<number>;
21
- };
22
- export declare const createStorageMetrics: (storageType: string) => {
23
- uploadLatencySummary: Metric.Metric.Summary<number>;
24
- activeUploadsGauge: Metric.Metric.Gauge<number>;
25
- uploadThroughputGauge: Metric.Metric.Gauge<number>;
26
- uploadDurationHistogram: Metric.Metric<import("effect/MetricKeyType").MetricKeyType.Histogram, number, import("effect/MetricState").MetricState.Histogram>;
27
- partUploadDurationHistogram: Metric.Metric<import("effect/MetricKeyType").MetricKeyType.Histogram, number, import("effect/MetricState").MetricState.Histogram>;
28
- fileSizeHistogram: Metric.Metric<import("effect/MetricKeyType").MetricKeyType.Histogram, number, import("effect/MetricState").MetricState.Histogram>;
29
- partSizeHistogram: Metric.Metric<import("effect/MetricKeyType").MetricKeyType.Histogram, number, import("effect/MetricState").MetricState.Histogram>;
30
- uploadRequestsTotal: Metric.Metric.Counter<number>;
31
- uploadPartsTotal: Metric.Metric.Counter<number>;
32
- uploadSuccessTotal: Metric.Metric.Counter<number>;
33
- uploadErrorsTotal: Metric.Metric.Counter<number>;
34
- apiCallsTotal: Metric.Metric.Counter<number>;
35
- };
36
- export type StorageMetrics = ReturnType<typeof createStorageMetrics>;
37
- //# sourceMappingURL=metrics.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"metrics.d.ts","sourceRoot":"","sources":["../../src/core/metrics.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAoB,MAAM,QAAQ,CAAC;AAOlD,eAAO,MAAM,mBAAmB,GAAI,aAAa,MAAM;;;;;;CAoBrD,CAAC;AAGH,eAAO,MAAM,sBAAsB,GAAI,aAAa,MAAM;;;;;CAwCxD,CAAC;AAGH,eAAO,MAAM,kBAAkB,GAAI,aAAa,MAAM;;;CAWpD,CAAC;AAGH,eAAO,MAAM,qBAAqB,GAAI,aAAa,MAAM;;CASvD,CAAC;AAGH,eAAO,MAAM,oBAAoB,GAAI,aAAa,MAAM;;;;;;;;;;;;;CAKtD,CAAC;AAGH,MAAM,MAAM,cAAc,GAAG,UAAU,CAAC,OAAO,oBAAoB,CAAC,CAAC"}
@@ -1,72 +0,0 @@
1
- import { Metric, MetricBoundaries } from "effect";
2
- // ============================================================================
3
- // Core Storage Metrics (reusable across all storage types)
4
- // ============================================================================
5
- // Counter metrics
6
- export const createUploadMetrics = (storageType) => ({
7
- uploadRequestsTotal: Metric.counter(`${storageType}_upload_requests_total`, {
8
- description: `Total number of upload requests for ${storageType}`,
9
- }),
10
- uploadPartsTotal: Metric.counter(`${storageType}_upload_parts_total`, {
11
- description: `Total number of individual parts uploaded for ${storageType}`,
12
- }),
13
- uploadSuccessTotal: Metric.counter(`${storageType}_upload_success_total`, {
14
- description: `Total number of successful uploads for ${storageType}`,
15
- }),
16
- uploadErrorsTotal: Metric.counter(`${storageType}_upload_errors_total`, {
17
- description: `Total number of upload errors for ${storageType}`,
18
- }),
19
- apiCallsTotal: Metric.counter(`${storageType}_api_calls_total`, {
20
- description: `Total number of API calls for ${storageType}`,
21
- }),
22
- });
23
- // Histogram metrics for timing and sizes (reusable)
24
- export const createUploadHistograms = (storageType) => ({
25
- uploadDurationHistogram: Metric.histogram(`${storageType}_upload_duration_seconds`, MetricBoundaries.exponential({
26
- start: 0.01, // 10ms
27
- factor: 2,
28
- count: 20, // Up to ~10 seconds
29
- }), `Duration of upload operations in seconds for ${storageType}`),
30
- partUploadDurationHistogram: Metric.histogram(`${storageType}_part_upload_duration_seconds`, MetricBoundaries.exponential({
31
- start: 0.001, // 1ms
32
- factor: 2,
33
- count: 15, // Up to ~32 seconds
34
- }), `Duration of individual part uploads in seconds for ${storageType}`),
35
- fileSizeHistogram: Metric.histogram(`${storageType}_file_size_bytes`, MetricBoundaries.exponential({
36
- start: 1024, // 1KB
37
- factor: 2,
38
- count: 25, // Up to ~33GB
39
- }), `Size of uploaded files in bytes for ${storageType}`),
40
- partSizeHistogram: Metric.histogram(`${storageType}_part_size_bytes`, MetricBoundaries.linear({
41
- start: 5_242_880, // 5MB (minimum part size)
42
- width: 1_048_576, // 1MB increments
43
- count: 20, // Up to ~25MB
44
- }), `Size of upload parts in bytes for ${storageType}`),
45
- });
46
- // Gauge metrics for current state (reusable)
47
- export const createUploadGauges = (storageType) => ({
48
- activeUploadsGauge: Metric.gauge(`${storageType}_active_uploads`, {
49
- description: `Number of currently active uploads for ${storageType}`,
50
- }),
51
- uploadThroughputGauge: Metric.gauge(`${storageType}_upload_throughput_bytes_per_second`, {
52
- description: `Current upload throughput in bytes per second for ${storageType}`,
53
- }),
54
- });
55
- // Summary metrics for percentiles (reusable)
56
- export const createUploadSummaries = (storageType) => ({
57
- uploadLatencySummary: Metric.summary({
58
- name: `${storageType}_upload_latency_seconds`,
59
- maxAge: "10 minutes",
60
- maxSize: 1000,
61
- error: 0.01,
62
- quantiles: [0.5, 0.9, 0.95, 0.99],
63
- description: `Upload latency percentiles for ${storageType}`,
64
- }),
65
- });
66
- // Combined metrics factory
67
- export const createStorageMetrics = (storageType) => ({
68
- ...createUploadMetrics(storageType),
69
- ...createUploadHistograms(storageType),
70
- ...createUploadGauges(storageType),
71
- ...createUploadSummaries(storageType),
72
- });
@@ -1,43 +0,0 @@
1
- import { Effect, Layer } from "effect";
2
- import { FlowObservability, StorageObservability, UploadObservability } from "./layers.js";
3
- /**
4
- * Mock storage observability for testing
5
- */
6
- export declare const makeTestStorageObservability: (storageType: string) => Layer.Layer<StorageObservability>;
7
- /**
8
- * Mock upload observability for testing
9
- */
10
- export declare const makeTestUploadObservability: () => Layer.Layer<UploadObservability>;
11
- /**
12
- * Mock flow observability for testing
13
- */
14
- export declare const makeTestFlowObservability: () => Layer.Layer<FlowObservability>;
15
- /**
16
- * Capture metrics snapshot from an effect for testing
17
- * Note: Metric snapshots are simplified - for full metric testing,
18
- * use Effect's built-in metric testing utilities
19
- */
20
- export declare const captureMetrics: <A, E, R>(effect: Effect.Effect<A, E, R>) => Effect.Effect<A, E, R>;
21
- /**
22
- * Test helper to capture metrics around effect execution
23
- * This is a simplified version - for production testing,
24
- * use Effect's metric testing utilities
25
- */
26
- export declare const withMetricTracking: <A, E, R>(effect: Effect.Effect<A, E, R>) => Effect.Effect<A, E, R>;
27
- /**
28
- * Test fixture for observability testing
29
- */
30
- export interface ObservabilityTestFixture {
31
- readonly storageObservability: Layer.Layer<StorageObservability>;
32
- readonly uploadObservability: Layer.Layer<UploadObservability>;
33
- readonly flowObservability: Layer.Layer<FlowObservability>;
34
- }
35
- /**
36
- * Create a complete test fixture with all observability layers
37
- */
38
- export declare const createTestFixture: (storageType?: string) => ObservabilityTestFixture;
39
- /**
40
- * Run an effect with test observability layers
41
- */
42
- export declare const runWithTestObservability: <A, E>(effect: Effect.Effect<A, E, StorageObservability | UploadObservability | FlowObservability>, storageType?: string) => Effect.Effect<A, E>;
43
- //# sourceMappingURL=testing.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"testing.d.ts","sourceRoot":"","sources":["../../src/core/testing.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,KAAK,EAAU,MAAM,QAAQ,CAAC;AAM/C,OAAO,EACL,iBAAiB,EACjB,oBAAoB,EACpB,mBAAmB,EACpB,MAAM,aAAa,CAAC;AAOrB;;GAEG;AACH,eAAO,MAAM,4BAA4B,GACvC,aAAa,MAAM,KAClB,KAAK,CAAC,KAAK,CAAC,oBAAoB,CASlC,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,2BAA2B,QAClC,KAAK,CAAC,KAAK,CAAC,mBAAmB,CAYlC,CAAC;AAEJ;;GAEG;AACH,eAAO,MAAM,yBAAyB,QAAO,KAAK,CAAC,KAAK,CAAC,iBAAiB,CAYzE,CAAC;AAMF;;;;GAIG;AACH,eAAO,MAAM,cAAc,GAAI,CAAC,EAAE,CAAC,EAAE,CAAC,EACpC,QAAQ,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,KAC7B,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAMpB,CAAC;AAEL;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,GAAI,CAAC,EAAE,CAAC,EAAE,CAAC,EACxC,QAAQ,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,KAC7B,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAQpB,CAAC;AAEL;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,oBAAoB,EAAE,KAAK,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC;IACjE,QAAQ,CAAC,mBAAmB,EAAE,KAAK,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAC;IAC/D,QAAQ,CAAC,iBAAiB,EAAE,KAAK,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;CAC5D;AAED;;GAEG;AACH,eAAO,MAAM,iBAAiB,GAC5B,oBAA4B,KAC3B,wBAID,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,wBAAwB,GAAI,CAAC,EAAE,CAAC,EAC3C,QAAQ,MAAM,CAAC,MAAM,CACnB,CAAC,EACD,CAAC,EACD,oBAAoB,GAAG,mBAAmB,GAAG,iBAAiB,CAC/D,EACD,oBAA4B,KAC3B,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAOpB,CAAC"}
@@ -1,93 +0,0 @@
1
- import { Effect, Layer, Metric } from "effect";
2
- import { FlowObservability, StorageObservability, UploadObservability, } from "./layers.js";
3
- import { createStorageMetrics } from "./metrics.js";
4
- // ============================================================================
5
- // Test Observability Layers
6
- // ============================================================================
7
- /**
8
- * Mock storage observability for testing
9
- */
10
- export const makeTestStorageObservability = (storageType) => {
11
- const metrics = createStorageMetrics(storageType);
12
- const service = {
13
- serviceName: `test-${storageType}-store`,
14
- storageType,
15
- metrics,
16
- enabled: true,
17
- };
18
- return Layer.succeed(StorageObservability, service);
19
- };
20
- /**
21
- * Mock upload observability for testing
22
- */
23
- export const makeTestUploadObservability = () => {
24
- const service = {
25
- serviceName: "test-upload-server",
26
- enabled: true,
27
- metrics: {
28
- uploadCreated: Effect.void,
29
- uploadCompleted: Effect.void,
30
- uploadFailed: Effect.void,
31
- chunkUploaded: Effect.void,
32
- },
33
- };
34
- return Layer.succeed(UploadObservability, service);
35
- };
36
- /**
37
- * Mock flow observability for testing
38
- */
39
- export const makeTestFlowObservability = () => {
40
- const service = {
41
- serviceName: "test-flow-engine",
42
- enabled: true,
43
- metrics: {
44
- flowStarted: Effect.void,
45
- flowCompleted: Effect.void,
46
- flowFailed: Effect.void,
47
- nodeExecuted: Effect.void,
48
- },
49
- };
50
- return Layer.succeed(FlowObservability, service);
51
- };
52
- // ============================================================================
53
- // Test Utilities
54
- // ============================================================================
55
- /**
56
- * Capture metrics snapshot from an effect for testing
57
- * Note: Metric snapshots are simplified - for full metric testing,
58
- * use Effect's built-in metric testing utilities
59
- */
60
- export const captureMetrics = (effect) => Effect.gen(function* () {
61
- const result = yield* effect;
62
- // Metrics are automatically captured by Effect runtime
63
- yield* Metric.snapshot;
64
- return result;
65
- });
66
- /**
67
- * Test helper to capture metrics around effect execution
68
- * This is a simplified version - for production testing,
69
- * use Effect's metric testing utilities
70
- */
71
- export const withMetricTracking = (effect) => Effect.gen(function* () {
72
- // Track metric before execution
73
- yield* Metric.snapshot;
74
- const result = yield* effect;
75
- // Track metric after execution
76
- yield* Metric.snapshot;
77
- return result;
78
- });
79
- /**
80
- * Create a complete test fixture with all observability layers
81
- */
82
- export const createTestFixture = (storageType = "test-storage") => ({
83
- storageObservability: makeTestStorageObservability(storageType),
84
- uploadObservability: makeTestUploadObservability(),
85
- flowObservability: makeTestFlowObservability(),
86
- });
87
- /**
88
- * Run an effect with test observability layers
89
- */
90
- export const runWithTestObservability = (effect, storageType = "test-storage") => {
91
- const fixture = createTestFixture(storageType);
92
- return effect.pipe(Effect.provide(fixture.storageObservability), Effect.provide(fixture.uploadObservability), Effect.provide(fixture.flowObservability));
93
- };
@@ -1,19 +0,0 @@
1
- import { Context, Effect, Layer } from "effect";
2
- export declare const TracingService: Context.Tag<{
3
- serviceName: string;
4
- }, {
5
- serviceName: string;
6
- }>;
7
- export declare const createTracingLayer: (options?: {
8
- serviceName?: string;
9
- }) => Layer.Layer<{
10
- serviceName: string;
11
- }, never, never>;
12
- export declare const createStorageTracingLayer: (storageType: string) => Layer.Layer<{
13
- serviceName: string;
14
- }, never, never>;
15
- export declare const withStorageSpan: <A, E, R>(operation: string, storageType: string, attributes?: Record<string, unknown>) => (effect: Effect.Effect<A, E, R>) => Effect.Effect<A, E, Exclude<R, import("effect/Tracer").ParentSpan>>;
16
- export declare const WebSdkLive: Layer.Layer<import("@effect/opentelemetry/Resource").Resource, never, never>;
17
- export declare const NodeSdkLive: Layer.Layer<import("@effect/opentelemetry/Resource").Resource, never, never>;
18
- export declare const WorkersSdkLive: Layer.Layer<import("@effect/opentelemetry/Resource").Resource, never, never>;
19
- //# sourceMappingURL=tracing.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"tracing.d.ts","sourceRoot":"","sources":["../../src/core/tracing.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AAOhD,eAAO,MAAM,cAAc;iBAAqC,MAAM;;iBAAN,MAAM;EAErE,CAAC;AAGF,eAAO,MAAM,kBAAkB,GAAI,UAAU;IAAE,WAAW,CAAC,EAAE,MAAM,CAAA;CAAE;iBALL,MAAM;gBAUrE,CAAC;AAGF,eAAO,MAAM,yBAAyB,GAAI,aAAa,MAAM;iBAbG,MAAM;gBAgBlE,CAAC;AAGL,eAAO,MAAM,eAAe,GACzB,CAAC,EAAE,CAAC,EAAE,CAAC,EACN,WAAW,MAAM,EACjB,aAAa,MAAM,EACnB,aAAa,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,MAErC,QAAQ,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,wEAS5B,CAAC;AAGN,eAAO,MAAM,UAAU,8EAIpB,CAAC;AAEJ,eAAO,MAAM,WAAW,8EAIrB,CAAC;AAGJ,eAAO,MAAM,cAAc,8EAIxB,CAAC"}
@@ -1,43 +0,0 @@
1
- import { NodeSdk, WebSdk } from "@effect/opentelemetry";
2
- import { BatchSpanProcessor, ConsoleSpanExporter, } from "@opentelemetry/sdk-trace-base";
3
- import { Context, Effect, Layer } from "effect";
4
- // ============================================================================
5
- // Universal Tracing (Environment-agnostic)
6
- // ============================================================================
7
- // Generic service tag for tracing context
8
- export const TracingService = Context.GenericTag("TracingService");
9
- // Create a tracing layer using Effect's native tracing (works in all environments)
10
- export const createTracingLayer = (options) => {
11
- const serviceName = options?.serviceName ?? "uploadista-storage";
12
- // Return a layer that provides tracing service context
13
- return Layer.succeed(TracingService, { serviceName });
14
- };
15
- // Storage-specific tracing layers
16
- export const createStorageTracingLayer = (storageType) => createTracingLayer({
17
- serviceName: `uploadista-${storageType}-store`,
18
- });
19
- // Utility to add storage context to spans
20
- export const withStorageSpan = (operation, storageType, attributes) => (effect) => effect.pipe(Effect.withSpan(`${storageType}-${operation}`, {
21
- attributes: {
22
- "storage.type": storageType,
23
- operation: operation,
24
- ...attributes,
25
- },
26
- }));
27
- // Set up tracing with the OpenTelemetry SDK
28
- export const WebSdkLive = WebSdk.layer(() => ({
29
- resource: { serviceName: "uploadista-storage" },
30
- // Export span data to the console
31
- spanProcessor: new BatchSpanProcessor(new ConsoleSpanExporter()),
32
- }));
33
- export const NodeSdkLive = NodeSdk.layer(() => ({
34
- resource: { serviceName: "uploadista-storage" },
35
- // Export span data to the console
36
- spanProcessor: new BatchSpanProcessor(new ConsoleSpanExporter()),
37
- }));
38
- // Cloudflare Workers SDK (uses WebSdk as base)
39
- export const WorkersSdkLive = WebSdk.layer(() => ({
40
- resource: { serviceName: "uploadista-storage-workers" },
41
- // Export span data to the console in Workers environment
42
- spanProcessor: new BatchSpanProcessor(new ConsoleSpanExporter()),
43
- }));
@@ -1,11 +0,0 @@
1
- import { Effect, Metric } from "effect";
2
- import type { StorageMetrics } from "./metrics.js";
3
- export declare const withUploadMetrics: <A, E, R>(metrics: StorageMetrics, uploadId: string, effect: Effect.Effect<A, E, R>) => Effect.Effect<A, E, R>;
4
- export declare const withApiMetrics: <A, E, R>(metrics: StorageMetrics, operation: string, effect: Effect.Effect<A, E, R>) => Effect.Effect<A, E, R>;
5
- export declare const withTimingMetrics: <A, E, R>(metric: Metric.Metric.Histogram<number>, effect: Effect.Effect<A, E, R>) => Effect.Effect<A, E, R>;
6
- export declare const trackFileSize: <A, E, R>(metrics: StorageMetrics, fileSize: number, effect: Effect.Effect<A, E, R>) => Effect.Effect<A, E, R>;
7
- export declare const trackPartSize: <A, E, R>(metrics: StorageMetrics, partSize: number, effect: Effect.Effect<A, E, R>) => Effect.Effect<A, E, R>;
8
- export declare const withActiveUploadTracking: <A, E, R>(metrics: StorageMetrics, effect: Effect.Effect<A, E, R>) => Effect.Effect<A, E, R>;
9
- export declare const withThroughputTracking: <A, E, R>(metrics: StorageMetrics, bytes: number, effect: Effect.Effect<A, E, R>) => Effect.Effect<A, E, R>;
10
- export declare const withStorageOperationMetrics: <A, E, R>(metrics: StorageMetrics, operation: string, uploadId: string, effect: Effect.Effect<A, E, R>, fileSize?: number) => Effect.Effect<A, E, R>;
11
- //# sourceMappingURL=utilities.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"utilities.d.ts","sourceRoot":"","sources":["../../src/core/utilities.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AACxC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAOnD,eAAO,MAAM,iBAAiB,GAAI,CAAC,EAAE,CAAC,EAAE,CAAC,EACvC,SAAS,cAAc,EACvB,UAAU,MAAM,EAChB,QAAQ,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,KAC7B,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAiBrB,CAAC;AAGJ,eAAO,MAAM,cAAc,GAAI,CAAC,EAAE,CAAC,EAAE,CAAC,EACpC,SAAS,cAAc,EACvB,WAAW,MAAM,EACjB,QAAQ,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,KAC7B,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAOrB,CAAC;AAGJ,eAAO,MAAM,iBAAiB,GAAI,CAAC,EAAE,CAAC,EAAE,CAAC,EACvC,QAAQ,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,EACvC,QAAQ,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,KAC7B,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAUpB,CAAC;AAGL,eAAO,MAAM,aAAa,GAAI,CAAC,EAAE,CAAC,EAAE,CAAC,EACnC,SAAS,cAAc,EACvB,UAAU,MAAM,EAChB,QAAQ,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,KAC7B,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAGrB,CAAC;AAGJ,eAAO,MAAM,aAAa,GAAI,CAAC,EAAE,CAAC,EAAE,CAAC,EACnC,SAAS,cAAc,EACvB,UAAU,MAAM,EAChB,QAAQ,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,KAC7B,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAGrB,CAAC;AAGJ,eAAO,MAAM,wBAAwB,GAAI,CAAC,EAAE,CAAC,EAAE,CAAC,EAC9C,SAAS,cAAc,EACvB,QAAQ,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,KAC7B,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAIrB,CAAC;AAGJ,eAAO,MAAM,sBAAsB,GAAI,CAAC,EAAE,CAAC,EAAE,CAAC,EAC5C,SAAS,cAAc,EACvB,OAAO,MAAM,EACb,QAAQ,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,KAC7B,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAWpB,CAAC;AAGL,eAAO,MAAM,2BAA2B,GAAI,CAAC,EAAE,CAAC,EAAE,CAAC,EACjD,SAAS,cAAc,EACvB,WAAW,MAAM,EACjB,UAAU,MAAM,EAChB,QAAQ,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAC9B,WAAW,MAAM,KAChB,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAgBvB,CAAC"}