@rkat/mobkit-sdk 0.5.2 → 0.6.3

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 (50) hide show
  1. package/dist/agent-builder.d.ts +13 -1
  2. package/dist/agent-builder.d.ts.map +1 -1
  3. package/dist/agent-builder.js +166 -1
  4. package/dist/agent-builder.js.map +1 -1
  5. package/dist/builder.d.ts +28 -0
  6. package/dist/builder.d.ts.map +1 -1
  7. package/dist/builder.js +57 -0
  8. package/dist/builder.js.map +1 -1
  9. package/dist/cjs/agent-builder.cjs +165 -0
  10. package/dist/cjs/builder.cjs +57 -0
  11. package/dist/cjs/errors.cjs +72 -2
  12. package/dist/cjs/events.cjs +15 -5
  13. package/dist/cjs/index.cjs +37 -2
  14. package/dist/cjs/models.cjs +2 -2
  15. package/dist/cjs/runtime.cjs +306 -16
  16. package/dist/cjs/sse.cjs +12 -8
  17. package/dist/cjs/transport.cjs +47 -17
  18. package/dist/cjs/types.cjs +483 -5
  19. package/dist/errors.d.ts +38 -1
  20. package/dist/errors.d.ts.map +1 -1
  21. package/dist/errors.js +68 -1
  22. package/dist/errors.js.map +1 -1
  23. package/dist/events.d.ts +7 -0
  24. package/dist/events.d.ts.map +1 -1
  25. package/dist/events.js +15 -5
  26. package/dist/events.js.map +1 -1
  27. package/dist/index.d.ts +3 -3
  28. package/dist/index.d.ts.map +1 -1
  29. package/dist/index.js +4 -2
  30. package/dist/index.js.map +1 -1
  31. package/dist/models.d.ts +2 -2
  32. package/dist/models.d.ts.map +1 -1
  33. package/dist/models.js +2 -2
  34. package/dist/models.js.map +1 -1
  35. package/dist/runtime.d.ts +93 -3
  36. package/dist/runtime.d.ts.map +1 -1
  37. package/dist/runtime.js +308 -18
  38. package/dist/runtime.js.map +1 -1
  39. package/dist/sse.d.ts.map +1 -1
  40. package/dist/sse.js +12 -8
  41. package/dist/sse.js.map +1 -1
  42. package/dist/transport.d.ts +13 -0
  43. package/dist/transport.d.ts.map +1 -1
  44. package/dist/transport.js +46 -16
  45. package/dist/transport.js.map +1 -1
  46. package/dist/types.d.ts +265 -4
  47. package/dist/types.d.ts.map +1 -1
  48. package/dist/types.js +454 -5
  49. package/dist/types.js.map +1 -1
  50. package/package.json +1 -1
@@ -32,7 +32,36 @@ exports.parseReconcileEdgesReport = parseReconcileEdgesReport;
32
32
  exports.parseRediscoverReport = parseRediscoverReport;
33
33
  exports.parsePersistedEvent = parsePersistedEvent;
34
34
  exports.eventQueryToDict = eventQueryToDict;
35
+ exports.parseMobStructuralEvent = parseMobStructuralEvent;
36
+ exports.parseStepRecord = parseStepRecord;
37
+ exports.parseFailureRecord = parseFailureRecord;
38
+ exports.parseFrameRecord = parseFrameRecord;
39
+ exports.parseLoopRecord = parseLoopRecord;
40
+ exports.parseLoopIterationRecord = parseLoopIterationRecord;
41
+ exports.parseMobRun = parseMobRun;
35
42
  exports.parseErrorEvent = parseErrorEvent;
43
+ exports.parseDurableAgentSpec = parseDurableAgentSpec;
44
+ exports.durableAgentSpecToDict = durableAgentSpecToDict;
45
+ exports.parseDispatchInput = parseDispatchInput;
46
+ exports.dispatchInputToDict = dispatchInputToDict;
47
+ exports.parseManagedPeerEdge = parseManagedPeerEdge;
48
+ exports.managedPeerEdgeToDict = managedPeerEdgeToDict;
49
+ exports.parseExternalToolDef = parseExternalToolDef;
50
+ exports.externalToolDefToDict = externalToolDefToDict;
51
+ exports.parseAgentBuildContext = parseAgentBuildContext;
52
+ exports.parseAgentBuildDraft = parseAgentBuildDraft;
53
+ exports.agentBuildDraftToDict = agentBuildDraftToDict;
54
+ exports.parseIdentityStatus = parseIdentityStatus;
55
+ exports.parseContinuityRecord = parseContinuityRecord;
56
+ exports.continuityRecordToDict = continuityRecordToDict;
57
+ exports.parseContinuityFailure = parseContinuityFailure;
58
+ exports.parseContinuityResolveState = parseContinuityResolveState;
59
+ exports.parseSessionSnapshot = parseSessionSnapshot;
60
+ exports.sessionSnapshotToDict = sessionSnapshotToDict;
61
+ exports.parseLeaseGrant = parseLeaseGrant;
62
+ exports.leaseGrantToDict = leaseGrantToDict;
63
+ exports.parseLeaseAcquireResult = parseLeaseAcquireResult;
64
+ exports.parseLeaseRenewResult = parseLeaseRenewResult;
36
65
  // -- Helpers (internal) ---------------------------------------------------
37
66
  function asRecord(value) {
38
67
  if (typeof value === "object" && value !== null) {
@@ -124,8 +153,8 @@ function parseSpawnResult(raw) {
124
153
  return {
125
154
  accepted: Boolean(d.accepted),
126
155
  moduleId: String(d.module_id ?? ""),
127
- meerkatId: typeof d.meerkat_id === "string" ? d.meerkat_id : null,
128
- profile: typeof d.profile === "string" ? d.profile : null,
156
+ agentIdentity: typeof d.agent_identity === "string" ? d.agent_identity : null,
157
+ role: typeof d.role === "string" ? d.role : null,
129
158
  };
130
159
  }
131
160
  function parseKeepAliveConfig(raw) {
@@ -146,7 +175,13 @@ function parseEventEnvelope(raw) {
146
175
  }
147
176
  function parseSubscribeResult(raw) {
148
177
  const d = asRecord(raw);
149
- const eventsRaw = Array.isArray(d.events) ? d.events : [];
178
+ // Pre-fix this mapped every entry including null/string/number —
179
+ // through `parseEventEnvelope`, where `asRecord` quietly returned
180
+ // `{}` and produced silently-empty envelopes. Filter to objects so
181
+ // non-object entries are dropped instead of becoming data-loss.
182
+ const eventsRaw = Array.isArray(d.events)
183
+ ? d.events.filter((entry) => typeof entry === "object" && entry !== null && !Array.isArray(entry))
184
+ : [];
150
185
  return {
151
186
  scope: String(d.scope ?? ""),
152
187
  replayFromEventId: typeof d.replay_from_event_id === "string"
@@ -219,8 +254,8 @@ function parseCallToolResult(raw) {
219
254
  function parseMemberSnapshot(raw) {
220
255
  const d = asRecord(raw);
221
256
  return {
222
- meerkatId: String(d.meerkat_id ?? ""),
223
- profile: String(d.profile ?? ""),
257
+ agentIdentity: String(d.agent_identity ?? ""),
258
+ role: String(d.role ?? ""),
224
259
  state: String(d.state ?? ""),
225
260
  wiredTo: asStringArray(d.wired_to),
226
261
  labels: asStringRecord(d.labels),
@@ -309,6 +344,9 @@ function parseUnifiedEvent(raw) {
309
344
  kind: "agent",
310
345
  agentId: String(agent.agent_id ?? ""),
311
346
  eventType: String(agent.event_type ?? ""),
347
+ payload: typeof agent.payload === "object" && agent.payload !== null
348
+ ? asRecord(agent.payload)
349
+ : null,
312
350
  };
313
351
  }
314
352
  if ("Module" in d) {
@@ -349,6 +387,14 @@ function eventQueryToDict(query) {
349
387
  d.until_ms = query.untilMs;
350
388
  if (query.memberId !== undefined)
351
389
  d.member_id = query.memberId;
390
+ if (query.identity !== undefined)
391
+ d.identity = query.identity;
392
+ if (query.mobId !== undefined)
393
+ d.mob_id = query.mobId;
394
+ if (query.runId !== undefined)
395
+ d.run_id = query.runId;
396
+ if (query.stepId !== undefined)
397
+ d.step_id = query.stepId;
352
398
  if (query.eventTypes !== undefined && query.eventTypes.length > 0) {
353
399
  d.event_types = [...query.eventTypes];
354
400
  }
@@ -358,6 +404,129 @@ function eventQueryToDict(query) {
358
404
  d.after_seq = query.afterSeq;
359
405
  return d;
360
406
  }
407
+ function parseMobStructuralEvent(raw) {
408
+ const d = asRecord(raw);
409
+ const data = d.data;
410
+ return {
411
+ eventId: String(d.event_id ?? ""),
412
+ cursor: Number(d.cursor ?? 0),
413
+ mobId: String(d.mob_id ?? ""),
414
+ timestampMs: Number(d.timestamp_ms ?? 0),
415
+ kind: String(d.kind ?? ""),
416
+ runId: typeof d.run_id === "string" ? d.run_id : null,
417
+ stepId: typeof d.step_id === "string" ? d.step_id : null,
418
+ agentIdentity: typeof d.agent_identity === "string" ? d.agent_identity : null,
419
+ mobLabels: asStringRecord(d.mob_labels),
420
+ runLabels: asStringRecord(d.run_labels),
421
+ data: typeof data === "object" && data !== null
422
+ ? data
423
+ : {},
424
+ };
425
+ }
426
+ function parseStepRecord(raw) {
427
+ const d = asRecord(raw);
428
+ return {
429
+ stepId: String(d.step_id ?? ""),
430
+ agentIdentity: String(d.agent_identity ?? ""),
431
+ status: String(d.status ?? ""),
432
+ output: d.output,
433
+ timestamp: String(d.timestamp ?? ""),
434
+ };
435
+ }
436
+ function parseFailureRecord(raw) {
437
+ const d = asRecord(raw);
438
+ return {
439
+ stepId: String(d.step_id ?? ""),
440
+ reason: String(d.reason ?? ""),
441
+ timestamp: String(d.timestamp ?? ""),
442
+ };
443
+ }
444
+ function parseFrameRecord(raw) {
445
+ const d = asRecord(raw);
446
+ return { kernelState: d.kernel_state };
447
+ }
448
+ function parseLoopRecord(raw) {
449
+ const d = asRecord(raw);
450
+ return { kernelState: d.kernel_state };
451
+ }
452
+ function parseLoopIterationRecord(raw) {
453
+ const d = asRecord(raw);
454
+ return {
455
+ loopInstanceId: String(d.loop_instance_id ?? ""),
456
+ iteration: Number(d.iteration ?? 0),
457
+ frameId: String(d.frame_id ?? ""),
458
+ };
459
+ }
460
+ function parseMobRunStatus(raw) {
461
+ const known = [
462
+ "pending",
463
+ "running",
464
+ "completed",
465
+ "failed",
466
+ "canceled",
467
+ ];
468
+ if (typeof raw === "string" && known.includes(raw)) {
469
+ return raw;
470
+ }
471
+ return "pending";
472
+ }
473
+ function parseMobRun(raw) {
474
+ const d = asRecord(raw);
475
+ const stepLedger = Array.isArray(d.step_ledger)
476
+ ? d.step_ledger.map(parseStepRecord)
477
+ : [];
478
+ const failureLedger = Array.isArray(d.failure_ledger)
479
+ ? d.failure_ledger.map(parseFailureRecord)
480
+ : [];
481
+ const iterations = Array.isArray(d.loop_iteration_ledger)
482
+ ? d.loop_iteration_ledger.map(parseLoopIterationRecord)
483
+ : [];
484
+ const framesIn = typeof d.frames === "object" && d.frames !== null
485
+ ? d.frames
486
+ : {};
487
+ const frames = {};
488
+ for (const [k, v] of Object.entries(framesIn)) {
489
+ if (typeof v === "object" && v !== null) {
490
+ frames[k] = parseFrameRecord(v);
491
+ }
492
+ }
493
+ const loopsIn = typeof d.loops === "object" && d.loops !== null
494
+ ? d.loops
495
+ : {};
496
+ const loops = {};
497
+ for (const [k, v] of Object.entries(loopsIn)) {
498
+ if (typeof v === "object" && v !== null) {
499
+ loops[k] = parseLoopRecord(v);
500
+ }
501
+ }
502
+ const rootOutputs = typeof d.root_step_outputs === "object" && d.root_step_outputs !== null
503
+ ? d.root_step_outputs
504
+ : {};
505
+ const iterOutputs = typeof d.loop_iteration_outputs === "object" &&
506
+ d.loop_iteration_outputs !== null
507
+ ? d.loop_iteration_outputs
508
+ : {};
509
+ return {
510
+ runId: String(d.run_id ?? ""),
511
+ mobId: String(d.mob_id ?? ""),
512
+ flowId: String(d.flow_id ?? ""),
513
+ status: parseMobRunStatus(d.status),
514
+ flowState: d.flow_state,
515
+ activationParams: d.activation_params,
516
+ createdAt: String(d.created_at ?? ""),
517
+ completedAt: d.completed_at === null || d.completed_at === undefined
518
+ ? null
519
+ : String(d.completed_at),
520
+ stepLedger,
521
+ failureLedger,
522
+ frames,
523
+ loops,
524
+ loopIterationLedger: iterations,
525
+ schemaVersion: Number(d.schema_version ?? 0),
526
+ rootStepOutputs: rootOutputs,
527
+ loopIterationOutputs: iterOutputs,
528
+ };
529
+ }
361
530
  // -- ErrorCategory / ErrorEvent -------------------------------------------
362
531
  exports.ErrorCategory = {
363
532
  SPAWN_FAILURE: "spawn_failure",
@@ -404,3 +573,312 @@ function parseErrorEvent(raw) {
404
573
  }
405
574
  return { category, message, context };
406
575
  }
576
+ function parseDurableAgentSpec(raw) {
577
+ const d = asRecord(raw);
578
+ return {
579
+ identity: String(d.identity ?? ""),
580
+ profile: String(d.profile ?? ""),
581
+ addressability: String(d.addressability ?? "addressable"),
582
+ displayName: typeof d.display_name === "string" ? d.display_name : null,
583
+ labels: asStringRecord(d.labels),
584
+ context: d.context !== undefined && d.context !== null ? d.context : null,
585
+ additionalInstructions: asStringArray(d.additional_instructions),
586
+ };
587
+ }
588
+ function durableAgentSpecToDict(spec) {
589
+ const result = {
590
+ identity: spec.identity,
591
+ profile: spec.profile,
592
+ addressability: spec.addressability,
593
+ };
594
+ if (spec.displayName !== null)
595
+ result.display_name = spec.displayName;
596
+ if (Object.keys(spec.labels).length > 0)
597
+ result.labels = { ...spec.labels };
598
+ if (spec.context !== null)
599
+ result.context = spec.context;
600
+ if (spec.additionalInstructions.length > 0) {
601
+ result.additional_instructions = [...spec.additionalInstructions];
602
+ }
603
+ return result;
604
+ }
605
+ function parseContentBlock(raw) {
606
+ const d = asRecord(raw);
607
+ if (d.type === "image") {
608
+ return {
609
+ type: "image",
610
+ mediaType: String(d.media_type ?? d.mediaType ?? ""),
611
+ data: String(d.data ?? ""),
612
+ };
613
+ }
614
+ return { type: "text", text: String(d.text ?? "") };
615
+ }
616
+ function contentBlockToDict(block) {
617
+ if (block.type === "image") {
618
+ return { type: "image", media_type: block.mediaType, data: block.data };
619
+ }
620
+ return { type: "text", text: block.text };
621
+ }
622
+ const DISPATCH_ORIGIN_VALUES = [
623
+ "connector",
624
+ "scheduler",
625
+ "policy",
626
+ "flow",
627
+ "system",
628
+ ];
629
+ function parseDispatchOrigin(raw) {
630
+ // Pre-fix this was `String(d.origin ?? "system") as DispatchOrigin`
631
+ // — an unchecked cast that admitted arbitrary strings, so a
632
+ // consumer's `switch (input.origin)` over the closed set hit no
633
+ // branch silently. Validate against the union and fall back to
634
+ // "system" for anything else.
635
+ if (typeof raw === "string" && DISPATCH_ORIGIN_VALUES.includes(raw)) {
636
+ return raw;
637
+ }
638
+ return "system";
639
+ }
640
+ function parseDispatchInput(raw) {
641
+ const d = asRecord(raw);
642
+ let content;
643
+ if (typeof d.content === "string") {
644
+ content = d.content;
645
+ }
646
+ else if (Array.isArray(d.content)) {
647
+ content = d.content.map(parseContentBlock);
648
+ }
649
+ else {
650
+ content = "";
651
+ }
652
+ return {
653
+ content,
654
+ origin: parseDispatchOrigin(d.origin),
655
+ correlationId: typeof d.correlation_id === "string" ? d.correlation_id : undefined,
656
+ idempotencyKey: typeof d.idempotency_key === "string" ? d.idempotency_key : undefined,
657
+ };
658
+ }
659
+ function dispatchInputToDict(input) {
660
+ const result = {
661
+ origin: input.origin,
662
+ };
663
+ if (typeof input.content === "string") {
664
+ result.content = input.content;
665
+ }
666
+ else {
667
+ result.content = input.content.map(contentBlockToDict);
668
+ }
669
+ if (input.correlationId !== undefined) {
670
+ result.correlation_id = input.correlationId;
671
+ }
672
+ if (input.idempotencyKey !== undefined) {
673
+ result.idempotency_key = input.idempotencyKey;
674
+ }
675
+ return result;
676
+ }
677
+ function parseManagedPeerEdge(raw) {
678
+ const d = asRecord(raw);
679
+ return { a: String(d.a ?? ""), b: String(d.b ?? "") };
680
+ }
681
+ function managedPeerEdgeToDict(edge) {
682
+ return { a: edge.a, b: edge.b };
683
+ }
684
+ function parseExternalToolDef(raw) {
685
+ const d = asRecord(raw);
686
+ return {
687
+ name: String(d.name ?? ""),
688
+ description: String(d.description ?? ""),
689
+ inputSchema: asRecord(d.input_schema),
690
+ };
691
+ }
692
+ function externalToolDefToDict(tool) {
693
+ return {
694
+ name: tool.name,
695
+ description: tool.description,
696
+ input_schema: tool.inputSchema,
697
+ };
698
+ }
699
+ function parseAgentBuildContext(raw) {
700
+ const d = asRecord(raw);
701
+ const rawEdges = Array.isArray(d.managed_edges) ? d.managed_edges : [];
702
+ return {
703
+ identity: String(d.identity ?? ""),
704
+ activePeers: asStringArray(d.active_peers),
705
+ managedEdges: rawEdges.map(parseManagedPeerEdge),
706
+ };
707
+ }
708
+ function parseAgentBuildDraft(raw) {
709
+ const d = asRecord(raw);
710
+ const rawTools = Array.isArray(d.external_tools) ? d.external_tools : [];
711
+ return {
712
+ model: typeof d.model === "string" ? d.model : null,
713
+ systemPrompt: typeof d.system_prompt === "string" ? d.system_prompt : null,
714
+ additionalInstructions: asStringArray(d.additional_instructions),
715
+ labels: asStringRecord(d.labels),
716
+ appContext: d.app_context !== undefined && d.app_context !== null ? d.app_context : null,
717
+ externalTools: rawTools.map(parseExternalToolDef),
718
+ };
719
+ }
720
+ function agentBuildDraftToDict(draft) {
721
+ const result = {};
722
+ if (draft.model !== null)
723
+ result.model = draft.model;
724
+ if (draft.systemPrompt !== null)
725
+ result.system_prompt = draft.systemPrompt;
726
+ if (draft.additionalInstructions.length > 0) {
727
+ result.additional_instructions = [...draft.additionalInstructions];
728
+ }
729
+ if (Object.keys(draft.labels).length > 0)
730
+ result.labels = { ...draft.labels };
731
+ if (draft.appContext !== null)
732
+ result.app_context = draft.appContext;
733
+ if (draft.externalTools.length > 0) {
734
+ result.external_tools = draft.externalTools.map(externalToolDefToDict);
735
+ }
736
+ return result;
737
+ }
738
+ function parseLeaseInfo(raw) {
739
+ if (raw == null || typeof raw !== "object")
740
+ return null;
741
+ const d = raw;
742
+ return {
743
+ fencingToken: Number(d.fencing_token ?? 0),
744
+ ttlRemainingMs: Number(d.ttl_remaining_ms ?? 0),
745
+ healthy: Boolean(d.healthy ?? false),
746
+ };
747
+ }
748
+ function parseDurabilityPolicy(raw) {
749
+ const d = asRecord(raw);
750
+ const wireKind = String(d.kind ?? "sync_write_through");
751
+ let kind;
752
+ switch (wireKind) {
753
+ case "async_replicated":
754
+ kind = "asyncReplicated";
755
+ break;
756
+ case "buffered_export":
757
+ kind = "bufferedExport";
758
+ break;
759
+ default:
760
+ kind = "syncWriteThrough";
761
+ break;
762
+ }
763
+ const result = { kind };
764
+ if (kind === "bufferedExport" && d.max_loss_window_ms !== undefined) {
765
+ return { kind, maxLossWindowMs: Number(d.max_loss_window_ms) };
766
+ }
767
+ return result;
768
+ }
769
+ function parseContinuityHealth(raw) {
770
+ if (raw == null || typeof raw !== "object")
771
+ return null;
772
+ const d = raw;
773
+ return {
774
+ storeReachable: Boolean(d.store_reachable ?? false),
775
+ durabilityPolicy: parseDurabilityPolicy(d.durability_policy),
776
+ lastCheckpointVersion: typeof d.last_checkpoint_version === "number"
777
+ ? d.last_checkpoint_version
778
+ : null,
779
+ };
780
+ }
781
+ function parseIdentityStatus(raw) {
782
+ const d = asRecord(raw);
783
+ return {
784
+ identity: String(d.identity ?? ""),
785
+ lifecycleState: String(d.state ?? ""),
786
+ agentRuntimeId: String(d.agent_runtime_id ?? ""),
787
+ sessionId: String(d.session_id ?? ""),
788
+ profile: String(d.profile ?? ""),
789
+ addressability: String(d.addressability ?? "addressable"),
790
+ displayName: typeof d.display_name === "string" ? d.display_name : null,
791
+ labels: asStringRecord(d.labels),
792
+ generation: Number(d.generation ?? 0),
793
+ checkpointVersion: Number(d.checkpoint_version ?? 0),
794
+ lease: parseLeaseInfo(d.lease),
795
+ continuityHealth: parseContinuityHealth(d.continuity_health),
796
+ };
797
+ }
798
+ function parseContinuityRecord(raw) {
799
+ const d = asRecord(raw);
800
+ return {
801
+ identity: String(d.identity ?? ""),
802
+ agentRuntimeId: String(d.agent_runtime_id ?? ""),
803
+ sessionId: String(d.session_id ?? ""),
804
+ generation: Number(d.generation ?? 0),
805
+ checkpointVersion: Number(d.checkpoint_version ?? 0),
806
+ };
807
+ }
808
+ function continuityRecordToDict(record) {
809
+ return {
810
+ identity: record.identity,
811
+ agent_runtime_id: record.agentRuntimeId,
812
+ session_id: record.sessionId,
813
+ generation: record.generation,
814
+ checkpoint_version: record.checkpointVersion,
815
+ };
816
+ }
817
+ function parseContinuityFailure(raw) {
818
+ const d = asRecord(raw);
819
+ return {
820
+ identity: String(d.identity ?? ""),
821
+ kind: String(d.kind ?? ""),
822
+ record: d.record != null ? parseContinuityRecord(d.record) : undefined,
823
+ detail: String(d.detail ?? ""),
824
+ };
825
+ }
826
+ function parseContinuityResolveState(raw) {
827
+ const d = asRecord(raw);
828
+ const state = String(d.state ?? "uninitialized");
829
+ return {
830
+ state,
831
+ record: d.record != null ? parseContinuityRecord(d.record) : undefined,
832
+ failure: d.failure != null ? parseContinuityFailure(d.failure) : undefined,
833
+ };
834
+ }
835
+ function parseSessionSnapshot(raw) {
836
+ const d = asRecord(raw);
837
+ const b64 = String(d.data ?? "");
838
+ const binary = atob(b64);
839
+ const bytes = new Uint8Array(binary.length);
840
+ for (let i = 0; i < binary.length; i++) {
841
+ bytes[i] = binary.charCodeAt(i);
842
+ }
843
+ return { data: bytes };
844
+ }
845
+ function sessionSnapshotToDict(snap) {
846
+ let binary = "";
847
+ for (let i = 0; i < snap.data.length; i++) {
848
+ binary += String.fromCharCode(snap.data[i]);
849
+ }
850
+ return { data: btoa(binary) };
851
+ }
852
+ function parseLeaseGrant(raw) {
853
+ const d = asRecord(raw);
854
+ return {
855
+ identity: String(d.identity ?? ""),
856
+ fencingToken: Number(d.fencing_token ?? 0),
857
+ ttlMs: Number(d.ttl_ms ?? 0),
858
+ };
859
+ }
860
+ function leaseGrantToDict(grant) {
861
+ return {
862
+ identity: grant.identity,
863
+ fencing_token: grant.fencingToken,
864
+ ttl_ms: grant.ttlMs,
865
+ };
866
+ }
867
+ function parseLeaseAcquireResult(raw) {
868
+ const d = asRecord(raw);
869
+ const wireStatus = String(d.status ?? "acquired");
870
+ const status = wireStatus === "already_held" ? "alreadyHeld" : "acquired";
871
+ return {
872
+ status,
873
+ grant: d.grant != null ? parseLeaseGrant(d.grant) : undefined,
874
+ holder: typeof d.holder === "string" ? d.holder : undefined,
875
+ };
876
+ }
877
+ function parseLeaseRenewResult(raw) {
878
+ const d = asRecord(raw);
879
+ const status = String(d.status ?? "renewed");
880
+ return {
881
+ status,
882
+ grant: d.grant != null ? parseLeaseGrant(d.grant) : undefined,
883
+ };
884
+ }
package/dist/errors.d.ts CHANGED
@@ -27,7 +27,33 @@ export declare class RpcError extends MobKitError {
27
27
  readonly code: number;
28
28
  readonly requestId: string;
29
29
  readonly method: string;
30
- constructor(code: number, message: string, requestId: string, method: string);
30
+ /** Optional structured payload from the JSON-RPC `error.data` field. */
31
+ readonly data?: unknown | undefined;
32
+ constructor(code: number, message: string, requestId: string, method: string,
33
+ /** Optional structured payload from the JSON-RPC `error.data` field. */
34
+ data?: unknown | undefined);
35
+ }
36
+ /**
37
+ * JSON-RPC error code returned when the caller's `after_seq` is past the
38
+ * current ledger frontier. Returned by `mobkit/mob_events/{query,subscribe}`
39
+ * and the `/mobkit/mob_events/stream` SSE route (HTTP 410 Gone).
40
+ */
41
+ export declare const MOB_EVENTS_STALE_CURSOR_CODE: -32010;
42
+ /**
43
+ * Raised when the caller passes an `after_seq` past the current ledger
44
+ * frontier. The server's `error.data` payload carries `after_cursor` and
45
+ * `latest_cursor` — use the latter to rewind and resume.
46
+ */
47
+ export declare class MobEventsStaleError extends RpcError {
48
+ readonly afterCursor: number;
49
+ readonly latestCursor: number;
50
+ constructor(message: string, afterCursor: number, latestCursor: number, requestId: string, method: string, data?: unknown);
51
+ /**
52
+ * Reify a generic {@link RpcError} with code `-32010` into the typed
53
+ * form. Reads `after_cursor` / `latest_cursor` from the JSON-RPC
54
+ * `error.data` payload; missing fields fall back to `0`.
55
+ */
56
+ static fromRpcError(err: RpcError): MobEventsStaleError;
31
57
  }
32
58
  /** Raised when a requested capability is not available on the runtime. */
33
59
  export declare class CapabilityUnavailableError extends MobKitError {
@@ -41,6 +67,17 @@ export declare class ContractMismatchError extends MobKitError {
41
67
  export declare class NotConnectedError extends MobKitError {
42
68
  constructor(message: string);
43
69
  }
70
+ /**
71
+ * Structural test for an `RpcError`. Pre-fix every site used
72
+ * `err instanceof RpcError`, but JS class identity is module-scoped:
73
+ * dual CJS+ESM packaging, vitest module isolation, and hoisted-vs-
74
+ * nested workspace deps can produce two `RpcError` constructors that
75
+ * fail `instanceof` for each other's instances. The structural check
76
+ * survives those splits.
77
+ */
78
+ export declare function isRpcError(err: unknown): err is RpcError;
79
+ /** Structural test for a `MobEventsStaleError`. See `isRpcError`. */
80
+ export declare function isMobEventsStaleError(err: unknown): err is MobEventsStaleError;
44
81
  /** @deprecated Use {@link RpcError} instead. */
45
82
  export declare const MobkitRpcError: typeof RpcError;
46
83
  /** @deprecated Use {@link RpcError} instead. */
@@ -1 +1 @@
1
- {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAIH,gDAAgD;AAChD,qBAAa,WAAY,SAAQ,KAAK;gBACxB,OAAO,EAAE,MAAM;CAI5B;AAID,yFAAyF;AACzF,qBAAa,cAAe,SAAQ,WAAW;gBACjC,OAAO,EAAE,MAAM;CAI5B;AAID,6DAA6D;AAC7D,qBAAa,QAAS,SAAQ,WAAW;IAErC,QAAQ,CAAC,IAAI,EAAE,MAAM;IAErB,QAAQ,CAAC,SAAS,EAAE,MAAM;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM;gBAHd,IAAI,EAAE,MAAM,EACrB,OAAO,EAAE,MAAM,EACN,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM;CAK1B;AAID,0EAA0E;AAC1E,qBAAa,0BAA2B,SAAQ,WAAW;gBAC7C,OAAO,EAAE,MAAM;CAI5B;AAID,0EAA0E;AAC1E,qBAAa,qBAAsB,SAAQ,WAAW;gBACxC,OAAO,EAAE,MAAM;CAI5B;AAID,mFAAmF;AACnF,qBAAa,iBAAkB,SAAQ,WAAW;gBACpC,OAAO,EAAE,MAAM;CAI5B;AAID,gDAAgD;AAChD,eAAO,MAAM,cAAc,iBAAW,CAAC;AACvC,gDAAgD;AAChD,MAAM,MAAM,cAAc,GAAG,QAAQ,CAAC"}
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAIH,gDAAgD;AAChD,qBAAa,WAAY,SAAQ,KAAK;gBACxB,OAAO,EAAE,MAAM;CAI5B;AAID,yFAAyF;AACzF,qBAAa,cAAe,SAAQ,WAAW;gBACjC,OAAO,EAAE,MAAM;CAI5B;AAID,6DAA6D;AAC7D,qBAAa,QAAS,SAAQ,WAAW;IAErC,QAAQ,CAAC,IAAI,EAAE,MAAM;IAErB,QAAQ,CAAC,SAAS,EAAE,MAAM;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM;IACvB,wEAAwE;IACxE,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO;gBALd,IAAI,EAAE,MAAM,EACrB,OAAO,EAAE,MAAM,EACN,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM;IACvB,wEAAwE;IAC/D,IAAI,CAAC,EAAE,OAAO,YAAA;CAK1B;AAED;;;;GAIG;AACH,eAAO,MAAM,4BAA4B,EAAG,CAAC,KAAc,CAAC;AAE5D;;;;GAIG;AACH,qBAAa,mBAAoB,SAAQ,QAAQ;IAG7C,QAAQ,CAAC,WAAW,EAAE,MAAM;IAC5B,QAAQ,CAAC,YAAY,EAAE,MAAM;gBAF7B,OAAO,EAAE,MAAM,EACN,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,MAAM,EAC7B,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,IAAI,CAAC,EAAE,OAAO;IAMhB;;;;OAIG;IACH,MAAM,CAAC,YAAY,CAAC,GAAG,EAAE,QAAQ,GAAG,mBAAmB;CAgBxD;AAID,0EAA0E;AAC1E,qBAAa,0BAA2B,SAAQ,WAAW;gBAC7C,OAAO,EAAE,MAAM;CAI5B;AAID,0EAA0E;AAC1E,qBAAa,qBAAsB,SAAQ,WAAW;gBACxC,OAAO,EAAE,MAAM;CAI5B;AAID,mFAAmF;AACnF,qBAAa,iBAAkB,SAAQ,WAAW;gBACpC,OAAO,EAAE,MAAM;CAI5B;AAID;;;;;;;GAOG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,OAAO,GAAG,GAAG,IAAI,QAAQ,CAYxD;AAED,qEAAqE;AACrE,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,OAAO,GAAG,GAAG,IAAI,mBAAmB,CAS9E;AAID,gDAAgD;AAChD,eAAO,MAAM,cAAc,iBAAW,CAAC;AACvC,gDAAgD;AAChD,MAAM,MAAM,cAAc,GAAG,QAAQ,CAAC"}
package/dist/errors.js CHANGED
@@ -36,14 +36,52 @@ export class RpcError extends MobKitError {
36
36
  code;
37
37
  requestId;
38
38
  method;
39
- constructor(code, message, requestId, method) {
39
+ data;
40
+ constructor(code, message, requestId, method,
41
+ /** Optional structured payload from the JSON-RPC `error.data` field. */
42
+ data) {
40
43
  super(message);
41
44
  this.code = code;
42
45
  this.requestId = requestId;
43
46
  this.method = method;
47
+ this.data = data;
44
48
  this.name = "RpcError";
45
49
  }
46
50
  }
51
+ /**
52
+ * JSON-RPC error code returned when the caller's `after_seq` is past the
53
+ * current ledger frontier. Returned by `mobkit/mob_events/{query,subscribe}`
54
+ * and the `/mobkit/mob_events/stream` SSE route (HTTP 410 Gone).
55
+ */
56
+ export const MOB_EVENTS_STALE_CURSOR_CODE = -32010;
57
+ /**
58
+ * Raised when the caller passes an `after_seq` past the current ledger
59
+ * frontier. The server's `error.data` payload carries `after_cursor` and
60
+ * `latest_cursor` — use the latter to rewind and resume.
61
+ */
62
+ export class MobEventsStaleError extends RpcError {
63
+ afterCursor;
64
+ latestCursor;
65
+ constructor(message, afterCursor, latestCursor, requestId, method, data) {
66
+ super(MOB_EVENTS_STALE_CURSOR_CODE, message, requestId, method, data);
67
+ this.afterCursor = afterCursor;
68
+ this.latestCursor = latestCursor;
69
+ this.name = "MobEventsStaleError";
70
+ }
71
+ /**
72
+ * Reify a generic {@link RpcError} with code `-32010` into the typed
73
+ * form. Reads `after_cursor` / `latest_cursor` from the JSON-RPC
74
+ * `error.data` payload; missing fields fall back to `0`.
75
+ */
76
+ static fromRpcError(err) {
77
+ const payload = typeof err.data === "object" && err.data !== null
78
+ ? err.data
79
+ : {};
80
+ const afterCursor = Number(payload.after_cursor ?? 0);
81
+ const latestCursor = Number(payload.latest_cursor ?? 0);
82
+ return new MobEventsStaleError(err.message, Number.isFinite(afterCursor) ? afterCursor : 0, Number.isFinite(latestCursor) ? latestCursor : 0, err.requestId, err.method, err.data);
83
+ }
84
+ }
47
85
  // -- Capability errors ----------------------------------------------------
48
86
  /** Raised when a requested capability is not available on the runtime. */
49
87
  export class CapabilityUnavailableError extends MobKitError {
@@ -68,6 +106,35 @@ export class NotConnectedError extends MobKitError {
68
106
  this.name = "NotConnectedError";
69
107
  }
70
108
  }
109
+ // -- Cross-module identity helpers ---------------------------------------
110
+ /**
111
+ * Structural test for an `RpcError`. Pre-fix every site used
112
+ * `err instanceof RpcError`, but JS class identity is module-scoped:
113
+ * dual CJS+ESM packaging, vitest module isolation, and hoisted-vs-
114
+ * nested workspace deps can produce two `RpcError` constructors that
115
+ * fail `instanceof` for each other's instances. The structural check
116
+ * survives those splits.
117
+ */
118
+ export function isRpcError(err) {
119
+ if (err instanceof RpcError) {
120
+ return true;
121
+ }
122
+ if (err === null || typeof err !== "object") {
123
+ return false;
124
+ }
125
+ const candidate = err;
126
+ return (candidate.name === "RpcError" ||
127
+ candidate.name === "MobEventsStaleError") && typeof candidate.code === "number";
128
+ }
129
+ /** Structural test for a `MobEventsStaleError`. See `isRpcError`. */
130
+ export function isMobEventsStaleError(err) {
131
+ if (err instanceof MobEventsStaleError) {
132
+ return true;
133
+ }
134
+ return (isRpcError(err) &&
135
+ err.code === MOB_EVENTS_STALE_CURSOR_CODE &&
136
+ err.name === "MobEventsStaleError");
137
+ }
71
138
  // -- Backward compatibility -----------------------------------------------
72
139
  /** @deprecated Use {@link RpcError} instead. */
73
140
  export const MobkitRpcError = RpcError;