stitchkit 0.99.0 → 0.100.1

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 (147) hide show
  1. package/CHANGELOG.md +124 -1
  2. package/dist/agent-runtime/contained-darwin.d.ts +0 -17
  3. package/dist/agent-runtime/contained-darwin.d.ts.map +1 -1
  4. package/dist/agent-runtime/contained-write.d.ts.map +1 -1
  5. package/dist/agent-runtime/invocation-attempt.d.ts +28 -0
  6. package/dist/agent-runtime/invocation-attempt.d.ts.map +1 -0
  7. package/dist/agent-runtime/invocation-failure.d.ts +6 -0
  8. package/dist/agent-runtime/invocation-failure.d.ts.map +1 -0
  9. package/dist/agent-runtime/invocation-payload.d.ts +20 -0
  10. package/dist/agent-runtime/invocation-payload.d.ts.map +1 -0
  11. package/dist/agent-runtime/invocation-read.d.ts +131 -0
  12. package/dist/agent-runtime/invocation-read.d.ts.map +1 -0
  13. package/dist/agent-runtime/invocation-schema.d.ts +378 -0
  14. package/dist/agent-runtime/invocation-schema.d.ts.map +1 -0
  15. package/dist/agent-runtime/invocations.d.ts +52 -0
  16. package/dist/agent-runtime/invocations.d.ts.map +1 -0
  17. package/dist/agent-runtime/projections.d.ts.map +1 -1
  18. package/dist/agent-runtime/run-acquisition.d.ts.map +1 -1
  19. package/dist/agent-runtime/run-execution-state.d.ts +4 -2
  20. package/dist/agent-runtime/run-execution-state.d.ts.map +1 -1
  21. package/dist/agent-runtime/run-execution.d.ts.map +1 -1
  22. package/dist/agent-runtime/run-failure.d.ts.map +1 -1
  23. package/dist/agent-runtime/run-model-attempts.d.ts.map +1 -1
  24. package/dist/agent-runtime/run-operation-lifecycle.d.ts +2 -2
  25. package/dist/agent-runtime/run-operation-lifecycle.d.ts.map +1 -1
  26. package/dist/agent-runtime/run-provider-ledger.d.ts +1 -0
  27. package/dist/agent-runtime/run-provider-ledger.d.ts.map +1 -1
  28. package/dist/agent-runtime/runtime.d.ts +11 -0
  29. package/dist/agent-runtime/runtime.d.ts.map +1 -1
  30. package/dist/agent-runtime/schedule-dispatch.d.ts +9 -2
  31. package/dist/agent-runtime/schedule-dispatch.d.ts.map +1 -1
  32. package/dist/agent-runtime/schedule-records.d.ts +8 -2
  33. package/dist/agent-runtime/schedule-records.d.ts.map +1 -1
  34. package/dist/agent-runtime/schedules.d.ts +5 -0
  35. package/dist/agent-runtime/schedules.d.ts.map +1 -1
  36. package/dist/agent-runtime/sqlite-events.d.ts.map +1 -1
  37. package/dist/agent-runtime/store-create.d.ts.map +1 -1
  38. package/dist/agent-runtime/store-driver-contract.d.ts +9 -0
  39. package/dist/agent-runtime/store-driver-contract.d.ts.map +1 -1
  40. package/dist/agent-runtime/store-event-once.d.ts +37 -0
  41. package/dist/agent-runtime/store-event-once.d.ts.map +1 -0
  42. package/dist/agent-runtime/store-memory.d.ts.map +1 -1
  43. package/dist/agent-runtime/store.d.ts +11 -0
  44. package/dist/agent-runtime/store.d.ts.map +1 -1
  45. package/dist/application/change-subscription.d.ts +36 -0
  46. package/dist/application/change-subscription.d.ts.map +1 -0
  47. package/dist/application/diagnostic-journal-contract.d.ts +3 -6
  48. package/dist/application/diagnostic-journal-contract.d.ts.map +1 -1
  49. package/dist/application/notification-delivery.d.ts +55 -0
  50. package/dist/application/notification-delivery.d.ts.map +1 -0
  51. package/dist/application/notification-outbox-state.d.ts +41 -0
  52. package/dist/application/notification-outbox-state.d.ts.map +1 -0
  53. package/dist/application/notification-outbox.d.ts +7 -1
  54. package/dist/application/notification-outbox.d.ts.map +1 -1
  55. package/dist/application/watch-hub-core.d.ts +14 -84
  56. package/dist/application/watch-hub-core.d.ts.map +1 -1
  57. package/dist/application/watch-hub-source.d.ts +98 -0
  58. package/dist/application/watch-hub-source.d.ts.map +1 -0
  59. package/dist/application/watch-hub.d.ts +10 -2
  60. package/dist/application/watch-hub.d.ts.map +1 -1
  61. package/dist/browser/session-credentials.d.ts +26 -0
  62. package/dist/browser/session-credentials.d.ts.map +1 -0
  63. package/dist/browser/session.d.ts +33 -0
  64. package/dist/browser/session.d.ts.map +1 -0
  65. package/dist/durability/events.d.ts +6 -0
  66. package/dist/durability/events.d.ts.map +1 -1
  67. package/dist/entrypoints/agent-runtime/coding-tools.js +3 -2
  68. package/dist/entrypoints/agent-runtime/harness.js +5 -3
  69. package/dist/entrypoints/agent-runtime/sandbox.js +3 -2
  70. package/dist/entrypoints/agent-runtime/sqlite/bun.js +3 -3
  71. package/dist/entrypoints/agent-runtime/sqlite/node.js +3 -3
  72. package/dist/entrypoints/agent-runtime/testing.js +3 -3
  73. package/dist/entrypoints/agent-runtime.d.ts +3 -0
  74. package/dist/entrypoints/agent-runtime.d.ts.map +1 -1
  75. package/dist/entrypoints/agent-runtime.js +65 -20
  76. package/dist/entrypoints/application/diagnostic-journal.js +2 -1
  77. package/dist/entrypoints/application.d.ts +3 -1
  78. package/dist/entrypoints/application.d.ts.map +1 -1
  79. package/dist/entrypoints/application.js +820 -294
  80. package/dist/entrypoints/files.js +9 -2
  81. package/dist/entrypoints/index.d.ts +2 -0
  82. package/dist/entrypoints/index.d.ts.map +1 -1
  83. package/dist/entrypoints/index.js +199 -0
  84. package/dist/entrypoints/live.js +78 -19
  85. package/dist/entrypoints/node.js +1 -1
  86. package/dist/entrypoints/react.d.ts +1 -1
  87. package/dist/entrypoints/react.d.ts.map +1 -1
  88. package/dist/entrypoints/react.js +59 -16
  89. package/dist/entrypoints/server.js +4 -4
  90. package/dist/{index-sp1tzwnb.js → index-10x2hbx0.js} +5 -2
  91. package/dist/{index-8p52kd5p.js → index-c6bxbsnc.js} +100 -14
  92. package/dist/{index-gxrt5h6v.js → index-cyktc4bp.js} +3 -0
  93. package/dist/{index-1m2thnq0.js → index-eaysmdtq.js} +11 -2
  94. package/dist/{index-jhx828hc.js → index-f4fx2tza.js} +948 -279
  95. package/dist/{index-px2gm2jp.js → index-fhwqwxe0.js} +17 -55
  96. package/dist/{index-e4hkgm5t.js → index-gw8bmyaj.js} +4 -2
  97. package/dist/{index-p3vsv1fb.js → index-hadmp193.js} +14 -5
  98. package/dist/{index-wt743f7f.js → index-k6gpggb9.js} +2 -1
  99. package/dist/index-q3pyb9n0.js +22 -0
  100. package/dist/{index-wsm5w4ee.js → index-vqr7f7v8.js} +51 -3
  101. package/dist/index-zjjyynm3.js +42 -0
  102. package/dist/internal/coalesced-task.d.ts +17 -0
  103. package/dist/internal/coalesced-task.d.ts.map +1 -0
  104. package/dist/internal/darwin-binding.d.ts +19 -0
  105. package/dist/internal/darwin-binding.d.ts.map +1 -0
  106. package/dist/internal/exclusive-lock.d.ts +20 -7
  107. package/dist/internal/exclusive-lock.d.ts.map +1 -1
  108. package/dist/internal/mutation-queue.d.ts +4 -0
  109. package/dist/internal/mutation-queue.d.ts.map +1 -0
  110. package/dist/internal/process-identity.d.ts +1 -1
  111. package/dist/internal/process-identity.d.ts.map +1 -1
  112. package/dist/internal/process-instance.d.ts +26 -0
  113. package/dist/internal/process-instance.d.ts.map +1 -0
  114. package/dist/internal/with-exclusive-lock.d.ts.map +1 -1
  115. package/dist/live/watch-client-state.d.ts +71 -0
  116. package/dist/live/watch-client-state.d.ts.map +1 -0
  117. package/dist/live/watch-client.d.ts +5 -1
  118. package/dist/live/watch-client.d.ts.map +1 -1
  119. package/dist/live/watch-contract.d.ts +12 -0
  120. package/dist/live/watch-contract.d.ts.map +1 -1
  121. package/dist/react/cache-bridge.d.ts +10 -0
  122. package/dist/react/cache-bridge.d.ts.map +1 -1
  123. package/dist/server/realtime.d.ts.map +1 -1
  124. package/llms/agent-runtime.2.txt +102 -0
  125. package/llms/agent-runtime.3.txt +30 -1
  126. package/llms/agent-runtime.txt +8 -3
  127. package/llms/application.2.txt +84 -2
  128. package/llms/application.txt +32 -2
  129. package/llms/files.txt +1 -1
  130. package/llms/live.txt +8 -0
  131. package/llms/react.txt +8 -0
  132. package/llms/server.3.txt +57 -0
  133. package/llms/stitchkit.2.txt +41 -0
  134. package/llms/stitchkit.3.txt +26 -0
  135. package/llms/stitchkit.txt +3 -3
  136. package/llms/upgrading-0.37.0.txt +176 -0
  137. package/llms/{upgrading-0.37.0-0.58.0.txt → upgrading-0.44.0-0.60.0.txt} +229 -169
  138. package/llms/{upgrading-0.59.0-0.71.0.txt → upgrading-0.61.0-0.73.0.txt} +122 -229
  139. package/llms/{upgrading-0.72.0-0.99.0.txt → upgrading-0.74.0-0.100.0.txt} +80 -123
  140. package/llms/upgrading.txt +4 -3
  141. package/llms-full.txt +471 -11
  142. package/llms.txt +10 -9
  143. package/native/darwin-arm64.node +0 -0
  144. package/native/darwin-x64.node +0 -0
  145. package/package.json +1 -1
  146. package/dist/agent-runtime/run-mutation-queue.d.ts +0 -21
  147. package/dist/agent-runtime/run-mutation-queue.d.ts.map +0 -1
@@ -1,6 +1,7 @@
1
1
  import {
2
2
  attemptExclusiveLock
3
- } from "../index-8p52kd5p.js";
3
+ } from "../index-c6bxbsnc.js";
4
+ import"../index-zjjyynm3.js";
4
5
  import {
5
6
  ManagedFileError,
6
7
  createManagedFileBoundary
@@ -46,6 +47,12 @@ function describeHolder(holder) {
46
47
  const machine = holder.machine === undefined ? "" : `, machine ${holder.machine}`;
47
48
  return `pid ${holder.pid} on ${holder.host}${machine} since ${holder.acquiredAt}`;
48
49
  }
50
+ function describeEvidence(diagnosis) {
51
+ if (!diagnosis)
52
+ return "";
53
+ const identity = diagnosis.identity === undefined ? "" : `, identity ${diagnosis.identity}`;
54
+ return ` (${diagnosis.attribution}, liveness ${diagnosis.liveness}${identity})`;
55
+ }
49
56
  function pause(ms, signal) {
50
57
  return new Promise((resolve) => {
51
58
  const done = () => {
@@ -93,7 +100,7 @@ async function withExclusiveLock(path, run, options = {}) {
93
100
  const remaining = deadline - performance.now();
94
101
  if (remaining <= 0) {
95
102
  const holder = attempt.diagnosis?.owner ?? null;
96
- throw new ExclusiveLockError("LOCK_TIMEOUT", label, holder, `[stitchkit] the lock on "${label}" is held by ${describeHolder(holder)}; gave up after ${timeoutMs} ms`, { cause: attempt.error });
103
+ throw new ExclusiveLockError("LOCK_TIMEOUT", label, holder, `[stitchkit] the lock on "${label}" is held by ${describeHolder(holder)}${describeEvidence(attempt.diagnosis)}; gave up after ${timeoutMs} ms`, { cause: attempt.error });
97
104
  }
98
105
  await pause(Math.min(delay * (0.5 + Math.random() / 2), remaining), signal);
99
106
  delay = Math.min(delay * 2, MAX_RETRY_MS);
@@ -5,6 +5,8 @@ export type { BindRealtimeClientOptions, BoundRealtimeClient, RealtimeClientTran
5
5
  export { bindRealtimeClient } from '../browser/realtime-client.js';
6
6
  export { type ResumableAttempt, type ResumableIteratorConfig, resumableIterator, } from '../browser/resumable.js';
7
7
  export { createRetainedTopics, type RetainedTopics } from '../browser/retained.js';
8
+ export { createSessionScope, SessionExpiredError, type SessionOperation, type SessionScope, } from '../browser/session.js';
9
+ export { createSessionCredentials, type SessionCredentials, type SessionCredentialsConfig, } from '../browser/session-credentials.js';
8
10
  export type { RealtimeClient, RealtimeClientOptions, SocketEventMap, SocketIOClient, SocketIOClientConfig, SocketIOClientPeerLoaders, } from '../browser/socket-io.js';
9
11
  export { createRealtimeClient, createSocketIOClient } from '../browser/socket-io.js';
10
12
  export { type ParseNDJSONOptions, type ParseSSEOptions, parseNDJSON, parseSSE, } from '../browser/stream.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/entrypoints/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,YAAY,EACjB,KAAK,cAAc,EACnB,KAAK,WAAW,EAChB,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,EACzB,wBAAwB,EACxB,YAAY,EACZ,aAAa,EACb,mBAAmB,EACnB,uBAAuB,EACvB,gBAAgB,EAChB,iBAAiB,EACjB,KAAK,cAAc,EACnB,KAAK,aAAa,EAClB,KAAK,kBAAkB,EACvB,KAAK,oBAAoB,EACzB,KAAK,wBAAwB,EAC7B,KAAK,gBAAgB,GACtB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,QAAQ,EACR,KAAK,QAAQ,EACb,KAAK,gBAAgB,EACrB,KAAK,oBAAoB,EACzB,gBAAgB,EAChB,KAAK,cAAc,EACnB,KAAK,UAAU,EACf,KAAK,gBAAgB,EACrB,KAAK,cAAc,EACnB,KAAK,mBAAmB,GACzB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,yBAAyB,EACzB,KAAK,mBAAmB,EACxB,KAAK,yBAAyB,EAC9B,KAAK,wBAAwB,EAC7B,KAAK,2BAA2B,EAChC,KAAK,yBAAyB,EAC9B,+BAA+B,EAC/B,KAAK,sBAAsB,EAC3B,KAAK,cAAc,EACnB,oBAAoB,EACpB,KAAK,eAAe,EACpB,KAAK,wBAAwB,EAC7B,KAAK,yBAAyB,EAC9B,KAAK,mBAAmB,EACxB,yBAAyB,EACzB,KAAK,wBAAwB,GAC9B,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EACV,yBAAyB,EACzB,mBAAmB,EACnB,uBAAuB,GACxB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAChE,OAAO,EACL,KAAK,gBAAgB,EACrB,KAAK,uBAAuB,EAC5B,iBAAiB,GAClB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,oBAAoB,EAAE,KAAK,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAChF,YAAY,EACV,cAAc,EACd,qBAAqB,EACrB,cAAc,EACd,cAAc,EACd,oBAAoB,EACpB,yBAAyB,GAC1B,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAClF,OAAO,EACL,KAAK,kBAAkB,EACvB,KAAK,eAAe,EACpB,WAAW,EACX,QAAQ,GACT,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,KAAK,OAAO,EACZ,KAAK,aAAa,EAClB,mBAAmB,EACnB,aAAa,GACd,MAAM,qBAAqB,CAAC;AAC7B,YAAY,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAKvD,OAAO,EAAE,cAAc,EAAE,KAAK,eAAe,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAGzF,OAAO,EACL,SAAS,EACT,kBAAkB,EAClB,iBAAiB,EACjB,gBAAgB,EAChB,KAAK,YAAY,GAClB,MAAM,wBAAwB,CAAC;AAChC,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/entrypoints/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,YAAY,EACjB,KAAK,cAAc,EACnB,KAAK,WAAW,EAChB,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,EACzB,wBAAwB,EACxB,YAAY,EACZ,aAAa,EACb,mBAAmB,EACnB,uBAAuB,EACvB,gBAAgB,EAChB,iBAAiB,EACjB,KAAK,cAAc,EACnB,KAAK,aAAa,EAClB,KAAK,kBAAkB,EACvB,KAAK,oBAAoB,EACzB,KAAK,wBAAwB,EAC7B,KAAK,gBAAgB,GACtB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,QAAQ,EACR,KAAK,QAAQ,EACb,KAAK,gBAAgB,EACrB,KAAK,oBAAoB,EACzB,gBAAgB,EAChB,KAAK,cAAc,EACnB,KAAK,UAAU,EACf,KAAK,gBAAgB,EACrB,KAAK,cAAc,EACnB,KAAK,mBAAmB,GACzB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,yBAAyB,EACzB,KAAK,mBAAmB,EACxB,KAAK,yBAAyB,EAC9B,KAAK,wBAAwB,EAC7B,KAAK,2BAA2B,EAChC,KAAK,yBAAyB,EAC9B,+BAA+B,EAC/B,KAAK,sBAAsB,EAC3B,KAAK,cAAc,EACnB,oBAAoB,EACpB,KAAK,eAAe,EACpB,KAAK,wBAAwB,EAC7B,KAAK,yBAAyB,EAC9B,KAAK,mBAAmB,EACxB,yBAAyB,EACzB,KAAK,wBAAwB,GAC9B,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EACV,yBAAyB,EACzB,mBAAmB,EACnB,uBAAuB,GACxB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAChE,OAAO,EACL,KAAK,gBAAgB,EACrB,KAAK,uBAAuB,EAC5B,iBAAiB,GAClB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,oBAAoB,EAAE,KAAK,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAChF,OAAO,EACL,kBAAkB,EAClB,mBAAmB,EACnB,KAAK,gBAAgB,EACrB,KAAK,YAAY,GAClB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,wBAAwB,EACxB,KAAK,kBAAkB,EACvB,KAAK,wBAAwB,GAC9B,MAAM,gCAAgC,CAAC;AACxC,YAAY,EACV,cAAc,EACd,qBAAqB,EACrB,cAAc,EACd,cAAc,EACd,oBAAoB,EACpB,yBAAyB,GAC1B,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAClF,OAAO,EACL,KAAK,kBAAkB,EACvB,KAAK,eAAe,EACpB,WAAW,EACX,QAAQ,GACT,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,KAAK,OAAO,EACZ,KAAK,aAAa,EAClB,mBAAmB,EACnB,aAAa,GACd,MAAM,qBAAqB,CAAC;AAC7B,YAAY,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAKvD,OAAO,EAAE,cAAc,EAAE,KAAK,eAAe,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAGzF,OAAO,EACL,SAAS,EACT,kBAAkB,EAClB,iBAAiB,EACjB,gBAAgB,EAChB,KAAK,YAAY,GAClB,MAAM,wBAAwB,CAAC;AAChC,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC"}
@@ -32,6 +32,9 @@ import {
32
32
  RealtimeRequestRejectedError,
33
33
  RealtimeRequestTimeoutError
34
34
  } from "../index-dce5wxcq.js";
35
+ import {
36
+ withDeadline
37
+ } from "../index-b9aefrqd.js";
35
38
  import"../index-48ffdxgk.js";
36
39
  import {
37
40
  createContractFactory,
@@ -44,6 +47,9 @@ import {
44
47
  ContractStreamFrameSchema,
45
48
  DEFAULT_CONTRACT_STREAM_FRAME_BYTES
46
49
  } from "../index-wqgjfstn.js";
50
+ import {
51
+ createMutationQueue
52
+ } from "../index-q3pyb9n0.js";
47
53
  import {
48
54
  LiveStateControllerStatusSchema,
49
55
  LiveStatePhaseSchema,
@@ -393,6 +399,196 @@ function createRetainedTopics() {
393
399
  }
394
400
  };
395
401
  }
402
+ // src/browser/session.ts
403
+ class SessionExpiredError extends Error {
404
+ constructor(options) {
405
+ super("The originating session is no longer active", options);
406
+ this.name = "SessionExpiredError";
407
+ }
408
+ }
409
+ function createSessionScope() {
410
+ let generation = 0;
411
+ let stopped = false;
412
+ let active;
413
+ let abort;
414
+ const invalidate = () => {
415
+ const previous = abort;
416
+ generation += 1;
417
+ active = undefined;
418
+ abort = undefined;
419
+ previous?.abort(new SessionExpiredError);
420
+ };
421
+ return {
422
+ get generation() {
423
+ return generation;
424
+ },
425
+ replace(context) {
426
+ if (stopped)
427
+ throw new SessionExpiredError;
428
+ const previous = abort;
429
+ generation += 1;
430
+ const controller = new AbortController;
431
+ abort = controller;
432
+ const id = generation;
433
+ const current = () => !stopped && generation === id && !controller.signal.aborted;
434
+ const assertCurrent = () => {
435
+ if (!current())
436
+ throw new SessionExpiredError;
437
+ };
438
+ const operation = {
439
+ context,
440
+ id: crypto.randomUUID(),
441
+ generation: id,
442
+ signal: controller.signal,
443
+ current,
444
+ assertCurrent,
445
+ async run(work) {
446
+ assertCurrent();
447
+ try {
448
+ const result = await work();
449
+ assertCurrent();
450
+ return result;
451
+ } catch (error) {
452
+ if (!current())
453
+ throw new SessionExpiredError({ cause: error });
454
+ throw error;
455
+ }
456
+ },
457
+ deliver(delivery) {
458
+ if (!current())
459
+ return false;
460
+ delivery();
461
+ return true;
462
+ },
463
+ bindFetch(fetch, headers) {
464
+ return async (input, init) => {
465
+ assertCurrent();
466
+ const request = new Request(input, init);
467
+ const extra = headers?.();
468
+ assertCurrent();
469
+ if (extra)
470
+ new Headers(extra).forEach((value, key) => {
471
+ request.headers.set(key, value);
472
+ });
473
+ const signal = AbortSignal.any([controller.signal, request.signal]);
474
+ return operation.run(() => fetch(new Request(request, { signal })));
475
+ };
476
+ }
477
+ };
478
+ active = Object.freeze(operation);
479
+ previous?.abort(new SessionExpiredError);
480
+ return operation;
481
+ },
482
+ clear: invalidate,
483
+ stop() {
484
+ stopped = true;
485
+ invalidate();
486
+ },
487
+ capture() {
488
+ if (!active)
489
+ throw new SessionExpiredError;
490
+ return active;
491
+ },
492
+ owns(operation) {
493
+ return active === operation && operation.current();
494
+ }
495
+ };
496
+ }
497
+ // src/browser/session-credentials.ts
498
+ function createSessionCredentials(config) {
499
+ const capacity = config.maxPendingWrites ?? 128;
500
+ if (!Number.isSafeInteger(capacity) || capacity < 1 || capacity > 65536)
501
+ throw new RangeError("maxPendingWrites must be between 1 and 65536");
502
+ const serialize = createMutationQueue(capacity);
503
+ const timeout = config.refreshTimeoutMs ?? 30000;
504
+ if (!Number.isInteger(timeout) || timeout < 1 || timeout > 3600000) {
505
+ throw new RangeError("refreshTimeoutMs must be between 1 and 3600000");
506
+ }
507
+ const storageTimeout = config.storageTimeoutMs ?? 30000;
508
+ if (!Number.isInteger(storageTimeout) || storageTimeout < 1 || storageTimeout > 3600000) {
509
+ throw new RangeError("storageTimeoutMs must be between 1 and 3600000");
510
+ }
511
+ let state;
512
+ const bounded = async (work, wrote) => {
513
+ const outcome = await withDeadline(work, storageTimeout);
514
+ if (outcome.settled)
515
+ return;
516
+ work.then(() => {
517
+ if (state?.credentials !== wrote)
518
+ return restore();
519
+ }).catch(() => {
520
+ return;
521
+ });
522
+ throw new Error("Session storage did not answer within storageTimeoutMs");
523
+ };
524
+ const restore = () => serialize(async () => {
525
+ const current = state;
526
+ if (current)
527
+ await bounded(config.storage.write(current.operation.context, current.credentials), current.credentials);
528
+ else
529
+ await bounded(config.storage.clear(), undefined);
530
+ });
531
+ let flight;
532
+ const read = (operation) => {
533
+ if (!config.scope.owns(operation) || state?.operation !== operation)
534
+ throw new SessionExpiredError;
535
+ return state.credentials;
536
+ };
537
+ const write = (operation, credentials) => serialize(async () => {
538
+ read(operation);
539
+ await bounded(config.storage.write(operation.context, credentials), credentials);
540
+ operation.assertCurrent();
541
+ });
542
+ return {
543
+ async login(session, credentials) {
544
+ const operation = config.scope.replace(session);
545
+ operation.assertCurrent();
546
+ state = { operation, credentials };
547
+ await write(operation, credentials);
548
+ return operation;
549
+ },
550
+ logout() {
551
+ config.scope.clear();
552
+ state = undefined;
553
+ const generation = config.scope.generation;
554
+ return serialize(async () => {
555
+ if (config.scope.generation === generation)
556
+ await bounded(config.storage.clear(), undefined);
557
+ });
558
+ },
559
+ read,
560
+ refresh(operation) {
561
+ const credentials = read(operation);
562
+ if (flight?.operation === operation)
563
+ return flight.result;
564
+ const controller = new AbortController;
565
+ const signal = AbortSignal.any([operation.signal, controller.signal]);
566
+ const timer = setTimeout(() => controller.abort(new DOMException("Refresh timed out", "TimeoutError")), timeout);
567
+ let onAbort = () => {
568
+ return;
569
+ };
570
+ const abortPromise = new Promise((_, reject) => {
571
+ onAbort = () => reject(signal.reason);
572
+ signal.addEventListener("abort", onAbort, { once: true });
573
+ });
574
+ const result = operation.run(async () => {
575
+ const next = await Promise.race([config.refresh(credentials, signal), abortPromise]);
576
+ read(operation);
577
+ state = { operation, credentials: next };
578
+ await write(operation, next);
579
+ read(operation);
580
+ return next;
581
+ }).finally(() => {
582
+ clearTimeout(timer);
583
+ signal.removeEventListener("abort", onAbort);
584
+ if (flight?.result === result)
585
+ flight = undefined;
586
+ });
587
+ flight = { operation, result };
588
+ return result;
589
+ }
590
+ };
591
+ }
396
592
  // src/browser/socket-io-connection.ts
397
593
  function toIoAuth(auth) {
398
594
  if (typeof auth !== "function")
@@ -724,6 +920,8 @@ export {
724
920
  createUrlBuilder,
725
921
  createTraceContext,
726
922
  createSocketIOClient,
923
+ createSessionScope,
924
+ createSessionCredentials,
727
925
  createScopedUrlBuilders,
728
926
  createScopedClients,
729
927
  createRetainedTopics,
@@ -742,6 +940,7 @@ export {
742
940
  asRealtimeRejection,
743
941
  appError,
744
942
  TOOL_TRANSPORTS,
943
+ SessionExpiredError,
745
944
  STITCH_ERROR_STATUS,
746
945
  RealtimeRequestTimeoutError,
747
946
  RealtimeRequestRejectedError,
@@ -14,7 +14,7 @@ import {
14
14
  diff,
15
15
  watchContract,
16
16
  watchKeyString
17
- } from "../index-wt743f7f.js";
17
+ } from "../index-k6gpggb9.js";
18
18
  import"../index-1j8pm5t0.js";
19
19
  import"../index-d9pk3td4.js";
20
20
  import {
@@ -73,23 +73,23 @@ function toRealtimeContract(declaration) {
73
73
  }
74
74
  return { serverToClient, clientToServer: {} };
75
75
  }
76
- // src/live/watch-client.ts
77
- function watchTransport(client) {
78
- return client;
79
- }
76
+ // src/live/watch-client-state.ts
80
77
  function publishState(entry, state) {
81
78
  entry.state = state;
82
79
  for (const listener of [...entry.listeners])
83
80
  listener.state?.(state);
84
81
  }
85
82
  async function openWatch(config, openTimeoutMs, entry) {
86
- if (entry.opened)
83
+ if (entry.opened || entry.released || config.session && !config.session.current())
87
84
  return;
85
+ const epoch = ++entry.epoch;
88
86
  entry.opened = true;
89
87
  entry.answered = false;
90
88
  try {
91
89
  const have = entry.hasValue && entry.fingerprint !== undefined ? { revision: entry.revision, fingerprint: entry.fingerprint } : undefined;
92
90
  const acknowledgement = await config.transport.request(WATCH_OPEN, { key: entry.key, args: entry.args, ...have !== undefined && { have } }, { timeoutMs: openTimeoutMs });
91
+ if (epoch !== entry.epoch || entry.released || config.session && !config.session.current())
92
+ return;
93
93
  if (!acknowledgement.accepted) {
94
94
  const reason = acknowledgement.reason ?? "the server refused this watch";
95
95
  config.onRefused?.(entry.key, reason);
@@ -101,6 +101,8 @@ async function openWatch(config, openTimeoutMs, entry) {
101
101
  });
102
102
  }
103
103
  } catch (error) {
104
+ if (epoch !== entry.epoch || entry.released || config.session && !config.session.current())
105
+ return;
104
106
  entry.opened = false;
105
107
  const code = typeof error === "object" && error !== null && "code" in error ? String(Reflect.get(error, "code")) : undefined;
106
108
  publishState(entry, {
@@ -160,8 +162,19 @@ function applyWatchFrame(entry, frame) {
160
162
  entry.answered = true;
161
163
  return { kind: "value", value };
162
164
  }
165
+
166
+ // src/live/watch-client.ts
167
+ function watchTransport(client) {
168
+ return client;
169
+ }
163
170
  function createWatchClient(contract, config) {
164
171
  const entries = new Map;
172
+ const valid = () => !config.session || config.session.current();
173
+ const maxKeys = config.maxKeys ?? 1024;
174
+ const maxListeners = config.maxListenersPerKey ?? 128;
175
+ for (const bound of [maxKeys, maxListeners])
176
+ if (!Number.isInteger(bound) || bound < 1)
177
+ throw new RangeError("Watch capacity must be positive");
165
178
  const holdMs = config.holdMs ?? 0;
166
179
  const openTimeoutMs = config.openTimeoutMs ?? 1e4;
167
180
  const service = contract.meta.prefix;
@@ -175,7 +188,9 @@ function createWatchClient(contract, config) {
175
188
  config.transport.emit(WATCH_CLOSE, { key: entry.key });
176
189
  openWatch(config, openTimeoutMs, entry);
177
190
  }
178
- config.transport.on(WATCH_VALUE, (frame) => {
191
+ const offValue = config.transport.on(WATCH_VALUE, (frame) => {
192
+ if (!valid())
193
+ return;
179
194
  const entry = entries.get(watchKeyString(frame.key));
180
195
  if (!entry)
181
196
  return;
@@ -189,16 +204,21 @@ function createWatchClient(contract, config) {
189
204
  for (const listener of [...entry.listeners])
190
205
  listener.value(outcome.value);
191
206
  });
192
- config.transport.on(WATCH_STATE, (frame) => {
207
+ const offState = config.transport.on(WATCH_STATE, (frame) => {
208
+ if (!valid())
209
+ return;
193
210
  const entry = entries.get(watchKeyString(frame.key));
194
211
  if (!entry)
195
212
  return;
196
213
  publishState(entry, frame);
197
214
  });
198
- config.transport.onConnectionChange((connected, reason) => {
215
+ const offConnection = config.transport.onConnectionChange((connected, reason) => {
216
+ if (!valid())
217
+ return;
199
218
  if (!connected) {
200
219
  for (const entry of entries.values()) {
201
220
  entry.opened = false;
221
+ entry.epoch += 1;
202
222
  publishState(entry, {
203
223
  key: entry.key,
204
224
  phase: "unavailable",
@@ -215,6 +235,25 @@ function createWatchClient(contract, config) {
215
235
  openWatch(config, openTimeoutMs, entry);
216
236
  }
217
237
  });
238
+ const shutdown = () => {
239
+ offValue();
240
+ offState();
241
+ offConnection();
242
+ for (const entry of entries.values()) {
243
+ entry.released = true;
244
+ entry.epoch++;
245
+ clearTimeout(entry.release);
246
+ entry.listeners.clear();
247
+ entry.value = undefined;
248
+ entry.hasValue = false;
249
+ config.transport.emit(WATCH_CLOSE, { key: entry.key });
250
+ }
251
+ entries.clear();
252
+ };
253
+ if (config.session?.signal.aborted)
254
+ shutdown();
255
+ else
256
+ config.session?.signal.addEventListener("abort", shutdown, { once: true });
218
257
  function entryFor(key, args) {
219
258
  const id = watchKeyString(key);
220
259
  const existing = entries.get(id);
@@ -223,7 +262,11 @@ function createWatchClient(contract, config) {
223
262
  existing.release = undefined;
224
263
  return existing;
225
264
  }
265
+ if (entries.size >= maxKeys)
266
+ throw new Error("Watch key capacity exceeded");
226
267
  const entry = {
268
+ epoch: 0,
269
+ released: false,
227
270
  key,
228
271
  args,
229
272
  listeners: new Set,
@@ -236,12 +279,14 @@ function createWatchClient(contract, config) {
236
279
  entries.set(id, entry);
237
280
  return entry;
238
281
  }
239
- function releaseEntry(entry) {
282
+ function releaseWatchClientEntry(entry) {
240
283
  if (entry.listeners.size > 0)
241
284
  return;
242
285
  const drop = () => {
243
286
  if (entry.listeners.size > 0)
244
287
  return;
288
+ entry.released = true;
289
+ entry.epoch++;
245
290
  entries.delete(watchKeyString(entry.key));
246
291
  config.transport.emit(WATCH_CLOSE, { key: entry.key });
247
292
  };
@@ -254,27 +299,41 @@ function createWatchClient(contract, config) {
254
299
  }
255
300
  function handleFor(action, args) {
256
301
  const mine = new Set;
257
- const entry = entryFor({ service, action, digest: argumentsDigest(args) }, args);
302
+ const key = {
303
+ service,
304
+ action,
305
+ digest: argumentsDigest(args),
306
+ ...config.session && { instance: config.session.id }
307
+ };
308
+ let entry;
258
309
  return {
259
310
  subscribe(listeners) {
311
+ config.session?.assertCurrent();
312
+ if (!entry || entry.released)
313
+ entry = entryFor(key, args);
314
+ const current = entry;
315
+ if (current.listeners.size >= maxListeners)
316
+ throw new Error("Watch listener capacity exceeded");
260
317
  const registered = listeners;
261
318
  mine.add(registered);
262
- entry.listeners.add(registered);
263
- if (entry.hasValue)
264
- registered.value(entry.value);
265
- registered.state?.(entry.state);
266
- openWatch(config, openTimeoutMs, entry);
319
+ current.listeners.add(registered);
320
+ if (current.hasValue)
321
+ registered.value(current.value);
322
+ registered.state?.(current.state);
323
+ openWatch(config, openTimeoutMs, current);
267
324
  return () => {
268
325
  mine.delete(registered);
269
- entry.listeners.delete(registered);
270
- releaseEntry(entry);
326
+ current.listeners.delete(registered);
327
+ releaseWatchClientEntry(current);
271
328
  };
272
329
  },
273
330
  close() {
331
+ if (!entry)
332
+ return;
274
333
  for (const listener of mine)
275
334
  entry.listeners.delete(listener);
276
335
  mine.clear();
277
- releaseEntry(entry);
336
+ releaseWatchClientEntry(entry);
278
337
  }
279
338
  };
280
339
  }
@@ -8,7 +8,7 @@ import {
8
8
  createSocketIOServer,
9
9
  createUnixClientTransport,
10
10
  implementRegistry
11
- } from "../index-p3vsv1fb.js";
11
+ } from "../index-hadmp193.js";
12
12
  import"../index-y91ry9h2.js";
13
13
  import {
14
14
  ShutdownOptionsSchema,
@@ -1,4 +1,4 @@
1
- export { type CacheBridge, type CacheBridgeConfig, type CacheBridgeContext, type CacheBridgeHandler, type CacheBridgeHandlers, type CacheBridgeSocket, createCacheBridge, createRealtimeCacheBridge, type RealtimeCacheBridgeConfig, } from '../react/cache-bridge.js';
1
+ export { type CacheBridge, type CacheBridgeConfig, type CacheBridgeContext, type CacheBridgeHandler, type CacheBridgeHandlers, type CacheBridgeSocket, createCacheBridge, createRealtimeCacheBridge, type RealtimeCacheBridgeConfig, type WatchCacheBinding, } from '../react/cache-bridge.js';
2
2
  export { type CursorQueryConfig, createCursorQuery } from '../react/cursor-query.js';
3
3
  export { createEntityCacheHandlers, type DeletedPayload, type EntityCacheConfig, type EntityCacheEvent, type EntityCacheHandlers, type EntityCacheKey, type EntityCacheListConfig, type EntityCacheListShape, type EntityCacheMembership, type EntityCacheMembershipPolicy, type EntityCacheTotalDeltaInput, type EntityCacheTotalPolicy, } from '../react/entity-cache.js';
4
4
  export { type ApiErrorRetryConfig, apiErrorRetry, createQueryClientFactory, type QueryClientFactoryConfig, type QueryClientServerCache, type QueryRetryValue, } from '../react/query-client.js';
@@ -1 +1 @@
1
- {"version":3,"file":"react.d.ts","sourceRoot":"","sources":["../../src/entrypoints/react.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,WAAW,EAChB,KAAK,iBAAiB,EACtB,KAAK,kBAAkB,EACvB,KAAK,kBAAkB,EACvB,KAAK,mBAAmB,EACxB,KAAK,iBAAiB,EACtB,iBAAiB,EACjB,yBAAyB,EACzB,KAAK,yBAAyB,GAC/B,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,KAAK,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAClF,OAAO,EACL,yBAAyB,EACzB,KAAK,cAAc,EACnB,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EACrB,KAAK,mBAAmB,EACxB,KAAK,cAAc,EACnB,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,EACzB,KAAK,qBAAqB,EAC1B,KAAK,2BAA2B,EAChC,KAAK,0BAA0B,EAC/B,KAAK,sBAAsB,GAC5B,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,KAAK,mBAAmB,EACxB,aAAa,EACb,wBAAwB,EACxB,KAAK,wBAAwB,EAC7B,KAAK,sBAAsB,EAC3B,KAAK,eAAe,GACrB,MAAM,uBAAuB,CAAC"}
1
+ {"version":3,"file":"react.d.ts","sourceRoot":"","sources":["../../src/entrypoints/react.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,WAAW,EAChB,KAAK,iBAAiB,EACtB,KAAK,kBAAkB,EACvB,KAAK,kBAAkB,EACvB,KAAK,mBAAmB,EACxB,KAAK,iBAAiB,EACtB,iBAAiB,EACjB,yBAAyB,EACzB,KAAK,yBAAyB,EAC9B,KAAK,iBAAiB,GACvB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,KAAK,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAClF,OAAO,EACL,yBAAyB,EACzB,KAAK,cAAc,EACnB,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EACrB,KAAK,mBAAmB,EACxB,KAAK,cAAc,EACnB,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,EACzB,KAAK,qBAAqB,EAC1B,KAAK,2BAA2B,EAChC,KAAK,0BAA0B,EAC/B,KAAK,sBAAsB,GAC5B,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,KAAK,mBAAmB,EACxB,aAAa,EACb,wBAAwB,EACxB,KAAK,wBAAwB,EAC7B,KAAK,sBAAsB,EAC3B,KAAK,eAAe,GACrB,MAAM,uBAAuB,CAAC"}
@@ -36,28 +36,71 @@ function createCacheBridge(config) {
36
36
  expiryTimers.clear();
37
37
  freshAt.clear();
38
38
  };
39
+ let connected = false;
40
+ let clearWatched;
41
+ const disconnect = () => {
42
+ for (const off of unsubscribers)
43
+ off();
44
+ unsubscribers = [];
45
+ connected = false;
46
+ clearFresh();
47
+ config.session?.signal.removeEventListener("abort", invalidateSession);
48
+ };
49
+ const invalidateSession = () => {
50
+ disconnect();
51
+ clearWatched?.();
52
+ };
39
53
  return {
40
54
  connect() {
41
- if (unsubscribers.length > 0)
55
+ config.session?.assertCurrent();
56
+ if (connected)
42
57
  return;
43
58
  const queryClient = typeof config.queryClient === "function" ? config.queryClient() : config.queryClient;
44
- const ctx = { queryClient, isFresh };
45
- const handlers = config.handlers;
46
- const socket = config.socket;
47
- for (const event of Object.keys(handlers)) {
48
- const handler = handlers[event];
49
- if (!handler)
50
- continue;
51
- const off = socket.on(event, (data) => handler(data, ctx));
52
- unsubscribers.push(off);
59
+ connected = true;
60
+ try {
61
+ clearWatched = () => {
62
+ for (const binding of config.watched ?? [])
63
+ queryClient.removeQueries({ queryKey: binding.queryKey, exact: true });
64
+ };
65
+ config.session?.signal.addEventListener("abort", invalidateSession, { once: true });
66
+ for (const binding of config.watched ?? []) {
67
+ unsubscribers.push(binding.handle.subscribe({
68
+ value(value) {
69
+ if (!config.session || config.session.current())
70
+ queryClient.setQueryData(binding.queryKey, value);
71
+ },
72
+ state(state) {
73
+ if (config.session && !config.session.current())
74
+ return;
75
+ if (state.phase !== "live")
76
+ queryClient.invalidateQueries({
77
+ queryKey: binding.queryKey,
78
+ exact: true,
79
+ refetchType: "none"
80
+ });
81
+ binding.state?.(state);
82
+ }
83
+ }));
84
+ }
85
+ const ctx = { queryClient, isFresh };
86
+ const handlers = config.handlers;
87
+ const socket = config.socket;
88
+ for (const event of Object.keys(handlers)) {
89
+ const handler = handlers[event];
90
+ if (!handler)
91
+ continue;
92
+ const off = socket.on(event, (data) => {
93
+ if (!config.session || config.session.current())
94
+ handler(data, ctx);
95
+ });
96
+ unsubscribers.push(off);
97
+ }
98
+ } catch (error) {
99
+ disconnect();
100
+ throw error;
53
101
  }
54
102
  },
55
- disconnect() {
56
- for (const off of unsubscribers)
57
- off();
58
- unsubscribers = [];
59
- clearFresh();
60
- },
103
+ disconnect,
61
104
  markFresh(key) {
62
105
  const serialised = JSON.stringify(key);
63
106
  const existingTimer = expiryTimers.get(serialised);
@@ -19,14 +19,11 @@ import {
19
19
  sseRoute,
20
20
  streamingRoute,
21
21
  webSocketLane
22
- } from "../index-p3vsv1fb.js";
22
+ } from "../index-hadmp193.js";
23
23
  import"../index-y91ry9h2.js";
24
24
  import {
25
25
  createFileStateStore
26
26
  } from "../index-tm88avnj.js";
27
- import {
28
- withDeadline
29
- } from "../index-b9aefrqd.js";
30
27
  import {
31
28
  ShutdownOptionsSchema,
32
29
  ShutdownResultSchema,
@@ -36,6 +33,9 @@ import {
36
33
  } from "../index-3z73fh2c.js";
37
34
  import"../index-ndddxtyx.js";
38
35
  import"../index-dce5wxcq.js";
36
+ import {
37
+ withDeadline
38
+ } from "../index-b9aefrqd.js";
39
39
  import {
40
40
  inputIsQuery
41
41
  } from "../index-48ffdxgk.js";
@@ -7,12 +7,12 @@ import {
7
7
  createAgentRuntimeStore,
8
8
  isActiveRunState,
9
9
  replaceMessage
10
- } from "./index-wsm5w4ee.js";
10
+ } from "./index-vqr7f7v8.js";
11
11
  import {
12
12
  AgentRecoverablePageSchema,
13
13
  AgentStoreEventEnvelopeSchema,
14
14
  AgentStoreEventPageSchema
15
- } from "./index-gxrt5h6v.js";
15
+ } from "./index-cyktc4bp.js";
16
16
  import {
17
17
  AgentMessageSchema,
18
18
  AgentRecordIdSchema
@@ -202,6 +202,9 @@ var memoryEvents = {
202
202
  items,
203
203
  ...selected.length > items.length && last ? { nextSeq: last.seq + 1 } : {}
204
204
  });
205
+ },
206
+ async find(transaction, input) {
207
+ return (transaction.events.get(input.conversationId) ?? []).find((event) => event.eventId === input.eventId);
205
208
  }
206
209
  };
207
210
  function scanMemoryRecoverable(runs, input) {