# @freeappstore/sdk 中文文档

规范地址：https://npmcn.com/package/%40freeappstore/sdk/

版本：0\.17\.1
npm 元数据更新时间：2026-11-14T03:50:21.594Z
中文译文更新时间：2026-11-15T12:55:34.857Z
软件包许可：MIT

本文由上游 README 翻译，可能存在偏差，请结合原文核对 API、命令与配置。版权与许可归原作者所有。

原始 npm 页面：https://www.npmjs.com/package/%40freeappstore/sdk
原文对照：https://npmcn.com/package/%40freeappstore/sdk/?lang=original
项目主页：https://github.com/freeappstore-online/platform#readme
源码仓库：https://github.com/freeappstore-online/platform

## 关键信息（来自 npm 元数据）

- 包体积（解压后）：660 kB，223 个文件
- 模块格式：ES Module
- TypeScript 类型：包内自带
- 运行依赖：1 个
- peer 依赖：react ^18\.0\.0 \|\| ^19\.0\.0，vite-plugin-pwa ^1\.0\.0
- 首次发布：2026-05-05T06:15:58.949Z
- 最新版本发布：2026-11-14T03:50:21.215Z
- 近 30 天下载量：14939（2026-10-16 至 2026-11-14，npm 官方下载统计）
- 已发布版本数：130（近 12 个月 130 个）

## 中文简介

浏览器 SDK for FreeAppStore — auth, KV, 收藏,柜台,房间,代理,加密的用户密钥,角色,朋友,电子邮件,推取提醒,设备本地持久性,验证的备份和文件导出,React hooks,和UI组件.

## 安装

```sh
npm install @freeappstore/sdk
```

也可以使用：`pnpm add @freeappstore/sdk`、`yarn add @freeappstore/sdk`、`bun add @freeappstore/sdk`

## README

# @ freeappstore/ sdk (英语)

浏览器 SDK 用于发布于 **freeappstore. online 在线**。 。 。 .

PWA 生命周期 API 生活在 `@freeappstore/sdk/pwa`,在 `@freeappstore/sdk/pwa-config`。见 [安全更新和离线能力](https://github.com/freeappstore-online/platform/blob/main/docs/pwa-lifecycle.md)。 。 。 .

设备本地首选项、索引数据库和大文件元数据实时 `@freeappstore/sdk/persist`。这些数据不是注册账户。 账户 键还原 `fas.kv`。失败的保存返回状态而不是丢弃状态 成功之路,腐败的价值观依然存在。 见 [设备本地持久性](https://github.com/freeappstore-online/platform/blob/main/docs/sdk.md#device-local-persistence-freeappstoresdkpersist)。 。 。 .

经验证的备份、导入和浏览器文件导出时间为 `@freeappstore/sdk/backup`。 。 。 . 这个子路径需要 `@freeappstore/sdk >=0.16.21`。 。 。 . 应用程序拥有记录和合并政策. 导入是全或全无的,是的 在安装或删除能力时,不删除数据。 见 [备份和文件导出](https://github.com/freeappstore-online/platform/blob/main/docs/sdk.md#backup-and-file-export-freeappstoresdkbackup)。 。 。 .

## 安装

```bash
npm i @freeappstore/sdk
```

## 使用量

```ts
import { initApp } from '@freeappstore/sdk';

const fas = initApp({ appId: 'my-app' });

// Capture the OAuth callback if we're returning from sign-in. Call this once
// at app start, before any UI that depends on auth state.
await fas.auth.init();

// React to sign-in / sign-out.
fas.auth.onChange((user) => {
  console.log(user ? `Hello @${user.login}` : 'signed out');
});

// Trigger sign-in (redirects to GitHub).
document.querySelector('#signin')?.addEventListener('click', () => {
  fas.auth.signIn();
});
```

## 模块

### 认证

GitHub OAuth通过重定向. 持续进行 `localStorage`。 。 。 .

```ts
fas.auth.user;             // User | null
fas.auth.token;            // string | null
fas.auth.signIn();         // redirects to GitHub
fas.auth.signOut();        // signs out of this app
fas.auth.onChange(cb);     // fires immediately + on change, returns Unsubscribe
await fas.auth.init();     // capture callback, must be called once
```

### 数据存取合同

| 型号 | 服务 | 保证 |
| --- | --- | --- |
| 设备本地 | `@freeappstore/sdk/persist` | 仅此浏览器配置和来源; 不是账户同步 . |
| 私人账户 | `fas.kv` | 服务器侧 `(appId, userId)` 孤立; 需要认证. |
| 共享文件 | `fas.collections` | 直到应用程序所有者分享收藏(`fas db share`);然后公开阅读,只写所有者. 共享收藏即使由所有者进行查询过滤,也是公开的. |
| 房间限制 | 后端数据室 HTTP API | 经认证的终点 强制加入会议室。 它们与公共收藏和实时会议室广播分开;SDK尚未提供包装. 见 [数据室 API](https://npmcn.com/package/docs/data-rooms.md)。 。 。 . |

一个收藏是 `'private'` (只拥有者) 默认. `fas.collections.collection(name, { visibility: 'public-read' })` 在代码中声明收藏是共享的; 服务器执行应用程序所有者设定的内容 `fas db share`。任何其他可见度被 SDK 类型和运行时间拒绝.

### 用户名 KV

私人每个账户云存储范围 `(appId, userId)` 服务器侧 。 用于跟踪用户在设备上签名的数据。 请求需要账户;不要在登录后打开无关的公共屏幕.

```ts
await fas.kv.set('theme', { color: 'plum' });
const theme = await fas.kv.get<{ color: string }>('theme');
await fas.kv.delete('theme');

const allKeys = await fas.kv.list();
const noteKeys = await fas.kv.list({ prefix: 'note:' });
const notes = await fas.kv.getMany<Note>(noteKeys);

// All methods accept { signal } for AbortController cleanup
const ctrl = new AbortController();
await fas.kv.get('key', { signal: ctrl.signal });
```

限制(服务器强制):每个用户最大1MB,每个用户最大100个密钥,每个值最大64KB.

### 共享计数器

App-wide原子计数器——不是用户范围. 任何人都可以阅读;认证用户可以递增. 降级保留给具有特权的应用程序所有者和用户(除此之外的其他任何) `member` 编号 : `viewer`) (中文(简体) ). 用于计票,取景计票,领跑板.

```ts
// Read (no auth required)
const all = await fas.counters.list();           // { likes: 5, views: 100 }
const views = await fas.counters.get('views');   // 100

// Increment (auth required)
const newVal = await fas.counters.increment('likes');      // +1, returns new value
const newVal2 = await fas.counters.increment('score', 10); // +10
await fas.counters.increment('lives', -1);                 // decrement — owner / privileged role only
```

限制:每个应用程序的最大1000个计数器,每起呼叫的增量范围为-1000至+1000.

### 实时会议室

持久目标支持的WebSocket粉丝出道. 以至——信息没有持续存在。 以光标存在,光合作用,和斯利特风格的多人游戏机(低状态,高频)为标码.

```ts
const room = fas.rooms.join('lobby');

room.onPeers((peers) => console.log('peers:', peers));
room.onMessage<{ text: string }>((msg) => {
  console.log(msg.from, msg.data.text);
});

room.send({ text: 'hello' });
// later:
room.close();
```

房间提供电平实时广播,而非耐用存储. 房间默认向任何登录用户开放. `fas.rooms.join('staff', { private: true })` 标记一个私人房间:从那时起,只有拥有该应用程序的应用角色的用户(该应用程序的拥有者,或拥有者授予的角色与角色 API `member` 每个用户自动得到的角色不计数)可以加入,只有这样的用户才能让房间变得私密. 每个人都得到 `room.denied === true` (状态) `error`,没有重试). `{ private: false }` 打开一个私人房间。 能够加入的私人房间大门;消息仍然被麻风广播,而不是存储. 除谁可以加入外,不要声称保密。 限制(服务器强制执行):每间32个同龄人,每同龄人100msg/sec,每条信息4KB,24h闲置驱逐,每套应用软件64个活动房间.

### 收藏(文件数据库)

可查询数据的文档存储 。 默认情况下,文件对所有人是保密的; `fas db share <collection>` 让每个人阅读一个集合(认证的拥有者仍然只写自己的集合). `owner` 只有你自己的身份证明,和 `_owner` 被隐藏于其他用户。 不需要SQL——只要JSON进入,JSON退出.

```ts
const posts = fas.collections.collection('posts', { visibility: 'public-read' });

// Create (auth required, you become the owner)
const post = await posts.create({ title: 'Hello', body: '...' });

// Query (your own documents, or everyone's once shared)
const { documents, total } = await posts.query({
  limit: 20,
  orderBy: 'created_at',
  order: 'desc',
  owner: userId,  // optional: only ever your own id
});

// Get single document
const doc = await posts.get('doc-id');

// Update (owner only)
await posts.update('doc-id', { title: 'Updated' });

// Delete (owner only)
await posts.delete('doc-id');
```

限制:每集一万份文件,每份文件64KB.

### 免费 APIs 库( 不需要代理) (L)

许多有用的工具不需要 API 键 。 直接使用它们:叶片 (地图), Recharts (图表), Tiptap (丰富的文本), 日期-fns, 反应-markdown, qrcode. react, dnd-kit (drag & drop), Framer Motion, Lucide React (icons), React Hook Form, Zustand. 自由APIs:Open-Meteo (weather),Nominatim (geocoding),OSRM (路由),REST国家等. 见 [杀手,md](https://freeappstore.online/skills.md) 完整名单.

### 加密输入代理

对于DO需要密钥的API,代理加密并注入服务器侧.

```ts
const res = await fas.proxy.fetch('api.openweathermap.org/data/2.5/weather?q=London');
const data = await res.json();
```

### 用户 API 密钥默认值

用户将自己的API密钥存储在平台上(加密了AES-256-GCM). Apps 从未看到纯文本密钥 .

```ts
// Check if user has a key configured
const hasKey = await fas.keys.has('openai');

// Redirect to platform key management page
fas.keys.manage('openai');

// Check all configured providers
const keys = await fas.keys.status();
```

被支持的提供商:OpenAI,Anthropic,Google AI,OpenRouter,复制,稳定AI,11Labs.

### 按下提醒键( P)`fas.push`(中文(简体) )

为登录用户预定的 Web Push 通知 。 当提醒到期(每15分钟检查一次)时,平台会向用户的每个设备发送一个推力,用于您的应用程序.

```ts
const { supported, reason } = fas.push.isSupported();
// reason 'requires-home-screen': on iPhone/iPad, add the app to the Home Screen first

// From a button tap (browsers block permission prompts outside a user gesture):
await fas.push.subscribe(); // asks permission, registers this device

await fas.push.schedule('period-due', { at: new Date('2026-11-02T09:00') });
await fas.push.schedule('log', { daily: '21:00' }, { quietHours: { start: '22:00', end: '07:00' } });
await fas.push.schedule('refill', { everyDays: 28, at: '09:00' }, { tz: 'Europe/London' });

const reminders = await fas.push.list(); // [{ reminderId, when, tz, quietHours, nextAt }]
await fas.push.cancel('log');
await fas.push.unsubscribe(); // this device only
```

错误 : `PushNotSignedInError`, (中文(简体) ), `PushNotSupportedError` (与 `reason`, (中文(简体) ), `PushPermissionDeniedError`, (中文(简体) ), `PushNotConfiguredError`。 。 。 .

推来推去 **无有效载荷**: 您的服务人员会显示通知文本, 所以提醒不会通过浏览器的推取服务 。 带着花花公子 `injectManifest` 策略,请将此添加到您的服务人员中:

```ts
import { registerFasPushHandler } from '@freeappstore/sdk/push-sw';
registerFasPushHandler({ title: 'Cycle', body: 'Time to check in.', onClick: () => '/' });
```

保留任何敏感的文字通用;它可以显示在锁屏幕上. 限制:每个应用程序有10个装置和20个提醒器.

### 反应钩

从 `@freeappstore/sdk/hooks`。要求将18+作为同伴依赖.

```tsx
import { useAuth, useTheme } from '@freeappstore/sdk/hooks';

function App() {
  const { user, loading, signIn, signOut, deleteAccount } = useAuth(fas);
  const { theme, preference, setPreference } = useTheme();
  // ...
}
```

### 应用程序外壳

每个应用程序都包入 `Shell` 从 `@freeappstore/sdk/ui`:上栏(应用程序名称、文本大小、主题、配置页的可视链接),应用程序的主要导航来自 `nav`,以及一个错误的边界,装入倒数,土司区域,离线横幅,并跳过屏幕周围的链接. 浮雕打开 `/profile` gitHub 和 Google 签出时的签入选择,签入时的帐号和首选项。 过 `profileHref` 用于一个应用程序的配置文件路径。 可选的登录门( :`requireAuth`)保护app内容,同时保持配置页面的可访问性.

```tsx
import { type NavItem, PageHeader, Shell, useToast } from '@freeappstore/sdk/ui';

const NAV: NavItem[] = [
  { label: 'Notes', href: '/', title: 'Notes' },
  { label: 'Tags', href: '/tags', title: 'Tags — Notes' },
];

<Shell app={fas} appName="Notes" nav={NAV} onNavigate={navigate}>
  <Screen />
</Shell>

// In a screen: its single h1, and feedback through the shell
<PageHeader title="Tags" />
const toast = useToast(); toast.show('Saved', { variant: 'success' });
```

`onNavigate` 使 nav 点击客户端侧(在路由更改时处理滚动和焦点);没有它,项目就是普通链接. `FasShell` 在其旧名下是同一组成部分。 全文 : [文献/文献](https://npmcn.com/package/docs/ui.md#shell-the-standard-app-frame)。 。 。 .

奥米 `profileHref` 雕像打开了内嵌 `/profile` 页 次`ProfilePage`在两个认证州。 设定 `profileHref` 并让两个州都成为自己. `headerActions` 是标题控制槽。 自定义框架用途 `ToastProvider`, (中文(简体) ), `AccountSection`,以及路由器帮助器,而不是补补壳DOM. `ProfileMenu` 是一个遗留下来. `Shell` 不挂载。 布局属性 : [可混合启动合同](https://npmcn.com/package/docs/composable-starter-contract.md). 移徙: [从 DOM 上移](https://npmcn.com/package/docs/ui.md#migrating-from-dom-overrides)。 。 。 .

### UI 组件

滴入反应组件 。 从 `@freeappstore/sdk/ui`. 组件使用 CSS 自定义属性( :`--ink`, (中文(简体) ), `--accent`)),以融合入您的应用主题.

```tsx
import {
  Shell, PageHeader, NavBar, useToast, useDocumentTitle, useOnline,
  Avatar, SignInButton, ThemeToggle, ProfileMenu, ProfilePage,
  Spinner, Badge, Card, Tabs, Modal, ConfirmDialog, EmptyState,
  ProgressBar, SearchInput, ListRow, ErrorBoundary, KeyPrompt,
} from '@freeappstore/sdk/ui';

// Building blocks
<Spinner size={24} />
<Badge variant="success">Live</Badge>
<Card onClick={fn}>content</Card>
<Tabs tabs={[{key:'a',label:'A'}]} active="a" onChange={setTab} />
<Modal open={show} onClose={close} title="Settings">content</Modal>
<ConfirmDialog open={show} onConfirm={ok} onCancel={cancel} title="Delete?" message="Sure?" variant="danger" />
<EmptyState message="Nothing here yet" />
<ProgressBar value={75} label="Progress" />
<SearchInput value={q} onChange={setQ} />
<ListRow title="Item" subtitle="details" onClick={fn} />
<ErrorBoundary>{children}</ErrorBoundary>
<KeyPrompt app={fas} provider="openai" providerName="OpenAI" />
```

完整文档 : [freeappstore.在线/技能.md](https://freeappstore.online/skills.md)

## 为大赦国际代理

用Claude Code, Cursor, 还是另一个AI工具? 两种选择:

**MCP 服务器( 建议)** -- 您的代理获得工具来检查部署, 查找 SDK 文档, 并列出应用程序 :

```json
{
  "mcpServers": {
    "freeappstore": {
      "command": "npx",
      "args": ["mcp-remote", "https://mcp.freeappstore.online/mcp"]
    }
  }
}
```

**杀手,md** - 完整平台指南(技术堆栈、SDK参考、CLI、部署流量、遵守):

```
https://freeappstore.online/skills.md
```

## 许可证

麻省理工学院.

## 尾风型 (SDK 5.16+)

React UI 需要 Tailwind 4. SDK 样式由您的应用程序编译;它们不是 在运行时注入。 单位 `web/src/index.css`,在 Tailwind 导入后添加:

```css
@source "../node_modules/@freeappstore/sdk/dist";
@source "../../node_modules/@freeappstore/sdk/dist";
```

路径与样式表相对并覆盖了网络局部和root自控安装. 还要加代号 `@theme inline` 绘图和动画键框来自 [样式向导](https://github.com/freeappstore-online/platform/blob/main/docs/ui.md#styling)。 。 。 . 这两个正式模板都包含完整的设置. 浮动 UI 使用不透明 `--popover` (默认) `var(--paper)`(三); `--panel` 不透明,玻璃是选入的.

相接的草稿钩和示例是支持的SDK配方. 犬形生成的相接模板在#350中没有被接通到这个功能;携带起动器接线和被采纳到#352,而不是声称已经生成的模板被改变.

## 临时照片( E)`fas.photos`(中文(简体) )

```ts
const photo = await fas.photos.upload(file, { visibility: 'public' });
// photo.url works in <img>; photo.expiresAt is an epoch timestamp in milliseconds.
await fas.photos.delete(photo.id);
```

奥米 `visibility` 用于私人照片; 使用 `fas.photos.download(id)` 要检索 那些有认证. `fas.photos.list()` 返回您的现场照片. SDK在最长边缘的缩放为 640 px, 重新编码为 JPEG( stripping) 目标为100KB或以下。 服务器独立执行 a 20万字节最大,JPEG/WebP仍为图像,维度和元数据剥取. 每次上传在90天后都会过期,包括私人相片. 上传配额 所有应用程序每天20/用户,100个直播/用户/应用程序和10,000个直播/应用程序,有字节和 应用日用限制也. 这是临时相片存储,不是耐用文件存储. 见 [平台合同](https://npmcn.com/package/docs/photo-uploads.md)。 。 。 .

## 常见问题

### @freeappstore/sdk 是什么？

浏览器 SDK for FreeAppStore — auth, KV, 收藏,柜台,房间,代理,加密的用户密钥,角色,朋友,电子邮件,推取提醒,设备本地持久性,验证的备份和文件导出,React hooks,和UI组件\.

### 如何安装 @freeappstore/sdk？

在项目目录运行 npm install @freeappstore/sdk，或使用 pnpm add / yarn add / bun add。

### @freeappstore/sdk 支持 TypeScript 吗？

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

### @freeappstore/sdk 支持 ESM 还是 CommonJS？

以 ES Module 形式发布，推荐使用 import 引入。在 CommonJS 项目中，Node\.js 20\.19\+ / 22\.12\+ 可以直接 require\(\) 不含顶层 await 的 ES Module，更早的版本需要改用动态 import\(\)。

### @freeappstore/sdk 可以商用吗？

@freeappstore/sdk 使用 MIT 许可。宽松许可：允许商业使用、修改和再分发，通常只需在分发时保留原版权与许可声明。以上为概括，不构成法律意见，请以许可原文为准。

### @freeappstore/sdk 的下载量有多少？

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

### @freeappstore/sdk 还在维护吗？

最新版本 0\.17\.1 发布于 2026/11/14（1 天前）；至今共发布 130 个版本，其中过去 12 个月发布了 130 个；首次发布于 2026/05/05。发布频率只是参考信号：功能稳定的工具可能很少需要更新，建议结合源码仓库的 issue 和提交记录判断。

