@goodandready/dsh-cron 0.3.17 → 0.3.19

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.
package/lib/secrets.js CHANGED
@@ -147,6 +147,7 @@ export function parseCredentialUri(value) {
147
147
  */
148
148
  export async function resolveCredentialReference(uri, ctx) {
149
149
  if (typeof uri !== 'string') return uri;
150
+ if (!isCredentialUri(uri)) return uri;
150
151
  const parsed = parseCredentialUri(uri);
151
152
  if (!parsed) return uri;
152
153
 
package/lib/store.js CHANGED
@@ -213,12 +213,45 @@ export class TaskStore {
213
213
  * Asynchronously serialize and write tasks store to disk using fs.promises queue (#244, #301, #303).
214
214
  * Safe mode 0600 on files and 0700 on dir (#222).
215
215
  */
216
+ /**
217
+ * Wait until diskVersion or lastSyncVersion is at least the target version (#372).
218
+ */
219
+ _waitForDiskVersion(version) {
220
+ if ((this._diskVersion || 0) >= version || (this._lastSyncVersion || 0) >= version) {
221
+ return Promise.resolve();
222
+ }
223
+ return new Promise((resolve, reject) => {
224
+ if (!this._diskWaiters) this._diskWaiters = [];
225
+ this._diskWaiters.push({ version, resolve, reject });
226
+ });
227
+ }
228
+
229
+ _notifyDiskVersion(writtenVersion, err = null) {
230
+ if (!this._diskWaiters || this._diskWaiters.length === 0) return;
231
+ const remaining = [];
232
+ for (const waiter of this._diskWaiters) {
233
+ if (err) {
234
+ waiter.reject(err);
235
+ } else if ((this._diskVersion || 0) >= waiter.version || (this._lastSyncVersion || 0) >= waiter.version) {
236
+ waiter.resolve();
237
+ } else {
238
+ remaining.push(waiter);
239
+ }
240
+ }
241
+ this._diskWaiters = remaining;
242
+ }
243
+
216
244
  async saveAsync() {
245
+ if (this._saveTimer) {
246
+ clearTimeout(this._saveTimer);
247
+ this._saveTimer = null;
248
+ }
217
249
  const version = ++this._saveVersion;
218
250
  const data = this._createSnapshot();
219
251
 
220
252
  const writeOp = async () => {
221
253
  if ((this._diskVersion || 0) >= version || (this._lastSyncVersion || 0) >= version) {
254
+ this._notifyDiskVersion(version);
222
255
  return;
223
256
  }
224
257
  const dir = path.dirname(this.filePath);
@@ -238,12 +271,14 @@ export class TaskStore {
238
271
  } catch (writeErr) {
239
272
  await fs.promises.unlink(tmp).catch(() => {});
240
273
  if (this._currentAsyncTmp === tmp) this._currentAsyncTmp = null;
274
+ this._notifyDiskVersion(null, writeErr);
241
275
  throw writeErr;
242
276
  }
243
277
 
244
278
  if ((this._diskVersion || 0) >= version || (this._lastSyncVersion || 0) >= version || this._saveVersion > version) {
245
279
  await fs.promises.unlink(tmp).catch(() => {});
246
280
  if (this._currentAsyncTmp === tmp) this._currentAsyncTmp = null;
281
+ // Do not notify waiters yet: a newer queued saveOp will write to disk and notify (#372)
247
282
  return;
248
283
  }
249
284
 
@@ -251,14 +286,17 @@ export class TaskStore {
251
286
  await fs.promises.rename(tmp, this.filePath);
252
287
  bestEffort('chmod-store', () => fs.chmodSync(this.filePath, 0o600));
253
288
  this._currentAsyncTmp = null;
254
- this._diskVersion = version;
255
- this._lastWrittenVersion = version;
289
+ this._diskVersion = Math.max(this._diskVersion || 0, version);
290
+ this._lastWrittenVersion = this._diskVersion;
291
+ this._notifyDiskVersion(this._diskVersion);
256
292
  } catch (err) {
257
293
  this._currentAsyncTmp = null;
258
294
  // If tmp was unlinked by newer sync save, rename will fail with ENOENT - safely ignore only in that case (#244)
259
295
  if (err.code === 'ENOENT' && (this._lastSyncVersion || 0) >= version) {
296
+ this._notifyDiskVersion(version);
260
297
  return;
261
298
  }
299
+ this._notifyDiskVersion(null, err);
262
300
  throw err;
263
301
  }
264
302
 
@@ -276,7 +314,8 @@ export class TaskStore {
276
314
  };
277
315
 
278
316
  this._savePromise = this._savePromise.then(writeOp, writeOp);
279
- return this._savePromise;
317
+ await this._savePromise;
318
+ await this._waitForDiskVersion(version);
280
319
  }
281
320
 
282
321
  /**
@@ -410,6 +449,7 @@ export class TaskStore {
410
449
  bestEffort('chmod-store', () => fs.chmodSync(this.filePath, 0o600));
411
450
  this._diskVersion = Math.max(this._diskVersion || 0, version);
412
451
  this._lastWrittenVersion = this._diskVersion;
452
+ this._notifyDiskVersion(this._diskVersion);
413
453
 
414
454
  // Throttled backup (.bak): avoid expensive copyFileSync on every micro-save
415
455
  const now = Date.now();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@goodandready/dsh-cron",
3
- "version": "0.3.17",
3
+ "version": "0.3.19",
4
4
  "description": "Background automation runner for DSH: isolated agent runs, script/HTTP/SSH/Docker runtimes, cost guard, notifications, heartbeats.",
5
5
  "type": "module",
6
6
  "main": "lib/index.js",
@@ -12,12 +12,14 @@
12
12
  },
13
13
  "files": [
14
14
  "lib/*.js",
15
+ "lib/client.css",
15
16
  "cordis.patch.yml",
16
17
  "README.md",
17
- "LICENSE"
18
+ "LICENSE",
19
+ "lib/locales.json"
18
20
  ],
19
21
  "scripts": {
20
- "test": "node --test test/*.test.mjs",
22
+ "test": "node --test test/*.test.mjs && node scripts/check-pack-size.mjs",
21
23
  "build:client": "node scripts/build-client.mjs",
22
24
  "pretest": "node scripts/build-client.mjs",
23
25
  "preflight": "node scripts/ci-preflight.mjs"
@@ -89,5 +91,14 @@
89
91
  "publishConfig": {
90
92
  "registry": "https://registry.npmjs.org",
91
93
  "access": "public"
94
+ },
95
+ "devDependencies": {
96
+ "@deepseek-ai/cordis": "^4.0.1",
97
+ "@deepseek-ai/dsh-agent": ">=0.1.0-rc.6 <0.1.1 || >=0.1.1-rc.1 <0.1.2 || >=0.1.2-alpha.1 <1.0.0",
98
+ "@deepseek-ai/dsh-llm": ">=0.1.0-rc.6 <0.1.1 || >=0.1.1-rc.1 <0.1.2 || >=0.1.2-alpha.1 <1.0.0",
99
+ "@deepseek-ai/dsh-session": ">=0.1.0-rc.6 <0.1.1 || >=0.1.1-rc.1 <0.1.2 || >=0.1.2-alpha.1 <1.0.0",
100
+ "@deepseek-ai/dsh-settings": ">=0.1.0-rc.6 <0.1.1 || >=0.1.1-rc.1 <0.1.2 || >=0.1.2-alpha.1 <1.0.0",
101
+ "@deepseek-ai/dsh-tools": ">=0.1.0-rc.6 <0.1.1 || >=0.1.1-rc.1 <0.1.2 || >=0.1.2-alpha.1 <1.0.0",
102
+ "@deepseek-ai/schemastery": "^3.18.1"
92
103
  }
93
104
  }