@workflow/web 5.0.0-beta.3 → 5.0.0-beta.5

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 (25) hide show
  1. package/build/client/assets/{encryption-80GMP4r0.js → encryption-CEh0YXii.js} +4 -2
  2. package/build/client/assets/{entry.client-BWsSsWQm.js → entry.client-DtOpLtMQ.js} +1 -1
  3. package/build/client/assets/{highlighted-body-B3W2YXNL-Be0uLJd8.js → highlighted-body-B3W2YXNL-L1CrwoL_.js} +2 -2
  4. package/build/client/assets/{home-Ce97yLJ7.js → home-B6UmDDP6.js} +4 -3
  5. package/build/client/assets/index-B4xuge0I.js +249 -0
  6. package/build/client/assets/{index-DQa-BExo.js → index-BsV8i_Jn.js} +20 -20
  7. package/build/client/assets/manifest-e4c1c787.js +1 -0
  8. package/build/client/assets/{mermaid-3ZIDBTTL-BSJR0c5A.js → mermaid-3ZIDBTTL-BQLU7GUr.js} +372 -208
  9. package/build/client/assets/root-C0Tu5TVN.css +1 -0
  10. package/build/client/assets/{root-DdOfCnSG.js → root-Yk3JVwUh.js} +2 -2
  11. package/build/client/assets/{run-detail-JQ32aJru.js → run-detail-DMUaWXhb.js} +444 -75
  12. package/build/client/assets/server-build-DqaxIrF0.css +1 -0
  13. package/build/client/assets/{workflow-graph-viewer-DYhMo9jl.js → workflow-graph-viewer-yqeN-U_2.js} +3 -3
  14. package/build/server/assets/{app-Bh_7yjpl.js → app-L1V62FgT.js} +1 -1
  15. package/build/server/assets/{highlighted-body-B3W2YXNL-Cdb-ypB4.js → highlighted-body-B3W2YXNL-CZjJIpdD.js} +6 -7
  16. package/build/server/assets/{index-CNvEtg5c.js → index-BwtNigf1.js} +18 -20
  17. package/build/server/assets/{mermaid-3ZIDBTTL-CE8Volk5.js → mermaid-3ZIDBTTL-Cc8IPTBj.js} +6 -7
  18. package/build/server/assets/{server-build-DztRAoMd.js → server-build-DtcOUEHS.js} +34997 -34048
  19. package/build/server/assets/{token-DMEdoEUo.js → token-DHnArVm7.js} +2 -2
  20. package/build/server/assets/{token-util-DsMisyo3.js → token-util-B3uKeZ0s.js} +2 -2
  21. package/build/server/index.js +1 -1
  22. package/package.json +8 -7
  23. package/build/client/assets/manifest-923d96a0.js +0 -1
  24. package/build/client/assets/root-DXDFWibD.css +0 -1
  25. package/build/client/assets/server-build-pZ5ucXET.css +0 -1
@@ -1,9 +1,9 @@
1
- const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/highlighted-body-B3W2YXNL-Be0uLJd8.js","assets/index-DQa-BExo.js"])))=>i.map(i=>d[i]);
1
+ const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/encryption-CEh0YXii.js","assets/index-B4xuge0I.js","assets/index-BsV8i_Jn.js","assets/highlighted-body-B3W2YXNL-L1CrwoL_.js"])))=>i.map(i=>d[i]);
2
2
  var __defProp = Object.defineProperty;
3
3
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
4
4
  var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
5
5
  var _a2;
6
- import { r as reactExports, j as jsxRuntimeExports, f as reactDomExports, H as React, R as ReactExports, C as ReactDOM, I as getDefaultExportFromCjs } from "./index-DQa-BExo.js";
6
+ import { r as reactExports, j as jsxRuntimeExports, f as reactDomExports, I as React, R as ReactExports, D as ReactDOM, g as getDefaultExportFromCjs } from "./index-BsV8i_Jn.js";
7
7
  function composeEventHandlers(originalEventHandler, ourEventHandler, { checkForDefaultPrevented = true } = {}) {
8
8
  return function handleEvent(event) {
9
9
  originalEventHandler == null ? void 0 : originalEventHandler(event);
@@ -6673,6 +6673,28 @@ const createLucideIcon = (iconName, iconNode) => {
6673
6673
  Component.displayName = toPascalCase(iconName);
6674
6674
  return Component;
6675
6675
  };
6676
+ /**
6677
+ * @license lucide-react v0.575.0 - ISC
6678
+ *
6679
+ * This source code is licensed under the ISC license.
6680
+ * See the LICENSE file in the root directory of this source tree.
6681
+ */
6682
+ const __iconNode$3 = [
6683
+ ["path", { d: "m12 19-7-7 7-7", key: "1l729n" }],
6684
+ ["path", { d: "M19 12H5", key: "x3x0zl" }]
6685
+ ];
6686
+ const ArrowLeft = createLucideIcon("arrow-left", __iconNode$3);
6687
+ /**
6688
+ * @license lucide-react v0.575.0 - ISC
6689
+ *
6690
+ * This source code is licensed under the ISC license.
6691
+ * See the LICENSE file in the root directory of this source tree.
6692
+ */
6693
+ const __iconNode$2 = [
6694
+ ["path", { d: "M5 12h14", key: "1ays0h" }],
6695
+ ["path", { d: "m12 5 7 7-7 7", key: "xquz4c" }]
6696
+ ];
6697
+ const ArrowRight = createLucideIcon("arrow-right", __iconNode$2);
6676
6698
  /**
6677
6699
  * @license lucide-react v0.575.0 - ISC
6678
6700
  *
@@ -6695,10 +6717,6 @@ const Lock = createLucideIcon("lock", __iconNode);
6695
6717
  function cn$4(...inputs) {
6696
6718
  return twMerge(clsx(inputs));
6697
6719
  }
6698
- const secondsFormatter = new Intl.NumberFormat(void 0, {
6699
- minimumFractionDigits: 2,
6700
- maximumFractionDigits: 2
6701
- });
6702
6720
  const MS_IN_SECOND = 1e3;
6703
6721
  const MS_IN_MINUTE = 60 * MS_IN_SECOND;
6704
6722
  const MS_IN_HOUR = 60 * MS_IN_MINUTE;
@@ -6707,23 +6725,28 @@ function formatDuration(ms, compact = false) {
6707
6725
  if (ms === 0) {
6708
6726
  return "0s";
6709
6727
  }
6710
- if (ms < MS_IN_MINUTE) {
6711
- return `${secondsFormatter.format(ms / MS_IN_SECOND)}s`;
6728
+ if (ms < MS_IN_SECOND) {
6729
+ const roundedMs2 = Math.round(ms);
6730
+ return roundedMs2 < MS_IN_SECOND ? `${roundedMs2}ms` : "1s";
6731
+ }
6732
+ const roundedMs = Math.round(ms / MS_IN_SECOND) * MS_IN_SECOND;
6733
+ if (roundedMs < MS_IN_MINUTE) {
6734
+ return `${Math.floor(roundedMs / MS_IN_SECOND)}s`;
6712
6735
  }
6713
6736
  if (compact) {
6714
- if (ms < MS_IN_HOUR) {
6715
- const m3 = Math.floor(ms / MS_IN_MINUTE);
6716
- const s2 = Math.floor(ms % MS_IN_MINUTE / MS_IN_SECOND);
6737
+ if (roundedMs < MS_IN_HOUR) {
6738
+ const m3 = Math.floor(roundedMs / MS_IN_MINUTE);
6739
+ const s2 = Math.floor(roundedMs % MS_IN_MINUTE / MS_IN_SECOND);
6717
6740
  return s2 > 0 ? `${m3}m ${s2}s` : `${m3}m`;
6718
6741
  }
6719
- const h2 = Math.floor(ms / MS_IN_HOUR);
6720
- const m2 = Math.floor(ms % MS_IN_HOUR / MS_IN_MINUTE);
6742
+ const h2 = Math.floor(roundedMs / MS_IN_HOUR);
6743
+ const m2 = Math.floor(roundedMs % MS_IN_HOUR / MS_IN_MINUTE);
6721
6744
  return m2 > 0 ? `${h2}h ${m2}m` : `${h2}h`;
6722
6745
  }
6723
- const days = Math.floor(ms / MS_IN_DAY);
6724
- const hours = Math.floor(ms % MS_IN_DAY / MS_IN_HOUR);
6725
- const minutes = Math.floor(ms % MS_IN_HOUR / MS_IN_MINUTE);
6726
- const seconds = ms % MS_IN_MINUTE / MS_IN_SECOND;
6746
+ const days = Math.floor(roundedMs / MS_IN_DAY);
6747
+ const hours = Math.floor(roundedMs % MS_IN_DAY / MS_IN_HOUR);
6748
+ const minutes = Math.floor(roundedMs % MS_IN_HOUR / MS_IN_MINUTE);
6749
+ const seconds = Math.floor(roundedMs % MS_IN_MINUTE / MS_IN_SECOND);
6727
6750
  const parts = [];
6728
6751
  if (days > 0) {
6729
6752
  parts.push(`${days}d`);
@@ -6734,7 +6757,7 @@ function formatDuration(ms, compact = false) {
6734
6757
  if (minutes > 0) {
6735
6758
  parts.push(`${minutes}m`);
6736
6759
  }
6737
- parts.push(`${secondsFormatter.format(seconds)}s`);
6760
+ parts.push(`${seconds}s`);
6738
6761
  return parts.join(" ");
6739
6762
  }
6740
6763
  function isDoStreamStep(stepName) {
@@ -10336,9 +10359,9 @@ function hydrateData(value, revivers) {
10336
10359
  async function hydrateDataWithKey(value, revivers, key) {
10337
10360
  if (value instanceof Uint8Array && isEncryptedData(value) && key) {
10338
10361
  const { decrypt } = await __vitePreload(async () => {
10339
- const { decrypt: decrypt2 } = await import("./encryption-80GMP4r0.js");
10362
+ const { decrypt: decrypt2 } = await import("./encryption-CEh0YXii.js");
10340
10363
  return { decrypt: decrypt2 };
10341
- }, true ? [] : void 0);
10364
+ }, true ? __vite__mapDeps([0,1,2]) : void 0);
10342
10365
  const { payload } = decodeFormatPrefix(value);
10343
10366
  const decrypted = await decrypt(key, payload);
10344
10367
  return hydrateData(decrypted, revivers);
@@ -10418,6 +10441,34 @@ const observabilityRevivers = {
10418
10441
  ReadableStream: streamToStreamRef,
10419
10442
  WritableStream: streamToStreamRef,
10420
10443
  TransformStream: streamToStreamRef,
10444
+ AbortController: (value) => `<AbortController(aborted: ${value.aborted})>`,
10445
+ AbortSignal: (value) => `<AbortSignal(aborted: ${value.aborted})>`,
10446
+ // DOMException needs an explicit reviver: without one, devalue.parse
10447
+ // throws on the `["DOMException", ...]` tag and `hydrateStepIO`'s
10448
+ // try/catch leaves the raw flat-encoded string in the UI. AbortController
10449
+ // synthesizes a DOMException as the default `signal.reason` when abort()
10450
+ // is called with no arg — so any abort that round-trips through a step
10451
+ // boundary surfaces here. Reconstruct as a real DOMException when the
10452
+ // global is available (modern browsers + Node 18+), else fall back to
10453
+ // an Error preserving name/message/stack/cause for display.
10454
+ DOMException: (value) => {
10455
+ const G2 = globalThis;
10456
+ if (typeof G2.DOMException === "function") {
10457
+ const e2 = new G2.DOMException(value.message, value.name);
10458
+ if (value.stack !== void 0)
10459
+ e2.stack = value.stack;
10460
+ if ("cause" in value)
10461
+ e2.cause = value.cause;
10462
+ return e2;
10463
+ }
10464
+ const e = new Error(value.message);
10465
+ e.name = value.name;
10466
+ if (value.stack !== void 0)
10467
+ e.stack = value.stack;
10468
+ if ("cause" in value)
10469
+ e.cause = value.cause;
10470
+ return e;
10471
+ },
10421
10472
  StepFunction: serializedStepFunctionToString,
10422
10473
  WorkflowFunction: (value) => `<workflow:${value.workflowId}>`,
10423
10474
  Instance: serializedInstanceToRef,
@@ -10426,6 +10477,7 @@ const observabilityRevivers = {
10426
10477
  function hydrateStepIO(resource, revivers) {
10427
10478
  let hydratedInput = resource.input;
10428
10479
  let hydratedOutput = resource.output;
10480
+ let hydratedError = resource.error;
10429
10481
  if (resource.input != null) {
10430
10482
  try {
10431
10483
  hydratedInput = hydrateData(resource.input, revivers);
@@ -10438,11 +10490,23 @@ function hydrateStepIO(resource, revivers) {
10438
10490
  } catch {
10439
10491
  }
10440
10492
  }
10441
- return { ...resource, input: hydratedInput, output: hydratedOutput };
10493
+ if (resource.error != null) {
10494
+ try {
10495
+ hydratedError = hydrateData(resource.error, revivers);
10496
+ } catch {
10497
+ }
10498
+ }
10499
+ return {
10500
+ ...resource,
10501
+ input: hydratedInput,
10502
+ output: hydratedOutput,
10503
+ error: hydratedError
10504
+ };
10442
10505
  }
10443
10506
  function hydrateWorkflowIO(resource, revivers) {
10444
10507
  let hydratedInput = resource.input;
10445
10508
  let hydratedOutput = resource.output;
10509
+ let hydratedError = resource.error;
10446
10510
  if (resource.input != null) {
10447
10511
  try {
10448
10512
  hydratedInput = hydrateData(resource.input, revivers);
@@ -10455,7 +10519,18 @@ function hydrateWorkflowIO(resource, revivers) {
10455
10519
  } catch {
10456
10520
  }
10457
10521
  }
10458
- return { ...resource, input: hydratedInput, output: hydratedOutput };
10522
+ if (resource.error != null) {
10523
+ try {
10524
+ hydratedError = hydrateData(resource.error, revivers);
10525
+ } catch {
10526
+ }
10527
+ }
10528
+ return {
10529
+ ...resource,
10530
+ input: hydratedInput,
10531
+ output: hydratedOutput,
10532
+ error: hydratedError
10533
+ };
10459
10534
  }
10460
10535
  function hydrateEventData(resource, revivers) {
10461
10536
  if (!resource.eventData)
@@ -10491,6 +10566,12 @@ function hydrateEventData(resource, revivers) {
10491
10566
  } catch {
10492
10567
  }
10493
10568
  }
10569
+ if ("error" in eventData && eventData.error != null) {
10570
+ try {
10571
+ eventData.error = hydrateData(eventData.error, revivers);
10572
+ } catch {
10573
+ }
10574
+ }
10494
10575
  return { ...resource, eventData };
10495
10576
  }
10496
10577
  function hydrateHookMetadata(resource, revivers) {
@@ -15286,16 +15367,18 @@ const StepFailedEventSchema = BaseEventSchema.extend({
15286
15367
  eventType: literal("step_failed"),
15287
15368
  correlationId: string$2(),
15288
15369
  eventData: object({
15289
- error: any(),
15290
- stack: string$2().optional()
15370
+ // The thrown value, serialized via the workflow serialization pipeline.
15371
+ // Can be any JavaScript value (string, number, object, Error, etc.)
15372
+ error: SerializedDataSchema
15291
15373
  })
15292
15374
  });
15293
15375
  const StepRetryingEventSchema = BaseEventSchema.extend({
15294
15376
  eventType: literal("step_retrying"),
15295
15377
  correlationId: string$2(),
15296
15378
  eventData: object({
15297
- error: any(),
15298
- stack: string$2().optional(),
15379
+ // The thrown value, serialized via the workflow serialization pipeline.
15380
+ // Can be any JavaScript value (string, number, object, Error, etc.)
15381
+ error: SerializedDataSchema,
15299
15382
  retryAfter: date().optional()
15300
15383
  })
15301
15384
  });
@@ -15319,7 +15402,9 @@ const HookCreatedEventSchema = BaseEventSchema.extend({
15319
15402
  correlationId: string$2(),
15320
15403
  eventData: object({
15321
15404
  token: string$2(),
15322
- metadata: SerializedDataSchema.optional()
15405
+ metadata: SerializedDataSchema.optional(),
15406
+ isWebhook: boolean$2().optional(),
15407
+ isSystem: boolean$2().optional()
15323
15408
  })
15324
15409
  });
15325
15410
  const HookReceivedEventSchema = BaseEventSchema.extend({
@@ -15378,7 +15463,13 @@ const RunCompletedEventSchema = BaseEventSchema.extend({
15378
15463
  const RunFailedEventSchema = BaseEventSchema.extend({
15379
15464
  eventType: literal("run_failed"),
15380
15465
  eventData: object({
15381
- error: any(),
15466
+ // The thrown value, serialized via the workflow serialization pipeline.
15467
+ // Can be any JavaScript value (string, number, object, Error, etc.)
15468
+ error: SerializedDataSchema,
15469
+ // The high-level error category (USER_ERROR, RUNTIME_ERROR, etc.) used
15470
+ // for routing and classification. Kept as plaintext metadata so
15471
+ // observability tools can filter/categorize without needing to decrypt
15472
+ // the full error payload.
15382
15473
  errorCode: string$2().optional()
15383
15474
  })
15384
15475
  });
@@ -15446,7 +15537,8 @@ object({
15446
15537
  createdAt: date(),
15447
15538
  // Optional in database for backwards compatibility, defaults to 1 (legacy) when reading
15448
15539
  specVersion: number$2().optional(),
15449
- isWebhook: boolean$2().optional()
15540
+ isWebhook: boolean$2().optional(),
15541
+ isSystem: boolean$2().optional()
15450
15542
  });
15451
15543
  const QueuePrefix = union([
15452
15544
  literal("__wkf_step_"),
@@ -15468,6 +15560,11 @@ const WorkflowInvokePayloadSchema = object({
15468
15560
  requestedAt: date().optional(),
15469
15561
  /** Number of times this message has been re-enqueued due to server errors (5xx) */
15470
15562
  serverErrorRetryCount: number$2().int().optional(),
15563
+ /** Step ID for inline step execution in combined handler. If provided, the flow execution
15564
+ * will jump directly to execute the step with the given ID before doing an event replay. */
15565
+ stepId: string$2().optional(),
15566
+ /** Step name, sent alongside stepId to avoid loading the event log just to resolve the name. */
15567
+ stepName: string$2().optional(),
15471
15568
  /** Run creation data, only present on the first queue delivery from start() */
15472
15569
  runInput: RunInputSchema.optional()
15473
15570
  });
@@ -15488,22 +15585,6 @@ union([
15488
15585
  StepInvokePayloadSchema,
15489
15586
  HealthCheckPayloadSchema
15490
15587
  ]);
15491
- const zodJsonSchema = lazy(() => {
15492
- return union([
15493
- string$2(),
15494
- number$2(),
15495
- boolean$2(),
15496
- _null(),
15497
- array(zodJsonSchema),
15498
- record(string$2(), zodJsonSchema)
15499
- ]);
15500
- });
15501
- const StructuredErrorSchema = object({
15502
- message: string$2(),
15503
- stack: string$2().optional(),
15504
- code: string$2().optional()
15505
- // Populated with RunErrorCode values (USER_ERROR, RUNTIME_ERROR) for run_failed events
15506
- });
15507
15588
  const WorkflowRunStatusSchema = _enum([
15508
15589
  "pending",
15509
15590
  "running",
@@ -15541,7 +15622,20 @@ const WorkflowRunBaseSchema = object({
15541
15622
  executionContext: record(string$2(), any()).optional(),
15542
15623
  input: SerializedDataSchema,
15543
15624
  output: SerializedDataSchema.optional(),
15544
- error: StructuredErrorSchema.optional(),
15625
+ /**
15626
+ * The thrown value from a run_failed event, serialized via the workflow
15627
+ * serialization pipeline. To display the error to a user, hydrate it via
15628
+ * `hydrateRunError` (with the encryption key if encryption is enabled).
15629
+ * Observability tools cannot view the error without going through the
15630
+ * decryption + hydration pipeline.
15631
+ */
15632
+ error: SerializedDataSchema.optional(),
15633
+ /**
15634
+ * The high-level error category (USER_ERROR, RUNTIME_ERROR, etc.) from a
15635
+ * run_failed event. Kept as plaintext metadata for routing and filtering
15636
+ * without needing to decrypt the full error payload.
15637
+ */
15638
+ errorCode: string$2().optional(),
15545
15639
  expiredAt: date().optional(),
15546
15640
  startedAt: date().optional(),
15547
15641
  completedAt: date().optional(),
@@ -15552,32 +15646,48 @@ discriminatedUnion("status", [
15552
15646
  // Non-final states
15553
15647
  WorkflowRunBaseSchema.extend({
15554
15648
  status: _enum(["pending", "running"]),
15555
- output: _undefined(),
15556
- error: _undefined(),
15557
- completedAt: _undefined()
15649
+ output: _undefined().optional(),
15650
+ error: _undefined().optional(),
15651
+ completedAt: _undefined().optional()
15558
15652
  }),
15559
15653
  // Cancelled state
15560
15654
  WorkflowRunBaseSchema.extend({
15561
15655
  status: literal("cancelled"),
15562
- output: _undefined(),
15563
- error: _undefined(),
15656
+ output: _undefined().optional(),
15657
+ error: _undefined().optional(),
15564
15658
  completedAt: date()
15565
15659
  }),
15566
15660
  // Completed state - output can be v1 or v2 format
15567
15661
  WorkflowRunBaseSchema.extend({
15568
15662
  status: literal("completed"),
15569
15663
  output: SerializedDataSchema,
15570
- error: _undefined(),
15664
+ error: _undefined().optional(),
15571
15665
  completedAt: date()
15572
15666
  }),
15573
15667
  // Failed state
15574
15668
  WorkflowRunBaseSchema.extend({
15575
15669
  status: literal("failed"),
15576
- output: _undefined(),
15577
- error: StructuredErrorSchema,
15670
+ output: _undefined().optional(),
15671
+ error: SerializedDataSchema,
15578
15672
  completedAt: date()
15579
15673
  })
15580
15674
  ]);
15675
+ const zodJsonSchema = lazy(() => {
15676
+ return union([
15677
+ string$2(),
15678
+ number$2(),
15679
+ boolean$2(),
15680
+ _null(),
15681
+ array(zodJsonSchema),
15682
+ record(string$2(), zodJsonSchema)
15683
+ ]);
15684
+ });
15685
+ object({
15686
+ message: string$2(),
15687
+ stack: string$2().optional(),
15688
+ code: string$2().optional()
15689
+ // Populated with RunErrorCode values (USER_ERROR, RUNTIME_ERROR) for run_failed events
15690
+ });
15581
15691
  const StepStatusSchema = _enum([
15582
15692
  "pending",
15583
15693
  "running",
@@ -15613,11 +15723,16 @@ object({
15613
15723
  input: SerializedDataSchema,
15614
15724
  output: SerializedDataSchema.optional(),
15615
15725
  /**
15616
- * The error from a step_retrying or step_failed event.
15617
- * This tracks the most recent error the step encountered, which may
15618
- * be from a retry attempt (step_retrying) or the final failure (step_failed).
15726
+ * The thrown value from a step_retrying or step_failed event, serialized
15727
+ * via the workflow serialization pipeline. Tracks the most recent error
15728
+ * the step encountered, which may be from a retry attempt (step_retrying)
15729
+ * or the final failure (step_failed).
15730
+ *
15731
+ * To display the error to a user, hydrate it via `hydrateStepError` (with
15732
+ * the encryption key if encryption is enabled). Observability tools cannot
15733
+ * view the error without going through the decryption + hydration pipeline.
15619
15734
  */
15620
- error: StructuredErrorSchema.optional(),
15735
+ error: SerializedDataSchema.optional(),
15621
15736
  attempt: number$2(),
15622
15737
  /**
15623
15738
  * When the step first started executing. Set by the first step_started event
@@ -15654,6 +15769,21 @@ function base64ToArrayBuffer(base642) {
15654
15769
  }
15655
15770
  return bytes.buffer;
15656
15771
  }
15772
+ function makeWebErrorSubclassReviver(name2) {
15773
+ return (value) => {
15774
+ const opts = "cause" in value ? { cause: value.cause } : void 0;
15775
+ const Ctor = globalThis[name2];
15776
+ let error;
15777
+ if (typeof Ctor === "function") {
15778
+ error = new Ctor(value.message, opts);
15779
+ } else {
15780
+ error = Object.assign(new Error(value.message, opts), { name: name2 });
15781
+ }
15782
+ if (value.stack !== void 0)
15783
+ error.stack = value.stack;
15784
+ return error;
15785
+ };
15786
+ }
15657
15787
  function getWebRevivers() {
15658
15788
  function reviveArrayBuffer(value) {
15659
15789
  return base64ToArrayBuffer(value);
@@ -15668,10 +15798,83 @@ function getWebRevivers() {
15668
15798
  BigInt64Array: (value) => new BigInt64Array(reviveArrayBuffer(value)),
15669
15799
  BigUint64Array: (value) => new BigUint64Array(reviveArrayBuffer(value)),
15670
15800
  Date: (value) => new Date(value),
15801
+ // Error family. The reducer side (see
15802
+ // `packages/core/src/serialization/reducers/common.ts`) emits a tagged
15803
+ // entry for each built-in Error subclass plus the workflow-specific
15804
+ // `FatalError` / `RetryableError` and `AggregateError`. Without
15805
+ // matching revivers here, `devalue.unflatten` throws "Unknown type X"
15806
+ // — which surfaces in the web o11y UI as "Failed to load resource
15807
+ // details: Unknown type FatalError".
15671
15808
  Error: (value) => {
15809
+ const opts = "cause" in value ? { cause: value.cause } : void 0;
15810
+ const error = new Error(value.message, opts);
15811
+ error.name = value.name;
15812
+ if (value.stack !== void 0)
15813
+ error.stack = value.stack;
15814
+ return error;
15815
+ },
15816
+ EvalError: makeWebErrorSubclassReviver("EvalError"),
15817
+ RangeError: makeWebErrorSubclassReviver("RangeError"),
15818
+ ReferenceError: makeWebErrorSubclassReviver("ReferenceError"),
15819
+ SyntaxError: makeWebErrorSubclassReviver("SyntaxError"),
15820
+ TypeError: makeWebErrorSubclassReviver("TypeError"),
15821
+ URIError: makeWebErrorSubclassReviver("URIError"),
15822
+ AggregateError: (value) => {
15823
+ const opts = "cause" in value ? { cause: value.cause } : void 0;
15824
+ const Ctor = globalThis.AggregateError;
15825
+ const error = typeof Ctor === "function" ? new Ctor(value.errors, value.message, opts) : Object.assign(new Error(value.message, opts), {
15826
+ name: "AggregateError",
15827
+ errors: value.errors
15828
+ });
15829
+ if (value.stack !== void 0)
15830
+ error.stack = value.stack;
15831
+ return error;
15832
+ },
15833
+ // `FatalError` and `RetryableError` are not built-in browser globals,
15834
+ // so we can't resolve a constructor from globalThis. The web o11y UI
15835
+ // doesn't need `instanceof FatalError` to pass (no user code runs
15836
+ // here) — it just needs `name`, `message`, `stack`, and any extra
15837
+ // enumerable fields to render. Construct a plain `Error` with `name`
15838
+ // set; ObjectInspector reads `constructor.name` for the displayed
15839
+ // class label, but we don't have the real class, so we emit a tagged
15840
+ // Error whose `name` field carries the class identity. This matches
15841
+ // how the existing base `Error` reviver presents unknown subclasses.
15842
+ FatalError: (value) => {
15843
+ const opts = "cause" in value ? { cause: value.cause } : void 0;
15844
+ const error = new Error(value.message, opts);
15845
+ error.name = "FatalError";
15846
+ if (value.stack !== void 0)
15847
+ error.stack = value.stack;
15848
+ return error;
15849
+ },
15850
+ RetryableError: (value) => {
15851
+ const opts = "cause" in value ? { cause: value.cause } : void 0;
15852
+ const error = new Error(value.message, opts);
15853
+ error.name = "RetryableError";
15854
+ if (value.stack !== void 0)
15855
+ error.stack = value.stack;
15856
+ if (value.retryAfter != null) {
15857
+ error.retryAfter = new Date(value.retryAfter);
15858
+ }
15859
+ return error;
15860
+ },
15861
+ DOMException: (value) => {
15862
+ const G2 = globalThis;
15863
+ if (typeof G2.DOMException === "function") {
15864
+ const e = new G2.DOMException(value.message, value.name);
15865
+ if (value.stack !== void 0)
15866
+ e.stack = value.stack;
15867
+ if ("cause" in value)
15868
+ e.cause = value.cause;
15869
+ return e;
15870
+ }
15672
15871
  const error = new Error(value.message);
15673
15872
  error.name = value.name;
15674
- error.stack = value.stack;
15873
+ if (value.stack !== void 0)
15874
+ error.stack = value.stack;
15875
+ if ("cause" in value) {
15876
+ error.cause = value.cause;
15877
+ }
15675
15878
  return error;
15676
15879
  },
15677
15880
  Float32Array: (value) => new Float32Array(reviveArrayBuffer(value)),
@@ -15809,9 +16012,9 @@ async function hydrateResourceIOWithKey(resource, key) {
15809
16012
  return { hydrateDataWithKey: hydrateDataWithKey3 };
15810
16013
  }, true ? void 0 : void 0);
15811
16014
  const { importKey } = await __vitePreload(async () => {
15812
- const { importKey: importKey2 } = await import("./encryption-80GMP4r0.js");
16015
+ const { importKey: importKey2 } = await import("./encryption-CEh0YXii.js");
15813
16016
  return { importKey: importKey2 };
15814
- }, true ? [] : void 0);
16017
+ }, true ? __vite__mapDeps([0,1,2]) : void 0);
15815
16018
  const cryptoKey = await importKey(key);
15816
16019
  const revivers = getRevivers();
15817
16020
  async function decryptField(value, rev, k2) {
@@ -42941,7 +43144,7 @@ var tn = f("block", "before:content-[counter(line)]", "before:inline-block", "be
42941
43144
  var et = ({ className: e, language: t, style: o, isIncomplete: n, ...s2 }) => jsxRuntimeExports.jsx("div", { className: f("my-4 flex w-full flex-col gap-2 rounded-xl border border-border bg-sidebar p-2", e), "data-incomplete": n || void 0, "data-language": t, "data-streamdown": "code-block", style: { contentVisibility: "auto", containIntrinsicSize: "auto 200px", ...o }, ...s2 });
42942
43145
  var Se = reactExports.createContext({ code: "" }), de = () => reactExports.useContext(Se);
42943
43146
  var ot = ({ language: e }) => jsxRuntimeExports.jsx("div", { className: "flex h-8 items-center text-muted-foreground text-xs", "data-language": e, "data-streamdown": "code-block-header", children: jsxRuntimeExports.jsx("span", { className: "ml-1 font-mono lowercase", children: e }) });
42944
- var cn$1 = /\n+$/, dn = reactExports.lazy(() => __vitePreload(() => import("./highlighted-body-B3W2YXNL-Be0uLJd8.js"), true ? __vite__mapDeps([0,1]) : void 0).then((e) => ({ default: e.HighlightedCodeBlockBody }))), rt = ({ code: e, language: t, className: o, children: n, isIncomplete: s2 = false, ...r2 }) => {
43147
+ var cn$1 = /\n+$/, dn = reactExports.lazy(() => __vitePreload(() => import("./highlighted-body-B3W2YXNL-L1CrwoL_.js"), true ? __vite__mapDeps([3,2]) : void 0).then((e) => ({ default: e.HighlightedCodeBlockBody }))), rt = ({ code: e, language: t, className: o, children: n, isIncomplete: s2 = false, ...r2 }) => {
42945
43148
  let i = reactExports.useMemo(() => e.replace(cn$1, ""), [e]), c = reactExports.useMemo(() => ({ bg: "transparent", fg: "inherit", tokens: i.split(`
42946
43149
  `).map((a2) => [{ content: a2, color: "inherit", bgColor: "transparent", htmlStyle: {}, offset: 0 }]) }), [i]);
42947
43150
  return jsxRuntimeExports.jsx(Se.Provider, { value: { code: e }, children: jsxRuntimeExports.jsxs(et, { isIncomplete: s2, language: t, children: [jsxRuntimeExports.jsx(ot, { language: t }), n ? jsxRuntimeExports.jsx("div", { className: "pointer-events-none sticky top-2 z-10 -mt-10 flex h-8 items-center justify-end", children: jsxRuntimeExports.jsx("div", { className: "pointer-events-auto flex shrink-0 items-center gap-2 rounded-md border border-sidebar bg-sidebar/80 px-1.5 py-1 supports-[backdrop-filter]:bg-sidebar/70 supports-[backdrop-filter]:backdrop-blur", "data-streamdown": "code-block-actions", children: n }) }) : null, jsxRuntimeExports.jsx(reactExports.Suspense, { fallback: jsxRuntimeExports.jsx(Qe, { className: o, language: t, result: c, ...r2 }), children: jsxRuntimeExports.jsx(dn, { className: o, code: i, language: t, raw: c, ...r2 }) })] }) });
@@ -44994,19 +45197,8 @@ function computeRootBounds(spans) {
44994
45197
  const duration2 = Math.max(maxEnd - minStart, 1);
44995
45198
  return { startTime: minStart, endTime: maxEnd, duration: duration2 };
44996
45199
  }
44997
- function buildTimeCompression(_spans, viewStart, viewEnd) {
44998
- const range = viewEnd - viewStart;
44999
- return {
45000
- isCompressed: false,
45001
- toVisual(time2) {
45002
- if (range <= 0)
45003
- return 0;
45004
- return Math.min(Math.max((time2 - viewStart) / range, 0), 1);
45005
- },
45006
- fromVisual(fraction) {
45007
- return viewStart + fraction * range;
45008
- }
45009
- };
45200
+ function getSpanDurationMs(span) {
45201
+ return Math.max(0, getHighResInMs(span.endTime) - getHighResInMs(span.startTime));
45010
45202
  }
45011
45203
  const NICE_INTERVALS = [
45012
45204
  1,
@@ -45061,37 +45253,18 @@ function computeTimeMarkers(viewDuration, offset2) {
45061
45253
  continue;
45062
45254
  markers2.push({
45063
45255
  position: Math.min(Math.max(position2, 0), 1),
45064
- label: formatDuration(Math.abs(t), true)
45256
+ label: formatDuration(Math.abs(t), true),
45257
+ value: t
45065
45258
  });
45066
45259
  if (markers2.length >= MAX_MARKERS)
45067
45260
  break;
45068
45261
  }
45069
45262
  return markers2;
45070
45263
  }
45071
- function computeCompressedTimeMarkers(compression, viewStart, viewEnd, rootStart) {
45072
- const viewDuration = viewEnd - viewStart;
45073
- if (viewDuration <= 0)
45264
+ function computeSpanGaps(spans, viewStart, viewEnd) {
45265
+ const range = viewEnd - viewStart;
45266
+ if (range <= 0)
45074
45267
  return [];
45075
- const maxTicks = 6;
45076
- const interval = pickInterval(viewDuration, maxTicks);
45077
- const offset2 = viewStart - rootStart;
45078
- const firstTick = Math.ceil(offset2 / interval) * interval;
45079
- const markers2 = [];
45080
- for (let t = firstTick; t <= offset2 + viewDuration; t += interval) {
45081
- const absTime = rootStart + t;
45082
- const position2 = compression.toVisual(absTime);
45083
- if (position2 < -0.01 || position2 > 1.01)
45084
- continue;
45085
- markers2.push({
45086
- position: Math.min(Math.max(position2, 0), 1),
45087
- label: formatDuration(Math.abs(t), true)
45088
- });
45089
- if (markers2.length >= MAX_MARKERS)
45090
- break;
45091
- }
45092
- return markers2;
45093
- }
45094
- function computeSpanGaps(spans, compression) {
45095
45268
  const gaps = [];
45096
45269
  for (let i = 0; i < spans.length - 1; i++) {
45097
45270
  const endTime = getHighResInMs(spans[i].endTime);
@@ -45099,8 +45272,8 @@ function computeSpanGaps(spans, compression) {
45099
45272
  const gapMs = startTime - endTime;
45100
45273
  if (gapMs <= 0)
45101
45274
  continue;
45102
- const leftFrac = compression.toVisual(endTime);
45103
- const rightFrac = compression.toVisual(startTime);
45275
+ const leftFrac = Math.min(Math.max((endTime - viewStart) / range, 0), 1);
45276
+ const rightFrac = Math.min(Math.max((startTime - viewStart) / range, 0), 1);
45104
45277
  if (rightFrac - leftFrac < 1e-3)
45105
45278
  continue;
45106
45279
  gaps.push({ gapMs, leftFrac, rightFrac, rowIndex: i });
@@ -45231,29 +45404,10 @@ function computeHookSegmentsFromSpan(startMs, duration2, events) {
45231
45404
  }
45232
45405
  return segments;
45233
45406
  }
45234
- function computeSleepSegmentsFromSpan(startMs, duration2, events) {
45235
- const segments = [];
45407
+ function computeSleepSegmentsFromSpan(_startMs, duration2, _events) {
45236
45408
  if (duration2 <= 0)
45237
- return segments;
45238
- const completedTime = events.filter((e) => e.name === "wait_completed").map((e) => getHighResInMs(e.timestamp)).sort((a2, b2) => a2 - b2)[0];
45239
- if (completedTime === void 0) {
45240
- segments.push({ startFraction: 0, endFraction: 1, status: "sleeping" });
45241
- return segments;
45242
- }
45243
- const completedFrac = timeToFraction(completedTime, startMs, duration2);
45244
- if (completedFrac > 1e-3) {
45245
- segments.push({
45246
- startFraction: 0,
45247
- endFraction: completedFrac,
45248
- status: "sleeping"
45249
- });
45250
- }
45251
- segments.push({
45252
- startFraction: completedFrac,
45253
- endFraction: 1,
45254
- status: "succeeded"
45255
- });
45256
- return segments;
45409
+ return [];
45410
+ return [{ startFraction: 0, endFraction: 1, status: "sleeping" }];
45257
45411
  }
45258
45412
  function computeRunSegmentsFromSpan(startMs, duration2, activeStartMs, events, attributes) {
45259
45413
  const segments = [];
@@ -45309,8 +45463,7 @@ function computeV1RunSegments(startMs, duration2, activeStartMs, runStatus) {
45309
45463
  }
45310
45464
  function computeSpanSegments(span) {
45311
45465
  const startMs = getHighResInMs(span.startTime);
45312
- const endMs = getHighResInMs(span.endTime);
45313
- const duration2 = endMs - startMs;
45466
+ const duration2 = getSpanDurationMs(span);
45314
45467
  const activeStartMs = span.activeStartTime ? getHighResInMs(span.activeStartTime) : void 0;
45315
45468
  switch (span.resource) {
45316
45469
  case "step":
@@ -45325,25 +45478,27 @@ function computeSpanSegments(span) {
45325
45478
  return [];
45326
45479
  }
45327
45480
  }
45328
- const QUEUED_BACKGROUND = "radial-gradient(circle, var(--ds-gray-400) 2px, transparent 2px) center / 20px 20px space no-repeat, var(--ds-gray-500)";
45329
- const HATCHED_BACKGROUND = "repeating-linear-gradient(-45deg, var(--ds-gray-400) 0px, var(--ds-gray-400) 3px, var(--ds-gray-500) 3px, var(--ds-gray-500) 6px)";
45330
45481
  const SEGMENT_CONFIG = {
45331
- queued: { style: { background: QUEUED_BACKGROUND } },
45482
+ queued: { className: "bg-gray-500" },
45332
45483
  retrying: {
45333
45484
  className: "box-border bg-gray-500"
45334
45485
  },
45335
- waiting: { style: { background: HATCHED_BACKGROUND } },
45486
+ waiting: { className: "bg-gray-500" },
45336
45487
  running: { className: "bg-blue-700" },
45337
45488
  failed: { className: "bg-red-700" },
45338
45489
  succeeded: { className: "bg-green-700" },
45339
- sleeping: { className: "bg-amber-700" },
45490
+ sleeping: { className: "bg-gray-500" },
45340
45491
  received: { className: "bg-blue-700" }
45341
45492
  };
45342
- const FIXED_BAR_WIDTH_PX = 4;
45493
+ const BAR_HEIGHT_PX = 24;
45494
+ const TINY_BAR_BOX_SIZE_PX = 24;
45495
+ const TINY_BAR_WIDTH_PX = 4;
45343
45496
  const SEGMENT_GAP_PX = 1;
45344
- const ROW_HEIGHT = 34;
45497
+ const ROW_HEIGHT = 40;
45345
45498
  const CONTAINER_PAD_Y = 8;
45346
45499
  const END_CAP_HEIGHT = 8;
45500
+ const TIMELINE_PADDING_PX = 16;
45501
+ const ORIGIN_MARKER_EPSILON = 1e-6;
45347
45502
  const DeltaIndicator = reactExports.memo(function DeltaIndicator2({ leftFrac, rightFrac, label, rowIndex }) {
45348
45503
  const centerY = CONTAINER_PAD_Y + (rowIndex + 1) * ROW_HEIGHT;
45349
45504
  return jsxRuntimeExports.jsxs("div", { className: "absolute pointer-events-none", style: {
@@ -45353,38 +45508,34 @@ const DeltaIndicator = reactExports.memo(function DeltaIndicator2({ leftFrac, ri
45353
45508
  height: END_CAP_HEIGHT
45354
45509
  }, children: [jsxRuntimeExports.jsx("div", { className: "absolute left-0 top-0 w-px h-full bg-amber-800" }), jsxRuntimeExports.jsx("div", { className: "absolute left-0 right-0 top-1/2 h-px bg-amber-800" }), jsxRuntimeExports.jsx("div", { className: "absolute right-0 top-0 w-px h-full bg-amber-800" }), jsxRuntimeExports.jsx("span", { className: "absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 text-label-12 leading-none whitespace-nowrap rounded-xs px-1 py-0.5 text-gray-100 bg-amber-800", children: label })] });
45355
45510
  });
45356
- const TimelineBar = reactExports.memo(function TimelineBar2({ span, compression, containerWidth, isSelected, onClick }) {
45511
+ const TimelineBar = reactExports.memo(function TimelineBar2({ span, viewStart, viewDuration, containerWidth, isSelected, onClick }) {
45357
45512
  var _a3;
45358
45513
  const startTime = getHighResInMs(span.startTime);
45359
45514
  const endTime = getHighResInMs(span.endTime);
45360
- const totalDurationMs = endTime - startTime;
45361
- const leftFrac = compression.toVisual(startTime);
45362
- const rightFrac = compression.toVisual(endTime);
45363
- const widthFrac = rightFrac - leftFrac;
45364
- const leftPct = leftFrac * 100;
45515
+ const totalDurationMs = getSpanDurationMs(span);
45516
+ const leftFracRaw = viewDuration > 0 ? (startTime - viewStart) / viewDuration : 0;
45517
+ const rightFracRaw = viewDuration > 0 ? (endTime - viewStart) / viewDuration : 0;
45518
+ const widthFrac = rightFracRaw - leftFracRaw;
45519
+ const leftPct = leftFracRaw * 100;
45365
45520
  const widthPct = widthFrac * 100;
45366
45521
  const pixelWidth = widthFrac * containerWidth;
45367
- const isCompressed = containerWidth > 0 && pixelWidth < FIXED_BAR_WIDTH_PX;
45522
+ const visibleLeftFrac = Math.max(0, Math.min(1, leftFracRaw));
45523
+ const visibleRightFrac = Math.max(0, Math.min(1, rightFracRaw));
45524
+ const visiblePixelWidth = Math.max(0, visibleRightFrac - visibleLeftFrac) * containerWidth;
45525
+ const isTinyBar = containerWidth > 0 && visiblePixelWidth < TINY_BAR_BOX_SIZE_PX;
45368
45526
  const [isRowHovered, setIsRowHovered] = reactExports.useState(false);
45369
45527
  const segments = reactExports.useMemo(() => computeSpanSegments(span), [span]);
45370
- const finalSegment = segments[segments.length - 1];
45371
45528
  const workflowStatus = (_a3 = span.attributes.data) == null ? void 0 : _a3.status;
45372
45529
  const isErrored = span.status.code === 2 || workflowStatus === "failed";
45373
45530
  const colors = getResourceColor(span.resource);
45374
45531
  const fallbackColor = isErrored ? colors.errorBar ?? "var(--ds-red-700)" : colors.bar;
45375
- const compressedSegmentStatus = isErrored ? "failed" : span.resource === "hook" ? "received" : finalSegment == null ? void 0 : finalSegment.status;
45376
- const compressedSegmentStyle = compressedSegmentStatus === "queued" ? { background: "var(--ds-gray-500)" } : compressedSegmentStatus ? SEGMENT_CONFIG[compressedSegmentStatus].style : void 0;
45377
- const compressedSegmentClassName = compressedSegmentStatus ? SEGMENT_CONFIG[compressedSegmentStatus].className : void 0;
45378
- const hasCompressedStatus = Boolean(compressedSegmentClassName || compressedSegmentStyle);
45379
45532
  const renderDurationLabel = (label) => jsxRuntimeExports.jsx("span", { className: "pointer-events-none absolute inset-0 flex items-center justify-start overflow-hidden px-1 text-[10px] font-mono font-medium leading-none whitespace-nowrap text-left text-white tabular-nums", style: { textShadow: "0 1px 1px rgba(0, 0, 0, 0.45)" }, children: label });
45380
45533
  const getMinDurationLabelWidthPx = (label) => Math.max(40, label.length * 6 + 12);
45381
45534
  const totalDurationLabel = formatDuration(totalDurationMs);
45382
45535
  const showBarDurationLabel = isRowHovered && pixelWidth >= getMinDurationLabelWidthPx(totalDurationLabel);
45383
- const barContent = isCompressed ? jsxRuntimeExports.jsx("div", { className: cn$4("relative h-4 rounded-[0.25rem] top-[3px]", compressedSegmentClassName), style: {
45384
- width: "100%",
45385
- background: hasCompressedStatus ? void 0 : fallbackColor,
45386
- ...compressedSegmentStyle
45387
- }, children: showBarDurationLabel ? renderDurationLabel(totalDurationLabel) : null }) : segments.length > 0 ? jsxRuntimeExports.jsx("div", { className: "relative w-full h-4 top-[3px]", children: segments.map((seg, i) => {
45536
+ const showBoundaryArrow = isTinyBar && (leftFracRaw < 0 || rightFracRaw > 1);
45537
+ const BoundaryArrow = leftFracRaw < 0.5 ? ArrowLeft : ArrowRight;
45538
+ const barContent = showBoundaryArrow ? jsxRuntimeExports.jsx("div", { className: "flex h-6 w-6 items-center justify-center rounded-[0.25rem]", children: jsxRuntimeExports.jsx(BoundaryArrow, { className: "size-3 text-gray-900" }) }) : isTinyBar ? jsxRuntimeExports.jsx("div", { className: "h-6 rounded-[0.25rem]", style: { background: fallbackColor } }) : segments.length > 0 ? jsxRuntimeExports.jsx("div", { className: "relative h-6 w-full", children: segments.map((seg, i) => {
45388
45539
  const segPixelWidth = (seg.endFraction - seg.startFraction) * pixelWidth;
45389
45540
  const segDurationLabel = formatDuration((seg.endFraction - seg.startFraction) * totalDurationMs);
45390
45541
  const showSegmentDurationLabel = isRowHovered && segPixelWidth >= getMinDurationLabelWidthPx(segDurationLabel);
@@ -45395,24 +45546,28 @@ const TimelineBar = reactExports.memo(function TimelineBar2({ span, compression,
45395
45546
  minWidth: 1,
45396
45547
  ...segStyle
45397
45548
  }, children: showSegmentDurationLabel ? renderDurationLabel(segDurationLabel) : null }, `${seg.status}-${i}`);
45398
- }) }) : jsxRuntimeExports.jsx("div", { className: "relative h-4 rounded-[0.25rem] top-[3px]", style: {
45549
+ }) }) : jsxRuntimeExports.jsx("div", { className: "relative h-6 rounded-[0.25rem]", style: {
45399
45550
  width: "100%",
45400
45551
  minWidth: 4,
45401
45552
  background: fallbackColor
45402
45553
  }, children: showBarDurationLabel ? renderDurationLabel(totalDurationLabel) : null });
45403
- return jsxRuntimeExports.jsx("div", { role: "treeitem", "aria-selected": isSelected, "aria-expanded": isSelected, "aria-level": 1, className: cn$4("h-[34px] relative flex items-center hover:bg-gray-100 aria-selected:bg-gray-100 rounded-sm aria-selected:hover:bg-gray-200"), onMouseEnter: () => setIsRowHovered(true), onMouseLeave: () => setIsRowHovered(false), onClick, children: jsxRuntimeExports.jsx("div", { className: "absolute top-1.5 h-[22px] rounded-sm", style: {
45404
- left: isCompressed ? `min(${leftPct}%, calc(100% - ${FIXED_BAR_WIDTH_PX}px))` : `${leftPct}%`,
45405
- width: isCompressed ? `${FIXED_BAR_WIDTH_PX}px` : `max(${widthPct}%, 4px)`
45406
- }, children: barContent }) });
45554
+ return jsxRuntimeExports.jsx("div", { role: "treeitem", "aria-selected": isSelected, "aria-expanded": isSelected, "aria-level": 1, className: cn$4("h-10 relative flex items-center hover:bg-gray-100 aria-selected:bg-gray-100 aria-selected:hover:bg-gray-200"), onMouseEnter: () => setIsRowHovered(true), onMouseLeave: () => setIsRowHovered(false), onClick, children: jsxRuntimeExports.jsx("div", { className: "absolute inset-y-0", style: {
45555
+ left: TIMELINE_PADDING_PX,
45556
+ right: TIMELINE_PADDING_PX
45557
+ }, children: jsxRuntimeExports.jsx("div", { className: "absolute top-1/2 -translate-y-1/2", style: {
45558
+ left: showBoundaryArrow ? `min(max(${leftPct}%, 0px), calc(100% - ${TINY_BAR_BOX_SIZE_PX}px))` : isTinyBar ? `min(${leftPct}%, calc(100% - ${TINY_BAR_WIDTH_PX}px))` : `${leftPct}%`,
45559
+ width: showBoundaryArrow ? `${TINY_BAR_BOX_SIZE_PX}px` : isTinyBar ? `${TINY_BAR_WIDTH_PX}px` : `max(${widthPct}%, 4px)`,
45560
+ height: BAR_HEIGHT_PX
45561
+ }, children: barContent }) }) });
45407
45562
  });
45408
- function TimelineHeader({ viewStart, viewDuration, rootStart, compression, isZoomed, onResetZoom, hoverInfo: hoverInfo2 }) {
45409
- const viewEnd = viewStart + viewDuration;
45410
- const markers2 = reactExports.useMemo(() => compression.isCompressed ? computeCompressedTimeMarkers(compression, viewStart, viewEnd, rootStart) : computeTimeMarkers(viewDuration, viewStart - rootStart), [compression, viewStart, viewEnd, viewDuration, rootStart]);
45411
- return jsxRuntimeExports.jsxs("div", { className: "relative bg-background-100 border-b border-gray-alpha-400 h-10 min-h-10 flex items-end px-2 pb-1", children: [jsxRuntimeExports.jsxs("div", { className: "relative h-full flex-1", children: [markers2.map((m2, i) => jsxRuntimeExports.jsx("span", { className: "absolute bottom-1 font-mono text-xs font-normal leading-4 text-gray-900 whitespace-nowrap", style: { left: `${m2.position * 100}%` }, children: m2.label }, i)), hoverInfo2 && jsxRuntimeExports.jsx("span", { className: "absolute top-1 pointer-events-none z-10 font-mono text-[11px] leading-4 text-gray-1000 whitespace-nowrap bg-background-100 border border-gray-alpha-400 rounded px-1 -translate-x-1/2", style: { left: `${hoverInfo2.fraction * 100}%` }, children: hoverInfo2.label })] }), isZoomed && jsxRuntimeExports.jsx("button", { type: "button", className: "absolute right-2 top-1/2 -translate-y-1/2 z-[5] flex items-center py-0.5 px-2 border border-gray-alpha-400 rounded-md bg-background-100 font-sans text-[11px] font-medium text-gray-900 cursor-pointer whitespace-nowrap transition-[color,border-color] duration-[120ms] ease-in-out hover:text-gray-1000 hover:border-gray-600", onClick: onResetZoom, children: "Reset zoom" })] });
45563
+ function TimelineHeader({ markers: markers2, hoverInfo: hoverInfo2 }) {
45564
+ return jsxRuntimeExports.jsx("div", { className: "relative bg-background-100 border-b border-gray-alpha-400 h-10 min-h-10 flex items-end px-4 pb-1", children: jsxRuntimeExports.jsxs("div", { className: "relative h-full flex-1", children: [markers2.map((m2) => jsxRuntimeExports.jsx("span", { className: "absolute bottom-1 font-mono text-xs font-normal leading-4 text-gray-900 whitespace-nowrap", style: { left: `${m2.position * 100}%` }, children: m2.label }, `${m2.position}-${m2.label}`)), hoverInfo2 && jsxRuntimeExports.jsx("span", { className: "absolute top-1 pointer-events-none z-10 font-mono text-[11px] leading-4 text-gray-1000 whitespace-nowrap bg-background-100 border border-gray-alpha-400 rounded px-1 -translate-x-1/2", style: { left: `${hoverInfo2.fraction * 100}%` }, children: hoverInfo2.label })] }) });
45412
45565
  }
45413
- function Timeline({ spans, compression, selectedId, onSelect, hoverFraction, altHeld = false }) {
45566
+ function Timeline({ spans, viewStart, viewEnd, markers: markers2, selectedId, onSelect, hoverFraction, altHeld = false }) {
45414
45567
  const containerRef = reactExports.useRef(null);
45415
45568
  const [containerWidth, setContainerWidth] = reactExports.useState(0);
45569
+ const viewDuration = viewEnd - viewStart;
45570
+ const timelineWidth = Math.max(0, containerWidth - TIMELINE_PADDING_PX * 2);
45416
45571
  reactExports.useEffect(() => {
45417
45572
  const el = containerRef.current;
45418
45573
  if (!el)
@@ -45423,8 +45578,17 @@ function Timeline({ spans, compression, selectedId, onSelect, hoverFraction, alt
45423
45578
  ro2.observe(el);
45424
45579
  return () => ro2.disconnect();
45425
45580
  }, []);
45426
- const gaps = reactExports.useMemo(() => computeSpanGaps(spans, compression), [spans, compression]);
45427
- return jsxRuntimeExports.jsxs("div", { ref: containerRef, className: "relative py-2", children: [hoverFraction != null && jsxRuntimeExports.jsx("div", { className: "absolute top-0 bottom-0 w-px bg-gray-alpha-400 pointer-events-none z-10", style: { left: `${hoverFraction * 100}%` } }), spans.map((span) => jsxRuntimeExports.jsx(TimelineBar, { span, compression, containerWidth, isSelected: selectedId === span.spanId, onClick: () => onSelect(span.spanId) }, span.spanId)), altHeld && jsxRuntimeExports.jsx("div", { "aria-hidden": true, className: "absolute inset-0 pointer-events-none", children: gaps.map((gap) => jsxRuntimeExports.jsx(DeltaIndicator, { leftFrac: gap.leftFrac, rightFrac: gap.rightFrac, label: formatDuration(gap.gapMs, true), rowIndex: gap.rowIndex }, gap.rowIndex)) })] });
45581
+ const gaps = reactExports.useMemo(() => computeSpanGaps(spans, viewStart, viewEnd), [spans, viewStart, viewEnd]);
45582
+ return jsxRuntimeExports.jsxs("div", { ref: containerRef, className: "relative h-full overflow-hidden", children: [jsxRuntimeExports.jsx("div", { "aria-hidden": true, className: "absolute inset-y-0 pointer-events-none", style: {
45583
+ left: TIMELINE_PADDING_PX,
45584
+ right: TIMELINE_PADDING_PX
45585
+ }, children: markers2.map((marker2) => Math.abs(marker2.value) > ORIGIN_MARKER_EPSILON ? jsxRuntimeExports.jsx("div", { className: "absolute top-0 bottom-0 w-px bg-gray-alpha-300", style: { left: `${marker2.position * 100}%` } }, `${marker2.position}-${marker2.label}`) : null) }), hoverFraction != null && jsxRuntimeExports.jsx("div", { className: "absolute inset-y-0 pointer-events-none z-10", style: {
45586
+ left: TIMELINE_PADDING_PX,
45587
+ right: TIMELINE_PADDING_PX
45588
+ }, children: jsxRuntimeExports.jsx("div", { className: "absolute top-0 bottom-0 w-px bg-gray-alpha-400", style: { left: `${hoverFraction * 100}%` } }) }), spans.map((span) => jsxRuntimeExports.jsx(TimelineBar, { span, viewStart, viewDuration, containerWidth: timelineWidth, isSelected: selectedId === span.spanId, onClick: () => onSelect(span.spanId) }, span.spanId)), altHeld && jsxRuntimeExports.jsx("div", { "aria-hidden": true, className: "absolute inset-y-0 pointer-events-none", style: {
45589
+ left: TIMELINE_PADDING_PX,
45590
+ right: TIMELINE_PADDING_PX
45591
+ }, children: gaps.map((gap) => jsxRuntimeExports.jsx(DeltaIndicator, { leftFrac: gap.leftFrac, rightFrac: gap.rightFrac, label: formatDuration(gap.gapMs, true), rowIndex: gap.rowIndex }, gap.rowIndex)) })] });
45428
45592
  }
45429
45593
  const ActiveSpanContext = reactExports.createContext(null);
45430
45594
  ActiveSpanContext.displayName = "ActiveSpanContext";
@@ -45433,16 +45597,14 @@ function ActiveSpanProvider({ spans, children: children2 }) {
45433
45597
  const [activeSpanId, setActiveSpanId] = reactExports.useState(((_a3 = spans[0]) == null ? void 0 : _a3.spanId) ?? null);
45434
45598
  reactExports.useEffect(() => {
45435
45599
  setActiveSpanId((currentSpanId) => {
45436
- if (spans.length === 0) {
45600
+ if (!currentSpanId) {
45437
45601
  return null;
45438
45602
  }
45439
- if (currentSpanId) {
45440
- const hasCurrentSpan = spans.some((span) => span.spanId === currentSpanId);
45441
- if (hasCurrentSpan) {
45442
- return currentSpanId;
45443
- }
45603
+ const hasCurrentSpan = spans.some((span) => span.spanId === currentSpanId);
45604
+ if (hasCurrentSpan) {
45605
+ return currentSpanId;
45444
45606
  }
45445
- return spans[0].spanId;
45607
+ return null;
45446
45608
  });
45447
45609
  }, [spans]);
45448
45610
  const activeSpan = reactExports.useMemo(() => {
@@ -48049,46 +48211,48 @@ export {
48049
48211
  EVENT_DATA_REF_FIELDS as a4,
48050
48212
  clsx as a5,
48051
48213
  cn$4 as a6,
48052
- getHighResInMs as a7,
48053
- ActiveSpanProvider as a8,
48054
- useActiveSpan as a9,
48055
- limitShift as aA,
48056
- flip as aB,
48057
- size as aC,
48058
- arrow as aD,
48059
- hide as aE,
48060
- autoUpdate as aF,
48061
- cancelRun as aG,
48062
- reenqueueRun as aH,
48063
- wakeUpRun as aI,
48064
- resumeHook as aJ,
48065
- recreateRun as aK,
48066
- useSidebarDataOptional as aa,
48067
- computeRootBounds as ab,
48068
- buildTimeCompression as ac,
48069
- Timeline as ad,
48070
- TimelineHeader as ae,
48071
- SidebarDataProvider as af,
48072
- hydrateResourceIOWithKey as ag,
48073
- hydrateResourceIO as ah,
48074
- fetchHook as ai,
48075
- fetchStep as aj,
48076
- hasEncryptedFields as ak,
48077
- fetchStreams as al,
48078
- Slot as am,
48079
- Slottable as an,
48080
- buttonVariants as ao,
48081
- isEncryptedData as ap,
48082
- hydrateData as aq,
48083
- getWebRevivers as ar,
48084
- LIVE_UPDATE_INTERVAL_MS as as,
48085
- fetchEvent as at,
48086
- getEncryptionKeyForRun as au,
48087
- StreamViewer as av,
48088
- composeRefs as aw,
48089
- useFloating as ax,
48090
- offset as ay,
48091
- shift as az,
48214
+ getSpanDurationMs as a7,
48215
+ getHighResInMs as a8,
48216
+ ActiveSpanProvider as a9,
48217
+ offset as aA,
48218
+ shift as aB,
48219
+ limitShift as aC,
48220
+ flip as aD,
48221
+ size as aE,
48222
+ arrow as aF,
48223
+ hide as aG,
48224
+ autoUpdate as aH,
48225
+ cancelRun as aI,
48226
+ reenqueueRun as aJ,
48227
+ wakeUpRun as aK,
48228
+ resumeHook as aL,
48229
+ recreateRun as aM,
48230
+ useActiveSpan as aa,
48231
+ useSidebarDataOptional as ab,
48232
+ computeRootBounds as ac,
48233
+ computeTimeMarkers as ad,
48234
+ TIMELINE_PADDING_PX as ae,
48235
+ Timeline as af,
48236
+ TimelineHeader as ag,
48237
+ SidebarDataProvider as ah,
48238
+ hydrateResourceIOWithKey as ai,
48239
+ hydrateResourceIO as aj,
48240
+ fetchHook as ak,
48241
+ fetchStep as al,
48242
+ hasEncryptedFields as am,
48243
+ fetchStreams as an,
48244
+ Slot as ao,
48245
+ Slottable as ap,
48246
+ buttonVariants as aq,
48247
+ isEncryptedData as ar,
48248
+ hydrateData as as,
48249
+ getWebRevivers as at,
48250
+ LIVE_UPDATE_INTERVAL_MS as au,
48251
+ fetchEvent as av,
48252
+ getEncryptionKeyForRun as aw,
48253
+ StreamViewer as ax,
48254
+ composeRefs as ay,
48255
+ useFloating as az,
48092
48256
  TooltipContent as b,
48093
48257
  createLucideIcon as c,
48094
48258
  cn as d,