@seaverse/data-sdk 0.2.0 → 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 CHANGED
@@ -5,9 +5,32 @@
5
5
 
6
6
  高性能数据服务 SDK,基于 PostgreSQL/AlloyDB + PostgREST + RLS 架构。
7
7
 
8
- ## 🚀 核心概念
8
+ ## 核心特性:零配置使用
9
9
 
10
- ### App ID 是什么?
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
- - ✅ **无缝接入** - 自动从 PostMessage 获取配置
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
- #### 方式 A:函数式 API(推荐 - 零配置)
49
-
50
- **适合 SeaVerse 平台应用** - SDK 自动从 PostMessage 获取配置,无需手动初始化
70
+ **最简单的方式 - 无需传参!** SDK 会自动通过 PostMessage 从父页面获取 `appId` 和 `token`。
51
71
 
52
72
  ```typescript
53
- import { query, create, update, deleteData } from '@seaverse/data-sdk';
73
+ import { DataClient } from '@seaverse/data-sdk';
54
74
 
55
- // 直接使用,无需初始化!
56
- // SDK 自动从 PostMessage 获取配置(需要父页面响应相应的消息)
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 deleteData('note-id-123');
98
+ await client.delete('note-id-123');
79
99
  ```
80
100
 
81
- **可选初始化(如需自定义配置):**
82
-
83
- ```typescript
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
- // 方式3: 完全显式提供
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
- #### 方式 B:类实例 API(传统方式)
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
- // 方式4: 指定环境
131
- const client = new DataClient({
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
- // 方式5: 完全自定义
138
- const client = new DataClient({
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
- **Token 自动获取:**
169
- SDK 会按照以下优先级自动获取 token:
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
- > - data-sdk 通过 PostMessage 协议与父页面通信获取配置
180
- > - 父页面需要监听并响应 `seaverse:get_token` `seaverse:get_appId` 消息
181
- > - 适用于 iframe 嵌入场景,实现安全的跨域配置传递
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
- ### 初始化和配置 API
189
+ ### 初始化
186
190
 
187
191
  | 方法 | 说明 | 参数 | 返回值 |
188
192
  |------|------|------|--------|
189
- | `initData(options?)` | 初始化 SDK(可选) | `Partial<DataClientOptions>` | `Promise<void>` |
190
- | `updateToken(token)` | 更新全局 token | `token: string` | `void` |
191
- | `updateAppId(appId)` | 更新全局 appId | `appId: string` | `void` |
192
- | `getCurrentAppId()` | 获取当前 appId | - | `string \| undefined` |
193
- | `clearConfig()` | 清除全局配置 | - | `void` |
193
+ | `DataClient.create(options?)` | 创建客户端实例(支持零配置) | `DataClientOptions?` | `Promise<DataClient>` |
194
+
195
+ ### 数据操作方法
194
196
 
195
- ### 数据操作 API(函数式)
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
- | `deleteData(id)` | 删除数据 | `id: string` | `Promise<void>` |
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
- ### DataClient 类方法
209
-
210
- 使用 `new DataClient(options)` 创建实例后可用的方法:
210
+ ### 配置查询方法
211
211
 
212
212
  | 方法 | 说明 | 参数 | 返回值 |
213
213
  |------|------|------|--------|
214
- | `query(options)` | 查询数据列表 | `QueryOptions` | `Promise<DataRecord[]>` |
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 { initData, query, create, updateToken } from '@seaverse/data-sdk';
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
- // SDK 会自动通过 PostMessage 从父页面获取配置
498
- initData({ debug: true });
487
+ // 应用启动时初始化 SDK
488
+ DataClient.create({ debug: true }).then(setClient);
499
489
  }, []);
500
490
 
501
491
  const loadNotes = async () => {
502
- // 直接使用,无需传递 client 实例
503
- const notes = await query({
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 { query } from '@seaverse/data-sdk';
558
+ import { DataClient } from '@seaverse/data-sdk';
568
559
 
569
- // 直接使用,SDK 会自动通过 PostMessage 从父页面获取 appId 和 token
570
- const notes = await query({ table: 'notes' });
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 { query, initData } from '@seaverse/data-sdk';
576
+ import { DataClient } from '@seaverse/data-sdk';
585
577
 
586
578
  export async function getServerSideProps() {
587
579
  // 服务端需要显式提供配置
588
- await initData({
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
- ### 动态更新 Token
594
+ ### 获取当前配置
603
595
 
604
596
  ```typescript
605
- import { updateToken } from '@seaverse/data-sdk';
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
- ```typescript
629
- import { clearConfig } from '@seaverse/data-sdk';
599
+ const client = await DataClient.create();
630
600
 
631
- // 用户登出时清除所有配置
632
- clearConfig();
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 字段查询