diff --git a/README.md b/README.md index 4e5fb87..54a63e2 100644 --- a/README.md +++ b/README.md @@ -70,7 +70,7 @@ Every [microlink.io](https://microlink.io) product maps to a client method: | Lighthouse | `lighthouse(url)` | | Technologies | `technologies(url)` | | Search | `search(query)` | -| Function | `run(url, code)` (alias `function`) | +| Function | `function(url, code)` | Plus library extras: `links` / `images` / `videos` / `audios` / `emails` collections and `extract` for custom data rules. @@ -254,19 +254,19 @@ while (page) { } ``` -### run(url, code, options) +### function(url, code, options) -Run any JavaScript remotely in a sandboxed runtime — no Lambda bundle, no browser fleet, no server ([guide](https://microlink.io/docs/guides/function)). Also exposed as `function`, matching the API parameter name. You write a plain function; the library handles serialization, compression and the API call for you. When the code doesn't reference `page`, no browser is started, making execution faster and cheaper: +Run any JavaScript remotely in a sandboxed runtime — no Lambda bundle, no browser fleet, no server ([guide](https://microlink.io/docs/guides/function)). You write a plain function; the library handles serialization, compression and the API call for you. When the code doesn't reference `page`, no browser is started, making execution faster and cheaper: ```mjs -const { value } = await microlink.run('https://example.com', () => 40 + 2) +const { value } = await microlink.function('https://example.com', () => 40 + 2) console.log(value) // → 42 ``` When it references `page`, Microlink starts a headless browser and navigates to the URL first, handing your code the full [puppeteer `page`](https://pptr.dev/api/puppeteer.page) for clicks, waits, evaluation and navigation ([browser interaction](https://microlink.io/docs/guides/function/browser-interaction)): ```mjs -const { value } = await microlink.run('https://example.com', async ({ page }) => { +const { value } = await microlink.function('https://example.com', async ({ page }) => { await page.waitForSelector('h1') return page.$eval('h1', el => el.textContent) }) @@ -276,7 +276,7 @@ console.log(value) // → 'Example Domain' Any extra option you pass is forwarded into the function scope — the simplest way to make one function reusable across requests ([custom parameters](https://microlink.io/docs/guides/function/writing-functions)): ```mjs -const { value } = await microlink.run( +const { value } = await microlink.function( 'https://example.com', ({ page, selector }) => page.$eval(selector, el => el.textContent), { selector: 'h1' } @@ -287,7 +287,7 @@ console.log(value) You can `require()` any npm package inside the function — dependencies are detected, installed on the fly into the sandbox, and cached for subsequent runs. Pin a version with `require('cheerio@1.0.0')`: ```mjs -const { value } = await microlink.run('https://news.ycombinator.com', async ({ page }) => { +const { value } = await microlink.function('https://news.ycombinator.com', async ({ page }) => { const cheerio = require('cheerio') const $ = cheerio.load(await page.content()) return $('.titleline > a').map((i, el) => $(el).text()).toArray() @@ -298,7 +298,7 @@ console.log(value) // → ['Top HN story', ...] The result carries more than the return value — `console.log` calls are captured in `logging`, and `profiling` reports peak cpu/memory plus per-phase timings (`install`/`build`/`spawn`/`run`) so you can spot the bottleneck ([profiling](https://microlink.io/docs/guides/function/profiling-and-performance)): ```mjs -const { isFulfilled, value, logging, profiling } = await microlink.run('https://example.com', ({ page }) => { +const { isFulfilled, value, logging, profiling } = await microlink.function('https://example.com', ({ page }) => { console.log('visiting page') return page.title() }) @@ -359,7 +359,7 @@ npx microlink.io function https://example.com --file ./fn.js - [@microlink/mql](https://github.com/microlinkhq/mql) — the low-level Microlink Query Language client (raw envelopes, `buffer`/`stream` access). - [@microlink/google](https://github.com/microlinkhq/google) — structured Google data, powering `search`. -- [@microlink/function](https://github.com/microlinkhq/function) — remote JavaScript functions, powering `function`/`run` ([guides](https://microlink.io/docs/guides/function)). +- [@microlink/function](https://github.com/microlinkhq/function) — remote JavaScript functions, powering `function` ([guides](https://microlink.io/docs/guides/function)). ## License diff --git a/packages/core/bin/help.js b/packages/core/bin/help.js index 990a5dd..09b468d 100644 --- a/packages/core/bin/help.js +++ b/packages/core/bin/help.js @@ -72,8 +72,6 @@ const COLLECTION = [ ['--type', 'Cast each value (url, image, email, ...)'] ] -const ALIAS = { run: 'function' } - const COMMANDS = { help: { usage: 'help [command]', @@ -371,7 +369,6 @@ const render = (name, product) => { } module.exports = command => { - const name = ALIAS[command] ?? command - if (COMMANDS[name]) return render(name, COMMANDS[name]) - return PRODUCTS[name] ? render(name, PRODUCTS[name]) : global + if (COMMANDS[command]) return render(command, COMMANDS[command]) + return PRODUCTS[command] ? render(command, PRODUCTS[command]) : global } diff --git a/packages/core/bin/run.js b/packages/core/bin/run.js index 271eccb..88c67c0 100644 --- a/packages/core/bin/run.js +++ b/packages/core/bin/run.js @@ -88,10 +88,7 @@ const run = async (argvInput, host) => { if (help || !target) return showHelp(command) if (command !== 'search') target = asUrl(target) ?? target - if ( - isTrace && - (command === 'search' || command === 'function' || command === 'run') - ) { + if (isTrace && (command === 'search' || command === 'function')) { writeLine(stderr, `\`--trace\` is not supported for \`${command}\`.`) return finish(1) } @@ -110,7 +107,7 @@ const run = async (argvInput, host) => { } } - if ((command === 'function' || command === 'run') && !file) { + if (command === 'function' && !file) { printFail({ message: 'Missing `--file` with the function source code' }) return finish(1) } @@ -119,7 +116,7 @@ const run = async (argvInput, host) => { if (command === 'extract') { return client.extract(target, rules, options) } - if (command === 'function' || command === 'run') { + if (command === 'function') { const code = host.readFile(file) return client.function(target, code, options) } diff --git a/packages/core/src/index.d.ts b/packages/core/src/index.d.ts index 2f7e605..f84e50a 100644 --- a/packages/core/src/index.d.ts +++ b/packages/core/src/index.d.ts @@ -169,7 +169,6 @@ interface MicrolinkClient { code: FunctionInput, options?: Options ): Promise> - run: MicrolinkClient['function'] } interface create { diff --git a/packages/core/src/index.js b/packages/core/src/index.js index 8bb7955..f7b1fc9 100644 --- a/packages/core/src/index.js +++ b/packages/core/src/index.js @@ -106,11 +106,6 @@ const create = (ctx = {}) => { ) } - const run = (url, code, options) => { - const { top, got } = route(options) - return fn(code, top, got)(url) - } - const client = { metadata: (url, options) => { const { top, got } = route(options) @@ -197,8 +192,10 @@ const create = (ctx = {}) => { const { top } = route(options) return googleClient(query, top) }, - function: run, - run + function: (url, code, options) => { + const { top, got } = route(options) + return fn(code, top, got)(url) + } } Object.defineProperty(client, 'last', { value: last }) diff --git a/packages/core/test/build.mjs b/packages/core/test/build.mjs index a8cda8f..febedc1 100644 --- a/packages/core/test/build.mjs +++ b/packages/core/test/build.mjs @@ -30,7 +30,6 @@ const PRODUCTS = [ 'markdown', 'metadata', 'pdf', - 'run', 'screenshot', 'search', 'technologies', diff --git a/packages/core/test/index.test-d.ts b/packages/core/test/index.test-d.ts index 38a6cef..f2181b2 100644 --- a/packages/core/test/index.test-d.ts +++ b/packages/core/test/index.test-d.ts @@ -66,7 +66,6 @@ async function assertions (): Promise { const fnResult = await client.function('https://example.com', '() => 1') expectType(fnResult.isFulfilled) - expectType(client.run) } void assertions() diff --git a/packages/core/test/integration.mjs b/packages/core/test/integration.mjs index 603d18a..65d28b7 100644 --- a/packages/core/test/integration.mjs +++ b/packages/core/test/integration.mjs @@ -50,7 +50,7 @@ test.skip('video detects the primary video', async t => { }) test('function runs code remotely with injected scope variables', async t => { - const { isFulfilled, value } = await microlink.run( + const { isFulfilled, value } = await microlink.function( targetUrl, ({ greeting }) => greeting, { greeting: 'hello' } diff --git a/packages/core/test/unit.mjs b/packages/core/test/unit.mjs index d06cff3..f23c8fb 100644 --- a/packages/core/test/unit.mjs +++ b/packages/core/test/unit.mjs @@ -268,12 +268,11 @@ test('per-call options override the factory context', async t => { t.is(calls[0].mqlOpts.apiKey, 'override') }) -test('function/run are the same method', async t => { +test('function runs remote code with routed options', async t => { const { create, fnCalls } = setup() const client = create({ apiKey: 'secret' }) - t.is(client.function, client.run) const code = '({ page }) => page.title()' - const result = await client.run(URL, code, { + const result = await client.function(URL, code, { headers: { 'x-foo': 'bar' } }) t.deepEqual(result, { isFulfilled: true, value: URL })