@seaverse/data-sdk 0.2.1 → 0.2.2
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/README.md +104 -131
- package/dist/index.cjs +16 -390
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +16 -322
- package/dist/index.js +17 -369
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -5,9 +5,32 @@
|
|
|
5
5
|
|
|
6
6
|
高性能数据服务 SDK,基于 PostgreSQL/AlloyDB + PostgREST + RLS 架构。
|
|
7
7
|
|
|
8
|
-
##
|
|
8
|
+
## ✨ 核心特性:零配置使用
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
**使用 `DataClient.create()` 无需传参!** SDK 会自动通过 PostMessage 协议从父页面获取 `appId` 和 `token`。
|
|
11
|
+
|
|
12
|
+
```typescript
|
|
13
|
+
import { DataClient } from '@seaverse/data-sdk';
|
|
14
|
+
|
|
15
|
+
// 无需任何配置,自动获取!
|
|
16
|
+
const client = await DataClient.create();
|
|
17
|
+
|
|
18
|
+
// 直接使用
|
|
19
|
+
const notes = await client.query({ table: 'notes' });
|
|
20
|
+
const newNote = await client.create({
|
|
21
|
+
table: 'notes',
|
|
22
|
+
data: { title: 'My Note', content: '...' },
|
|
23
|
+
});
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
**工作原理:**
|
|
27
|
+
- 📡 **自动初始化**:`DataClient.create()` 自动向父页面发送 `seaverse:get_token` 和 `seaverse:get_appId` 消息
|
|
28
|
+
- 🔄 **PostMessage 协议**:父页面响应消息,返回配置信息
|
|
29
|
+
- ⚡ **即时可用**:适用于 iframe 嵌入场景和 SeaVerse 平台应用
|
|
30
|
+
|
|
31
|
+
> 💡 **父页面需要监听并响应 PostMessage 请求**(详见 [PostMessage 协议集成](#postmessage-协议集成))
|
|
32
|
+
|
|
33
|
+
## 🚀 App ID 是什么?
|
|
11
34
|
|
|
12
35
|
**App ID** 是您在 SeaVerse 平台上创建的应用的唯一标识符。它用于:
|
|
13
36
|
- ✅ 多租户数据隔离(每个应用的数据互不干扰)
|
|
@@ -31,9 +54,8 @@
|
|
|
31
54
|
- ✅ 完整的错误处理
|
|
32
55
|
- ✅ 支持过滤、排序、分页
|
|
33
56
|
- ✅ 支持标签和 JSONB 字段查询
|
|
34
|
-
- ✅
|
|
35
|
-
- ✅
|
|
36
|
-
- ✅ **函数式 API** - 提供便捷的函数调用方式
|
|
57
|
+
- ✅ **零配置使用** - 自动从 PostMessage 获取配置
|
|
58
|
+
- ✅ **类实例 API** - 清晰的面向对象设计
|
|
37
59
|
|
|
38
60
|
## 安装
|
|
39
61
|
|
|
@@ -43,99 +65,65 @@ npm install @seaverse/data-sdk
|
|
|
43
65
|
|
|
44
66
|
## 快速开始
|
|
45
67
|
|
|
46
|
-
###
|
|
68
|
+
### 方式 1:零配置使用(推荐)
|
|
47
69
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
**适合 SeaVerse 平台应用** - SDK 自动从 PostMessage 获取配置,无需手动初始化
|
|
70
|
+
**最简单的方式 - 无需传参!** SDK 会自动通过 PostMessage 从父页面获取 `appId` 和 `token`。
|
|
51
71
|
|
|
52
72
|
```typescript
|
|
53
|
-
import {
|
|
73
|
+
import { DataClient } from '@seaverse/data-sdk';
|
|
54
74
|
|
|
55
|
-
//
|
|
56
|
-
|
|
75
|
+
// 无需传参,自动获取配置
|
|
76
|
+
const client = await DataClient.create();
|
|
57
77
|
|
|
58
78
|
// 查询数据
|
|
59
|
-
const notes = await query({
|
|
79
|
+
const notes = await client.query({
|
|
60
80
|
table: 'notes',
|
|
61
81
|
filters: { category: 'work' },
|
|
62
82
|
order: { field: 'created_at', direction: 'desc' },
|
|
63
83
|
});
|
|
64
84
|
|
|
65
85
|
// 创建数据
|
|
66
|
-
const newNote = await create({
|
|
86
|
+
const newNote = await client.create({
|
|
67
87
|
table: 'notes',
|
|
68
88
|
data: { title: 'My Note', content: '...' },
|
|
69
89
|
visibility: 'private',
|
|
70
90
|
});
|
|
71
91
|
|
|
72
92
|
// 更新数据
|
|
73
|
-
await update('note-id-123', {
|
|
93
|
+
const updated = await client.update('note-id-123', {
|
|
74
94
|
data: { title: 'Updated' },
|
|
75
95
|
});
|
|
76
96
|
|
|
77
97
|
// 删除数据
|
|
78
|
-
await
|
|
98
|
+
await client.delete('note-id-123');
|
|
79
99
|
```
|
|
80
100
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
import { initData, query } from '@seaverse/data-sdk';
|
|
85
|
-
|
|
86
|
-
// 方式1: 完全自动获取(零配置)
|
|
87
|
-
await initData();
|
|
88
|
-
// appId 和 token 都会自动获取
|
|
89
|
-
|
|
90
|
-
// 方式2: 只提供 appId
|
|
91
|
-
await initData({
|
|
92
|
-
appId: 'my-app-123', // 显式提供
|
|
93
|
-
// token 会自动获取
|
|
94
|
-
});
|
|
101
|
+
> 📡 **自动配置获取**:`DataClient.create()` 会自动向父页面发送 PostMessage 请求获取配置
|
|
102
|
+
> 🎯 **适用场景**:iframe 嵌入应用、SeaVerse 平台应用
|
|
103
|
+
> ⚠️ **前置条件**:父页面需要监听并响应 PostMessage 请求(详见 [PostMessage 协议集成](#postmessage-协议集成))
|
|
95
104
|
|
|
96
|
-
|
|
97
|
-
await initData({
|
|
98
|
-
appId: 'my-app-123',
|
|
99
|
-
token: 'user-jwt-token',
|
|
100
|
-
debug: true,
|
|
101
|
-
});
|
|
102
|
-
|
|
103
|
-
// 然后直接使用
|
|
104
|
-
const notes = await query({ table: 'notes' });
|
|
105
|
-
```
|
|
105
|
+
### 方式 2:显式传参
|
|
106
106
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
**适合需要多个实例或完全自定义配置的场景**
|
|
107
|
+
**适合非 iframe 环境或需要自定义配置的场景**
|
|
110
108
|
|
|
111
109
|
```typescript
|
|
112
110
|
import { DataClient } from '@seaverse/data-sdk';
|
|
113
111
|
|
|
114
|
-
// 方式1:
|
|
115
|
-
const client = await DataClient.create();
|
|
116
|
-
// appId 和 token 都会自动获取
|
|
117
|
-
|
|
118
|
-
// 方式2: 部分配置 + 自动获取
|
|
112
|
+
// 方式 2.1: 显式提供所有配置
|
|
119
113
|
const client = await DataClient.create({
|
|
120
|
-
appId: 'my-app-123', // 显式提供 appId
|
|
121
|
-
// token 会自动获取
|
|
122
|
-
});
|
|
123
|
-
|
|
124
|
-
// 方式3: 显式提供所有配置(传统方式)
|
|
125
|
-
const client = new DataClient({
|
|
126
114
|
appId: 'my-app-123',
|
|
127
115
|
token: 'user-jwt-token',
|
|
128
116
|
});
|
|
129
117
|
|
|
130
|
-
// 方式
|
|
131
|
-
const client =
|
|
118
|
+
// 方式 2.2: 指定环境
|
|
119
|
+
const client = await DataClient.create({
|
|
132
120
|
appId: 'my-app-123',
|
|
133
121
|
token: 'user-jwt-token',
|
|
134
122
|
environment: 'production', // 'production' | 'staging' | 'development' | 'local'
|
|
135
123
|
});
|
|
136
124
|
|
|
137
|
-
// 方式
|
|
138
|
-
const client =
|
|
125
|
+
// 方式 2.3: 自定义 API 地址
|
|
126
|
+
const client = await DataClient.create({
|
|
139
127
|
appId: 'my-app-123',
|
|
140
128
|
token: 'user-jwt-token',
|
|
141
129
|
baseURL: 'https://custom-api.example.com',
|
|
@@ -163,36 +151,50 @@ const notes = await client.query({ table: 'notes' });
|
|
|
163
151
|
> ```
|
|
164
152
|
> 如果启用 `debug: true`,还会打印完整的 token 和详细的配置信息(⚠️ 注意:生产环境建议关闭 debug 模式)。
|
|
165
153
|
|
|
166
|
-
|
|
154
|
+
## 📡 配置自动获取规则
|
|
155
|
+
|
|
156
|
+
### 核心机制
|
|
157
|
+
|
|
158
|
+
**SDK 采用 PostMessage 协议自动获取配置**,首次调用任何 API 时会自动触发:
|
|
159
|
+
|
|
160
|
+
1. **发送请求**:SDK 向父页面发送 `seaverse:get_token` 和 `seaverse:get_appId` 消息
|
|
161
|
+
2. **父页面响应**:父页面监听消息并返回配置信息
|
|
162
|
+
3. **完成初始化**:SDK 接收配置后立即可用
|
|
167
163
|
|
|
168
|
-
|
|
169
|
-
|
|
164
|
+
### 获取优先级
|
|
165
|
+
|
|
166
|
+
**Token 获取优先级:**
|
|
170
167
|
1. 显式传入的 `token` 参数(最高优先级)
|
|
171
168
|
2. PostMessage 从父窗口获取(使用 `seaverse:get_token` 协议)
|
|
172
169
|
|
|
173
|
-
**AppId
|
|
174
|
-
SDK 会按照以下优先级自动获取 appId:
|
|
170
|
+
**AppId 获取优先级:**
|
|
175
171
|
1. 显式传入的 `appId` 参数(最高优先级)
|
|
176
172
|
2. PostMessage 从父窗口获取(使用 `seaverse:get_appId` 协议)
|
|
177
173
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
174
|
+
### PostMessage 协议说明
|
|
175
|
+
|
|
176
|
+
| 协议 | 请求 type | 响应 type | 响应 payload |
|
|
177
|
+
|------|----------|----------|-------------|
|
|
178
|
+
| Token | `seaverse:get_token` | `seaverse:token` | `{ accessToken: string, expiresIn: number }` |
|
|
179
|
+
| AppId | `seaverse:get_appId` | `seaverse:appId` | `{ appId: string }` |
|
|
180
|
+
| 错误 | - | `seaverse:error` | `{ error: string }` |
|
|
181
|
+
|
|
182
|
+
> ⚠️ **重要提示**:
|
|
183
|
+
> - 父页面**必须**监听并响应上述 PostMessage 消息,否则 SDK 无法自动获取配置
|
|
184
|
+
> - 如果父页面未响应,需要显式传入 `appId` 和 `token` 参数
|
|
185
|
+
> - 详细的父页面集成代码请参见 [PostMessage 协议集成](#postmessage-协议集成)
|
|
182
186
|
|
|
183
187
|
## API 文档
|
|
184
188
|
|
|
185
|
-
###
|
|
189
|
+
### 初始化
|
|
186
190
|
|
|
187
191
|
| 方法 | 说明 | 参数 | 返回值 |
|
|
188
192
|
|------|------|------|--------|
|
|
189
|
-
| `
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
| `getCurrentAppId()` | 获取当前 appId | - | `string \| undefined` |
|
|
193
|
-
| `clearConfig()` | 清除全局配置 | - | `void` |
|
|
193
|
+
| `DataClient.create(options?)` | 创建客户端实例(支持零配置) | `DataClientOptions?` | `Promise<DataClient>` |
|
|
194
|
+
|
|
195
|
+
### 数据操作方法
|
|
194
196
|
|
|
195
|
-
|
|
197
|
+
使用 `await DataClient.create()` 创建实例后可用的方法:
|
|
196
198
|
|
|
197
199
|
| 方法 | 说明 | 参数 | 返回值 |
|
|
198
200
|
|------|------|------|--------|
|
|
@@ -200,29 +202,16 @@ SDK 会按照以下优先级自动获取 appId:
|
|
|
200
202
|
| `get(id)` | 获取单条数据 | `id: string` | `Promise<DataRecord \| null>` |
|
|
201
203
|
| `create(options)` | 创建数据 | `CreateDataOptions` | `Promise<DataRecord>` |
|
|
202
204
|
| `update(id, options)` | 更新数据 | `id: string`, `UpdateDataOptions` | `Promise<DataRecord>` |
|
|
203
|
-
| `
|
|
205
|
+
| `delete(id)` | 删除数据 | `id: string` | `Promise<void>` |
|
|
204
206
|
| `batchDelete(ids)` | 批量删除 | `ids: string[]` | `Promise<void>` |
|
|
205
207
|
| `queryWithPagination(options)` | 查询带分页信息 | `QueryOptions` | `Promise<PaginatedResponse<DataRecord>>` |
|
|
206
208
|
| `isAdmin()` | 检查管理员权限 | - | `Promise<boolean>` |
|
|
207
209
|
|
|
208
|
-
###
|
|
209
|
-
|
|
210
|
-
使用 `new DataClient(options)` 创建实例后可用的方法:
|
|
210
|
+
### 配置查询方法
|
|
211
211
|
|
|
212
212
|
| 方法 | 说明 | 参数 | 返回值 |
|
|
213
213
|
|------|------|------|--------|
|
|
214
|
-
| `
|
|
215
|
-
| `get(id)` | 获取单条数据 | `id: string` | `Promise<DataRecord \| null>` |
|
|
216
|
-
| `create(options)` | 创建数据 | `CreateDataOptions` | `Promise<DataRecord>` |
|
|
217
|
-
| `update(id, options)` | 更新数据 | `id: string`, `UpdateDataOptions` | `Promise<DataRecord>` |
|
|
218
|
-
| `delete(id)` | 删除数据 | `id: string` | `Promise<void>` |
|
|
219
|
-
| `batchDelete(ids)` | 批量删除 | `ids: string[]` | `Promise<void>` |
|
|
220
|
-
| `queryWithPagination(options)` | 查询带分页信息 | `QueryOptions` | `Promise<PaginatedResponse<DataRecord>>` |
|
|
221
|
-
| `isAdmin()` | 检查管理员权限 | - | `Promise<boolean>` |
|
|
222
|
-
| `updateToken(token)` | 更新实例 token | `token: string` | `void` |
|
|
223
|
-
| `updateAppId(appId)` | 更新实例 appId | `appId: string` | `void` |
|
|
224
|
-
| `getAppId()` | 获取实例 appId | - | `string` |
|
|
225
|
-
| `getUserId()` | 获取当前用户 ID | - | `string` |
|
|
214
|
+
| `getConfig()` | 获取当前 SDK 配置 | - | `{ appId: string; token: string; url: string }` |
|
|
226
215
|
|
|
227
216
|
### 查询选项(QueryOptions)
|
|
228
217
|
|
|
@@ -483,24 +472,26 @@ const notes = await query({ table: 'notes' });
|
|
|
483
472
|
1. 显式传入的 `token` 参数(最高优先级)
|
|
484
473
|
2. PostMessage 从父窗口获取(使用 `seaverse:get_token` 协议)
|
|
485
474
|
|
|
486
|
-
###
|
|
475
|
+
### 使用场景示例
|
|
487
476
|
|
|
488
477
|
#### React 应用中使用
|
|
489
478
|
|
|
490
479
|
```typescript
|
|
491
|
-
import {
|
|
492
|
-
import { useEffect } from 'react';
|
|
480
|
+
import { DataClient } from '@seaverse/data-sdk';
|
|
481
|
+
import { useEffect, useState } from 'react';
|
|
493
482
|
|
|
494
483
|
function App() {
|
|
484
|
+
const [client, setClient] = useState<DataClient | null>(null);
|
|
485
|
+
|
|
495
486
|
useEffect(() => {
|
|
496
|
-
//
|
|
497
|
-
|
|
498
|
-
initData({ debug: true });
|
|
487
|
+
// 应用启动时初始化 SDK
|
|
488
|
+
DataClient.create({ debug: true }).then(setClient);
|
|
499
489
|
}, []);
|
|
500
490
|
|
|
501
491
|
const loadNotes = async () => {
|
|
502
|
-
|
|
503
|
-
|
|
492
|
+
if (!client) return [];
|
|
493
|
+
|
|
494
|
+
const notes = await client.query({
|
|
504
495
|
table: 'notes',
|
|
505
496
|
order: { field: 'created_at', direction: 'desc' },
|
|
506
497
|
});
|
|
@@ -564,10 +555,11 @@ window.addEventListener('message', (event) => {
|
|
|
564
555
|
**iframe 页面(自动获取):**
|
|
565
556
|
|
|
566
557
|
```typescript
|
|
567
|
-
import {
|
|
558
|
+
import { DataClient } from '@seaverse/data-sdk';
|
|
568
559
|
|
|
569
|
-
//
|
|
570
|
-
const
|
|
560
|
+
// 无需传参,SDK 会自动通过 PostMessage 从父页面获取配置
|
|
561
|
+
const client = await DataClient.create();
|
|
562
|
+
const notes = await client.query({ table: 'notes' });
|
|
571
563
|
```
|
|
572
564
|
|
|
573
565
|
**PostMessage 协议说明:**
|
|
@@ -581,16 +573,16 @@ const notes = await query({ table: 'notes' });
|
|
|
581
573
|
#### 服务端渲染(SSR/SSG)
|
|
582
574
|
|
|
583
575
|
```typescript
|
|
584
|
-
import {
|
|
576
|
+
import { DataClient } from '@seaverse/data-sdk';
|
|
585
577
|
|
|
586
578
|
export async function getServerSideProps() {
|
|
587
579
|
// 服务端需要显式提供配置
|
|
588
|
-
await
|
|
580
|
+
const client = await DataClient.create({
|
|
589
581
|
appId: process.env.APP_ID,
|
|
590
582
|
token: process.env.API_SERVICE_TOKEN,
|
|
591
583
|
});
|
|
592
584
|
|
|
593
|
-
const notes = await query({
|
|
585
|
+
const notes = await client.query({
|
|
594
586
|
table: 'notes',
|
|
595
587
|
filters: { visibility: 'public' },
|
|
596
588
|
});
|
|
@@ -599,37 +591,18 @@ export async function getServerSideProps() {
|
|
|
599
591
|
}
|
|
600
592
|
```
|
|
601
593
|
|
|
602
|
-
###
|
|
594
|
+
### 获取当前配置
|
|
603
595
|
|
|
604
596
|
```typescript
|
|
605
|
-
import {
|
|
606
|
-
|
|
607
|
-
// JWT 过期后更新 token(函数式 API)
|
|
608
|
-
updateToken('new-jwt-token');
|
|
609
|
-
|
|
610
|
-
// 或使用类实例
|
|
611
|
-
client.updateToken('new-jwt-token');
|
|
612
|
-
```
|
|
613
|
-
|
|
614
|
-
### 切换应用
|
|
615
|
-
|
|
616
|
-
```typescript
|
|
617
|
-
import { updateAppId } from '@seaverse/data-sdk';
|
|
618
|
-
|
|
619
|
-
// 切换到其他应用(函数式 API)
|
|
620
|
-
updateAppId('another-app-id');
|
|
621
|
-
|
|
622
|
-
// 或使用类实例
|
|
623
|
-
client.updateAppId('another-app-id');
|
|
624
|
-
```
|
|
625
|
-
|
|
626
|
-
### 清除配置(登出场景)
|
|
597
|
+
import { DataClient } from '@seaverse/data-sdk';
|
|
627
598
|
|
|
628
|
-
|
|
629
|
-
import { clearConfig } from '@seaverse/data-sdk';
|
|
599
|
+
const client = await DataClient.create();
|
|
630
600
|
|
|
631
|
-
//
|
|
632
|
-
|
|
601
|
+
// 获取当前 SDK 配置
|
|
602
|
+
const config = client.getConfig();
|
|
603
|
+
console.log('App ID:', config.appId);
|
|
604
|
+
console.log('Token:', config.token);
|
|
605
|
+
console.log('API URL:', config.url);
|
|
633
606
|
```
|
|
634
607
|
|
|
635
608
|
### JSONB 字段查询
|