lexmount
v0.5.4
Published
Node.js SDK for Lexmount browser automation service
Readme
Lexmount Node.js SDK
English
Node.js SDK for the Lexmount browser automation service.
Features
- Node.js 18+ only
- Typed public API with ESM and CommonJS support
- Session management with pagination support
- Persistent context management
- Extension upload/list/get/delete
- Session downloads list/get/archive/delete
- Session creation with upstream proxy support
- Structured SDK errors
- Configurable SDK logging
- TSDoc + TypeDoc based API documentation generation
Requirements
- Node.js 18 LTS or later
- npm 9+ recommended
- Playwright is optional and only needed when you connect to browser sessions
Installation
Internal package / tgz
npm install <lexmount-package-or-tgz>From source
git clone <repository-url>
cd lexmount-js-sdk
npm install
npm run buildConfiguration
The SDK reads credentials from constructor options or environment variables.
LEXMOUNT_API_KEY=your-api-key
LEXMOUNT_PROJECT_ID=your-project-id
LEXMOUNT_BASE_URL=https://api.lexmount.cnLEXMOUNT_BASE_URL is optional. The default is https://api.lexmount.cn.
Quick Start
import { Lexmount } from 'lexmount';
const client = new Lexmount({
apiKey: process.env.LEXMOUNT_API_KEY,
projectId: process.env.LEXMOUNT_PROJECT_ID,
});
const session = await client.sessions.create();
console.log(session.id);
console.log(session.connectUrl);
await session.close();
client.close();Sessions
Create a session:
const session = await client.sessions.create({
browserMode: 'normal',
});Create a session with a persistent context:
const context = await client.contexts.create({
metadata: { userId: '1001' },
});
const session = await client.sessions.create({
context: { id: context.id, mode: 'readWrite' },
});Create a session with extensions and an upstream proxy:
const session = await client.sessions.create({
extensionIds: ['ext_123'],
proxy: {
type: 'external',
server: 'http://10.3.6.54:28080',
username: 'user',
password: 'pass',
},
});List sessions with pagination metadata:
const result = await client.sessions.list({ status: 'active' });
console.log(result.pagination.totalCount);
for (const session of result) {
console.log(session.id, session.status);
}Delete a session:
await client.sessions.delete({ sessionId: 'session-id' });List and archive session downloads:
const downloads = await client.sessions.downloads.list(session.id);
console.log(downloads.summary.count);
const archive = await client.sessions.downloads.archive(session.id);Contexts
Create and inspect contexts:
const context = await client.contexts.create({
metadata: { owner: 'demo' },
});
const details = await client.contexts.get(context.id);
console.log(details.status);Fork an available context into a new context:
const source = await client.contexts.create();
const forked = await client.contexts.fork(source.id);
console.log(forked.id);List contexts:
const contexts = await client.contexts.list({
status: 'available',
limit: 20,
});Force release a stuck lock:
await client.contexts.forceRelease('context-id');Current context fork limitations:
- Only supports offline snapshot copy from an
availablecontext - Does not support hot fork from a
lockedcontext - Does not support copy-on-write
- Does not support parent/child lineage tracking
Extensions
Upload an extension archive:
const extension = await client.extensions.upload('/absolute/path/to/extension.zip', {
name: 'demo-extension',
});List and inspect extensions:
const extensions = await client.extensions.list({ limit: 10 });
const details = await client.extensions.get(extension.id);
console.log(details.name);Delete an uploaded extension:
await client.extensions.delete(extension.id);Playwright Example
import { chromium } from 'playwright';
import { Lexmount } from 'lexmount';
const client = new Lexmount();
const session = await client.sessions.create();
const browser = await chromium.connectOverCDP(session.connectUrl);
const context = browser.contexts()[0];
const page = context.pages()[0] ?? (await context.newPage());
await page.goto('https://example.com');
console.log(await page.title());
await browser.close();
await session.close();
client.close();Error Handling
import {
AuthenticationError,
ContextLockedError,
NetworkError,
TimeoutError,
} from 'lexmount';
try {
await client.sessions.create({
context: { id: 'ctx_123', mode: 'readWrite' },
});
} catch (error) {
if (error instanceof AuthenticationError) {
console.error('Authentication failed');
} else if (error instanceof ContextLockedError) {
console.error(error.activeSessionId, error.retryAfter);
} else if (error instanceof TimeoutError || error instanceof NetworkError) {
console.error('Temporary connectivity issue');
} else {
throw error;
}
}Logging
import { setLogLevel } from 'lexmount';
setLogLevel('DEBUG');Available levels:
DEBUGINFOWARNINGERRORCRITICALSILENT
Documentation Generation
Public API docs are generated from TSDoc comments.
npm run docs:api
npm run docs:htmlGenerated files are written to generated-docs/ and are not meant to be committed.
Examples
Example scripts live in examples:
playwright-basic.tssession-management.tscontext-basic.tscontext-fork.tscontext-list-get.tscontext-modes.tscontext-lock-handling.tsextension-basic.tsproxy-session.tssession-downloads.ts
Run them with:
cd examples
npm install
npm run context-fork
npm run playwright-basic
npm run session-management
npm run extension-basic
npm run proxy-session
npm run session-downloadsDevelopment
npm run build
npm run typecheck
npm test
npm run docs:apiLicense
MIT License
中文
Lexmount 浏览器自动化服务的 Node.js SDK。
特性
- 仅支持 Node.js 18+
- 提供完整类型定义,同时支持 ESM 和 CommonJS
- 会话管理,支持分页信息
- 持久化 context 管理
- 扩展上传、查询、详情、删除
- 会话下载的查询、获取、归档、清理
- 支持通过上游代理创建会话
- 结构化 SDK 异常
- 可配置 SDK 日志
- 基于 TSDoc + TypeDoc 的自动文档生成能力
运行要求
- Node.js 18 LTS 或更高版本
- 建议使用 npm 9+
- 如果需要连接浏览器会话,才需要额外安装 Playwright
安装
内部包 / tgz
npm install <lexmount-package-or-tgz>从源码安装
git clone <repository-url>
cd lexmount-js-sdk
npm install
npm run build配置
SDK 会优先读取构造参数,其次读取环境变量:
LEXMOUNT_API_KEY=your-api-key
LEXMOUNT_PROJECT_ID=your-project-id
LEXMOUNT_BASE_URL=https://api.lexmount.cnLEXMOUNT_BASE_URL 可选,默认值是 https://api.lexmount.cn。
快速开始
import { Lexmount } from 'lexmount';
const client = new Lexmount({
apiKey: process.env.LEXMOUNT_API_KEY,
projectId: process.env.LEXMOUNT_PROJECT_ID,
});
const session = await client.sessions.create();
console.log(session.id);
console.log(session.connectUrl);
await session.close();
client.close();Sessions
创建会话:
const session = await client.sessions.create({
browserMode: 'normal',
});结合持久化 context 创建会话:
const context = await client.contexts.create({
metadata: { userId: '1001' },
});
const session = await client.sessions.create({
context: { id: context.id, mode: 'readWrite' },
});结合扩展和上游代理创建会话:
const session = await client.sessions.create({
extensionIds: ['ext_123'],
proxy: {
type: 'external',
server: 'http://10.3.6.54:28080',
username: 'user',
password: 'pass',
},
});分页列出会话:
const result = await client.sessions.list({ status: 'active' });
console.log(result.pagination.totalCount);
for (const session of result) {
console.log(session.id, session.status);
}删除会话:
await client.sessions.delete({ sessionId: 'session-id' });列出并归档会话下载:
const downloads = await client.sessions.downloads.list(session.id);
console.log(downloads.summary.count);
const archive = await client.sessions.downloads.archive(session.id);Contexts
创建并查看 context:
const context = await client.contexts.create({
metadata: { owner: 'demo' },
});
const details = await client.contexts.get(context.id);
console.log(details.status);基于一个 available context 创建新的 fork:
const source = await client.contexts.create();
const forked = await client.contexts.fork(source.id);
console.log(forked.id);列出 context:
const contexts = await client.contexts.list({
status: 'available',
limit: 20,
});强制释放卡住的锁:
await client.contexts.forceRelease('context-id');当前 context fork 第一版限制:
- 只支持对
available context做离线快照复制 - 不支持
lockedcontext 的热 fork - 不支持 copy-on-write
- 不支持父子链追踪
Extensions
上传扩展压缩包:
const extension = await client.extensions.upload('/absolute/path/to/extension.zip', {
name: 'demo-extension',
});列出并查看扩展详情:
const extensions = await client.extensions.list({ limit: 10 });
const details = await client.extensions.get(extension.id);
console.log(details.name);删除已上传扩展:
await client.extensions.delete(extension.id);Playwright 示例
import { chromium } from 'playwright';
import { Lexmount } from 'lexmount';
const client = new Lexmount();
const session = await client.sessions.create();
const browser = await chromium.connectOverCDP(session.connectUrl);
const context = browser.contexts()[0];
const page = context.pages()[0] ?? (await context.newPage());
await page.goto('https://example.com');
console.log(await page.title());
await browser.close();
await session.close();
client.close();错误处理
import {
AuthenticationError,
ContextLockedError,
NetworkError,
TimeoutError,
} from 'lexmount';
try {
await client.sessions.create({
context: { id: 'ctx_123', mode: 'readWrite' },
});
} catch (error) {
if (error instanceof AuthenticationError) {
console.error('鉴权失败');
} else if (error instanceof ContextLockedError) {
console.error(error.activeSessionId, error.retryAfter);
} else if (error instanceof TimeoutError || error instanceof NetworkError) {
console.error('网络或超时问题');
} else {
throw error;
}
}日志
import { setLogLevel } from 'lexmount';
setLogLevel('DEBUG');可用级别:
DEBUGINFOWARNINGERRORCRITICALSILENT
自动文档生成
公开 API 文档基于源码里的 TSDoc 注释生成。
npm run docs:api
npm run docs:html生成文件会输出到 generated-docs/,默认不提交到仓库。
示例
示例脚本位于 examples:
playwright-basic.tssession-management.tscontext-basic.tscontext-fork.tscontext-list-get.tscontext-modes.tscontext-lock-handling.tsextension-basic.tsproxy-session.tssession-downloads.ts
运行方式:
cd examples
npm install
npm run context-fork
npm run playwright-basic
npm run session-management
npm run extension-basic
npm run proxy-session
npm run session-downloads开发
npm run build
npm run typecheck
npm test
npm run docs:api许可证
MIT License
