@andreroggeri/adapter-pi-local-serialized 0.1.1 → 0.1.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.
@@ -1 +1 @@
1
- {"version":3,"file":"concurrency.d.ts","sourceRoot":"","sources":["../../src/server/concurrency.ts"],"names":[],"mappings":"AAMA,wBAAsB,uBAAuB,CAAC,CAAC,EAC7C,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,CAAC,MAAM,EAAE,QAAQ,GAAG,QAAQ,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,EACpE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GACnB,OAAO,CAAC,CAAC,CAAC,CAsBZ"}
1
+ {"version":3,"file":"concurrency.d.ts","sourceRoot":"","sources":["../../src/server/concurrency.ts"],"names":[],"mappings":"AAgBA,wBAAsB,uBAAuB,CAAC,CAAC,EAC7C,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,CAAC,MAAM,EAAE,QAAQ,GAAG,QAAQ,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,EACpE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GACnB,OAAO,CAAC,CAAC,CAAC,CAqCZ"}
@@ -1,6 +1,15 @@
1
1
  // Global mutex ensuring at most one pi_local_serialized execution runs at a time.
2
2
  // Implemented as a promise chain — each caller appends to the tail and waits
3
3
  // for the previous occupant to release before proceeding.
4
+ const HEARTBEAT_INTERVAL_MS = 30_000;
5
+ function formatWaitDuration(ms) {
6
+ const totalSeconds = Math.floor(ms / 1000);
7
+ const minutes = Math.floor(totalSeconds / 60);
8
+ const seconds = totalSeconds % 60;
9
+ if (minutes === 0)
10
+ return `${seconds}s`;
11
+ return `${minutes}m ${seconds}s`;
12
+ }
4
13
  let tail = Promise.resolve();
5
14
  export async function withSerializedExecution(label, onLog, fn) {
6
15
  let release;
@@ -10,11 +19,26 @@ export async function withSerializedExecution(label, onLog, fn) {
10
19
  // Snapshot the current tail and atomically replace it with our waiter.
11
20
  const wait = tail;
12
21
  tail = tail.then(() => next);
13
- if (wait !== Promise.resolve()) {
14
- // There's something ahead of us — let the agent know it's queued.
22
+ const isQueued = wait !== Promise.resolve();
23
+ if (isQueued) {
15
24
  await onLog("stdout", `[paperclip] pi_local_serialized: another run is in progress, queuing "${label}"...\n`);
25
+ const waitStart = Date.now();
26
+ const heartbeat = setInterval(() => {
27
+ const elapsed = formatWaitDuration(Date.now() - waitStart);
28
+ onLog("stdout", `[paperclip] pi_local_serialized: "${label}" still waiting for the lock (${elapsed})...\n`).catch(() => undefined);
29
+ }, HEARTBEAT_INTERVAL_MS);
30
+ try {
31
+ await wait;
32
+ }
33
+ finally {
34
+ clearInterval(heartbeat);
35
+ }
36
+ const totalWait = formatWaitDuration(Date.now() - waitStart);
37
+ await onLog("stdout", `[paperclip] pi_local_serialized: "${label}" acquired the lock after ${totalWait}, starting now.\n`);
38
+ }
39
+ else {
40
+ await wait;
16
41
  }
17
- await wait;
18
42
  try {
19
43
  return await fn();
20
44
  }
@@ -1 +1 @@
1
- {"version":3,"file":"concurrency.js","sourceRoot":"","sources":["../../src/server/concurrency.ts"],"names":[],"mappings":"AAAA,kFAAkF;AAClF,6EAA6E;AAC7E,0DAA0D;AAE1D,IAAI,IAAI,GAAkB,OAAO,CAAC,OAAO,EAAE,CAAC;AAE5C,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC3C,KAAa,EACb,KAAoE,EACpE,EAAoB;IAEpB,IAAI,OAAoB,CAAC;IACzB,MAAM,IAAI,GAAG,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;QACzC,OAAO,GAAG,OAAO,CAAC;IACpB,CAAC,CAAC,CAAC;IAEH,uEAAuE;IACvE,MAAM,IAAI,GAAG,IAAI,CAAC;IAClB,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;IAE7B,IAAI,IAAI,KAAK,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC;QAC/B,kEAAkE;QAClE,MAAM,KAAK,CAAC,QAAQ,EAAE,yEAAyE,KAAK,QAAQ,CAAC,CAAC;IAChH,CAAC;IAED,MAAM,IAAI,CAAC;IAEX,IAAI,CAAC;QACH,OAAO,MAAM,EAAE,EAAE,CAAC;IACpB,CAAC;YAAS,CAAC;QACT,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"concurrency.js","sourceRoot":"","sources":["../../src/server/concurrency.ts"],"names":[],"mappings":"AAAA,kFAAkF;AAClF,6EAA6E;AAC7E,0DAA0D;AAE1D,MAAM,qBAAqB,GAAG,MAAM,CAAC;AAErC,SAAS,kBAAkB,CAAC,EAAU;IACpC,MAAM,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC;IAC3C,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,GAAG,EAAE,CAAC,CAAC;IAC9C,MAAM,OAAO,GAAG,YAAY,GAAG,EAAE,CAAC;IAClC,IAAI,OAAO,KAAK,CAAC;QAAE,OAAO,GAAG,OAAO,GAAG,CAAC;IACxC,OAAO,GAAG,OAAO,KAAK,OAAO,GAAG,CAAC;AACnC,CAAC;AAED,IAAI,IAAI,GAAkB,OAAO,CAAC,OAAO,EAAE,CAAC;AAE5C,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC3C,KAAa,EACb,KAAoE,EACpE,EAAoB;IAEpB,IAAI,OAAoB,CAAC;IACzB,MAAM,IAAI,GAAG,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;QACzC,OAAO,GAAG,OAAO,CAAC;IACpB,CAAC,CAAC,CAAC;IAEH,uEAAuE;IACvE,MAAM,IAAI,GAAG,IAAI,CAAC;IAClB,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;IAE7B,MAAM,QAAQ,GAAG,IAAI,KAAK,OAAO,CAAC,OAAO,EAAE,CAAC;IAC5C,IAAI,QAAQ,EAAE,CAAC;QACb,MAAM,KAAK,CAAC,QAAQ,EAAE,yEAAyE,KAAK,QAAQ,CAAC,CAAC;QAE9G,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC7B,MAAM,SAAS,GAAG,WAAW,CAAC,GAAG,EAAE;YACjC,MAAM,OAAO,GAAG,kBAAkB,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC,CAAC;YAC3D,KAAK,CAAC,QAAQ,EAAE,qCAAqC,KAAK,iCAAiC,OAAO,QAAQ,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;QACrI,CAAC,EAAE,qBAAqB,CAAC,CAAC;QAE1B,IAAI,CAAC;YACH,MAAM,IAAI,CAAC;QACb,CAAC;gBAAS,CAAC;YACT,aAAa,CAAC,SAAS,CAAC,CAAC;QAC3B,CAAC;QAED,MAAM,SAAS,GAAG,kBAAkB,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC,CAAC;QAC7D,MAAM,KAAK,CAAC,QAAQ,EAAE,qCAAqC,KAAK,6BAA6B,SAAS,mBAAmB,CAAC,CAAC;IAC7H,CAAC;SAAM,CAAC;QACN,MAAM,IAAI,CAAC;IACb,CAAC;IAED,IAAI,CAAC;QACH,OAAO,MAAM,EAAE,EAAE,CAAC;IACpB,CAAC;YAAS,CAAC;QACT,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@andreroggeri/adapter-pi-local-serialized",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
4
  "license": "MIT",
5
5
  "homepage": "https://github.com/paperclipai/paperclip",
6
6
  "bugs": {
@@ -37,8 +37,10 @@
37
37
  "dist"
38
38
  ],
39
39
  "dependencies": {
40
- "picocolors": "^1.1.1",
41
- "@paperclipai/adapter-utils": "0.3.1"
40
+ "picocolors": "^1.1.1"
41
+ },
42
+ "peerDependencies": {
43
+ "@paperclipai/adapter-utils": "*"
42
44
  },
43
45
  "devDependencies": {
44
46
  "@types/node": "^24.6.0",