@attlaz/client 1.105.0 → 1.106.0

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.
@@ -0,0 +1,20 @@
1
+ import { ApiRecord } from '../../Model/ApiRecord.js';
2
+ /**
3
+ * One page of a crawl — `pulse.crawl_job_page`.
4
+ *
5
+ * A worker takes pages by claiming them, which is what `status` and `claimedAt` record: a claimed
6
+ * page is nobody else's to fetch until its owner finishes or its lease expires.
7
+ */
8
+ export type CrawlJobPageStatus = 'pending' | 'running' | 'complete' | 'failed';
9
+ export declare class CrawlJobPage {
10
+ id: string;
11
+ crawlJobId: string;
12
+ url: string;
13
+ status: CrawlJobPageStatus;
14
+ /** When a worker took this page; its lease runs from here. */
15
+ claimedAt: Date | null;
16
+ /** How many times it has been claimed — a page released by an expired lease is retried. */
17
+ attempts: number;
18
+ constructor(id: string, crawlJobId: string, url: string);
19
+ static parse(raw: ApiRecord): CrawlJobPage;
20
+ }
@@ -0,0 +1,22 @@
1
+ export class CrawlJobPage {
2
+ id;
3
+ crawlJobId;
4
+ url;
5
+ status = 'pending';
6
+ /** When a worker took this page; its lease runs from here. */
7
+ claimedAt = null;
8
+ /** How many times it has been claimed — a page released by an expired lease is retried. */
9
+ attempts = 0;
10
+ constructor(id, crawlJobId, url) {
11
+ this.id = id;
12
+ this.crawlJobId = crawlJobId;
13
+ this.url = url;
14
+ }
15
+ static parse(raw) {
16
+ const page = new CrawlJobPage(raw.id, raw.crawl_job_id ?? raw.crawl_job ?? '', raw.url ?? '');
17
+ page.status = (raw.status ?? 'pending');
18
+ page.claimedAt = raw.claimed_at === undefined || raw.claimed_at === null ? null : new Date(raw.claimed_at);
19
+ page.attempts = Number(raw.attempts ?? 0);
20
+ return page;
21
+ }
22
+ }
@@ -1,6 +1,7 @@
1
1
  import { CatalogId } from '../../Catalog/Model/CatalogId.js';
2
2
  import { CursorPagination } from '../../Model/Pagination/CursorPagination.js';
3
3
  import { CrawlJob, CrawlJobStatus } from '../Model/CrawlJob.js';
4
+ import { CrawlJobPage } from '../Model/CrawlJobPage.js';
4
5
  import { CollectionResult } from '../../Model/Result/CollectionResult.js';
5
6
  import { Endpoint } from '../../Service/Endpoint.js';
6
7
  /**
@@ -32,6 +33,16 @@ export declare class CrawlJobEndpoint extends Endpoint {
32
33
  markPagesParsed(crawlJobId: string, urls: string[]): Promise<void>;
33
34
  /** Mark pages as failed (terminal, e.g. blocked/unfetchable). */
34
35
  markPagesFailed(crawlJobId: string, urls: string[]): Promise<void>;
36
+ /**
37
+ * Atomically take up to `limit` of this crawl's pending pages to work on.
38
+ *
39
+ * Concurrent workers get disjoint sets, so a page is never fetched twice. An empty array means
40
+ * there is nothing left to do — that is how a worker knows to stop, not an error.
41
+ *
42
+ * Claiming starts a lease: finish the pages (mark them parsed or failed) or they are handed back
43
+ * to another worker once the lease expires.
44
+ */
45
+ claimPages(crawlJobId: string, limit: number): Promise<CrawlJobPage[]>;
35
46
  /** @param suffix a literal trailing segment, e.g. `/pages/crawled` — not caller data. */
36
47
  private postUrls;
37
48
  }
@@ -1,6 +1,7 @@
1
1
  import { path } from '../../Http/Data/Path.js';
2
2
  import { QueryString } from '../../Http/Data/QueryString.js';
3
3
  import { CrawlJob } from '../Model/CrawlJob.js';
4
+ import { CrawlJobPage } from '../Model/CrawlJobPage.js';
4
5
  import { Endpoint } from '../../Service/Endpoint.js';
5
6
  /**
6
7
  * Market Pulse crawl jobs — `/pulse/crawl-jobs`. Mirrors the PHP client's MarketPulse\CrawlJobEndpoint.
@@ -64,6 +65,19 @@ export class CrawlJobEndpoint extends Endpoint {
64
65
  async markPagesFailed(crawlJobId, urls) {
65
66
  await this.postUrls(crawlJobId, '/pages/failed', urls);
66
67
  }
68
+ /**
69
+ * Atomically take up to `limit` of this crawl's pending pages to work on.
70
+ *
71
+ * Concurrent workers get disjoint sets, so a page is never fetched twice. An empty array means
72
+ * there is nothing left to do — that is how a worker knows to stop, not an error.
73
+ *
74
+ * Claiming starts a lease: finish the pages (mark them parsed or failed) or they are handed back
75
+ * to another worker once the lease expires.
76
+ */
77
+ async claimPages(crawlJobId, limit) {
78
+ const result = await this.requestCollection(path('/pulse/crawl-jobs/:crawlJobId', { crawlJobId }) + '/pages/claim', CrawlJobPage.parse, { limit }, 'POST');
79
+ return result.getData();
80
+ }
67
81
  /** @param suffix a literal trailing segment, e.g. `/pages/crawled` — not caller data. */
68
82
  async postUrls(crawlJobId, suffix, urls) {
69
83
  if (urls.length === 0) {
package/dist/index.d.ts CHANGED
@@ -85,6 +85,7 @@ export { VendorProduct } from './MarketPulse/Model/VendorProduct.js';
85
85
  export { StockStatus, parseStockStatus, stockStatusFromBoolean } from './MarketPulse/Model/StockStatus.js';
86
86
  export { VendorProductEndpoint } from './MarketPulse/Service/VendorProductEndpoint.js';
87
87
  export { CrawlJob, CrawlJobStatus } from './MarketPulse/Model/CrawlJob.js';
88
+ export { CrawlJobPage, CrawlJobPageStatus } from './MarketPulse/Model/CrawlJobPage.js';
88
89
  export { CrawlJobEndpoint } from './MarketPulse/Service/CrawlJobEndpoint.js';
89
90
  export { VendorProductPriceHistoryEntry } from './MarketPulse/Model/VendorProductPriceHistoryEntry.js';
90
91
  export { Catalog } from './Catalog/Model/Catalog.js';
package/dist/index.js CHANGED
@@ -71,6 +71,7 @@ export { VendorProduct } from './MarketPulse/Model/VendorProduct.js';
71
71
  export { parseStockStatus, stockStatusFromBoolean } from './MarketPulse/Model/StockStatus.js';
72
72
  export { VendorProductEndpoint } from './MarketPulse/Service/VendorProductEndpoint.js';
73
73
  export { CrawlJob } from './MarketPulse/Model/CrawlJob.js';
74
+ export { CrawlJobPage } from './MarketPulse/Model/CrawlJobPage.js';
74
75
  export { CrawlJobEndpoint } from './MarketPulse/Service/CrawlJobEndpoint.js';
75
76
  export { VendorProductPriceHistoryEntry } from './MarketPulse/Model/VendorProductPriceHistoryEntry.js';
76
77
  export { Catalog } from './Catalog/Model/Catalog.js';
package/dist/version.d.ts CHANGED
@@ -1 +1 @@
1
- export declare const VERSION = "1.104.0";
1
+ export declare const VERSION = "1.105.0";
package/dist/version.js CHANGED
@@ -1 +1 @@
1
- export const VERSION = "1.104.0";
1
+ export const VERSION = "1.105.0";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@attlaz/client",
3
- "version": "1.105.0",
3
+ "version": "1.106.0",
4
4
  "description": "Javascript Client to access Attlaz API",
5
5
  "types": "./dist/index.d.ts",
6
6
  "main": "./dist/index.js",