@digo-labs/services

中文文档
0.2.19发布于 2026/11/13TypeScriptESM + CJS近 30 天下载 2191

Digo平台的浏览器客户端:auth,设备密钥,后端API,数据库表格,文件存储,websocket通道,AI生成和AI任务.

中文使用文档
文档目录12 节
  1. 设置
  2. 认证 : useAuth , (中文(简体) ), useGoogleSignIn , (中文(简体) ), Auth…
  3. 设备密钥 : Devices , (中文(简体) ), useDevice , (中文(简体) ), DeviceHe…
  4. 数据库 : Database<T>
  5. 实例 : Instances , (中文(简体) ), useInstance , (中文(简体) ), Instan…
  6. 存储 : Storage
  7. 网络锁定 : Websockets<TMap>
  8. 大赦国际: Ai
  9. AI 任务 : ai.jobs
  10. 大赦国际的预算: ai.budgets
  11. 低级和中央领导才能
  12. 抓到他们了

@digo-labs/服务

Digo平台的浏览器客户端:auth,设备密钥,后端API,数据库表格,文件存储,websocket通道,AI生成和AI任务.

如何是观此相. 这个带包的向导船,因此与您所安装的版本相匹配;站点描述了最新的发布. 类型 node_modules/@digo-labs/services/dist/*.d.ts 如果他们不同意,是准确的,是赢的。 更深的页面 : https://design.digo-labs.com/docs/guide/package-services (中文(简体) )。 。 。 .

设置

不要手动关闭此软件包 . defineApp 从 @digo-labs/app 注册应用程序名称、电话 AuthHelper.init (与 auth和 ApiHelper.init (与 backend: true,然后运行您的 services 工厂,在工厂里建造以下的类(...databases, (中文(简体) ), new Storage(), (中文(简体) ), new Websockets<Channels>(), (中文(简体) ), new Ai()) (中文(简体) ).

认证 : useAuth, (中文(简体) ), useGoogleSignIn, (中文(简体) ), AuthHelper

import { useAuth } from '@digo-labs/services';

const { user, session, device, instance, isReadOnly, tier, globalTier, isLoading, isOffline, isAuthenticated, signIn, signOut } = useAuth();

await signIn.social({ provider: 'google', callbackURL: window.location.href });

tier 实值 'public' | 'user' | 'org' | 'admin' 在选定的实例中: 注册设备的分级胜出; 否则 org 是一个已验证的 @productionclub.net 电子邮件,以及 admin 管理者的角色或管理者. instance 是所选实例的弹出和 globalTier 忽略实例角色:门实例管理、预算限制、文本、代理和其中的DMX. isReadOnly 当实例被存档时是真实的( 一个归档撤销了实例的设备密钥, 因此设备获得 401) (中文(简体) ). isAuthenticated 对用户或设备来说是真实的. AuthHelper.auth 是原始的更好的 Auth 客户端(包括admin 插件).

对于谷歌的登录按钮, useGoogleSignIn({ callbackPath }) (默认) '/'返回时 { signIn, isSigningIn, error }数字 : signIn() 重定向到谷歌并返回 callbackPath 并决心 Result<void> tu; isSigningIn 在浏览器离开或请求失败之前是真实的; error 保持失败.

import { useGoogleSignIn } from '@digo-labs/services';

const { signIn, isSigningIn } = useGoogleSignIn({ callbackPath: from });

async function handleSignIn() {
  const [, error] = await signIn();

  if (error) {
    console.error(error);
    setMessage('Sign in failed. Please try again.');
  }
}

<button onClick={handleSignIn} disabled={isSigningIn}>Continue with Google</button>

设备密钥 : Devices, (中文(简体) ), useDevice, (中文(简体) ), DeviceHelper

一个设备密钥让一个亭子在层上行动,没有人签字. 它属于它创建于,生活于 localStorage 并发送到每个 API 呼叫中; 装入设备将它的浏览器切换到它的密钥实例中 .

const devices = new Devices();

await devices.enrol({ name: 'Booth 1', tier: 'org', expiresInDays: 30 }); // create and store the key here, then sign this browser out
await devices.create({ name: 'Booth 2' });  // { device, key }, key not stored
await devices.list();                       // DeviceRecord[]
await devices.revoke(id);                   // boolean
await devices.regenerate(id);               // { device, key }: old key revoked, new one revealable
devices.forget();                           // drop this device's key

await devices.create({ name: 'Booth 3', isRevealable: true }); // keep an encrypted copy
await devices.reveal(id);                   // the key again (admin, while revealable)
await devices.lock(id);                     // boolean: drop the copy for good, key keeps working
await devices.lockAll();                    // number of keys locked in this instance

tier 实值 'user' | 'org' (默认) 'org', (中文(简体) ), expiresInDays 最多365起(违约30起)或 null 为永远. DeviceRecord.isRevealable 说钥匙是否还有副本. useDevice() 返回时 { device, isLoading, isOffline }页:1 401 丢弃存储的密钥, 而其它任何失败( 网络出错、 超时、 其它) 4xx页:1 5xx(组数) isOffline,保留 device 作为记录,最后确认的后端(插入 localStorage自行检讨; DeviceHelper.setKey(key) 编号 : clearKey() 管理存储的密钥.

数据库 : Database<T>

每表一例. 类型实例来自 defineDatabases (单位:千美元)@digo-labs/app/database; 直接为共享表格构建一个: new Database<StyleRecord>('styles') (第二个参数:主键,默认值) 'id') (中文(简体) ).

await services.items.getAll(50, 0);                                            // T[]  (limit?, offset?), in primary-key order
await services.items.get(id);                                                   // T | null
await services.items.getBy('name', 'Hello');                                    // T[]  (column, value, limit?, offset?)
await services.items.readAll();                                                 // T[]  every row, paged by primary key
await services.items.readAllBy('name', 'Hello');                                // T[]  every matching row
await services.items.create({ name: 'Hello' });                                 // T
await services.items.update(id, { name: 'Hi' });                                // boolean
await services.items.update(id, { status: 'printing' }, { status: 'queued' }); // only if it still matches (needs read too)
await services.items.delete(id);                                                // boolean

读取整个表格的使用 readAll编号 :readAllBy没有循环 offset:它们在上一个主键读取后再行行,所以每个从起到终所存在的行都会被精确地读取一次,即使其他行被更改,添加或去除(单列主键只有;其他表格得到400个).

访问量为每张表格,在 src/db.ts 并同步 by digo-db push;没有规则的表格被拒绝。 客户端可能不会发送 id (给它一个数据库默认) 或表格的 owner 栏(后端从会话中填充).

实例 : Instances, (中文(简体) ), useInstance, (中文(简体) ), InstanceHelper

一个应用软件的孤立装置(schema,文件,已签名的频道,设备密钥,AI预算各一;开放频道只获得其名下的实例). main 总是存在的; 请求将实例带入 X-Digo-Instance: 页面主机( q)jon.<app>.digo-labs.com 实值 jon),否则浏览器的选择,否则 main。一个未知的存储选择被丢弃,页面重新装入 main,是否签名.

const instances = new Instances();

await instances.list();                                  // main, then all for a global admin or the ones you administer
await instances.current();                               // { instance, tier, isReadOnly }
instances.select('jon');                                 // store for this browser and reload
instances.getSelected();                                 // 'jon'
await instances.create({ slug: 'jon', name: 'Jon' });    // global admins only, like the calls below
await instances.rename('main', 'Las Vegas');
await instances.archive('jon');                          // read-only, device keys revoked
await instances.reopen('jon');
await instances.setAdmins('jon', ['[email protected]']);   // replaces the list; admins of that instance only, never main
await instances.getAdmins('jon');

useInstance({ userId }) 返回时 { instance, access, isLoading } (单位:千美元)access 仅在外部获取 main,在网络错误上重新测试,并丢弃一个未知存储实例; useAuth() 已经用过了.

存储 : Storage

应用程序的 S3 桶中的文件通过预签名链接 . new Storage() 用途 <app-name>-digo-labs-storage;通过共享桶的名称(new Storage('common-styles-digo-labs-storage')) (中文(简体) ).

const { path, url } = await storage.uploadFile(`sketches/${id}.png`, file);  // File | Blob | ArrayBuffer, contentType?
await storage.uploadImage(path, { base64, mediaType: 'image/png' });
await storage.uploadFromUrl(path, remoteUrl, 'image/png');

storage.getUrl(path);                                   // sync link through the files route
await storage.getSignedUrl(path, { expiresIn: 300 });   // short-lived link for private prefixes
await storage.download(path);                           // Blob
await storage.list('sketches/', { limit: 100 });        // StorageObject[]
await storage.delete([path]);                           // deleted paths
storage.getPathFromUrl(url);                            // string | null

在表格中存储路径,而不是链接 。 前缀规则来自 defineStorage 内 src/db.ts。路径相对选定的实例: jon 他们住在地下 _instances/jon/,哪个 getUrl, (中文(简体) ), getPathFromUrl 财务报告和审定财务报表 list 为您添加并删除.

网络锁定 : Websockets<TMap>

A. 在websocket中枢上打入的酒吧/分站; TMap 将频道名称映射到有效载荷。 它在构造器中连接,并自己重新连接.

interface Channels { cursor: { x: number; y: number; }; }

const ws = new Websockets<Channels>({ auth: true });

ws.subscribe('cursor', data => move(data.x, data.y));
ws.send('cursor', { x: 1, y: 2 });       // to current subscribers
ws.setState('cursor', { x: 1, y: 2 });   // kept on the hub, replayed to new subscribers
ws.unsubscribe('cursor');
ws.onReady(() => refresh());             // also onOpen, onClose, onError, offReady, isLive, close

选项 : auth, (中文(简体) ), url (默认) wss://ws.digo-labs.com, (中文(简体) ), app, (中文(简体) ), id, (中文(简体) ), reconnect, (中文(简体) ), reconnectInterval, (中文(简体) ), maxReconnectInterval, (中文(简体) ), getToken。 。 。 .

  • 打开 (默认):频道外出作为 <app>:<channel> (单位:千美元)<app>__<instance>:<channel> 外部 main),除非含有: : 或从 _。命名大会;任何人都可以读取.
  • 签署于 (单位:千美元)auth: true: 显示后端符号(会话或设备密钥); 名称按写并对照应用程序检查 defineChannels 规则.

大赦国际: Ai

const ai = new Ai();

const stream = ai.text.generate({ messages: [{ role: 'user', content: 'Hi' }], systemPrompt, maxTokens: 400 });
for await (const { text } of stream) append(text);
const { text, stopReason, isBlocked } = await stream.collect();

const image = await ai.image.generate({ prompt, aspectRatio: '16:9' }, { persist: 'generations/a.jpg' });
await ai.image.edit({ prompt, image: url, strength: 0.6 });
await ai.image.upscale({ image: url, factor: 2 });
await ai.image.removeBackground({ image: url });
await ai.video.generate({ prompt, aspectRatio: '9:16', durationSeconds: 5 });
await ai.audio.speech({ text, voice: 'af_heart' });
await ai.audio.music({ prompt, durationSeconds: 30 });
await ai.audio.transcribe({ audio: url, language: 'en' });

中途丢出失败的文本流 TextStreamError 带有 reason (单位:千美元)busy, (中文(简体) ), model_unavailable, (中文(简体) ), provider_down, (中文(简体) ), invalid_request 或者说 unknown) (中文(简体) ). 文字运行于贝德罗克;媒体运行于fal. 媒体选项是 { persist?, signal?, onProgress? } (单位:千美元)transcribe 财务报告和审定财务报表 text.generate 带 { signal } 页:1 结果为: { url, contentType?, width?, height?, seed?, durationSeconds?, model? }; 无 persist, (中文(简体) ), url 是提供者的临时链接,文件被复制到您的桶中 url 实值 storage.getUrl(persist)。原始供应商: ai.bedrock.converseStream(body, signal?), (中文(简体) ), ai.fal (单位:千美元)subscribe, (中文(简体) ), run, (中文(简体) ), stream, (中文(简体) ), queue,(......)和 ai.replicate (单位:千美元) replicate SDK),也导出为 Bedrock, (中文(简体) ), Fal, (中文(简体) ), Replicate。 。 。 .

AI 任务 : ai.jobs

后端运行的图像管道:输入检查,任务,输出保存到您的桶上,输出检查. 重新装入毫无损失.

const job = await services.ai.jobs.create({
  key:      `guest-${guestId}`,                       // idempotent per app instance
  inputs:   { sketch: `sketches/${guestId}.png` },
  checks:   [{ type: 'rekognition', input: 'sketch' }],
  tasks:    [{
    key:      'traditional',
    endpoint: 'fal:openai/gpt-image-2.5/flare/edit',   // AI_JOB_ENDPOINTS in @digo-labs/common
    input:    { prompt, image_urls: [{ $input: 'sketch' }] },
    output:   { path: `designs/${guestId}/traditional.png` }, // under a write: 'server' prefix
  }],
  outputChecks: [{ type: 'rekognition' }],
});

const stop = services.ai.jobs.watch(job.id, current => setTasks(current.tasks));

还有 add(id, tasks), (中文(简体) ), check(id, taskKey, checks), (中文(简体) ), cancel(id), (中文(简体) ), get(id),以及 list(filters): 实例的工作是一页时间, 最古老的第一, 形状 get 返回; 过滤器 from 编号 : to (关于创作时间的ISO 8601, to (不包括), statuses, (中文(简体) ), limit (默认为100,最多为200),页面的 next,以 cursor 直到它变成这样 null。 。 。 . onReview 实值 'reject' (违约)或 'continue'。 。 。 . create 采取不 tasks 工作目前只检查其投入; add 然后工作的时候 checking,它的任务等待检查。 检查是 { type: 'rekognition', input?, reject?, review?, minConfidence?, timeoutMs? } 或者说 { type: 'bedrock', prompt, input?, guardrail?, model?, provider?, timeoutMs? }时 provider 实值 'bedrock' (违约)或 'anthropic' (无) guardrail 和(或) timeoutMs 3至25 s(默认情况下为25 s). watch 等待每个修改的后端( n)get(id, { since, signal }) 并停止一切. endpoint: 'fake:echo' 建造时没有损失 一个任务 fallbacks (最多2个) { endpoint, input? }(a) 在其提供商失败时接管 fallbackAfter (ms) 当电流缓慢时,也开始下一个; servedBy 命名保存图像的终点。 任何检查最多需要两个 fallbacks (或一个) fallback克劳德按顺序审查, 只有在前一个不能运行或时间用完的时候.

大赦国际的预算: ai.budgets

每个实例对工作的限制, 保留在后端. null 谓无量相.

const { budget, usage } = await services.ai.budgets.get();
await services.ai.budgets.update({ maxInFlight: null, dailyUsd: 200 }); // only the fields sent change

budget 实值 { maxTasksPerJob, maxInFlight, hourlyUsd, dailyUsd, isPaused } (违约30、8、10、50, false(三); usage 实值 { hourlyUsd, dailyUsd, inFlight },估计在最后一小时和一天的开支, 以及现在供应商的要求。 两种调用都根据呼叫者自己的应用程序和实例行事;改变限制需要一个全局管理员,而一个实例管理员只能暂停和恢复(isPaused) (中文(简体) ). 工作请求超过答案的上限 429。 。 。 .

低级和中央领导才能

  • ApiHelper.client 是每个后端路由的被打入的Hono客户端; ApiHelper.unwrap<T>(promise) 返回 JSON 或丢出一个 Error 与后端的信息.
  • new Dmx().send(channel, value) 设置 DMX 频道(仅限管理员). Realtime 是空占位符; 使用 Websockets。 。 。 .
  • 这个 digo-db 二进制( e)npm run db:push 应用程序中 : push 创建计划, 运行 drizzle-kit push,同步 access, (中文(简体) ), storage 财务报告和审定财务报表 channels 出口额 src/db.ts 并推进应用程序的每一个实例计划 drop, (中文(简体) ), verify, (中文(简体) ), refresh, (中文(简体) ), schema-name需求 DATABASE_URL_MONOREPO (和 ADMIN_SECRET 在环境, 即应用模板的 scripts/with-monorepo-secrets.sh 从 AWS 机密管理器中读取 :npm run db:push 运行 push 通过它; 运行其他子命令 通过它),和 drizzle-kit 已安装.

抓到他们了

  • 内建服务 services 工厂. Storage 财务报告和审定财务报表 Websockets 需要应用程序名称 defineApp 登记和扔出没有它; new Ai() 构建一个 Storage,所以它投掷也.
  • useAuth 需求 auth 内 defineApp,或 AuthHelper.auth 掷出. 每页一个认证项目 .
  • backendURL 没有到达荒地或复制:他们的代理人总是使用 https://api.digo-labs.com。 。 。 .
  • 分级后端执行 : 文本, fal/ 复制, 全部 ai.jobs 电话和 ai.budgets.get 需求 org· ; ai.budgets.update 和设备创建/列表/撤销需要 admin, (中文(简体) ), instances.list 登录( e)instances.current 实例管理是全球性的管理。 一个实例是 admin 仅根据该实例本身的数据、文件、频道、设备和工作;文本、fal/复制和DMX检查其全球层级。 存档实例解答写法 423。 。 。 . 401 签字后, 403 当阶梯太低的时候.
  • 共享桌名取胜 . 后端决定 common 表格(例如: styles)在应用程序之前,所以一个同名的应用程序表是无法到达的.
  • getUrl 仅在 a 下装入 read: 'public' 前缀 (次数) 404; 使用情况 getSignedUrl。 。 。 . getPublicUrl 构建一个不装入的原始S3地址:桶是私有的.
  • 固定的 AI 值抛出其他 : 图像 aspectRatio 1:1, (中文(简体) ), 16:9, (中文(简体) ), 9:16, (中文(简体) ), 4:3, (中文(简体) ), 3:4; 视频 16:9, (中文(简体) ), 9:16, (中文(简体) ), 1:1(一) 持续时间中断至5或10秒; voice 必须是克克洛的声音(af_heart, (中文(简体) ), am_adam(中文(简体) ).
  • 网页 send编号 :setState 已断开未排队。 重读状态 onReady。 。 。 .

版本与发布记录

@digo-labs/services 共发布 32 个版本,首次发布于 2026/05/06;过去 12 个月发布了 32 个版本。

版本发布日期距今
0.2.19latest2026/11/13今天
0.2.172026/11/131 天前
0.2.162026/11/131 天前
0.2.152026/11/131 天前
0.2.142026/11/121 天前
0.2.132026/11/112 天前

关于 @digo-labs/services 的常见问题

@digo-labs/services 是什么?

Digo平台的浏览器客户端:auth,设备密钥,后端API,数据库表格,文件存储,websocket通道,AI生成和AI任务.

如何安装 @digo-labs/services?

在项目目录运行 npm install @digo-labs/services,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:react(^19.0.0)、react-dom(^19.0.0)、@digo-labs/ws(^0.2.2)、@digo-labs/common(^0.2.23)、@digo-labs/backend(^0.2.15)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。它还提供命令行工具 digo-db,可以用 npx digo-db 直接运行。

@digo-labs/services 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@digo-labs/services 支持 ESM 还是 CommonJS?

同时提供 ES Module 与 CommonJS 入口,import 和 require() 都可以使用,打包工具会自动选择合适的版本。

@digo-labs/services 可以商用吗?

@digo-labs/services 使用 未声明 许可。package.json 没有声明许可证。没有许可证的代码默认保留全部权利,商用前请联系作者或查看仓库中的 LICENSE 文件。以上为概括,不构成法律意见,请以许可原文为准。

@digo-labs/services 的下载量有多少?

根据 npm 官方下载统计,@digo-labs/services 在 2026/10/12 – 2026/11/10 这 30 天内被下载 2,191 次,日均约 73 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@digo-labs/services 还在维护吗?

最新版本 0.2.19 发布于 2026/11/13(今天);至今共发布 32 个版本,其中过去 12 个月发布了 32 个;首次发布于 2026/05/06。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。