@opencraw/driver 0.4.0 → 0.5.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.
- package/dist/index.esm.js +15 -14
- package/dist/main.esm.js +15 -14
- package/dist/src/index.d.ts +1 -1
- package/dist/src/session/index.d.ts +1 -1
- package/dist/src/session/run-session.use-case.d.ts +12 -1
- package/package.json +1 -1
package/dist/index.esm.js
CHANGED
|
@@ -240,8 +240,8 @@ function clientAccessPlugins(names, runId, ask) {
|
|
|
240
240
|
// src/site-access/resolve-site-access.use-case.ts
|
|
241
241
|
import { resolveAccess } from "@opencraw/cli";
|
|
242
242
|
async function resolveSiteAccess(params, runId, ask, env = process.env) {
|
|
243
|
-
const file = params.accessConfig ?? env.OPENCRAW_ACCESS;
|
|
244
|
-
if (file === void 0 && params.access !== void 0) throw new Error(`access profile "${params.access}" needs an access config:
|
|
243
|
+
const file = params.accessConfig ?? (env.OPENCRAW_ACCESS === "" ? void 0 : env.OPENCRAW_ACCESS);
|
|
244
|
+
if (file === void 0 && params.access !== void 0) throw new Error(`access profile "${params.access}" needs an access config, and there is none: no "accessConfig" was given, and OPENCRAW_ACCESS is not set where OpenCraw runs`);
|
|
245
245
|
const access = await resolveAccess({ insecureTls: false, access: file, accessProfile: params.access });
|
|
246
246
|
return { access, accessPlugins: clientAccessPlugins(params.accessPlugins ?? [], runId, ask) };
|
|
247
247
|
}
|
|
@@ -344,17 +344,17 @@ function streamingSink() {
|
|
|
344
344
|
}
|
|
345
345
|
|
|
346
346
|
// src/session/run-session.use-case.ts
|
|
347
|
-
function runSessions(notify, ask) {
|
|
347
|
+
function runSessions(notify, ask, local = {}) {
|
|
348
348
|
const running = /* @__PURE__ */ new Map();
|
|
349
349
|
let next = 1;
|
|
350
350
|
const crawlerFor = async (runId, params) => {
|
|
351
351
|
const { access, accessPlugins } = await resolveSiteAccess(params, runId, ask);
|
|
352
352
|
return createCrawler({
|
|
353
353
|
sink: params.out === void 0 ? streamingSink() : fileSink2(params.out, { append: params.append, browser: { executablePath: params.browser?.executablePath } }),
|
|
354
|
-
hooks: clientHooks(params.hooks ?? [], runId, ask),
|
|
355
|
-
captchaSolvers: clientCaptchaSolvers(params.captchaSolvers ?? [], runId, ask),
|
|
354
|
+
hooks: { ...local.hooks, ...clientHooks(params.hooks ?? [], runId, ask) },
|
|
355
|
+
captchaSolvers: [...local.captchaSolvers ?? [], ...clientCaptchaSolvers(params.captchaSolvers ?? [], runId, ask)],
|
|
356
356
|
access,
|
|
357
|
-
accessPlugins,
|
|
357
|
+
accessPlugins: [...local.accessPlugins ?? [], ...accessPlugins],
|
|
358
358
|
profilesDir: process.env.OPENCRAW_PROFILES,
|
|
359
359
|
parallel: params.parallel,
|
|
360
360
|
resume: params.resume,
|
|
@@ -380,15 +380,16 @@ function runSessions(notify, ask) {
|
|
|
380
380
|
}
|
|
381
381
|
})();
|
|
382
382
|
};
|
|
383
|
+
const startLoaded = async (loaded, params) => {
|
|
384
|
+
const set = params.dryRun === true ? new RecipeSet(loaded.output, loaded.inputs.map((input) => ({ ...input, limits: { ...input.limits, maxRecords: 1 } }))) : loaded;
|
|
385
|
+
const runId = `run-${next++}`;
|
|
386
|
+
const crawler = await crawlerFor(runId, params);
|
|
387
|
+
track(runId, crawler, async () => await crawler.run(set));
|
|
388
|
+
return runId;
|
|
389
|
+
};
|
|
383
390
|
return {
|
|
384
|
-
start: async (params) =>
|
|
385
|
-
|
|
386
|
-
const set = params.dryRun === true ? new RecipeSet(loaded.output, loaded.inputs.map((input) => ({ ...input, limits: { ...input.limits, maxRecords: 1 } }))) : loaded;
|
|
387
|
-
const runId = `run-${next++}`;
|
|
388
|
-
const crawler = await crawlerFor(runId, params);
|
|
389
|
-
track(runId, crawler, async () => await crawler.run(set));
|
|
390
|
-
return runId;
|
|
391
|
-
},
|
|
391
|
+
start: async (params) => await startLoaded(await loadRecipes(params), params),
|
|
392
|
+
startLoaded,
|
|
392
393
|
startWork: async (params) => {
|
|
393
394
|
const set = await loadRecipes(params);
|
|
394
395
|
const runId = `run-${next++}`;
|
package/dist/main.esm.js
CHANGED
|
@@ -201,8 +201,8 @@ function clientAccessPlugins(names, runId, ask) {
|
|
|
201
201
|
// src/site-access/resolve-site-access.use-case.ts
|
|
202
202
|
import { resolveAccess } from "@opencraw/cli";
|
|
203
203
|
async function resolveSiteAccess(params, runId, ask, env = process.env) {
|
|
204
|
-
const file = params.accessConfig ?? env.OPENCRAW_ACCESS;
|
|
205
|
-
if (file === void 0 && params.access !== void 0) throw new Error(`access profile "${params.access}" needs an access config:
|
|
204
|
+
const file = params.accessConfig ?? (env.OPENCRAW_ACCESS === "" ? void 0 : env.OPENCRAW_ACCESS);
|
|
205
|
+
if (file === void 0 && params.access !== void 0) throw new Error(`access profile "${params.access}" needs an access config, and there is none: no "accessConfig" was given, and OPENCRAW_ACCESS is not set where OpenCraw runs`);
|
|
206
206
|
const access = await resolveAccess({ insecureTls: false, access: file, accessProfile: params.access });
|
|
207
207
|
return { access, accessPlugins: clientAccessPlugins(params.accessPlugins ?? [], runId, ask) };
|
|
208
208
|
}
|
|
@@ -305,17 +305,17 @@ function streamingSink() {
|
|
|
305
305
|
}
|
|
306
306
|
|
|
307
307
|
// src/session/run-session.use-case.ts
|
|
308
|
-
function runSessions(notify, ask) {
|
|
308
|
+
function runSessions(notify, ask, local = {}) {
|
|
309
309
|
const running = /* @__PURE__ */ new Map();
|
|
310
310
|
let next = 1;
|
|
311
311
|
const crawlerFor = async (runId, params) => {
|
|
312
312
|
const { access, accessPlugins } = await resolveSiteAccess(params, runId, ask);
|
|
313
313
|
return createCrawler({
|
|
314
314
|
sink: params.out === void 0 ? streamingSink() : fileSink2(params.out, { append: params.append, browser: { executablePath: params.browser?.executablePath } }),
|
|
315
|
-
hooks: clientHooks(params.hooks ?? [], runId, ask),
|
|
316
|
-
captchaSolvers: clientCaptchaSolvers(params.captchaSolvers ?? [], runId, ask),
|
|
315
|
+
hooks: { ...local.hooks, ...clientHooks(params.hooks ?? [], runId, ask) },
|
|
316
|
+
captchaSolvers: [...local.captchaSolvers ?? [], ...clientCaptchaSolvers(params.captchaSolvers ?? [], runId, ask)],
|
|
317
317
|
access,
|
|
318
|
-
accessPlugins,
|
|
318
|
+
accessPlugins: [...local.accessPlugins ?? [], ...accessPlugins],
|
|
319
319
|
profilesDir: process.env.OPENCRAW_PROFILES,
|
|
320
320
|
parallel: params.parallel,
|
|
321
321
|
resume: params.resume,
|
|
@@ -341,15 +341,16 @@ function runSessions(notify, ask) {
|
|
|
341
341
|
}
|
|
342
342
|
})();
|
|
343
343
|
};
|
|
344
|
+
const startLoaded = async (loaded, params) => {
|
|
345
|
+
const set = params.dryRun === true ? new RecipeSet(loaded.output, loaded.inputs.map((input) => ({ ...input, limits: { ...input.limits, maxRecords: 1 } }))) : loaded;
|
|
346
|
+
const runId = `run-${next++}`;
|
|
347
|
+
const crawler = await crawlerFor(runId, params);
|
|
348
|
+
track(runId, crawler, async () => await crawler.run(set));
|
|
349
|
+
return runId;
|
|
350
|
+
};
|
|
344
351
|
return {
|
|
345
|
-
start: async (params) =>
|
|
346
|
-
|
|
347
|
-
const set = params.dryRun === true ? new RecipeSet(loaded.output, loaded.inputs.map((input) => ({ ...input, limits: { ...input.limits, maxRecords: 1 } }))) : loaded;
|
|
348
|
-
const runId = `run-${next++}`;
|
|
349
|
-
const crawler = await crawlerFor(runId, params);
|
|
350
|
-
track(runId, crawler, async () => await crawler.run(set));
|
|
351
|
-
return runId;
|
|
352
|
-
},
|
|
352
|
+
start: async (params) => await startLoaded(await loadRecipes(params), params),
|
|
353
|
+
startLoaded,
|
|
353
354
|
startWork: async (params) => {
|
|
354
355
|
const set = await loadRecipes(params);
|
|
355
356
|
const runId = `run-${next++}`;
|
package/dist/src/index.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ export type { InitializeParams, InitializeResult, ValidateParams, ValidateResult
|
|
|
5
5
|
export { openLineChannel, RPC_ERRORS, RpcFailure } from './transport/index.js';
|
|
6
6
|
export type { LineChannel, RequestHandler, RpcError, RpcMessage } from './transport/index.js';
|
|
7
7
|
export { runSessions, validateRecipes, streamingSink } from './session/index.js';
|
|
8
|
-
export type { RunSessions } from './session/index.js';
|
|
8
|
+
export type { LocalPlugins, RunSessions } from './session/index.js';
|
|
9
9
|
export { clientHooks, clientCaptchaSolvers, clientAccessPlugins } from './callout-bridge/index.js';
|
|
10
10
|
export type { AskClient, NotifyClient } from './callout-bridge/index.js';
|
|
11
11
|
export { clientWorkSource } from './work-bridge/index.js';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { runSessions } from './run-session.use-case.js';
|
|
2
|
-
export type { RunSessions } from './run-session.use-case.js';
|
|
2
|
+
export type { LocalPlugins, RunSessions } from './run-session.use-case.js';
|
|
3
3
|
export { validateRecipes, hooksOf, loadRecipes, sourceOf } from './recipe-loading.use-case.js';
|
|
4
4
|
export { streamingSink } from './streaming-sink.repository.js';
|
|
5
5
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1,12 +1,22 @@
|
|
|
1
|
+
import { RecipeSet } from '@opencraw/core';
|
|
2
|
+
import type { AccessPlugin, CaptchaSolver, HookMap } from '@opencraw/core';
|
|
1
3
|
import type { AskClient, NotifyClient } from '../callout-bridge/index.js';
|
|
2
4
|
import type { RunParams, WorkParams } from '../protocol/index.js';
|
|
3
5
|
/** The runs a driver has going, by id, so `cancel` can reach them and `shutdown` close them all. */
|
|
4
6
|
export interface RunSessions {
|
|
5
7
|
start: (params: RunParams) => Promise<string>;
|
|
8
|
+
/** As `start`, for recipes the host has already loaded and bound (`params`' recipe source is ignored). */
|
|
9
|
+
startLoaded: (set: RecipeSet, params: Omit<RunParams, 'paths' | 'recipes'>) => Promise<string>;
|
|
6
10
|
startWork: (params: WorkParams) => Promise<string>;
|
|
7
11
|
cancel: (runId: string) => Promise<boolean>;
|
|
8
12
|
closeAll: () => Promise<void>;
|
|
9
13
|
}
|
|
14
|
+
/** What the host serves itself, in process, besides what the client serves: an MCP server's plugins module. */
|
|
15
|
+
export interface LocalPlugins {
|
|
16
|
+
hooks?: HookMap;
|
|
17
|
+
captchaSolvers?: CaptchaSolver[];
|
|
18
|
+
accessPlugins?: AccessPlugin[];
|
|
19
|
+
}
|
|
10
20
|
/**
|
|
11
21
|
* Starts and tracks runs and worker pools. `start` and `startWork` load and bind the recipes (a bad
|
|
12
22
|
* recipe fails the request itself, with its problems), answer with a run id at once, and crawl in the
|
|
@@ -18,7 +28,8 @@ export interface RunSessions {
|
|
|
18
28
|
*
|
|
19
29
|
* @param notify - The channel's notify.
|
|
20
30
|
* @param ask - The channel's request, for callouts and work.
|
|
31
|
+
* @param local - Hooks, captcha solvers and access plugins the host serves itself, beside the client's.
|
|
21
32
|
* @returns The sessions.
|
|
22
33
|
*/
|
|
23
|
-
export declare function runSessions(notify: NotifyClient, ask: AskClient): RunSessions;
|
|
34
|
+
export declare function runSessions(notify: NotifyClient, ask: AskClient, local?: LocalPlugins): RunSessions;
|
|
24
35
|
//# sourceMappingURL=run-session.use-case.d.ts.map
|