完善图片画布素材库持久化

新增账号级素材文件夹和素材表,并接入 SpacetimeDB procedure、spacetime-client facade 与 api-server BFF。

编辑器素材栏支持文件夹新建、折叠、重命名、删除、多文件上传、拖拽定向上传、框选和批量删除。

画布支持拖拽上传落点创建图层、图层打组、小地图拖拽、普通滚轮纵向滚动和 Ctrl 滚轮缩放。

更新图片画布技术方案、后端数据契约、TRACKING 和团队决策记录。
This commit is contained in:
2026-06-14 14:29:13 +08:00
parent 6bc2f11d04
commit a6025365f7
43 changed files with 4459 additions and 125 deletions
+8
View File
@@ -2238,3 +2238,11 @@
- 影响范围:主站路由、平台创作入口、图片画布编辑器组件、editor project API client、`api-server` BFF、`spacetime-client` facade、`spacetime-module` 表 / procedure、后端数据契约文档和前端架构文档。
- 验证方式:`npm run test -- src/components/image-editor/ImageCanvasEditorView.test.tsx`、`npm run test -- src/services/image-editor/editorProjectClient.test.ts`、`npm run typecheck`、`cargo check -p spacetime-client --manifest-path server-rs/Cargo.toml`、`cargo check -p api-server --manifest-path server-rs/Cargo.toml`、`npm run check:spacetime-schema`、`npm run check:encoding`、`git diff --check`、headless Playwright smoke。
- 关联文档:`docs/technical/【前端架构】图片画布编辑器MVP接入方案-2026-06-11.md`。
## 2026-06-14 图片画布素材库按账号级持久化
- 背景:图片画布需要 Lovart 式素材管理,素材不应只挂在单个 project 临时状态里;用户在任意项目上传的图片素材,都应作为账号素材库在其它项目中可见,同时画布自身的图层、视图和分组仍属于项目下的画布数据。
- 决策:新增 `editor_asset_folder` / `editor_asset` 作为账号级素材库表,以 `owner_user_id` 为归属;`editor_project` 继续承载工程元数据,`editor_canvas` 继续承载 project 下的画布视图和图层布局,`editor_project_resource` 继续承载具体画布资源引用。素材库 CRUD 统一经 `spacetime-client` facade 和 `/api/editor/assets*` BFF,前端只保留选择模式、框选、拖拽上传、图层打组和小地图拖拽等交互状态,不直接绕过后端持久化。
- 影响范围:`server-rs/crates/spacetime-module/src/editor_project_storage.rs`、`server-rs/crates/spacetime-client/src/editor_project.rs`、`server-rs/crates/api-server/src/editor_project.rs`、`src/services/image-editor/editorProjectClient.ts`、`src/components/image-editor/ImageCanvasEditorView.tsx`、后端数据契约文档和图片画布前端技术方案。
- 验证方式:`npm run spacetime:generate -- --rust-only`、`npm run test -- src/components/image-editor/ImageCanvasEditorView.test.tsx src/services/image-editor/editorProjectClient.test.ts`、`npm run typecheck`、`npm run check:spacetime-schema`、`npm run check:encoding`、`cargo check -p spacetime-client -p api-server --manifest-path server-rs/Cargo.toml`、`git diff --check`。
- 关联文档:`docs/technical/【前端架构】图片画布编辑器MVP接入方案-2026-06-11.md`、`docs/【后端架构】server-rs与SpacetimeDB数据契约-2026-05-15.md`。
+11 -1
View File
@@ -1,6 +1,6 @@
# 图片画布编辑器 Lovart 化执行跟踪
更新时间:`2026-06-13`
更新时间:`2026-06-14`
## 目标
@@ -15,6 +15,8 @@
| 测试用例 | 已完成 | 已补前端交互测试和 editor project client 测试。 |
| 后端持久化 | 已完成 | 已新增 editor project/resource 表、SpacetimeDB procedure、spacetime-client facade 与 api-server BFF。 |
| 前端交互 | 已完成 | 已实现缩放菜单、工具模式、Space 抓手、中键平移、吸附线、元数据弹窗和右侧真实修改结果。 |
| 素材库增强 | 已完成 | 已实现账号级素材库持久化、文件夹新建 / 折叠 / 重命名 / 删除、多文件上传、拖拽定向上传、素材框选与批量删除。 |
| 画布增强 | 已完成 | 已实现拖拽上传到画布并创建图层、图层打组、Ctrl/Cmd 滚轮缩放、普通滚轮纵向滚动和小地图拖拽移动视图。 |
| 验证 | 已完成 | 聚焦测试、类型检查、Rust 检查、schema guard、编码检查、diff 空白检查和浏览器 smoke 已通过。 |
## 待办清单
@@ -34,6 +36,13 @@
- [x] 执行并记录验证命令。
- [x] 新增 `/project` 项目页,接入项目列表、单项重命名 / 删除、批量选择和批量删除。
- [x] 接入“我的”页项目入口与 `/editor/canvas?projectid=<projectId>` 精准加载。
- [x] 新增账号级素材库表、API、前端服务和编辑器接入。
- [x] 素材文件夹支持新建、折叠、重命名和删除。
- [x] 上传按钮与拖拽上传均支持多文件;拖到文件夹 / 素材行进入对应文件夹,拖到画布进入默认文件夹并创建图层。
- [x] 素材选择模式支持框选多选和批量删除。
- [x] 图层面板支持对当前选中图层打组并持久化 groupId。
- [x] 小地图支持拖拽移动画布视图。
- [x] 滚轮语义调整为普通滚轮纵向滚动,Ctrl/Cmd 滚轮缩放并阻止浏览器缩放。
## 决策记录
@@ -85,3 +94,4 @@
- 2026-06-14 组件复用修正:编辑器画布背景色菜单改为复用 `PlatformFloatingMenu` 和 `PlatformFloatingMenuItem`,删除局部菜单容器定位 / 边框 / 阴影样式;验证命令:`npm run test -- src/components/image-editor/ImageCanvasEditorView.test.tsx src/components/common/PlatformFloatingMenu.test.tsx`、`npm run typecheck`、`npm run check:encoding`、`git diff --check`。
- 2026-06-14 组件复用修正:编辑器“修改图片”弹窗提交按钮改为复用 `PlatformActionButton`,删除局部提交按钮颜色、边框和禁用态样式;验证命令:`npm run test -- src/components/image-editor/ImageCanvasEditorView.test.tsx src/components/common/PlatformActionButton.test.tsx`、`npm run typecheck`、`npm run check:encoding`、`git diff --check`。
- 2026-06-14 组件复用修正:项目卡片预览改为复用 `PlatformMediaFrame`,删除项目页局部预览框比例、图片填充和背景样式;验证命令:`npm run test -- src/components/project/ProjectGalleryView.test.tsx src/components/common/PlatformMediaFrame.test.tsx`、`npm run typecheck`、`npm run check:encoding`、`git diff --check`。
- 2026-06-14 素材库与画布持久化修正:新增 `editor_asset_folder` / `editor_asset` 账号级素材库表、SpacetimeDB procedure、spacetime-client facade 和 api-server `/api/editor/assets*` BFF;编辑器接入文件夹新建 / 折叠 / 重命名 / 删除、素材重命名 / 删除、多文件上传、拖拽定向上传、拖入画布生成图层、素材框选批量删除、图层打组、小地图拖拽、普通滚轮纵向滚动与 Ctrl/Cmd 滚轮缩放。验证命令:`npm run spacetime:generate -- --rust-only`、`npm run test -- src/components/image-editor/ImageCanvasEditorView.test.tsx src/services/image-editor/editorProjectClient.test.ts`、`npm run typecheck`、`npm run check:spacetime-schema`、`npm run check:encoding`、`cargo check -p spacetime-client -p api-server --manifest-path server-rs/Cargo.toml`、`git diff --check`。
@@ -35,9 +35,12 @@
- 新增 `editor_project` 表保存图片画布工程:`projectId`、`ownerUserId`、标题、创建时间和更新时间;历史 layout 字段暂保留为兼容列,不再作为权威画布数据。
- 新增 `editor_canvas` 表保存工程下的画布:`canvasId`、`projectId`、`ownerUserId`、标题、viewport、图层布局 JSON、创建时间和更新时间。当前编辑器使用项目默认画布,后续可扩展为一个 project 下多个 canvas。
- 新增 `editor_project_resource` 表保存画布资源:`resourceId`、`projectId`、`ownerUserId`、OSS / asset object 引用、图片尺寸、来源类型、prompt、actualPrompt、model、provider、taskId、sourceResourceId、创建时间和更新时间。
- 新增 `editor_asset_folder` 表保存账号级素材文件夹:`folderId`、`ownerUserId`、名称、排序、折叠状态、系统默认标记、创建时间和更新时间。素材文件夹不归属于 project,同一个账号进入任一项目都能看到。
- 新增 `editor_asset` 表保存账号级素材:`assetId`、`ownerUserId`、`folderId`、名称、图片读取地址、OSS / asset object 引用、图片尺寸、来源类型、prompt、actualPrompt、model、provider、taskId、创建时间和更新时间。素材只跟账号走,不跟 project 走。
- `editor_project_resource` 表保存工程画布引用过的资源快照:`resourceId`、`projectId`、`ownerUserId`、OSS / asset object 引用、图片尺寸、来源类型、prompt、actualPrompt、model、provider、taskId、sourceResourceId、创建时间和更新时间。上传素材被拖入画布时会复制为 project resource,图层只引用 resourceId。
- 图片文件本体继续走 OSS,浏览器读取私有 generated 对象仍经 `/api/assets/read-url` 换签。
- 资源表只保存资源元数据;图层位置、尺寸、缩放、层级和选中所需 ID 保存在 `editor_canvas` 的布局 JSON。
- 当前 MVP 的本地上传先以 data URL 持久化在素材记录中,保证刷新和跨项目可见;后续接入正式 OSS 上传时,只替换 `imageSrc/objectKey/assetObjectId` 的写入方式,账号级素材表和画布资源表不变。
- 资源表只保存资源元数据;图层位置、尺寸、缩放、层级、分组选中所需 ID 和 groupId 保存在 `editor_canvas` 的布局 JSON。图层组第一版是画布内布局语义,不单独建表。
- 前端不直接订阅 SpacetimeDB,统一通过 api-server 的 `/api/editor/projects*` BFF 读写。
- 未登录用户可以使用本地演示态,但不触发工程自动保存;真实图片生成 / 修改需要登录。编辑器 API 请求允许使用 refresh cookie 静默补 access token,但 401 / 403 只在编辑器局部提示登录,不清空整站登录态,也不把后端 requestId 直接作为生图弹窗主文案。
@@ -51,6 +54,13 @@
- `PATCH /api/editor/projects/{projectId}/metadata`:重命名指定工程。
- `DELETE /api/editor/projects/{projectId}`:删除指定工程,并级联删除默认画布和资源元数据。
- `POST /api/editor/projects/{projectId}/resources`:创建画布资源记录,接收上传资源或真实生成资源元数据。
- `GET /api/editor/assets/library`:读取当前账号的素材文件夹和素材。首次读取时自动创建“项目素材”默认文件夹。
- `POST /api/editor/assets/folders`:新建素材文件夹。
- `PATCH /api/editor/assets/folders/{folderId}`:重命名、折叠 / 展开素材文件夹。
- `DELETE /api/editor/assets/folders/{folderId}`:删除素材文件夹;系统默认文件夹不能删除,普通文件夹删除时素材移入默认文件夹。
- `POST /api/editor/assets`:批量或单个创建账号级素材,支持按钮上传和拖拽上传后的 data URL / 后续 OSS 元数据。
- `PATCH /api/editor/assets/{assetId}`:重命名素材或移动素材到文件夹。
- `DELETE /api/editor/assets/{assetId}`:删除素材。已放入画布的 project resource 不被级联删除,避免旧画布丢图。
- `POST /api/editor/images/generations`:按提示词调用 VectorEngine `gpt-image-2` 生成图片,返回 data URL、尺寸、prompt、model、provider 和 taskId。
- `POST /api/editor/images/edits`:按提示词和当前生成图 Data URL 调用 VectorEngine edits,返回新的生成图片元数据。
@@ -74,6 +84,12 @@
- 生成工具点击后显示画布内 `Image Generator` 占位框和跟随占位框的生成输入框,生成失败保留占位和输入状态,生成成功后在占位位置创建真实图层,并让输入框继续跟随该生成图。
- 生成资源显示元数据按钮,元数据窗口展示来源、prompt、model、provider、task、尺寸和 OSS 引用。
- 修改生成资源后,右侧出现新生成结果图层,并自动 fit 原图 + 新图。
- 素材文件夹可以新建、折叠、重命名和删除;删除普通文件夹后,其素材移动到“项目素材”。
- 上传按钮和拖拽上传都支持多文件;拖到文件夹或该文件夹内素材时进入目标文件夹;拖到画布时进入默认文件夹并在投放点创建画布图层。
- 素材面板支持选择模式框选,一次选中多个素材,并可批量移动或删除上传素材。
- 图层面板支持选择多个图层后创建图层组,组名和 groupId 随画布布局保存。
- 小地图支持拖拽视口框,拖动时画布 viewport 跟随移动。
- 鼠标滚轮默认垂直滚动画布视口;按住 Ctrl / Cmd 滚轮才缩放画布,并阻止浏览器页面缩放。
- 工程刷新后能从后端恢复资源、图层布局和 viewport。
- “我的”页项目入口能进入 `/project`;项目页能列出工程、重命名 / 删除单个工程、批量选择和批量删除;点击工程后进入 `/editor/canvas?projectid=<projectId>` 并按 query 加载该工程。
@@ -447,9 +447,23 @@ npm run check:server-rs-ddd
- Rust 结构体:`EditorProjectResource`
- 源码:`server-rs/crates/spacetime-module/src/editor_project_storage.rs`
- 说明:图片画布资源元数据表,保存上传 / 生成 / mock 生成图片的 OSS 引用、尺寸、来源类型、prompt、provider、task 和源资源关系;图片本体仍由资产 / OSS 链路承载。
- 说明:图片画布工程资源元数据表,保存已经放入某个 project 画布的上传 / 生成图片资源快照、OSS 引用、尺寸、来源类型、prompt、provider、task 和源资源关系;账号级素材删除不级联删除该表,避免历史画布丢图。
- 索引:`by_editor_project_resource_project_id`、`by_editor_project_resource_owner_user_id`。
### `editor_asset_folder`
- Rust 结构体:`EditorAssetFolder`
- 源码:`server-rs/crates/spacetime-module/src/editor_project_storage.rs`
- 说明:图片画布账号级素材文件夹表,归属于用户账号而不是 project;首次读取素材库时自动创建系统默认“项目素材”文件夹。文件夹支持重命名、折叠和删除,系统默认文件夹不能删除。
- 索引:`by_editor_asset_folder_owner_user_id`。
### `editor_asset`
- Rust 结构体:`EditorAsset`
- 源码:`server-rs/crates/spacetime-module/src/editor_project_storage.rs`
- 说明:图片画布账号级素材表,保存用户上传 / 生成素材的名称、文件夹、图片读取地址、OSS 引用、尺寸、来源类型和生成元数据;素材在同一账号的所有项目中可见。素材放入画布时复制为 `editor_project_resource` 并由图层引用 resourceId。
- 索引:`by_editor_asset_owner_user_id`、`by_editor_asset_folder_id`。
### `inventory_slot`
- Rust 结构体:`InventorySlot`
@@ -8,8 +8,11 @@ use serde::{Deserialize, Serialize};
use serde_json::{Value, json};
use shared_kernel::build_prefixed_uuid_id;
use spacetime_client::{
EditorCanvasRecord, EditorCanvasViewportRecord, EditorProjectCreateRecordInput,
EditorProjectDeleteRecordInput, EditorProjectGetRecordInput,
EditorAssetCreateRecordInput, EditorAssetDeleteRecordInput, EditorAssetFolderCreateRecordInput,
EditorAssetFolderDeleteRecordInput, EditorAssetFolderRecord, EditorAssetFolderUpdateRecordInput,
EditorAssetLibraryRecord, EditorAssetRecord, EditorAssetUpdateRecordInput, EditorCanvasRecord,
EditorCanvasViewportRecord, EditorProjectCreateRecordInput, EditorProjectDeleteRecordInput,
EditorProjectGetRecordInput,
EditorProjectLayoutSaveRecordInput, EditorProjectRecord, EditorProjectRenameRecordInput,
EditorProjectResourceCreateRecordInput, EditorProjectResourceRecord, SpacetimeClientError,
};
@@ -29,6 +32,8 @@ use crate::{
const EDITOR_PROJECT_ID_PREFIX: &str = "editor-project-";
const EDITOR_RESOURCE_ID_PREFIX: &str = "editor-resource-";
const EDITOR_ASSET_FOLDER_ID_PREFIX: &str = "editor-asset-folder-";
const EDITOR_ASSET_ID_PREFIX: &str = "editor-asset-";
const EDITOR_LAYOUT_MAX_BYTES: usize = 256 * 1024;
const EDITOR_PROJECT_DEFAULT_TITLE: &str = "未命名画布";
const EDITOR_IMAGE_GENERATION_SIZE: &str = "1024x1024";
@@ -77,6 +82,45 @@ pub struct EditorProjectResourceCreateRequest {
source_resource_id: Option<String>,
}
#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct EditorAssetFolderCreateRequest {
label: String,
sort_order: Option<u32>,
}
#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct EditorAssetFolderUpdateRequest {
label: Option<String>,
collapsed: Option<bool>,
}
#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct EditorAssetCreateRequest {
folder_id: String,
label: String,
image_src: String,
object_key: Option<String>,
asset_object_id: Option<String>,
width: u32,
height: u32,
source_type: String,
prompt: Option<String>,
actual_prompt: Option<String>,
model: Option<String>,
provider: Option<String>,
task_id: Option<String>,
}
#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct EditorAssetUpdateRequest {
label: Option<String>,
folder_id: Option<String>,
}
#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct EditorImageGenerationRequest {
@@ -120,6 +164,30 @@ pub struct EditorProjectResourceResponse {
resource: EditorProjectResourcePayload,
}
#[derive(Debug, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct EditorAssetLibraryResponse {
library: EditorAssetLibraryPayload,
}
#[derive(Debug, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct EditorAssetFolderResponse {
folder: EditorAssetFolderPayload,
}
#[derive(Debug, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct EditorAssetFolderDeleteResponse {
library: EditorAssetLibraryPayload,
}
#[derive(Debug, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct EditorAssetResponse {
asset: EditorAssetPayload,
}
#[derive(Debug, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct EditorImageGenerationResponse {
@@ -179,6 +247,46 @@ pub struct EditorProjectResourcePayload {
updated_at: String,
}
#[derive(Debug, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct EditorAssetLibraryPayload {
folders: Vec<EditorAssetFolderPayload>,
assets: Vec<EditorAssetPayload>,
}
#[derive(Debug, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct EditorAssetFolderPayload {
folder_id: String,
label: String,
sort_order: u32,
collapsed: bool,
system_default: bool,
created_at: String,
updated_at: String,
}
#[derive(Debug, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct EditorAssetPayload {
asset_id: String,
folder_id: String,
label: String,
image_src: String,
object_key: Option<String>,
asset_object_id: Option<String>,
width: u32,
height: u32,
source_type: String,
prompt: Option<String>,
actual_prompt: Option<String>,
model: Option<String>,
provider: Option<String>,
task_id: Option<String>,
created_at: String,
updated_at: String,
}
pub async fn load_recent_editor_project(
State(state): State<AppState>,
Extension(request_context): Extension<RequestContext>,
@@ -386,6 +494,189 @@ pub async fn create_editor_project_resource(
))
}
pub async fn get_editor_asset_library(
State(state): State<AppState>,
Extension(request_context): Extension<RequestContext>,
Extension(authenticated): Extension<AuthenticatedAccessToken>,
) -> Result<Json<Value>, AppError> {
let library = state
.spacetime_client()
.get_editor_asset_library(current_owner_user_id(&authenticated), current_utc_micros())
.await
.map_err(map_editor_project_error)?;
Ok(json_success_body(
Some(&request_context),
EditorAssetLibraryResponse {
library: editor_asset_library_payload_from_record(library),
},
))
}
pub async fn create_editor_asset_folder(
State(state): State<AppState>,
Extension(request_context): Extension<RequestContext>,
Extension(authenticated): Extension<AuthenticatedAccessToken>,
Json(payload): Json<EditorAssetFolderCreateRequest>,
) -> Result<Json<Value>, AppError> {
let folder = state
.spacetime_client()
.create_editor_asset_folder(EditorAssetFolderCreateRecordInput {
folder_id: build_prefixed_uuid_id(EDITOR_ASSET_FOLDER_ID_PREFIX),
owner_user_id: current_owner_user_id(&authenticated),
label: payload.label,
sort_order: payload.sort_order.unwrap_or(100),
now_micros: current_utc_micros(),
})
.await
.map_err(map_editor_project_error)?;
Ok(json_success_body(
Some(&request_context),
EditorAssetFolderResponse {
folder: editor_asset_folder_payload_from_record(folder),
},
))
}
pub async fn update_editor_asset_folder(
State(state): State<AppState>,
Path(folder_id): Path<String>,
Extension(request_context): Extension<RequestContext>,
Extension(authenticated): Extension<AuthenticatedAccessToken>,
Json(payload): Json<EditorAssetFolderUpdateRequest>,
) -> Result<Json<Value>, AppError> {
let folder = state
.spacetime_client()
.update_editor_asset_folder(EditorAssetFolderUpdateRecordInput {
folder_id,
owner_user_id: current_owner_user_id(&authenticated),
label: normalize_optional_string(payload.label),
collapsed: payload.collapsed,
updated_at_micros: current_utc_micros(),
})
.await
.map_err(map_editor_project_error)?;
Ok(json_success_body(
Some(&request_context),
EditorAssetFolderResponse {
folder: editor_asset_folder_payload_from_record(folder),
},
))
}
pub async fn delete_editor_asset_folder(
State(state): State<AppState>,
Path(folder_id): Path<String>,
Extension(request_context): Extension<RequestContext>,
Extension(authenticated): Extension<AuthenticatedAccessToken>,
) -> Result<Json<Value>, AppError> {
let library = state
.spacetime_client()
.delete_editor_asset_folder(EditorAssetFolderDeleteRecordInput {
folder_id,
owner_user_id: current_owner_user_id(&authenticated),
updated_at_micros: current_utc_micros(),
})
.await
.map_err(map_editor_project_error)?;
Ok(json_success_body(
Some(&request_context),
EditorAssetFolderDeleteResponse {
library: editor_asset_library_payload_from_record(library),
},
))
}
pub async fn create_editor_asset(
State(state): State<AppState>,
Extension(request_context): Extension<RequestContext>,
Extension(authenticated): Extension<AuthenticatedAccessToken>,
Json(payload): Json<EditorAssetCreateRequest>,
) -> Result<Json<Value>, AppError> {
let asset = state
.spacetime_client()
.create_editor_asset(EditorAssetCreateRecordInput {
asset_id: build_prefixed_uuid_id(EDITOR_ASSET_ID_PREFIX),
owner_user_id: current_owner_user_id(&authenticated),
folder_id: payload.folder_id,
label: payload.label,
asset_object_id: normalize_optional_string(payload.asset_object_id),
image_src: payload.image_src,
object_key: normalize_optional_string(payload.object_key),
width: payload.width,
height: payload.height,
source_type: payload.source_type,
prompt: normalize_optional_string(payload.prompt),
actual_prompt: normalize_optional_string(payload.actual_prompt),
model: normalize_optional_string(payload.model),
provider: normalize_optional_string(payload.provider),
task_id: normalize_optional_string(payload.task_id),
now_micros: current_utc_micros(),
})
.await
.map_err(map_editor_project_error)?;
Ok(json_success_body(
Some(&request_context),
EditorAssetResponse {
asset: editor_asset_payload_from_record(asset),
},
))
}
pub async fn update_editor_asset(
State(state): State<AppState>,
Path(asset_id): Path<String>,
Extension(request_context): Extension<RequestContext>,
Extension(authenticated): Extension<AuthenticatedAccessToken>,
Json(payload): Json<EditorAssetUpdateRequest>,
) -> Result<Json<Value>, AppError> {
let asset = state
.spacetime_client()
.update_editor_asset(EditorAssetUpdateRecordInput {
asset_id,
owner_user_id: current_owner_user_id(&authenticated),
label: normalize_optional_string(payload.label),
folder_id: normalize_optional_string(payload.folder_id),
updated_at_micros: current_utc_micros(),
})
.await
.map_err(map_editor_project_error)?;
Ok(json_success_body(
Some(&request_context),
EditorAssetResponse {
asset: editor_asset_payload_from_record(asset),
},
))
}
pub async fn delete_editor_asset(
State(state): State<AppState>,
Path(asset_id): Path<String>,
Extension(request_context): Extension<RequestContext>,
Extension(authenticated): Extension<AuthenticatedAccessToken>,
) -> Result<Json<Value>, AppError> {
let asset = state
.spacetime_client()
.delete_editor_asset(EditorAssetDeleteRecordInput {
asset_id,
owner_user_id: current_owner_user_id(&authenticated),
})
.await
.map_err(map_editor_project_error)?;
Ok(json_success_body(
Some(&request_context),
EditorAssetResponse {
asset: editor_asset_payload_from_record(asset),
},
))
}
pub async fn generate_editor_image(
State(state): State<AppState>,
Extension(request_context): Extension<RequestContext>,
@@ -576,6 +867,58 @@ fn editor_project_resource_payload_from_record(
}
}
fn editor_asset_library_payload_from_record(
record: EditorAssetLibraryRecord,
) -> EditorAssetLibraryPayload {
EditorAssetLibraryPayload {
folders: record
.folders
.into_iter()
.map(editor_asset_folder_payload_from_record)
.collect(),
assets: record
.assets
.into_iter()
.map(editor_asset_payload_from_record)
.collect(),
}
}
fn editor_asset_folder_payload_from_record(
record: EditorAssetFolderRecord,
) -> EditorAssetFolderPayload {
EditorAssetFolderPayload {
folder_id: record.folder_id,
label: record.label,
sort_order: record.sort_order,
collapsed: record.collapsed,
system_default: record.system_default,
created_at: record.created_at,
updated_at: record.updated_at,
}
}
fn editor_asset_payload_from_record(record: EditorAssetRecord) -> EditorAssetPayload {
EditorAssetPayload {
asset_id: record.asset_id,
folder_id: record.folder_id,
label: record.label,
image_src: record.image_src,
object_key: record.object_key,
asset_object_id: record.asset_object_id,
width: record.width,
height: record.height,
source_type: record.source_type,
prompt: record.prompt,
actual_prompt: record.actual_prompt,
model: record.model,
provider: record.provider,
task_id: record.task_id,
created_at: record.created_at,
updated_at: record.updated_at,
}
}
impl EditorCanvasViewportPayload {
fn into_record(self) -> EditorCanvasViewportRecord {
EditorCanvasViewportRecord {
@@ -586,6 +929,10 @@ impl EditorCanvasViewportPayload {
}
}
fn current_owner_user_id(authenticated: &AuthenticatedAccessToken) -> String {
authenticated.claims().user_id().to_string()
}
fn serialize_editor_layers(layers: Value) -> Result<String, AppError> {
let payload = serde_json::to_string(&layers).map_err(|error| {
AppError::from_status(StatusCode::BAD_REQUEST).with_details(json!({
@@ -6,9 +6,12 @@ use axum::{
use crate::{
auth::require_bearer_auth,
editor_project::{
create_editor_project, create_editor_project_resource, delete_editor_project,
edit_editor_image, generate_editor_image, get_editor_project, list_editor_projects,
create_editor_asset, create_editor_asset_folder, create_editor_project,
create_editor_project_resource, delete_editor_asset, delete_editor_asset_folder,
delete_editor_project, edit_editor_image, generate_editor_image,
get_editor_asset_library, get_editor_project, list_editor_projects,
load_recent_editor_project, rename_editor_project, save_editor_project_layout,
update_editor_asset, update_editor_asset_folder,
},
state::AppState,
};
@@ -55,6 +58,45 @@ pub fn router(state: AppState) -> Router<AppState> {
require_bearer_auth,
)),
)
.route(
"/api/editor/assets/library",
get(get_editor_asset_library).route_layer(middleware::from_fn_with_state(
state.clone(),
require_bearer_auth,
)),
)
.route(
"/api/editor/assets/folders",
post(create_editor_asset_folder).route_layer(middleware::from_fn_with_state(
state.clone(),
require_bearer_auth,
)),
)
.route(
"/api/editor/assets/folders/{folder_id}",
patch(update_editor_asset_folder)
.delete(delete_editor_asset_folder)
.route_layer(middleware::from_fn_with_state(
state.clone(),
require_bearer_auth,
)),
)
.route(
"/api/editor/assets",
post(create_editor_asset).route_layer(middleware::from_fn_with_state(
state.clone(),
require_bearer_auth,
)),
)
.route(
"/api/editor/assets/{asset_id}",
patch(update_editor_asset)
.delete(delete_editor_asset)
.route_layer(middleware::from_fn_with_state(
state.clone(),
require_bearer_auth,
)),
)
.route(
"/api/editor/images/generations",
post(generate_editor_image).route_layer(middleware::from_fn_with_state(
@@ -188,4 +188,174 @@ impl SpacetimeClient {
)
.await
}
pub async fn get_editor_asset_library(
&self,
owner_user_id: String,
now_micros: i64,
) -> Result<EditorAssetLibraryRecord, SpacetimeClientError> {
let procedure_input = EditorAssetLibraryGetInput {
owner_user_id,
now_micros,
};
self.call_after_connect(
"get_editor_asset_library_and_return",
move |connection, sender| {
connection
.procedures()
.get_editor_asset_library_and_return_then(
procedure_input,
move |_, result| {
let mapped = result
.map_err(SpacetimeClientError::from_sdk_error)
.and_then(map_editor_asset_library_procedure_result);
send_once(&sender, mapped);
},
);
},
)
.await
}
pub async fn create_editor_asset_folder(
&self,
input: EditorAssetFolderCreateRecordInput,
) -> Result<EditorAssetFolderRecord, SpacetimeClientError> {
let procedure_input = input.into();
self.call_after_connect(
"create_editor_asset_folder_and_return",
move |connection, sender| {
connection
.procedures()
.create_editor_asset_folder_and_return_then(
procedure_input,
move |_, result| {
let mapped = result
.map_err(SpacetimeClientError::from_sdk_error)
.and_then(map_editor_asset_folder_procedure_result);
send_once(&sender, mapped);
},
);
},
)
.await
}
pub async fn update_editor_asset_folder(
&self,
input: EditorAssetFolderUpdateRecordInput,
) -> Result<EditorAssetFolderRecord, SpacetimeClientError> {
let procedure_input = input.into();
self.call_after_connect(
"update_editor_asset_folder_and_return",
move |connection, sender| {
connection
.procedures()
.update_editor_asset_folder_and_return_then(
procedure_input,
move |_, result| {
let mapped = result
.map_err(SpacetimeClientError::from_sdk_error)
.and_then(map_editor_asset_folder_procedure_result);
send_once(&sender, mapped);
},
);
},
)
.await
}
pub async fn delete_editor_asset_folder(
&self,
input: EditorAssetFolderDeleteRecordInput,
) -> Result<EditorAssetLibraryRecord, SpacetimeClientError> {
let procedure_input = input.into();
self.call_after_connect(
"delete_editor_asset_folder_and_return",
move |connection, sender| {
connection
.procedures()
.delete_editor_asset_folder_and_return_then(
procedure_input,
move |_, result| {
let mapped = result
.map_err(SpacetimeClientError::from_sdk_error)
.and_then(map_editor_asset_folder_library_procedure_result);
send_once(&sender, mapped);
},
);
},
)
.await
}
pub async fn create_editor_asset(
&self,
input: EditorAssetCreateRecordInput,
) -> Result<EditorAssetRecord, SpacetimeClientError> {
let procedure_input = input.into();
self.call_after_connect(
"create_editor_asset_and_return",
move |connection, sender| {
connection
.procedures()
.create_editor_asset_and_return_then(procedure_input, move |_, result| {
let mapped = result
.map_err(SpacetimeClientError::from_sdk_error)
.and_then(map_editor_asset_procedure_result);
send_once(&sender, mapped);
});
},
)
.await
}
pub async fn update_editor_asset(
&self,
input: EditorAssetUpdateRecordInput,
) -> Result<EditorAssetRecord, SpacetimeClientError> {
let procedure_input = input.into();
self.call_after_connect(
"update_editor_asset_and_return",
move |connection, sender| {
connection
.procedures()
.update_editor_asset_and_return_then(procedure_input, move |_, result| {
let mapped = result
.map_err(SpacetimeClientError::from_sdk_error)
.and_then(map_editor_asset_procedure_result);
send_once(&sender, mapped);
});
},
)
.await
}
pub async fn delete_editor_asset(
&self,
input: EditorAssetDeleteRecordInput,
) -> Result<EditorAssetRecord, SpacetimeClientError> {
let procedure_input = input.into();
self.call_after_connect(
"delete_editor_asset_and_return",
move |connection, sender| {
connection
.procedures()
.delete_editor_asset_and_return_then(procedure_input, move |_, result| {
let mapped = result
.map_err(SpacetimeClientError::from_sdk_error)
.and_then(map_editor_asset_procedure_result);
send_once(&sender, mapped);
});
},
)
.await
}
}
+8 -4
View File
@@ -30,10 +30,14 @@ pub use mapper::{
CustomWorldPublishGateRecord, CustomWorldPublishWorldRecord,
CustomWorldPublishWorldRecordInput, CustomWorldPublishedProfileCompileRecord,
CustomWorldResultPreviewBlockerRecord, CustomWorldSupportedActionRecord,
CustomWorldWorkSummaryRecord, EditorCanvasRecord, EditorCanvasViewportRecord,
EditorProjectCreateRecordInput, EditorProjectDeleteRecordInput, EditorProjectGetRecordInput,
EditorProjectLayoutSaveRecordInput, EditorProjectRecord, EditorProjectRenameRecordInput,
EditorProjectResourceCreateRecordInput, EditorProjectResourceRecord,
CustomWorldWorkSummaryRecord, EditorAssetCreateRecordInput, EditorAssetDeleteRecordInput,
EditorAssetFolderCreateRecordInput, EditorAssetFolderDeleteRecordInput,
EditorAssetFolderRecord, EditorAssetFolderUpdateRecordInput, EditorAssetLibraryRecord,
EditorAssetRecord, EditorAssetUpdateRecordInput, EditorCanvasRecord,
EditorCanvasViewportRecord, EditorProjectCreateRecordInput, EditorProjectDeleteRecordInput,
EditorProjectGetRecordInput, EditorProjectLayoutSaveRecordInput, EditorProjectRecord,
EditorProjectRenameRecordInput, EditorProjectResourceCreateRecordInput,
EditorProjectResourceRecord,
ExternalGenerationJobClaimRecordInput,
ExternalGenerationJobCompleteRecordInput, ExternalGenerationJobEnqueueRecordInput,
ExternalGenerationJobFailRecordInput, ExternalGenerationJobGetRecordInput,
@@ -43,8 +43,11 @@ pub use self::combat::{
ResolveCombatActionRecord,
};
pub use self::editor_project::{
EditorCanvasRecord, EditorCanvasViewportRecord, EditorProjectCreateRecordInput,
EditorProjectDeleteRecordInput, EditorProjectGetRecordInput,
EditorAssetCreateRecordInput, EditorAssetDeleteRecordInput, EditorAssetFolderCreateRecordInput,
EditorAssetFolderDeleteRecordInput, EditorAssetFolderRecord, EditorAssetFolderUpdateRecordInput,
EditorAssetLibraryRecord, EditorAssetRecord, EditorAssetUpdateRecordInput, EditorCanvasRecord,
EditorCanvasViewportRecord, EditorProjectCreateRecordInput, EditorProjectDeleteRecordInput,
EditorProjectGetRecordInput,
EditorProjectLayoutSaveRecordInput, EditorProjectRecord, EditorProjectRenameRecordInput,
EditorProjectResourceCreateRecordInput, EditorProjectResourceRecord,
};
@@ -194,9 +197,11 @@ pub(crate) use self::custom_world::{
parse_rpg_agent_stage_record,
};
pub(crate) use self::editor_project::{
map_editor_project_delete_procedure_result, map_editor_project_list_procedure_result,
map_editor_project_optional_procedure_result, map_editor_project_required_procedure_result,
map_editor_project_resource_procedure_result,
map_editor_asset_folder_library_procedure_result,
map_editor_asset_folder_procedure_result, map_editor_asset_library_procedure_result,
map_editor_asset_procedure_result, map_editor_project_delete_procedure_result,
map_editor_project_list_procedure_result, map_editor_project_optional_procedure_result,
map_editor_project_required_procedure_result, map_editor_project_resource_procedure_result,
};
pub(crate) use self::external_generation::{
map_external_generation_job_claim_result, map_external_generation_job_procedure_result,
@@ -51,6 +51,43 @@ pub struct EditorProjectResourceRecord {
pub updated_at: String,
}
#[derive(Clone, Debug, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
pub struct EditorAssetFolderRecord {
pub folder_id: String,
pub label: String,
pub sort_order: u32,
pub collapsed: bool,
pub system_default: bool,
pub created_at: String,
pub updated_at: String,
}
#[derive(Clone, Debug, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
pub struct EditorAssetRecord {
pub asset_id: String,
pub folder_id: String,
pub label: String,
pub asset_object_id: Option<String>,
pub image_src: String,
pub object_key: Option<String>,
pub width: u32,
pub height: u32,
pub source_type: String,
pub prompt: Option<String>,
pub actual_prompt: Option<String>,
pub model: Option<String>,
pub provider: Option<String>,
pub task_id: Option<String>,
pub created_at: String,
pub updated_at: String,
}
#[derive(Clone, Debug, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
pub struct EditorAssetLibraryRecord {
pub folders: Vec<EditorAssetFolderRecord>,
pub assets: Vec<EditorAssetRecord>,
}
#[derive(Clone, Debug, PartialEq)]
pub struct EditorProjectCreateRecordInput {
pub project_id: String,
@@ -108,6 +145,66 @@ pub struct EditorProjectResourceCreateRecordInput {
pub updated_at_micros: i64,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct EditorAssetFolderCreateRecordInput {
pub folder_id: String,
pub owner_user_id: String,
pub label: String,
pub sort_order: u32,
pub now_micros: i64,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct EditorAssetFolderUpdateRecordInput {
pub folder_id: String,
pub owner_user_id: String,
pub label: Option<String>,
pub collapsed: Option<bool>,
pub updated_at_micros: i64,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct EditorAssetFolderDeleteRecordInput {
pub folder_id: String,
pub owner_user_id: String,
pub updated_at_micros: i64,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct EditorAssetCreateRecordInput {
pub asset_id: String,
pub owner_user_id: String,
pub folder_id: String,
pub label: String,
pub asset_object_id: Option<String>,
pub image_src: String,
pub object_key: Option<String>,
pub width: u32,
pub height: u32,
pub source_type: String,
pub prompt: Option<String>,
pub actual_prompt: Option<String>,
pub model: Option<String>,
pub provider: Option<String>,
pub task_id: Option<String>,
pub now_micros: i64,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct EditorAssetUpdateRecordInput {
pub asset_id: String,
pub owner_user_id: String,
pub label: Option<String>,
pub folder_id: Option<String>,
pub updated_at_micros: i64,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct EditorAssetDeleteRecordInput {
pub asset_id: String,
pub owner_user_id: String,
}
impl From<EditorProjectCreateRecordInput> for crate::module_bindings::EditorProjectCreateInput {
fn from(input: EditorProjectCreateRecordInput) -> Self {
Self {
@@ -191,6 +288,90 @@ impl From<EditorProjectResourceCreateRecordInput>
}
}
impl From<EditorAssetFolderCreateRecordInput>
for crate::module_bindings::EditorAssetFolderCreateInput
{
fn from(input: EditorAssetFolderCreateRecordInput) -> Self {
Self {
folder_id: input.folder_id,
owner_user_id: input.owner_user_id,
label: input.label,
sort_order: input.sort_order,
now_micros: input.now_micros,
}
}
}
impl From<EditorAssetFolderUpdateRecordInput>
for crate::module_bindings::EditorAssetFolderUpdateInput
{
fn from(input: EditorAssetFolderUpdateRecordInput) -> Self {
Self {
folder_id: input.folder_id,
owner_user_id: input.owner_user_id,
label: input.label,
collapsed: input.collapsed,
updated_at_micros: input.updated_at_micros,
}
}
}
impl From<EditorAssetFolderDeleteRecordInput>
for crate::module_bindings::EditorAssetFolderDeleteInput
{
fn from(input: EditorAssetFolderDeleteRecordInput) -> Self {
Self {
folder_id: input.folder_id,
owner_user_id: input.owner_user_id,
updated_at_micros: input.updated_at_micros,
}
}
}
impl From<EditorAssetCreateRecordInput> for crate::module_bindings::EditorAssetCreateInput {
fn from(input: EditorAssetCreateRecordInput) -> Self {
Self {
asset_id: input.asset_id,
owner_user_id: input.owner_user_id,
folder_id: input.folder_id,
label: input.label,
asset_object_id: input.asset_object_id,
image_src: input.image_src,
object_key: input.object_key,
width: input.width,
height: input.height,
source_type: input.source_type,
prompt: input.prompt,
actual_prompt: input.actual_prompt,
model: input.model,
provider: input.provider,
task_id: input.task_id,
now_micros: input.now_micros,
}
}
}
impl From<EditorAssetUpdateRecordInput> for crate::module_bindings::EditorAssetUpdateInput {
fn from(input: EditorAssetUpdateRecordInput) -> Self {
Self {
asset_id: input.asset_id,
owner_user_id: input.owner_user_id,
label: input.label,
folder_id: input.folder_id,
updated_at_micros: input.updated_at_micros,
}
}
}
impl From<EditorAssetDeleteRecordInput> for crate::module_bindings::EditorAssetDeleteInput {
fn from(input: EditorAssetDeleteRecordInput) -> Self {
Self {
asset_id: input.asset_id,
owner_user_id: input.owner_user_id,
}
}
}
pub(crate) fn map_editor_project_optional_procedure_result(
result: EditorProjectProcedureResult,
) -> Result<Option<EditorProjectRecord>, SpacetimeClientError> {
@@ -248,6 +429,58 @@ pub(crate) fn map_editor_project_resource_procedure_result(
.ok_or_else(|| SpacetimeClientError::missing_snapshot("图片画布资源快照"))
}
pub(crate) fn map_editor_asset_library_procedure_result(
result: EditorAssetLibraryProcedureResult,
) -> Result<EditorAssetLibraryRecord, SpacetimeClientError> {
if !result.ok {
return Err(SpacetimeClientError::procedure_failed(result.error_message));
}
result
.library
.map(map_editor_asset_library_snapshot)
.ok_or_else(|| SpacetimeClientError::missing_snapshot("图片画布素材库快照"))
}
pub(crate) fn map_editor_asset_folder_procedure_result(
result: EditorAssetFolderProcedureResult,
) -> Result<EditorAssetFolderRecord, SpacetimeClientError> {
if !result.ok {
return Err(SpacetimeClientError::procedure_failed(result.error_message));
}
result
.folder
.map(map_editor_asset_folder_snapshot)
.ok_or_else(|| SpacetimeClientError::missing_snapshot("图片画布素材文件夹快照"))
}
pub(crate) fn map_editor_asset_folder_library_procedure_result(
result: EditorAssetFolderProcedureResult,
) -> Result<EditorAssetLibraryRecord, SpacetimeClientError> {
if !result.ok {
return Err(SpacetimeClientError::procedure_failed(result.error_message));
}
result
.library
.map(map_editor_asset_library_snapshot)
.ok_or_else(|| SpacetimeClientError::missing_snapshot("图片画布素材库快照"))
}
pub(crate) fn map_editor_asset_procedure_result(
result: EditorAssetProcedureResult,
) -> Result<EditorAssetRecord, SpacetimeClientError> {
if !result.ok {
return Err(SpacetimeClientError::procedure_failed(result.error_message));
}
result
.asset
.map(map_editor_asset_snapshot)
.ok_or_else(|| SpacetimeClientError::missing_snapshot("图片画布素材快照"))
}
fn map_editor_project_snapshot(
snapshot: EditorProjectSnapshot,
) -> Result<EditorProjectRecord, SpacetimeClientError> {
@@ -309,3 +542,55 @@ fn map_editor_project_resource_snapshot(
updated_at: format_timestamp_micros(snapshot.updated_at_micros),
}
}
fn map_editor_asset_library_snapshot(
snapshot: EditorAssetLibrarySnapshot,
) -> EditorAssetLibraryRecord {
EditorAssetLibraryRecord {
folders: snapshot
.folders
.into_iter()
.map(map_editor_asset_folder_snapshot)
.collect(),
assets: snapshot
.assets
.into_iter()
.map(map_editor_asset_snapshot)
.collect(),
}
}
fn map_editor_asset_folder_snapshot(
snapshot: EditorAssetFolderSnapshot,
) -> EditorAssetFolderRecord {
EditorAssetFolderRecord {
folder_id: snapshot.folder_id,
label: snapshot.label,
sort_order: snapshot.sort_order,
collapsed: snapshot.collapsed,
system_default: snapshot.system_default,
created_at: format_timestamp_micros(snapshot.created_at_micros),
updated_at: format_timestamp_micros(snapshot.updated_at_micros),
}
}
fn map_editor_asset_snapshot(snapshot: EditorAssetSnapshot) -> EditorAssetRecord {
EditorAssetRecord {
asset_id: snapshot.asset_id,
folder_id: snapshot.folder_id,
label: snapshot.label,
asset_object_id: snapshot.asset_object_id,
image_src: snapshot.image_src,
object_key: snapshot.object_key,
width: snapshot.width,
height: snapshot.height,
source_type: snapshot.source_type,
prompt: snapshot.prompt,
actual_prompt: snapshot.actual_prompt,
model: snapshot.model,
provider: snapshot.provider,
task_id: snapshot.task_id,
created_at: format_timestamp_micros(snapshot.created_at_micros),
updated_at: format_timestamp_micros(snapshot.updated_at_micros),
}
}
@@ -236,6 +236,8 @@ pub mod create_battle_state_and_return_procedure;
pub mod create_battle_state_reducer;
pub mod create_big_fish_session_procedure;
pub mod create_custom_world_agent_session_procedure;
pub mod create_editor_asset_and_return_procedure;
pub mod create_editor_asset_folder_and_return_procedure;
pub mod create_editor_project_and_return_procedure;
pub mod create_editor_project_resource_and_return_procedure;
pub mod create_jump_hop_agent_session_procedure;
@@ -338,6 +340,8 @@ pub mod delete_bark_battle_work_procedure;
pub mod delete_big_fish_work_procedure;
pub mod delete_custom_world_agent_session_procedure;
pub mod delete_custom_world_profile_and_return_procedure;
pub mod delete_editor_asset_and_return_procedure;
pub mod delete_editor_asset_folder_and_return_procedure;
pub mod delete_editor_project_and_return_procedure;
pub mod delete_jump_hop_work_procedure;
pub mod delete_match_3_d_work_procedure;
@@ -348,6 +352,23 @@ pub mod delete_visual_novel_work_procedure;
pub mod delete_wooden_fish_work_procedure;
pub mod drag_puzzle_piece_or_group_procedure;
pub mod drop_square_hole_shape_procedure;
pub mod editor_asset_create_input_type;
pub mod editor_asset_delete_input_type;
pub mod editor_asset_folder_create_input_type;
pub mod editor_asset_folder_delete_input_type;
pub mod editor_asset_folder_procedure_result_type;
pub mod editor_asset_folder_snapshot_type;
pub mod editor_asset_folder_table;
pub mod editor_asset_folder_type;
pub mod editor_asset_folder_update_input_type;
pub mod editor_asset_library_get_input_type;
pub mod editor_asset_library_procedure_result_type;
pub mod editor_asset_library_snapshot_type;
pub mod editor_asset_procedure_result_type;
pub mod editor_asset_snapshot_type;
pub mod editor_asset_table;
pub mod editor_asset_type;
pub mod editor_asset_update_input_type;
pub mod editor_canvas_snapshot_type;
pub mod editor_canvas_table;
pub mod editor_canvas_type;
@@ -414,6 +435,7 @@ pub mod get_custom_world_agent_session_procedure;
pub mod get_custom_world_gallery_detail_by_code_procedure;
pub mod get_custom_world_gallery_detail_procedure;
pub mod get_custom_world_library_detail_procedure;
pub mod get_editor_asset_library_and_return_procedure;
pub mod get_editor_project_and_return_procedure;
pub mod get_external_generation_job_and_return_procedure;
pub mod get_external_generation_queue_stats_and_return_procedure;
@@ -1063,6 +1085,8 @@ pub mod unequip_inventory_item_input_type;
pub mod unpublish_custom_world_profile_and_return_procedure;
pub mod unpublish_custom_world_profile_reducer;
pub mod update_bark_battle_draft_config_procedure;
pub mod update_editor_asset_and_return_procedure;
pub mod update_editor_asset_folder_and_return_procedure;
pub mod update_jump_hop_work_procedure;
pub mod update_match_3_d_work_procedure;
pub mod update_puzzle_clear_work_procedure;
@@ -1402,6 +1426,8 @@ pub use create_battle_state_and_return_procedure::create_battle_state_and_return
pub use create_battle_state_reducer::create_battle_state;
pub use create_big_fish_session_procedure::create_big_fish_session;
pub use create_custom_world_agent_session_procedure::create_custom_world_agent_session;
pub use create_editor_asset_and_return_procedure::create_editor_asset_and_return;
pub use create_editor_asset_folder_and_return_procedure::create_editor_asset_folder_and_return;
pub use create_editor_project_and_return_procedure::create_editor_project_and_return;
pub use create_editor_project_resource_and_return_procedure::create_editor_project_resource_and_return;
pub use create_jump_hop_agent_session_procedure::create_jump_hop_agent_session;
@@ -1504,6 +1530,8 @@ pub use delete_bark_battle_work_procedure::delete_bark_battle_work;
pub use delete_big_fish_work_procedure::delete_big_fish_work;
pub use delete_custom_world_agent_session_procedure::delete_custom_world_agent_session;
pub use delete_custom_world_profile_and_return_procedure::delete_custom_world_profile_and_return;
pub use delete_editor_asset_and_return_procedure::delete_editor_asset_and_return;
pub use delete_editor_asset_folder_and_return_procedure::delete_editor_asset_folder_and_return;
pub use delete_editor_project_and_return_procedure::delete_editor_project_and_return;
pub use delete_jump_hop_work_procedure::delete_jump_hop_work;
pub use delete_match_3_d_work_procedure::delete_match_3_d_work;
@@ -1514,6 +1542,23 @@ pub use delete_visual_novel_work_procedure::delete_visual_novel_work;
pub use delete_wooden_fish_work_procedure::delete_wooden_fish_work;
pub use drag_puzzle_piece_or_group_procedure::drag_puzzle_piece_or_group;
pub use drop_square_hole_shape_procedure::drop_square_hole_shape;
pub use editor_asset_create_input_type::EditorAssetCreateInput;
pub use editor_asset_delete_input_type::EditorAssetDeleteInput;
pub use editor_asset_folder_create_input_type::EditorAssetFolderCreateInput;
pub use editor_asset_folder_delete_input_type::EditorAssetFolderDeleteInput;
pub use editor_asset_folder_procedure_result_type::EditorAssetFolderProcedureResult;
pub use editor_asset_folder_snapshot_type::EditorAssetFolderSnapshot;
pub use editor_asset_folder_table::*;
pub use editor_asset_folder_type::EditorAssetFolder;
pub use editor_asset_folder_update_input_type::EditorAssetFolderUpdateInput;
pub use editor_asset_library_get_input_type::EditorAssetLibraryGetInput;
pub use editor_asset_library_procedure_result_type::EditorAssetLibraryProcedureResult;
pub use editor_asset_library_snapshot_type::EditorAssetLibrarySnapshot;
pub use editor_asset_procedure_result_type::EditorAssetProcedureResult;
pub use editor_asset_snapshot_type::EditorAssetSnapshot;
pub use editor_asset_table::*;
pub use editor_asset_type::EditorAsset;
pub use editor_asset_update_input_type::EditorAssetUpdateInput;
pub use editor_canvas_snapshot_type::EditorCanvasSnapshot;
pub use editor_canvas_table::*;
pub use editor_canvas_type::EditorCanvas;
@@ -1580,6 +1625,7 @@ pub use get_custom_world_agent_session_procedure::get_custom_world_agent_session
pub use get_custom_world_gallery_detail_by_code_procedure::get_custom_world_gallery_detail_by_code;
pub use get_custom_world_gallery_detail_procedure::get_custom_world_gallery_detail;
pub use get_custom_world_library_detail_procedure::get_custom_world_library_detail;
pub use get_editor_asset_library_and_return_procedure::get_editor_asset_library_and_return;
pub use get_editor_project_and_return_procedure::get_editor_project_and_return;
pub use get_external_generation_job_and_return_procedure::get_external_generation_job_and_return;
pub use get_external_generation_queue_stats_and_return_procedure::get_external_generation_queue_stats_and_return;
@@ -2229,6 +2275,8 @@ pub use unequip_inventory_item_input_type::UnequipInventoryItemInput;
pub use unpublish_custom_world_profile_and_return_procedure::unpublish_custom_world_profile_and_return;
pub use unpublish_custom_world_profile_reducer::unpublish_custom_world_profile;
pub use update_bark_battle_draft_config_procedure::update_bark_battle_draft_config;
pub use update_editor_asset_and_return_procedure::update_editor_asset_and_return;
pub use update_editor_asset_folder_and_return_procedure::update_editor_asset_folder_and_return;
pub use update_jump_hop_work_procedure::update_jump_hop_work;
pub use update_match_3_d_work_procedure::update_match_3_d_work;
pub use update_puzzle_clear_work_procedure::update_puzzle_clear_work;
@@ -2649,6 +2697,8 @@ pub struct DbUpdate {
custom_world_session: __sdk::TableUpdate<CustomWorldSession>,
database_migration_import_chunk: __sdk::TableUpdate<DatabaseMigrationImportChunk>,
database_migration_operator: __sdk::TableUpdate<DatabaseMigrationOperator>,
editor_asset: __sdk::TableUpdate<EditorAsset>,
editor_asset_folder: __sdk::TableUpdate<EditorAssetFolder>,
editor_canvas: __sdk::TableUpdate<EditorCanvas>,
editor_project: __sdk::TableUpdate<EditorProject>,
editor_project_resource: __sdk::TableUpdate<EditorProjectResource>,
@@ -2865,6 +2915,12 @@ impl TryFrom<__ws::v2::TransactionUpdate> for DbUpdate {
"database_migration_operator" => db_update.database_migration_operator.append(
database_migration_operator_table::parse_table_update(table_update)?,
),
"editor_asset" => db_update
.editor_asset
.append(editor_asset_table::parse_table_update(table_update)?),
"editor_asset_folder" => db_update
.editor_asset_folder
.append(editor_asset_folder_table::parse_table_update(table_update)?),
"editor_canvas" => db_update
.editor_canvas
.append(editor_canvas_table::parse_table_update(table_update)?),
@@ -3337,6 +3393,15 @@ impl __sdk::DbUpdate for DbUpdate {
&self.database_migration_operator,
)
.with_updates_by_pk(|row| &row.operator_identity);
diff.editor_asset = cache
.apply_diff_to_table::<EditorAsset>("editor_asset", &self.editor_asset)
.with_updates_by_pk(|row| &row.asset_id);
diff.editor_asset_folder = cache
.apply_diff_to_table::<EditorAssetFolder>(
"editor_asset_folder",
&self.editor_asset_folder,
)
.with_updates_by_pk(|row| &row.folder_id);
diff.editor_canvas = cache
.apply_diff_to_table::<EditorCanvas>("editor_canvas", &self.editor_canvas)
.with_updates_by_pk(|row| &row.canvas_id);
@@ -3882,6 +3947,12 @@ impl __sdk::DbUpdate for DbUpdate {
"database_migration_operator" => db_update
.database_migration_operator
.append(__sdk::parse_row_list_as_inserts(table_rows.rows)?),
"editor_asset" => db_update
.editor_asset
.append(__sdk::parse_row_list_as_inserts(table_rows.rows)?),
"editor_asset_folder" => db_update
.editor_asset_folder
.append(__sdk::parse_row_list_as_inserts(table_rows.rows)?),
"editor_canvas" => db_update
.editor_canvas
.append(__sdk::parse_row_list_as_inserts(table_rows.rows)?),
@@ -4261,6 +4332,12 @@ impl __sdk::DbUpdate for DbUpdate {
"database_migration_operator" => db_update
.database_migration_operator
.append(__sdk::parse_row_list_as_deletes(table_rows.rows)?),
"editor_asset" => db_update
.editor_asset
.append(__sdk::parse_row_list_as_deletes(table_rows.rows)?),
"editor_asset_folder" => db_update
.editor_asset_folder
.append(__sdk::parse_row_list_as_deletes(table_rows.rows)?),
"editor_canvas" => db_update
.editor_canvas
.append(__sdk::parse_row_list_as_deletes(table_rows.rows)?),
@@ -4566,6 +4643,8 @@ pub struct AppliedDiff<'r> {
custom_world_session: __sdk::TableAppliedDiff<'r, CustomWorldSession>,
database_migration_import_chunk: __sdk::TableAppliedDiff<'r, DatabaseMigrationImportChunk>,
database_migration_operator: __sdk::TableAppliedDiff<'r, DatabaseMigrationOperator>,
editor_asset: __sdk::TableAppliedDiff<'r, EditorAsset>,
editor_asset_folder: __sdk::TableAppliedDiff<'r, EditorAssetFolder>,
editor_canvas: __sdk::TableAppliedDiff<'r, EditorCanvas>,
editor_project: __sdk::TableAppliedDiff<'r, EditorProject>,
editor_project_resource: __sdk::TableAppliedDiff<'r, EditorProjectResource>,
@@ -4850,6 +4929,16 @@ impl<'r> __sdk::AppliedDiff<'r> for AppliedDiff<'r> {
&self.database_migration_operator,
event,
);
callbacks.invoke_table_row_callbacks::<EditorAsset>(
"editor_asset",
&self.editor_asset,
event,
);
callbacks.invoke_table_row_callbacks::<EditorAssetFolder>(
"editor_asset_folder",
&self.editor_asset_folder,
event,
);
callbacks.invoke_table_row_callbacks::<EditorCanvas>(
"editor_canvas",
&self.editor_canvas,
@@ -5952,6 +6041,8 @@ impl __sdk::SpacetimeModule for RemoteModule {
custom_world_session_table::register_table(client_cache);
database_migration_import_chunk_table::register_table(client_cache);
database_migration_operator_table::register_table(client_cache);
editor_asset_table::register_table(client_cache);
editor_asset_folder_table::register_table(client_cache);
editor_canvas_table::register_table(client_cache);
editor_project_table::register_table(client_cache);
editor_project_resource_table::register_table(client_cache);
@@ -6076,6 +6167,8 @@ impl __sdk::SpacetimeModule for RemoteModule {
"custom_world_session",
"database_migration_import_chunk",
"database_migration_operator",
"editor_asset",
"editor_asset_folder",
"editor_canvas",
"editor_project",
"editor_project_resource",
@@ -0,0 +1,59 @@
// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
#![allow(unused, clippy::all)]
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
use super::editor_asset_create_input_type::EditorAssetCreateInput;
use super::editor_asset_procedure_result_type::EditorAssetProcedureResult;
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
#[sats(crate = __lib)]
struct CreateEditorAssetAndReturnArgs {
pub input: EditorAssetCreateInput,
}
impl __sdk::InModule for CreateEditorAssetAndReturnArgs {
type Module = super::RemoteModule;
}
#[allow(non_camel_case_types)]
/// Extension trait for access to the procedure `create_editor_asset_and_return`.
///
/// Implemented for [`super::RemoteProcedures`].
pub trait create_editor_asset_and_return {
fn create_editor_asset_and_return(&self, input: EditorAssetCreateInput) {
self.create_editor_asset_and_return_then(input, |_, _| {});
}
fn create_editor_asset_and_return_then(
&self,
input: EditorAssetCreateInput,
__callback: impl FnOnce(
&super::ProcedureEventContext,
Result<EditorAssetProcedureResult, __sdk::InternalError>,
) + Send
+ 'static,
);
}
impl create_editor_asset_and_return for super::RemoteProcedures {
fn create_editor_asset_and_return_then(
&self,
input: EditorAssetCreateInput,
__callback: impl FnOnce(
&super::ProcedureEventContext,
Result<EditorAssetProcedureResult, __sdk::InternalError>,
) + Send
+ 'static,
) {
self.imp
.invoke_procedure_with_callback::<_, EditorAssetProcedureResult>(
"create_editor_asset_and_return",
CreateEditorAssetAndReturnArgs { input },
__callback,
);
}
}
@@ -0,0 +1,59 @@
// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
#![allow(unused, clippy::all)]
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
use super::editor_asset_folder_create_input_type::EditorAssetFolderCreateInput;
use super::editor_asset_folder_procedure_result_type::EditorAssetFolderProcedureResult;
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
#[sats(crate = __lib)]
struct CreateEditorAssetFolderAndReturnArgs {
pub input: EditorAssetFolderCreateInput,
}
impl __sdk::InModule for CreateEditorAssetFolderAndReturnArgs {
type Module = super::RemoteModule;
}
#[allow(non_camel_case_types)]
/// Extension trait for access to the procedure `create_editor_asset_folder_and_return`.
///
/// Implemented for [`super::RemoteProcedures`].
pub trait create_editor_asset_folder_and_return {
fn create_editor_asset_folder_and_return(&self, input: EditorAssetFolderCreateInput) {
self.create_editor_asset_folder_and_return_then(input, |_, _| {});
}
fn create_editor_asset_folder_and_return_then(
&self,
input: EditorAssetFolderCreateInput,
__callback: impl FnOnce(
&super::ProcedureEventContext,
Result<EditorAssetFolderProcedureResult, __sdk::InternalError>,
) + Send
+ 'static,
);
}
impl create_editor_asset_folder_and_return for super::RemoteProcedures {
fn create_editor_asset_folder_and_return_then(
&self,
input: EditorAssetFolderCreateInput,
__callback: impl FnOnce(
&super::ProcedureEventContext,
Result<EditorAssetFolderProcedureResult, __sdk::InternalError>,
) + Send
+ 'static,
) {
self.imp
.invoke_procedure_with_callback::<_, EditorAssetFolderProcedureResult>(
"create_editor_asset_folder_and_return",
CreateEditorAssetFolderAndReturnArgs { input },
__callback,
);
}
}
@@ -0,0 +1,59 @@
// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
#![allow(unused, clippy::all)]
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
use super::editor_asset_delete_input_type::EditorAssetDeleteInput;
use super::editor_asset_procedure_result_type::EditorAssetProcedureResult;
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
#[sats(crate = __lib)]
struct DeleteEditorAssetAndReturnArgs {
pub input: EditorAssetDeleteInput,
}
impl __sdk::InModule for DeleteEditorAssetAndReturnArgs {
type Module = super::RemoteModule;
}
#[allow(non_camel_case_types)]
/// Extension trait for access to the procedure `delete_editor_asset_and_return`.
///
/// Implemented for [`super::RemoteProcedures`].
pub trait delete_editor_asset_and_return {
fn delete_editor_asset_and_return(&self, input: EditorAssetDeleteInput) {
self.delete_editor_asset_and_return_then(input, |_, _| {});
}
fn delete_editor_asset_and_return_then(
&self,
input: EditorAssetDeleteInput,
__callback: impl FnOnce(
&super::ProcedureEventContext,
Result<EditorAssetProcedureResult, __sdk::InternalError>,
) + Send
+ 'static,
);
}
impl delete_editor_asset_and_return for super::RemoteProcedures {
fn delete_editor_asset_and_return_then(
&self,
input: EditorAssetDeleteInput,
__callback: impl FnOnce(
&super::ProcedureEventContext,
Result<EditorAssetProcedureResult, __sdk::InternalError>,
) + Send
+ 'static,
) {
self.imp
.invoke_procedure_with_callback::<_, EditorAssetProcedureResult>(
"delete_editor_asset_and_return",
DeleteEditorAssetAndReturnArgs { input },
__callback,
);
}
}
@@ -0,0 +1,59 @@
// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
#![allow(unused, clippy::all)]
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
use super::editor_asset_folder_delete_input_type::EditorAssetFolderDeleteInput;
use super::editor_asset_folder_procedure_result_type::EditorAssetFolderProcedureResult;
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
#[sats(crate = __lib)]
struct DeleteEditorAssetFolderAndReturnArgs {
pub input: EditorAssetFolderDeleteInput,
}
impl __sdk::InModule for DeleteEditorAssetFolderAndReturnArgs {
type Module = super::RemoteModule;
}
#[allow(non_camel_case_types)]
/// Extension trait for access to the procedure `delete_editor_asset_folder_and_return`.
///
/// Implemented for [`super::RemoteProcedures`].
pub trait delete_editor_asset_folder_and_return {
fn delete_editor_asset_folder_and_return(&self, input: EditorAssetFolderDeleteInput) {
self.delete_editor_asset_folder_and_return_then(input, |_, _| {});
}
fn delete_editor_asset_folder_and_return_then(
&self,
input: EditorAssetFolderDeleteInput,
__callback: impl FnOnce(
&super::ProcedureEventContext,
Result<EditorAssetFolderProcedureResult, __sdk::InternalError>,
) + Send
+ 'static,
);
}
impl delete_editor_asset_folder_and_return for super::RemoteProcedures {
fn delete_editor_asset_folder_and_return_then(
&self,
input: EditorAssetFolderDeleteInput,
__callback: impl FnOnce(
&super::ProcedureEventContext,
Result<EditorAssetFolderProcedureResult, __sdk::InternalError>,
) + Send
+ 'static,
) {
self.imp
.invoke_procedure_with_callback::<_, EditorAssetFolderProcedureResult>(
"delete_editor_asset_folder_and_return",
DeleteEditorAssetFolderAndReturnArgs { input },
__callback,
);
}
}
@@ -0,0 +1,30 @@
// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
#![allow(unused, clippy::all)]
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
#[sats(crate = __lib)]
pub struct EditorAssetCreateInput {
pub asset_id: String,
pub owner_user_id: String,
pub folder_id: String,
pub label: String,
pub asset_object_id: Option<String>,
pub image_src: String,
pub object_key: Option<String>,
pub width: u32,
pub height: u32,
pub source_type: String,
pub prompt: Option<String>,
pub actual_prompt: Option<String>,
pub model: Option<String>,
pub provider: Option<String>,
pub task_id: Option<String>,
pub now_micros: i64,
}
impl __sdk::InModule for EditorAssetCreateInput {
type Module = super::RemoteModule;
}
@@ -0,0 +1,16 @@
// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
#![allow(unused, clippy::all)]
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
#[sats(crate = __lib)]
pub struct EditorAssetDeleteInput {
pub asset_id: String,
pub owner_user_id: String,
}
impl __sdk::InModule for EditorAssetDeleteInput {
type Module = super::RemoteModule;
}
@@ -0,0 +1,19 @@
// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
#![allow(unused, clippy::all)]
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
#[sats(crate = __lib)]
pub struct EditorAssetFolderCreateInput {
pub folder_id: String,
pub owner_user_id: String,
pub label: String,
pub sort_order: u32,
pub now_micros: i64,
}
impl __sdk::InModule for EditorAssetFolderCreateInput {
type Module = super::RemoteModule;
}
@@ -0,0 +1,17 @@
// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
#![allow(unused, clippy::all)]
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
#[sats(crate = __lib)]
pub struct EditorAssetFolderDeleteInput {
pub folder_id: String,
pub owner_user_id: String,
pub updated_at_micros: i64,
}
impl __sdk::InModule for EditorAssetFolderDeleteInput {
type Module = super::RemoteModule;
}
@@ -0,0 +1,21 @@
// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
#![allow(unused, clippy::all)]
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
use super::editor_asset_folder_snapshot_type::EditorAssetFolderSnapshot;
use super::editor_asset_library_snapshot_type::EditorAssetLibrarySnapshot;
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
#[sats(crate = __lib)]
pub struct EditorAssetFolderProcedureResult {
pub ok: bool,
pub folder: Option<EditorAssetFolderSnapshot>,
pub library: Option<EditorAssetLibrarySnapshot>,
pub error_message: Option<String>,
}
impl __sdk::InModule for EditorAssetFolderProcedureResult {
type Module = super::RemoteModule;
}
@@ -0,0 +1,21 @@
// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
#![allow(unused, clippy::all)]
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
#[sats(crate = __lib)]
pub struct EditorAssetFolderSnapshot {
pub folder_id: String,
pub label: String,
pub sort_order: u32,
pub collapsed: bool,
pub system_default: bool,
pub created_at_micros: i64,
pub updated_at_micros: i64,
}
impl __sdk::InModule for EditorAssetFolderSnapshot {
type Module = super::RemoteModule;
}
@@ -0,0 +1,161 @@
// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
#![allow(unused, clippy::all)]
use super::editor_asset_folder_type::EditorAssetFolder;
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
/// Table handle for the table `editor_asset_folder`.
///
/// Obtain a handle from the [`EditorAssetFolderTableAccess::editor_asset_folder`] method on [`super::RemoteTables`],
/// like `ctx.db.editor_asset_folder()`.
///
/// Users are encouraged not to explicitly reference this type,
/// but to directly chain method calls,
/// like `ctx.db.editor_asset_folder().on_insert(...)`.
pub struct EditorAssetFolderTableHandle<'ctx> {
imp: __sdk::TableHandle<EditorAssetFolder>,
ctx: std::marker::PhantomData<&'ctx super::RemoteTables>,
}
#[allow(non_camel_case_types)]
/// Extension trait for access to the table `editor_asset_folder`.
///
/// Implemented for [`super::RemoteTables`].
pub trait EditorAssetFolderTableAccess {
#[allow(non_snake_case)]
/// Obtain a [`EditorAssetFolderTableHandle`], which mediates access to the table `editor_asset_folder`.
fn editor_asset_folder(&self) -> EditorAssetFolderTableHandle<'_>;
}
impl EditorAssetFolderTableAccess for super::RemoteTables {
fn editor_asset_folder(&self) -> EditorAssetFolderTableHandle<'_> {
EditorAssetFolderTableHandle {
imp: self
.imp
.get_table::<EditorAssetFolder>("editor_asset_folder"),
ctx: std::marker::PhantomData,
}
}
}
pub struct EditorAssetFolderInsertCallbackId(__sdk::CallbackId);
pub struct EditorAssetFolderDeleteCallbackId(__sdk::CallbackId);
impl<'ctx> __sdk::Table for EditorAssetFolderTableHandle<'ctx> {
type Row = EditorAssetFolder;
type EventContext = super::EventContext;
fn count(&self) -> u64 {
self.imp.count()
}
fn iter(&self) -> impl Iterator<Item = EditorAssetFolder> + '_ {
self.imp.iter()
}
type InsertCallbackId = EditorAssetFolderInsertCallbackId;
fn on_insert(
&self,
callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static,
) -> EditorAssetFolderInsertCallbackId {
EditorAssetFolderInsertCallbackId(self.imp.on_insert(Box::new(callback)))
}
fn remove_on_insert(&self, callback: EditorAssetFolderInsertCallbackId) {
self.imp.remove_on_insert(callback.0)
}
type DeleteCallbackId = EditorAssetFolderDeleteCallbackId;
fn on_delete(
&self,
callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static,
) -> EditorAssetFolderDeleteCallbackId {
EditorAssetFolderDeleteCallbackId(self.imp.on_delete(Box::new(callback)))
}
fn remove_on_delete(&self, callback: EditorAssetFolderDeleteCallbackId) {
self.imp.remove_on_delete(callback.0)
}
}
pub struct EditorAssetFolderUpdateCallbackId(__sdk::CallbackId);
impl<'ctx> __sdk::TableWithPrimaryKey for EditorAssetFolderTableHandle<'ctx> {
type UpdateCallbackId = EditorAssetFolderUpdateCallbackId;
fn on_update(
&self,
callback: impl FnMut(&Self::EventContext, &Self::Row, &Self::Row) + Send + 'static,
) -> EditorAssetFolderUpdateCallbackId {
EditorAssetFolderUpdateCallbackId(self.imp.on_update(Box::new(callback)))
}
fn remove_on_update(&self, callback: EditorAssetFolderUpdateCallbackId) {
self.imp.remove_on_update(callback.0)
}
}
/// Access to the `folder_id` unique index on the table `editor_asset_folder`,
/// which allows point queries on the field of the same name
/// via the [`EditorAssetFolderFolderIdUnique::find`] method.
///
/// Users are encouraged not to explicitly reference this type,
/// but to directly chain method calls,
/// like `ctx.db.editor_asset_folder().folder_id().find(...)`.
pub struct EditorAssetFolderFolderIdUnique<'ctx> {
imp: __sdk::UniqueConstraintHandle<EditorAssetFolder, String>,
phantom: std::marker::PhantomData<&'ctx super::RemoteTables>,
}
impl<'ctx> EditorAssetFolderTableHandle<'ctx> {
/// Get a handle on the `folder_id` unique index on the table `editor_asset_folder`.
pub fn folder_id(&self) -> EditorAssetFolderFolderIdUnique<'ctx> {
EditorAssetFolderFolderIdUnique {
imp: self.imp.get_unique_constraint::<String>("folder_id"),
phantom: std::marker::PhantomData,
}
}
}
impl<'ctx> EditorAssetFolderFolderIdUnique<'ctx> {
/// Find the subscribed row whose `folder_id` column value is equal to `col_val`,
/// if such a row is present in the client cache.
pub fn find(&self, col_val: &String) -> Option<EditorAssetFolder> {
self.imp.find(col_val)
}
}
#[doc(hidden)]
pub(super) fn register_table(client_cache: &mut __sdk::ClientCache<super::RemoteModule>) {
let _table = client_cache.get_or_make_table::<EditorAssetFolder>("editor_asset_folder");
_table.add_unique_constraint::<String>("folder_id", |row| &row.folder_id);
}
#[doc(hidden)]
pub(super) fn parse_table_update(
raw_updates: __ws::v2::TableUpdate,
) -> __sdk::Result<__sdk::TableUpdate<EditorAssetFolder>> {
__sdk::TableUpdate::parse_table_update(raw_updates).map_err(|e| {
__sdk::InternalError::failed_parse("TableUpdate<EditorAssetFolder>", "TableUpdate")
.with_cause(e)
.into()
})
}
#[allow(non_camel_case_types)]
/// Extension trait for query builder access to the table `EditorAssetFolder`.
///
/// Implemented for [`__sdk::QueryTableAccessor`].
pub trait editor_asset_folderQueryTableAccess {
#[allow(non_snake_case)]
/// Get a query builder for the table `EditorAssetFolder`.
fn editor_asset_folder(&self) -> __sdk::__query_builder::Table<EditorAssetFolder>;
}
impl editor_asset_folderQueryTableAccess for __sdk::QueryTableAccessor {
fn editor_asset_folder(&self) -> __sdk::__query_builder::Table<EditorAssetFolder> {
__sdk::__query_builder::Table::new("editor_asset_folder")
}
}
@@ -0,0 +1,72 @@
// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
#![allow(unused, clippy::all)]
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
#[sats(crate = __lib)]
pub struct EditorAssetFolder {
pub folder_id: String,
pub owner_user_id: String,
pub label: String,
pub sort_order: u32,
pub collapsed: bool,
pub system_default: bool,
pub created_at: __sdk::Timestamp,
pub updated_at: __sdk::Timestamp,
}
impl __sdk::InModule for EditorAssetFolder {
type Module = super::RemoteModule;
}
/// Column accessor struct for the table `EditorAssetFolder`.
///
/// Provides typed access to columns for query building.
pub struct EditorAssetFolderCols {
pub folder_id: __sdk::__query_builder::Col<EditorAssetFolder, String>,
pub owner_user_id: __sdk::__query_builder::Col<EditorAssetFolder, String>,
pub label: __sdk::__query_builder::Col<EditorAssetFolder, String>,
pub sort_order: __sdk::__query_builder::Col<EditorAssetFolder, u32>,
pub collapsed: __sdk::__query_builder::Col<EditorAssetFolder, bool>,
pub system_default: __sdk::__query_builder::Col<EditorAssetFolder, bool>,
pub created_at: __sdk::__query_builder::Col<EditorAssetFolder, __sdk::Timestamp>,
pub updated_at: __sdk::__query_builder::Col<EditorAssetFolder, __sdk::Timestamp>,
}
impl __sdk::__query_builder::HasCols for EditorAssetFolder {
type Cols = EditorAssetFolderCols;
fn cols(table_name: &'static str) -> Self::Cols {
EditorAssetFolderCols {
folder_id: __sdk::__query_builder::Col::new(table_name, "folder_id"),
owner_user_id: __sdk::__query_builder::Col::new(table_name, "owner_user_id"),
label: __sdk::__query_builder::Col::new(table_name, "label"),
sort_order: __sdk::__query_builder::Col::new(table_name, "sort_order"),
collapsed: __sdk::__query_builder::Col::new(table_name, "collapsed"),
system_default: __sdk::__query_builder::Col::new(table_name, "system_default"),
created_at: __sdk::__query_builder::Col::new(table_name, "created_at"),
updated_at: __sdk::__query_builder::Col::new(table_name, "updated_at"),
}
}
}
/// Indexed column accessor struct for the table `EditorAssetFolder`.
///
/// Provides typed access to indexed columns for query building.
pub struct EditorAssetFolderIxCols {
pub folder_id: __sdk::__query_builder::IxCol<EditorAssetFolder, String>,
pub owner_user_id: __sdk::__query_builder::IxCol<EditorAssetFolder, String>,
}
impl __sdk::__query_builder::HasIxCols for EditorAssetFolder {
type IxCols = EditorAssetFolderIxCols;
fn ix_cols(table_name: &'static str) -> Self::IxCols {
EditorAssetFolderIxCols {
folder_id: __sdk::__query_builder::IxCol::new(table_name, "folder_id"),
owner_user_id: __sdk::__query_builder::IxCol::new(table_name, "owner_user_id"),
}
}
}
impl __sdk::__query_builder::CanBeLookupTable for EditorAssetFolder {}
@@ -0,0 +1,19 @@
// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
#![allow(unused, clippy::all)]
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
#[sats(crate = __lib)]
pub struct EditorAssetFolderUpdateInput {
pub folder_id: String,
pub owner_user_id: String,
pub label: Option<String>,
pub collapsed: Option<bool>,
pub updated_at_micros: i64,
}
impl __sdk::InModule for EditorAssetFolderUpdateInput {
type Module = super::RemoteModule;
}
@@ -0,0 +1,16 @@
// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
#![allow(unused, clippy::all)]
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
#[sats(crate = __lib)]
pub struct EditorAssetLibraryGetInput {
pub owner_user_id: String,
pub now_micros: i64,
}
impl __sdk::InModule for EditorAssetLibraryGetInput {
type Module = super::RemoteModule;
}

Some files were not shown because too many files have changed in this diff Show More